diff --git a/src/ui/frames.c b/src/ui/frames.c index 3339b1e3f..743e90c1e 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1136,6 +1136,64 @@ meta_frame_right_click_event(MetaUIFrame *frame, return meta_frame_titlebar_event (frame, event, action); } +static gboolean +meta_frames_try_grab_op (MetaFrames *frames, + MetaUIFrame *frame, + MetaGrabOp op, + gdouble grab_x, + gdouble grab_y, + guint32 time) +{ + Display *display; + gboolean ret; + + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + ret = meta_core_begin_grab_op (display, + frame->xwindow, + op, + FALSE, + TRUE, + frame->grab_button, + 0, + time, + grab_x, grab_y); + if (!ret) + { + frames->current_grab_op = op; + frames->grab_frame = frame; + frames->grab_x = grab_x; + frames->grab_y = grab_y; + } + + return ret; +} + +static gboolean +meta_frames_retry_grab_op (MetaFrames *frames, + guint time) +{ + Display *display; + MetaGrabOp op; + + if (frames->current_grab_op == META_GRAB_OP_NONE) + return TRUE; + + op = frames->current_grab_op; + frames->current_grab_op = META_GRAB_OP_NONE; + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + return meta_core_begin_grab_op (display, + frames->grab_frame->xwindow, + op, + FALSE, + TRUE, + frames->grab_frame->grab_button, + 0, + time, + frames->grab_x, + frames->grab_y); +} + static gboolean meta_frames_button_press_event (GtkWidget *widget, GdkEventButton *event) @@ -1190,6 +1248,8 @@ meta_frames_button_press_event (GtkWidget *widget, if (meta_core_get_grab_op (display) != META_GRAB_OP_NONE) return FALSE; /* already up to something */ + frame->grab_button = event->button; + if (event->button == 1 && (control == META_FRAME_CONTROL_MAXIMIZE || control == META_FRAME_CONTROL_UNMAXIMIZE || @@ -1293,16 +1353,9 @@ meta_frames_button_press_event (GtkWidget *widget, break; } - meta_core_begin_grab_op (display, - frame->xwindow, - op, - TRUE, - TRUE, - event->button, - 0, - event->time, - event->x_root, - event->y_root); + meta_frames_try_grab_op (frames, frame, op, + event->x_root, event->y_root, + event->time); } else if (control == META_FRAME_CONTROL_TITLE && event->button == 1) @@ -1315,16 +1368,10 @@ meta_frames_button_press_event (GtkWidget *widget, if (flags & META_FRAME_ALLOWS_MOVE) { - meta_core_begin_grab_op (display, - frame->xwindow, + meta_frames_try_grab_op (frames, frame, META_GRAB_OP_MOVING, - TRUE, - TRUE, - event->button, - 0, - event->time, - event->x_root, - event->y_root); + event->x_root, event->y_root, + event->time); } } else if (event->button == 2) @@ -1349,6 +1396,7 @@ meta_frames_button_release_event (GtkWidget *widget, frames = META_FRAMES (widget); display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + frames->current_grab_op = META_GRAB_OP_NONE; frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); if (frame == NULL) @@ -1560,6 +1608,10 @@ meta_frames_motion_notify_event (GtkWidget *widget, meta_frames_update_prelit_control (frames, frame, control); } + if ((event->state & GDK_BUTTON1_MASK) && + frames->current_grab_op != META_GRAB_OP_NONE) + meta_frames_retry_grab_op (frames, event->time); + return TRUE; } diff --git a/src/ui/frames.h b/src/ui/frames.h index d0af95d68..3a29ffd31 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -100,6 +100,12 @@ struct _MetaFrames GtkStyleContext *normal_style; GHashTable *style_variants; + MetaGrabOp current_grab_op; + MetaUIFrame *grab_frame; + guint grab_button; + gdouble grab_x; + gdouble grab_y; + Window grab_xwindow; }; diff --git a/src/ui/ui.c b/src/ui/ui.c index 4ca859538..1acb70c44 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -221,6 +221,9 @@ maybe_redirect_mouse_event (XEvent *xevent) gevent->motion.time = xev_d->time; gevent->motion.x_root = xev_d->root_x; gevent->motion.y_root = xev_d->root_y; + + if (XIMaskIsSet (xev_d->buttons.mask, 1)) + gevent->motion.state |= GDK_BUTTON1_MASK; break; case XI_Enter: case XI_Leave: