display: Move the pointer event handling code to work in terms of Clutter events

There is now a meta_display_handle_event alongside the
meta_display_handle_xevent function which handles events in terms of
Clutter events instead of X events. A Clutter event filter is
registered so that all Clutter events will pass through this function.
The pointer event handling code from the X event version has been moved
into this new function and has been modified to use the details from
the Clutter event instead of the X event. This is a step towards
moving all of the event handling code over to use Clutter events.

Based-heavily-on-a-patch-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Jasper St. Pierre 2013-10-03 15:29:44 -04:00
parent d69d566087
commit 13a7c8da85
4 changed files with 340 additions and 332 deletions

View File

@ -39,6 +39,7 @@
#include "keybindings-private.h" #include "keybindings-private.h"
#include <meta/prefs.h> #include <meta/prefs.h>
#include <meta/barrier.h> #include <meta/barrier.h>
#include <clutter/clutter.h>
#ifdef HAVE_STARTUP_NOTIFICATION #ifdef HAVE_STARTUP_NOTIFICATION
#include <libsn/sn.h> #include <libsn/sn.h>
@ -189,7 +190,7 @@ struct _MetaDisplay
MetaWindow* autoraise_window; MetaWindow* autoraise_window;
/* Alt+click button grabs */ /* Alt+click button grabs */
unsigned int window_grab_modifiers; ClutterModifierType window_grab_modifiers;
/* current window operation */ /* current window operation */
MetaGrabOp grab_op; MetaGrabOp grab_op;
@ -485,6 +486,9 @@ guint meta_display_get_above_tab_keycode (MetaDisplay *display);
gboolean meta_display_handle_xevent (MetaDisplay *display, gboolean meta_display_handle_xevent (MetaDisplay *display,
XEvent *event); XEvent *event);
gboolean meta_display_handle_event (MetaDisplay *display,
const ClutterEvent *event);
#ifdef HAVE_XI23 #ifdef HAVE_XI23
gboolean meta_display_process_barrier_event (MetaDisplay *display, gboolean meta_display_process_barrier_event (MetaDisplay *display,
XIEvent *event); XIEvent *event);

View File

@ -174,8 +174,10 @@ static void meta_spew_event (MetaDisplay *display,
XEvent *event); XEvent *event);
#endif #endif
static gboolean event_callback (XEvent *event, static gboolean xevent_callback (XEvent *event,
gpointer data); gpointer data);
static gboolean event_callback (const ClutterEvent *event,
gpointer data);
static Window event_get_modified_window (MetaDisplay *display, static Window event_get_modified_window (MetaDisplay *display,
XEvent *event); XEvent *event);
static Window xievent_get_modified_window (MetaDisplay *display, static Window xievent_get_modified_window (MetaDisplay *display,
@ -603,8 +605,9 @@ meta_display_open (void)
/* Get events */ /* Get events */
meta_ui_add_event_func (the_display->xdisplay, meta_ui_add_event_func (the_display->xdisplay,
event_callback, xevent_callback,
the_display); the_display);
clutter_event_add_filter (event_callback, the_display);
the_display->xids = g_hash_table_new (meta_unsigned_long_hash, the_display->xids = g_hash_table_new (meta_unsigned_long_hash,
meta_unsigned_long_equal); meta_unsigned_long_equal);
@ -1134,8 +1137,9 @@ meta_display_close (MetaDisplay *display,
/* Stop caring about events */ /* Stop caring about events */
meta_ui_remove_event_func (display->xdisplay, meta_ui_remove_event_func (display->xdisplay,
event_callback, xevent_callback,
display); display);
clutter_event_remove_filter (event_callback, display);
/* Free all screens */ /* Free all screens */
tmp = display->screens; tmp = display->screens;
@ -1866,6 +1870,32 @@ handle_net_restack_window (MetaDisplay* display,
} }
#endif #endif
static MetaWindow *
get_window_for_actor (ClutterActor *actor,
gboolean *frame_was_receiver)
{
/* Look for any ancestor that is a MetaWindowActor to determine
which window the actor's event belongs to */
*frame_was_receiver = TRUE;
while (actor)
{
if (META_IS_WINDOW_ACTOR (actor))
return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
/* If the frame is the receiver then the source will directly be
the MetaWindowActor, otherwise it will be a child of a
MetaWindowActor so if we make it here then the event isn't
referring to the frame. */
*frame_was_receiver = FALSE;
actor = clutter_actor_get_parent (actor);
}
return NULL;
}
static XIEvent * static XIEvent *
get_input_event (MetaDisplay *display, get_input_event (MetaDisplay *display,
XEvent *event) XEvent *event)
@ -2193,26 +2223,260 @@ handle_window_focus_event (MetaDisplay *display,
} }
} }
gboolean
meta_display_handle_event (MetaDisplay *display,
const ClutterEvent *event)
{
MetaWindow *window;
gboolean frame_was_receiver;
window = get_window_for_actor (event->any.source, &frame_was_receiver);
display->current_time = event->any.time;
if (window && !window->override_redirect && event->type == CLUTTER_BUTTON_PRESS)
{
if (CurrentTime == display->current_time)
{
/* We can't use missing (i.e. invalid) timestamps to set user time,
* nor do we want to use them to sanity check other timestamps.
* See bug 313490 for more details.
*/
meta_warning ("Event has no timestamp! You may be using a broken "
"program such as xse. Please ask the authors of that "
"program to fix it.\n");
}
else
{
meta_window_set_user_time (window, display->current_time);
sanity_check_timestamps (display, display->current_time);
}
}
switch (event->type)
{
case CLUTTER_BUTTON_PRESS:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
display->overlay_key_only_pressed = FALSE;
if ((window &&
meta_grab_op_is_mouse (display->grab_op) &&
(event->button.modifier_state & display->window_grab_modifiers) &&
display->grab_button != (int) event->button.button &&
display->grab_window == window) ||
grab_op_is_keyboard (display->grab_op))
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u on window %s due to button press\n",
display->grab_op,
(display->grab_window ?
display->grab_window->desc :
"none"));
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Syncing to old stack positions.\n");
/* XXX: I'm not sure if this is the right thing to do.
The pre-Wayland code was only calling
meta_stack_set_positions if the modified window was a
root window */
if (event->any.source == CLUTTER_ACTOR (event->any.stage) && window && window->screen)
meta_stack_set_positions (window->screen->stack,
display->grab_old_window_stacking);
}
meta_display_end_grab_op (display,
event->any.time);
}
else if (window && display->grab_op == META_GRAB_OP_NONE)
{
gboolean begin_move = FALSE;
ClutterModifierType grab_mask;
gboolean unmodified;
grab_mask = display->window_grab_modifiers;
if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
grab_mask |= CLUTTER_CONTROL_MASK;
/* Two possible sources of an unmodified event; one is a
* client that's letting button presses pass through to the
* frame, the other is our focus_window_grab on unmodified
* button 1. So for all such events we focus the window.
*/
unmodified = (event->button.modifier_state & grab_mask) == 0;
if (unmodified ||
event->button.button == 1)
{
/* don't focus if frame received, will be lowered in
* frames.c or special-cased if the click was on a
* minimize/close button.
*/
if (!frame_was_receiver)
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
else
meta_topic (META_DEBUG_FOCUS,
"Not raising window on click due to don't-raise-on-click option\n");
/* Don't focus panels--they must explicitly request focus.
* See bug 160470
*/
if (window->type != META_WINDOW_DOCK)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s due to unmodified button %u press (display.c)\n",
window->desc, event->button.button);
meta_window_focus (window, event->any.time);
}
else
/* However, do allow terminals to lose focus due to new
* window mappings after the user clicks on a panel.
*/
display->allow_terminal_deactivation = TRUE;
}
/* you can move on alt-click but not on
* the click-to-focus
*/
if (!unmodified)
begin_move = TRUE;
}
else if (!unmodified && ((int) event->button.button == meta_prefs_get_mouse_button_resize ()))
{
if (window->has_resize_func)
{
gboolean north, south;
gboolean west, east;
int root_x, root_y;
MetaGrabOp op;
meta_window_get_position (window, &root_x, &root_y);
west = event->button.x < (root_x + 1 * window->rect.width / 3);
east = event->button.x > (root_x + 2 * window->rect.width / 3);
north = event->button.y < (root_y + 1 * window->rect.height / 3);
south = event->button.y > (root_y + 2 * window->rect.height / 3);
if (north && west)
op = META_GRAB_OP_RESIZING_NW;
else if (north && east)
op = META_GRAB_OP_RESIZING_NE;
else if (south && west)
op = META_GRAB_OP_RESIZING_SW;
else if (south && east)
op = META_GRAB_OP_RESIZING_SE;
else if (north)
op = META_GRAB_OP_RESIZING_N;
else if (west)
op = META_GRAB_OP_RESIZING_W;
else if (east)
op = META_GRAB_OP_RESIZING_E;
else if (south)
op = META_GRAB_OP_RESIZING_S;
else /* Middle region is no-op to avoid user triggering wrong action */
op = META_GRAB_OP_NONE;
if (op != META_GRAB_OP_NONE)
meta_display_begin_grab_op (display,
window->screen,
window,
op,
TRUE,
FALSE,
event->button.button,
0,
event->any.time,
event->button.x,
event->button.y);
}
}
else if ((int) event->button.button == meta_prefs_get_mouse_button_menu ())
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_show_menu (window,
event->button.x,
event->button.y,
event->button.button,
event->any.time);
}
if (!frame_was_receiver && unmodified)
{
/* This is from our synchronous grab since
* it has no modifiers and was on the client window
*/
meta_verbose ("Allowing events time %u\n",
(unsigned int) event->any.time);
/* XXX -- implement this in Wayland */
XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
XIReplayDevice, event->any.time);
}
if (begin_move && window->has_move_func)
{
meta_display_begin_grab_op (display,
window->screen,
window,
META_GRAB_OP_MOVING,
TRUE,
FALSE,
event->button.button,
0,
event->any.time,
event->button.x,
event->button.y);
}
}
break;
case CLUTTER_BUTTON_RELEASE:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
display->overlay_key_only_pressed = FALSE;
if (display->grab_window == window &&
meta_grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case CLUTTER_MOTION:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
if (display->grab_window == window &&
meta_grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
default:
break;
}
return FALSE;
}
static gboolean static gboolean
handle_input_xevent (MetaDisplay *display, handle_input_xevent (MetaDisplay *display,
XIEvent *input_event, XIEvent *input_event,
gulong serial) gulong serial)
{ {
XIDeviceEvent *device_event = (XIDeviceEvent *) input_event;
XIEnterEvent *enter_event = (XIEnterEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
Window modified; Window modified;
MetaWindow *window; MetaWindow *window;
gboolean frame_was_receiver;
if (input_event == NULL) if (input_event == NULL)
return FALSE; return FALSE;
modified = xievent_get_modified_window (display, input_event); modified = xievent_get_modified_window (display, input_event);
window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL;
frame_was_receiver = (window && window->frame && modified == window->frame->xwindow);
if (window && !window->override_redirect && if (window && !window->override_redirect && input_event->type == XI_KeyPress)
((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress)))
{ {
if (CurrentTime == display->current_time) if (CurrentTime == display->current_time)
{ {
@ -2245,206 +2509,6 @@ handle_input_xevent (MetaDisplay *display,
if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event))
return TRUE; return TRUE;
break; break;
case XI_ButtonPress:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
display->overlay_key_only_pressed = FALSE;
if (device_event->detail == 4 || device_event->detail == 5)
/* Scrollwheel event, do nothing and deliver event to compositor below */
break;
if ((window &&
meta_grab_op_is_mouse (display->grab_op) &&
(device_event->mods.effective & display->window_grab_modifiers) &&
display->grab_button != device_event->detail &&
display->grab_window == window) ||
grab_op_is_keyboard (display->grab_op))
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u on window %s due to button press\n",
display->grab_op,
(display->grab_window ?
display->grab_window->desc :
"none"));
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
{
MetaScreen *screen;
meta_topic (META_DEBUG_WINDOW_OPS,
"Syncing to old stack positions.\n");
screen =
meta_display_screen_for_root (display, device_event->event);
if (screen!=NULL)
meta_stack_set_positions (screen->stack,
display->grab_old_window_stacking);
}
meta_display_end_grab_op (display,
device_event->time);
}
else if (window && display->grab_op == META_GRAB_OP_NONE)
{
gboolean begin_move = FALSE;
unsigned int grab_mask;
gboolean unmodified;
grab_mask = display->window_grab_modifiers;
if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
grab_mask |= ControlMask;
/* Two possible sources of an unmodified event; one is a
* client that's letting button presses pass through to the
* frame, the other is our focus_window_grab on unmodified
* button 1. So for all such events we focus the window.
*/
unmodified = (device_event->mods.effective & grab_mask) == 0;
if (unmodified ||
device_event->detail == 1)
{
/* don't focus if frame received, will be lowered in
* frames.c or special-cased if the click was on a
* minimize/close button.
*/
if (!frame_was_receiver)
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
else
meta_topic (META_DEBUG_FOCUS,
"Not raising window on click due to don't-raise-on-click option\n");
/* Don't focus panels--they must explicitly request focus.
* See bug 160470
*/
if (window->type != META_WINDOW_DOCK)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s due to unmodified button %u press (display.c)\n",
window->desc, device_event->detail);
meta_window_focus (window, device_event->time);
}
else
/* However, do allow terminals to lose focus due to new
* window mappings after the user clicks on a panel.
*/
display->allow_terminal_deactivation = TRUE;
}
/* you can move on alt-click but not on
* the click-to-focus
*/
if (!unmodified)
begin_move = TRUE;
}
else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize())
{
if (window->has_resize_func)
{
gboolean north, south;
gboolean west, east;
int root_x, root_y;
MetaGrabOp op;
meta_window_get_position (window, &root_x, &root_y);
west = device_event->root_x < (root_x + 1 * window->rect.width / 3);
east = device_event->root_x > (root_x + 2 * window->rect.width / 3);
north = device_event->root_y < (root_y + 1 * window->rect.height / 3);
south = device_event->root_y > (root_y + 2 * window->rect.height / 3);
if (north && west)
op = META_GRAB_OP_RESIZING_NW;
else if (north && east)
op = META_GRAB_OP_RESIZING_NE;
else if (south && west)
op = META_GRAB_OP_RESIZING_SW;
else if (south && east)
op = META_GRAB_OP_RESIZING_SE;
else if (north)
op = META_GRAB_OP_RESIZING_N;
else if (west)
op = META_GRAB_OP_RESIZING_W;
else if (east)
op = META_GRAB_OP_RESIZING_E;
else if (south)
op = META_GRAB_OP_RESIZING_S;
else /* Middle region is no-op to avoid user triggering wrong action */
op = META_GRAB_OP_NONE;
if (op != META_GRAB_OP_NONE)
meta_display_begin_grab_op (display,
window->screen,
window,
op,
TRUE,
FALSE,
device_event->detail,
0,
device_event->time,
device_event->root_x,
device_event->root_y);
}
}
else if (device_event->detail == meta_prefs_get_mouse_button_menu())
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_show_menu (window,
device_event->root_x,
device_event->root_y,
device_event->detail,
device_event->time);
}
if (!frame_was_receiver && unmodified)
{
/* This is from our synchronous grab since
* it has no modifiers and was on the client window
*/
meta_verbose ("Allowing events time %u\n",
(unsigned int)device_event->time);
XIAllowEvents (display->xdisplay, device_event->deviceid,
XIReplayDevice, device_event->time);
}
if (begin_move && window->has_move_func)
{
meta_display_begin_grab_op (display,
window->screen,
window,
META_GRAB_OP_MOVING,
TRUE,
FALSE,
device_event->detail,
0,
device_event->time,
device_event->root_x,
device_event->root_y);
}
}
break;
case XI_ButtonRelease:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
display->overlay_key_only_pressed = FALSE;
if (display->grab_window == window &&
meta_grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, device_event);
break;
case XI_Motion:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
if (display->grab_window == window &&
meta_grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, device_event);
break;
case XI_Enter: case XI_Enter:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
@ -3251,8 +3315,8 @@ meta_display_handle_xevent (MetaDisplay *display,
} }
static gboolean static gboolean
event_callback (XEvent *event, xevent_callback (XEvent *event,
gpointer data) gpointer data)
{ {
MetaDisplay *display = data; MetaDisplay *display = data;
@ -3274,6 +3338,15 @@ event_callback (XEvent *event,
return meta_display_handle_xevent (display, event); return meta_display_handle_xevent (display, event);
} }
static gboolean
event_callback (const ClutterEvent *event,
gpointer data)
{
MetaDisplay *display = data;
return meta_display_handle_event (display, event);
}
static Window static Window
xievent_get_modified_window (MetaDisplay *display, xievent_get_modified_window (MetaDisplay *display,
XIEvent *input_event) XIEvent *input_event)

View File

@ -44,6 +44,7 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <cairo.h> #include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf/gdk-pixbuf.h>
#include <clutter/clutter.h>
#include "meta-wayland-types.h" #include "meta-wayland-types.h"
typedef struct _MetaWindowQueue MetaWindowQueue; typedef struct _MetaWindowQueue MetaWindowQueue;
@ -642,8 +643,8 @@ void meta_window_update_sync_request_counter (MetaWindow *window,
gint64 new_counter_value); gint64 new_counter_value);
#endif /* HAVE_XSYNC */ #endif /* HAVE_XSYNC */
void meta_window_handle_mouse_grab_op_event (MetaWindow *window, void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
XIDeviceEvent *xev); const ClutterEvent *event);
GList* meta_window_get_workspaces (MetaWindow *window); GList* meta_window_get_workspaces (MetaWindow *window);

View File

@ -63,6 +63,7 @@
#include <X11/extensions/Xcomposite.h> #include <X11/extensions/Xcomposite.h>
#include "meta-wayland-private.h" #include "meta-wayland-private.h"
#include "meta/compositor-mutter.h"
/* Windows that unmaximize to a size bigger than that fraction of the workarea /* Windows that unmaximize to a size bigger than that fraction of the workarea
* will be scaled down to that size (while maintaining aspect ratio). * will be scaled down to that size (while maintaining aspect ratio).
@ -9901,96 +9902,20 @@ update_resize (MetaWindow *window,
g_get_current_time (&window->display->grab_last_moveresize_time); g_get_current_time (&window->display->grab_last_moveresize_time);
} }
typedef struct
{
Window window;
int count;
guint32 last_time;
} EventScannerData;
static Bool
find_last_time_predicate (Display *display,
XEvent *ev,
XPointer arg)
{
EventScannerData *esd = (void*) arg;
XIEvent *xev;
if (ev->type != GenericEvent)
return False;
/* We are peeking into events not yet handled by GDK,
* Allocate cookie events here so we can handle XI2.
*
* GDK will handle later these events, and eventually
* free the cookie data itself.
*/
XGetEventData (display, &ev->xcookie);
xev = (XIEvent *) ev->xcookie.data;
if (xev->evtype != XI_Motion)
return False;
if (esd->window != ((XIDeviceEvent *) xev)->event)
return False;
esd->count += 1;
esd->last_time = xev->time;
return False;
}
static gboolean static gboolean
check_use_this_motion_notify (MetaWindow *window, check_use_this_motion_notify (MetaWindow *window,
XIDeviceEvent *xev) const ClutterEvent *event)
{ {
EventScannerData esd; /* XXX: Previously this code would walk through the X event queue
XEvent useless; and filter out motion events that are followed by a later motion
event. There currently isn't any API to do the equivalent
/* This code is copied from Owen's GDK code. */ procedure with the Clutter event queue so this function does
nothing. Clutter does its own motion event squashing so it may be
if (window->display->grab_motion_notify_time != 0) the case that this function isn't necessary. If it turns out that
{ we do need additional motion event squashing we could add some
/* == is really the right test, but I'm all for paranoia */ extra API to the Clutter event queue and implement this function
if (window->display->grab_motion_notify_time <= properly. */
xev->time) return TRUE;
{
meta_topic (META_DEBUG_RESIZING,
"Arrived at event with time %u (waiting for %u), using it\n",
(unsigned int)xev->time,
window->display->grab_motion_notify_time);
window->display->grab_motion_notify_time = 0;
return TRUE;
}
else
return FALSE; /* haven't reached the saved timestamp yet */
}
esd.window = xev->event;
esd.count = 0;
esd.last_time = 0;
/* "useless" isn't filled in because the predicate never returns True */
XCheckIfEvent (window->display->xdisplay,
&useless,
find_last_time_predicate,
(XPointer) &esd);
if (esd.count > 0)
meta_topic (META_DEBUG_RESIZING,
"Will skip %d motion events and use the event with time %u\n",
esd.count, (unsigned int) esd.last_time);
if (esd.last_time == 0)
return TRUE;
else
{
/* Save this timestamp, and ignore all motion notify
* until we get to the one with this stamp.
*/
window->display->grab_motion_notify_time = esd.last_time;
return FALSE;
}
} }
static void static void
@ -10064,17 +9989,23 @@ meta_window_update_sync_request_counter (MetaWindow *window,
#endif /* HAVE_XSYNC */ #endif /* HAVE_XSYNC */
void void
meta_window_handle_mouse_grab_op_event (MetaWindow *window, meta_window_handle_mouse_grab_op_event (MetaWindow *window,
XIDeviceEvent *xev) const ClutterEvent *event)
{ {
switch (xev->evtype) gboolean is_window_root = (event->any.stage != NULL &&
window &&
window->screen &&
CLUTTER_ACTOR (event->any.stage) ==
meta_get_stage_for_screen (window->screen));
switch (event->type)
{ {
case XI_ButtonRelease: case CLUTTER_BUTTON_RELEASE:
if (xev->detail == 1) if (event->button.button == 1)
{ {
meta_display_check_threshold_reached (window->display, meta_display_check_threshold_reached (window->display,
xev->root_x, event->button.x,
xev->root_y); event->button.y);
/* If the user was snap moving then ignore the button /* If the user was snap moving then ignore the button
* release because they may have let go of shift before * release because they may have let go of shift before
* releasing the mouse button and they almost certainly do * releasing the mouse button and they almost certainly do
@ -10087,19 +10018,19 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
{ {
if (window->tile_mode != META_TILE_NONE) if (window->tile_mode != META_TILE_NONE)
meta_window_tile (window); meta_window_tile (window);
else if (xev->root == window->screen->xroot) else if (is_window_root)
update_move (window, update_move (window,
xev->mods.effective & ShiftMask, event->button.modifier_state & CLUTTER_SHIFT_MASK,
xev->root_x, event->button.x,
xev->root_y); event->button.y);
} }
else if (meta_grab_op_is_resizing (window->display->grab_op)) else if (meta_grab_op_is_resizing (window->display->grab_op))
{ {
if (xev->root == window->screen->xroot) if (is_window_root)
update_resize (window, update_resize (window,
xev->mods.effective & ShiftMask, event->button.modifier_state & CLUTTER_SHIFT_MASK,
xev->root_x, event->button.x,
xev->root_y, event->button.y,
TRUE); TRUE);
/* If a tiled window has been dragged free with a /* If a tiled window has been dragged free with a
@ -10111,37 +10042,36 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
*/ */
update_tile_mode (window); update_tile_mode (window);
} }
meta_display_end_grab_op (window->display, event->any.time);
} }
meta_display_end_grab_op (window->display, xev->time);
} }
break; break;
case XI_Motion: case CLUTTER_MOTION:
meta_display_check_threshold_reached (window->display, meta_display_check_threshold_reached (window->display,
xev->root_x, event->motion.x,
xev->root_y); event->motion.y);
if (meta_grab_op_is_moving (window->display->grab_op)) if (meta_grab_op_is_moving (window->display->grab_op))
{ {
if (xev->root == window->screen->xroot) if (is_window_root)
{ {
if (check_use_this_motion_notify (window, if (check_use_this_motion_notify (window, event))
xev))
update_move (window, update_move (window,
xev->mods.effective & ShiftMask, event->button.modifier_state & CLUTTER_SHIFT_MASK,
xev->root_x, event->motion.x,
xev->root_y); event->motion.y);
} }
} }
else if (meta_grab_op_is_resizing (window->display->grab_op)) else if (meta_grab_op_is_resizing (window->display->grab_op))
{ {
if (xev->root == window->screen->xroot) if (is_window_root)
{ {
if (check_use_this_motion_notify (window, if (check_use_this_motion_notify (window, event))
xev))
update_resize (window, update_resize (window,
xev->mods.effective & ShiftMask, event->button.modifier_state & CLUTTER_SHIFT_MASK,
xev->root_x, event->motion.x,
xev->root_y, event->motion.y,
FALSE); FALSE);
} }
} }