Port mutter to use XInput2 events instead of Core Events

Mechanically transform the event processing of mutter to care
about XI2 events instead of Core Events. Core Events will be left
in the dust soon, and removed entirely.

https://bugzilla.gnome.org/show_bug.cgi?id=688779
This commit is contained in:
Jasper St. Pierre
2012-11-15 16:35:42 -05:00
parent 881d256ce0
commit 1d827049d6
7 changed files with 394 additions and 349 deletions

View File

@@ -6814,9 +6814,45 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
}
}
void
meta_window_lost_focus (MetaWindow *window)
{
if (window == window->display->focus_window)
{
meta_topic (META_DEBUG_FOCUS,
"%s is now the previous focus window due to being focused out or unmapped\n",
window->desc);
meta_topic (META_DEBUG_FOCUS,
"* Focus --> NULL (was %s)\n", window->desc);
meta_window_propagate_focus_appearance (window, FALSE);
window->display->focus_window = NULL;
g_object_notify (G_OBJECT (window->display), "focus-window");
window->has_focus = FALSE;
if (!window->attached_focus_window)
meta_window_appears_focused_changed (window);
meta_error_trap_push (window->display);
XUninstallColormap (window->display->xdisplay,
window->colormap);
meta_error_trap_pop (window->display);
/* move out of FOCUSED_WINDOW layer */
meta_window_update_layer (window);
/* Re-grab for click to focus and raise-on-click, if necessary */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
!meta_prefs_get_raise_on_click ())
meta_display_grab_focus_window_button (window->display, window);
}
}
gboolean
meta_window_notify_focus (MetaWindow *window,
XEvent *event)
meta_window_notify_focus (MetaWindow *window,
XIEnterEvent *event)
{
/* note the event can be on either the window or the frame,
* we focus the frame for shaded windows
@@ -6839,20 +6875,17 @@ meta_window_notify_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Focus %s event received on %s 0x%lx (%s) "
"mode %s detail %s\n",
event->type == FocusIn ? "in" :
event->type == FocusOut ? "out" :
event->type == UnmapNotify ? "unmap" :
event->evtype == XI_FocusIn ? "in" :
event->evtype == XI_FocusOut ? "out" :
"???",
window->desc, event->xany.window,
event->xany.window == window->xwindow ?
window->desc, event->event,
event->event == window->xwindow ?
"client window" :
(window->frame && event->xany.window == window->frame->xwindow) ?
(window->frame && event->event == window->frame->xwindow) ?
"frame window" :
"unknown window",
event->type != UnmapNotify ?
meta_event_mode_to_string (event->xfocus.mode) : "n/a",
event->type != UnmapNotify ?
meta_event_detail_to_string (event->xfocus.detail) : "n/a");
meta_event_mode_to_string (event->mode),
meta_event_detail_to_string (event->detail));
/* FIXME our pointer tracking is broken; see how
* gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c
@@ -6873,19 +6906,19 @@ meta_window_notify_focus (MetaWindow *window,
* http://bugzilla.gnome.org/show_bug.cgi?id=90382
*/
if ((event->type == FocusIn ||
event->type == FocusOut) &&
(event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab ||
if ((event->evtype == XI_FocusIn ||
event->evtype == XI_FocusOut) &&
(event->mode == NotifyGrab ||
event->mode == NotifyUngrab ||
/* From WindowMaker, ignore all funky pointer root events */
event->xfocus.detail > NotifyNonlinearVirtual))
event->detail > NotifyNonlinearVirtual))
{
meta_topic (META_DEBUG_FOCUS,
"Ignoring focus event generated by a grab or other weirdness\n");
return TRUE;
}
if (event->type == FocusIn)
if (event->evtype == XI_FocusIn)
{
if (window->override_redirect)
{
@@ -6965,11 +6998,9 @@ meta_window_notify_focus (MetaWindow *window,
meta_window_propagate_focus_appearance (window, TRUE);
}
}
else if (event->type == FocusOut ||
event->type == UnmapNotify)
else if (event->evtype == XI_FocusOut)
{
if (event->type == FocusOut &&
event->xfocus.detail == NotifyInferior)
if (event->detail == NotifyInferior)
{
/* This event means the client moved focus to a subwindow */
meta_topic (META_DEBUG_FOCUS,
@@ -6977,38 +7008,10 @@ meta_window_notify_focus (MetaWindow *window,
window->desc);
return TRUE;
}
if (window == window->display->focus_window)
else
{
meta_topic (META_DEBUG_FOCUS,
"%s is now the previous focus window due to being focused out or unmapped\n",
window->desc);
meta_topic (META_DEBUG_FOCUS,
"* Focus --> NULL (was %s)\n", window->desc);
meta_window_propagate_focus_appearance (window, FALSE);
window->display->focus_window = NULL;
g_object_notify (G_OBJECT (window->display), "focus-window");
window->has_focus = FALSE;
if (!window->attached_focus_window)
meta_window_appears_focused_changed (window);
meta_error_trap_push (window->display);
XUninstallColormap (window->display->xdisplay,
window->colormap);
meta_error_trap_pop (window->display);
/* move out of FOCUSED_WINDOW layer */
meta_window_update_layer (window);
/* Re-grab for click to focus and raise-on-click, if necessary */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
!meta_prefs_get_raise_on_click ())
meta_display_grab_focus_window_button (window->display, window);
}
meta_window_lost_focus (window);
}
}
/* Now set _NET_ACTIVE_WINDOW hint */
@@ -9133,31 +9136,46 @@ update_resize (MetaWindow *window,
typedef struct
{
const XEvent *current_event;
int count;
guint32 last_time;
Window window;
int count;
guint32 last_time;
} EventScannerData;
static Bool
find_last_time_predicate (Display *display,
XEvent *xevent,
XEvent *ev,
XPointer arg)
{
EventScannerData *esd = (void*) arg;
XIEvent *xev;
if (esd->current_event->type == xevent->type &&
esd->current_event->xany.window == xevent->xany.window)
{
esd->count += 1;
esd->last_time = xevent->xmotion.time;
}
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
check_use_this_motion_notify (MetaWindow *window,
XEvent *event)
XIDeviceEvent *xev)
{
EventScannerData esd;
XEvent useless;
@@ -9168,11 +9186,11 @@ check_use_this_motion_notify (MetaWindow *window,
{
/* == is really the right test, but I'm all for paranoia */
if (window->display->grab_motion_notify_time <=
event->xmotion.time)
xev->time)
{
meta_topic (META_DEBUG_RESIZING,
"Arrived at event with time %u (waiting for %u), using it\n",
(unsigned int)event->xmotion.time,
(unsigned int)xev->time,
window->display->grab_motion_notify_time);
window->display->grab_motion_notify_time = 0;
return TRUE;
@@ -9181,7 +9199,7 @@ check_use_this_motion_notify (MetaWindow *window,
return FALSE; /* haven't reached the saved timestamp yet */
}
esd.current_event = event;
esd.window = xev->event;
esd.count = 0;
esd.last_time = 0;
@@ -9284,14 +9302,14 @@ meta_window_update_sync_request_counter (MetaWindow *window,
void
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
XEvent *event)
XIDeviceEvent *xev)
{
switch (event->type)
switch (xev->evtype)
{
case ButtonRelease:
case XI_ButtonRelease:
meta_display_check_threshold_reached (window->display,
event->xbutton.x_root,
event->xbutton.y_root);
xev->root_x,
xev->root_y);
/* If the user was snap moving then ignore the button release
* because they may have let go of shift before releasing the
* mouse button and they almost certainly do not want a
@@ -9303,17 +9321,19 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
{
if (window->tile_mode != META_TILE_NONE)
meta_window_tile (window);
else if (event->xbutton.root == window->screen->xroot)
update_move (window, event->xbutton.state & ShiftMask,
event->xbutton.x_root, event->xbutton.y_root);
else if (xev->root == window->screen->xroot)
update_move (window,
xev->mods.effective & ShiftMask,
xev->root_x,
xev->root_y);
}
else if (meta_grab_op_is_resizing (window->display->grab_op))
{
if (event->xbutton.root == window->screen->xroot)
if (xev->root == window->screen->xroot)
update_resize (window,
event->xbutton.state & ShiftMask,
event->xbutton.x_root,
event->xbutton.y_root,
xev->mods.effective & ShiftMask,
xev->root_x,
xev->root_y,
TRUE);
if (window->display->compositor)
meta_compositor_set_updates (window->display->compositor, window, TRUE);
@@ -9329,35 +9349,35 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
}
}
meta_display_end_grab_op (window->display, event->xbutton.time);
meta_display_end_grab_op (window->display, xev->time);
break;
case MotionNotify:
case XI_Motion:
meta_display_check_threshold_reached (window->display,
event->xmotion.x_root,
event->xmotion.y_root);
xev->root_x,
xev->root_y);
if (meta_grab_op_is_moving (window->display->grab_op))
{
if (event->xmotion.root == window->screen->xroot)
if (xev->root == window->screen->xroot)
{
if (check_use_this_motion_notify (window,
event))
xev))
update_move (window,
event->xmotion.state & ShiftMask,
event->xmotion.x_root,
event->xmotion.y_root);
xev->mods.effective & ShiftMask,
xev->root_x,
xev->root_y);
}
}
else if (meta_grab_op_is_resizing (window->display->grab_op))
{
if (event->xmotion.root == window->screen->xroot)
if (xev->root == window->screen->xroot)
{
if (check_use_this_motion_notify (window,
event))
xev))
update_resize (window,
event->xmotion.state & ShiftMask,
event->xmotion.x_root,
event->xmotion.y_root,
xev->mods.effective & ShiftMask,
xev->root_x,
xev->root_y,
FALSE);
}
}