[mutter/wip/xinput2b: 12/22] Port mutter to use XInput2 events instead of Core Events



commit 953e36130cb514636622af9fc56f77d41bd399af
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Nov 15 16:35:42 2012 -0500

    Port mutter to use XInput2 events instead of Core Events

 src/core/display.c             |  254 ++++++++++++++++++---------------
 src/core/keybindings-private.h |    6 +-
 src/core/keybindings.c         |  309 ++++++++++++++++++++--------------------
 src/core/window-private.h      |    5 +-
 src/core/window.c              |  206 +++++++++++++++------------
 src/meta/keybindings.h         |    2 +-
 src/meta/prefs.h               |    2 +-
 7 files changed, 415 insertions(+), 369 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index c7a6613..934ade2 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1796,23 +1796,37 @@ handle_net_restack_window (MetaDisplay* display,
 }
 #endif
 
-static XEvent *
-get_input_event (MetaDisplay  *display,
-                 XEvent       *event)
+static XIEvent *
+get_input_event (MetaDisplay *display,
+                 XEvent      *event)
 {
-  switch (event->type) {
-  case MotionNotify:
-  case ButtonPress:
-  case ButtonRelease:
-  case KeyPress:
-  case KeyRelease:
-  case FocusIn:
-  case FocusOut:
-  case EnterNotify:
-  case LeaveNotify:
-    return event;
-    break;
-  }
+  if (event->type == GenericEvent &&
+      event->xcookie.extension == display->xinput2_opcode)
+    {
+      XIEvent *xev;
+
+      /* NB: GDK event filters already have generic events
+       * allocated, so no need to do XGetEventData() on our own
+       */
+      xev = (XIEvent *) event->xcookie.data;
+
+      switch (xev->evtype)
+        {
+        case XI_Motion:
+        case XI_ButtonPress:
+        case XI_ButtonRelease:
+        case XI_KeyPress:
+        case XI_KeyRelease:
+        case XI_FocusIn:
+        case XI_FocusOut:
+        case XI_Enter:
+        case XI_Leave:
+          return xev;
+          break;
+        default:
+          break;
+        }
+    }
 
   return NULL;
 }
@@ -1842,7 +1856,7 @@ event_callback (XEvent   *event,
   gboolean frame_was_receiver;
   gboolean bypass_compositor;
   gboolean filter_out_event;
-  XEvent *xev;
+  XIEvent *xev;
 
   display = data;
   
@@ -1876,8 +1890,8 @@ event_callback (XEvent   *event,
         }
     }
   else if (xev &&
-           xev->type == LeaveNotify &&
-           xev->xcrossing.mode == NotifyUngrab &&
+           xev->evtype == XI_Leave &&
+           ((XILeaveEvent *)xev)->mode == NotifyUngrab &&
            modified == display->ungrab_should_not_cause_focus_window)
     {
       meta_display_add_ignored_crossing_serial (display, event->xany.serial);
@@ -1923,11 +1937,11 @@ event_callback (XEvent   *event,
       ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
     {
       filter_out_event = TRUE; /* GTK doesn't want to see this really */
-      
+
       if (display->grab_op != META_GRAB_OP_NONE &&
           display->grab_window != NULL &&
           grab_op_is_mouse (display->grab_op))
-	meta_window_handle_mouse_grab_op_event (display->grab_window, event);
+	meta_window_handle_mouse_grab_op_sync_event (display->grab_window, event);
     }
 #endif /* HAVE_XSYNC */
 
@@ -1981,8 +1995,11 @@ event_callback (XEvent   *event,
 
   if (xev != NULL)
     {
+      XIDeviceEvent *xev_d = (XIDeviceEvent *) xev;
+      XIEnterEvent *xev_e = (XIEnterEvent *) xev;
+
       if (window && !window->override_redirect &&
-          ((evtype == KeyPress) || (evtype == ButtonPress)))
+          ((xev->evtype == XI_KeyPress) || (xev->evtype == XI_ButtonPress)))
         {
           if (CurrentTime == display->current_time)
             {
@@ -2001,10 +2018,10 @@ event_callback (XEvent   *event,
             }
         }
   
-      switch (evtype)
+      switch (xev->evtype)
         {
-        case KeyPress:
-        case KeyRelease:
+        case XI_KeyPress:
+        case XI_KeyRelease:
 
           /* For key events, it's important to enforce single-handling, or
            * we can get into a confused state. So if a keybinding is
@@ -2012,22 +2029,22 @@ event_callback (XEvent   *event,
            * in a keyboard-grabbed mode like moving a window, we don't
            * want to pass the key event to the compositor or GTK+ at all.
            */
-          if (meta_display_process_key_event (display, window, event))
+          if (meta_display_process_key_event (display, window, (XIDeviceEvent *) xev))
             filter_out_event = bypass_compositor = TRUE;
           break;
-        case ButtonPress:
+        case XI_ButtonPress:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
           display->overlay_key_only_pressed = FALSE;
 
-          if (event->xbutton.button == 4 || event->xbutton.button == 5)
+          if (xev_d->detail == 4 || xev_d->detail == 5)
             /* Scrollwheel event, do nothing and deliver event to compositor below */
             break;
 
           if ((window &&
                grab_op_is_mouse (display->grab_op) &&
-               display->grab_button != (int) event->xbutton.button &&
+               display->grab_button != xev_d->detail &&
                display->grab_window == window) ||
               grab_op_is_keyboard (display->grab_op))
             {
@@ -2043,14 +2060,14 @@ event_callback (XEvent   *event,
                   meta_topic (META_DEBUG_WINDOW_OPS, 
                               "Syncing to old stack positions.\n");
                   screen = 
-                    meta_display_screen_for_root (display, event->xany.window);
+                    meta_display_screen_for_root (display, xev_d->event);
 
                   if (screen!=NULL)
                     meta_stack_set_positions (screen->stack,
                                               display->grab_old_window_stacking);
                 }
               meta_display_end_grab_op (display,
-                                        event->xbutton.time);
+                                        xev_d->detail);
             }
           else if (window && display->grab_op == META_GRAB_OP_NONE)
             {
@@ -2067,10 +2084,10 @@ event_callback (XEvent   *event,
                * frame, the other is our focus_window_grab on unmodified
                * button 1.  So for all such events we focus the window.
                */
-              unmodified = (event->xbutton.state & grab_mask) == 0;
+              unmodified = (xev_d->mods.effective & grab_mask) == 0;
           
               if (unmodified ||
-                  event->xbutton.button == 1)
+                  xev_d->detail == 1)
                 {
                   /* don't focus if frame received, will be lowered in
                    * frames.c or special-cased if the click was on a
@@ -2091,8 +2108,8 @@ event_callback (XEvent   *event,
                         {
                           meta_topic (META_DEBUG_FOCUS,
                                       "Focusing %s due to unmodified button %u press (display.c)\n",
-                                      window->desc, event->xbutton.button);
-                          meta_window_focus (window, event->xbutton.time);
+                                      window->desc, xev_d->detail);
+                          meta_window_focus (window, xev_d->time);
                         }
                       else
                         /* However, do allow terminals to lose focus due to new
@@ -2107,7 +2124,7 @@ event_callback (XEvent   *event,
                   if (!unmodified)
                     begin_move = TRUE;
                 }
-              else if (!unmodified && event->xbutton.button == meta_prefs_get_mouse_button_resize())
+              else if (!unmodified && xev_d->detail == meta_prefs_get_mouse_button_resize())
                 {
                   if (window->has_resize_func)
                     {
@@ -2118,10 +2135,10 @@ event_callback (XEvent   *event,
 
                       meta_window_get_position (window, &root_x, &root_y);
 
-                      west = event->xbutton.x_root <  (root_x + 1 * window->rect.width  / 3);
-                      east = event->xbutton.x_root >  (root_x + 2 * window->rect.width  / 3);
-                      north = event->xbutton.y_root < (root_y + 1 * window->rect.height / 3);
-                      south = event->xbutton.y_root > (root_y + 2 * window->rect.height / 3);
+                      west = xev_d->root_x <  (root_x + 1 * window->rect.width  / 3);
+                      east = xev_d->root_x >  (root_x + 2 * window->rect.width  / 3);
+                      north = xev_d->root_y < (root_y + 1 * window->rect.height / 3);
+                      south = xev_d->root_y > (root_y + 2 * window->rect.height / 3);
 
                       if (north && west)
                         op = META_GRAB_OP_RESIZING_NW;
@@ -2149,22 +2166,22 @@ event_callback (XEvent   *event,
                                                     op,
                                                     TRUE,
                                                     FALSE,
-                                                    event->xbutton.button,
+                                                    xev_d->detail,
                                                     0,
-                                                    event->xbutton.time,
-                                                    event->xbutton.x_root,
-                                                    event->xbutton.y_root);
+                                                    xev_d->time,
+                                                    xev_d->root_x,
+                                                    xev_d->root_y);
                     }
                 }
-              else if (event->xbutton.button == meta_prefs_get_mouse_button_menu())
+              else if (xev_d->detail == meta_prefs_get_mouse_button_menu())
                 {
                   if (meta_prefs_get_raise_on_click ())
                     meta_window_raise (window);
                   meta_window_show_menu (window,
-                                         event->xbutton.x_root,
-                                         event->xbutton.y_root,
-                                         event->xbutton.button,
-                                         event->xbutton.time);
+                                         xev_d->root_x,
+                                         xev_d->root_y,
+                                         xev_d->detail,
+                                         xev_d->time);
                 }
 
               if (!frame_was_receiver && unmodified)
@@ -2192,10 +2209,10 @@ event_callback (XEvent   *event,
 
                   meta_verbose ("Allowing events mode %s time %u\n",
                                 mode == AsyncPointer ? "AsyncPointer" : "ReplayPointer",
-                                (unsigned int)event->xbutton.time);
-              
-                  XAllowEvents (display->xdisplay,
-                                mode, event->xbutton.time);
+                                (unsigned int)xev_d->time);
+
+                  XIAllowEvents (display->xdisplay, xev_d->deviceid,
+                                 mode, xev_d->time);
                 }
 
               if (begin_move && window->has_move_func)
@@ -2206,15 +2223,15 @@ event_callback (XEvent   *event,
                                               META_GRAB_OP_MOVING,
                                               TRUE,
                                               FALSE,
-                                              event->xbutton.button,
+                                              xev_d->detail,
                                               0,
-                                              event->xbutton.time,
-                                              event->xbutton.x_root,
-                                              event->xbutton.y_root);
+                                              xev_d->time,
+                                              xev_d->root_x,
+                                              xev_d->root_y);
                 }
             }
           break;
-        case ButtonRelease:
+        case XI_ButtonRelease:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
@@ -2222,17 +2239,17 @@ event_callback (XEvent   *event,
 
           if (display->grab_window == window &&
               grab_op_is_mouse (display->grab_op))
-            meta_window_handle_mouse_grab_op_event (window, event);
+            meta_window_handle_mouse_grab_op_event (window, xev_d);
           break;
-        case MotionNotify:
+        case XI_Motion:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
           if (display->grab_window == window &&
               grab_op_is_mouse (display->grab_op))
-            meta_window_handle_mouse_grab_op_event (window, event);
+            meta_window_handle_mouse_grab_op_event (window, xev_d);
           break;
-        case EnterNotify:
+        case XI_Enter:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
@@ -2242,21 +2259,21 @@ event_callback (XEvent   *event,
            */
           {
             MetaScreen *new_screen = 
-              meta_display_screen_for_root (display, event->xcrossing.root);
+              meta_display_screen_for_root (display, xev_e->root);
 
             if (new_screen != NULL && display->active_screen != new_screen)
               meta_workspace_focus_default_window (new_screen->active_workspace, 
                                                    NULL,
-                                                   event->xcrossing.time);
+                                                   xev_e->time);
           }
 
           /* Check if we've entered a window; do this even if window->has_focus to
            * avoid races.
            */
           if (window && !crossing_serial_is_ignored (display, event->xany.serial) &&
-              event->xcrossing.mode != NotifyGrab && 
-              event->xcrossing.mode != NotifyUngrab &&
-              event->xcrossing.detail != NotifyInferior &&
+              xev_e->mode != NotifyGrab && 
+              xev_e->mode != NotifyUngrab &&
+              xev_e->detail != NotifyInferior &&
               meta_display_focus_sentinel_clear (display))
             {
               switch (meta_prefs_get_focus_mode ())
@@ -2272,15 +2289,15 @@ event_callback (XEvent   *event,
                                   "and setting display->mouse_mode to TRUE.\n",
                                   window->desc,
                                   event->xany.serial,
-                                  event->xcrossing.time);
+                                  xev_e->time);
 
                       if (meta_prefs_get_focus_change_on_pointer_rest())
                         meta_display_queue_focus_callback (display, window,
-                                                           event->xcrossing.x_root,
-                                                           event->xcrossing.y_root);
+                                                           xev_e->root_x,
+                                                           xev_e->root_y);
                       else
                         meta_display_mouse_mode_focus (display, window,
-                                                       event->xcrossing.time);
+                                                       xev_e->time);
 
                       /* stop ignoring stuff */
                       reset_ignored_crossing_serials (display);
@@ -2294,58 +2311,58 @@ event_callback (XEvent   *event,
                 meta_window_raise (window);
             }
           break;
-        case LeaveNotify:
+        case XI_Leave:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
           if (window != NULL)
             {
               if (window->type == META_WINDOW_DOCK &&
-                  event->xcrossing.mode != NotifyGrab &&
-                  event->xcrossing.mode != NotifyUngrab &&
+                  xev_e->mode != NotifyGrab &&
+                  xev_e->mode != NotifyUngrab &&
                   !window->has_focus)
                 meta_window_lower (window);
             }
           break;
-        case FocusIn:
-        case FocusOut:
+        case XI_FocusIn:
+        case XI_FocusOut:
           if (window)
             {
-              meta_window_notify_focus (window, event);
+              meta_window_notify_focus (window, xev_e);
             }
           else if (meta_display_xwindow_is_a_no_focus_window (display,
-                                                              event->xany.window))
+                                                              xev_e->event))
             {
               meta_topic (META_DEBUG_FOCUS,
                           "Focus %s event received on no_focus_window 0x%lx "
                           "mode %s detail %s\n",
-                          evtype == FocusIn ? "in" :
-                          evtype == FocusOut ? "out" :
+                          xev_e->evtype == XI_FocusIn ? "in" :
+                          xev_e->evtype == XI_FocusOut ? "out" :
                           "???",
-                          event->xany.window,
-                          meta_event_mode_to_string (event->xfocus.mode),
-                          meta_event_detail_to_string (event->xfocus.detail));
+                          xev_e->event,
+                          meta_event_mode_to_string (xev_e->mode),
+                          meta_event_detail_to_string (xev_e->detail));
             }
           else
             {
               MetaScreen *screen =
                 meta_display_screen_for_root(display,
-                                             event->xany.window);
+                                             xev_e->event);
               if (screen == NULL)
                 break;
 
               meta_topic (META_DEBUG_FOCUS,
                           "Focus %s event received on root window 0x%lx "
                           "mode %s detail %s\n",
-                          evtype == FocusIn ? "in" :
-                          evtype == FocusOut ? "out" :
+                          xev_e->evtype == XI_FocusIn ? "in" :
+                          xev_e->evtype == XI_FocusOut ? "out" :
                           "???",
-                          event->xany.window,
-                          meta_event_mode_to_string (event->xfocus.mode),
-                          meta_event_detail_to_string (event->xfocus.detail));
+                          xev_e->event,
+                          meta_event_mode_to_string (xev_e->mode),
+                          meta_event_detail_to_string (xev_e->detail));
           
-              if (evtype == FocusIn &&
-                  event->xfocus.detail == NotifyDetailNone)
+              if (xev_e->evtype == XI_FocusIn &&
+                  xev_e->mode == NotifyDetailNone)
                 {
                   meta_topic (META_DEBUG_FOCUS, 
                               "Focus got set to None, probably due to "
@@ -2355,9 +2372,9 @@ event_callback (XEvent   *event,
                                                        NULL,
                                                        meta_display_get_current_time_roundtrip (display));
                 }
-              else if (evtype == FocusIn &&
-                       event->xfocus.mode == NotifyNormal &&
-                       event->xfocus.detail == NotifyInferior)
+              else if (xev_e->evtype == XI_FocusIn &&
+                       xev_e->mode == NotifyNormal &&
+                       xev_e->detail == NotifyInferior)
                 {
                   meta_topic (META_DEBUG_FOCUS,
                               "Focus got set to root window, probably due to "
@@ -2479,7 +2496,7 @@ event_callback (XEvent   *event,
                * and move focus to another window
                */
               if (window)
-                meta_window_notify_focus (window, event);
+                meta_window_unmap_notify (window);
             }
           break;
         case MapNotify:
@@ -2884,15 +2901,28 @@ static Window
 event_get_modified_window (MetaDisplay *display,
                            XEvent *event)
 {
+  XIEvent *xev = get_input_event (display, event);
+
+  if (xev)
+    {
+      switch (xev->evtype)
+        {
+        case XI_Motion:
+        case XI_ButtonPress:
+        case XI_ButtonRelease:
+        case XI_KeyPress:
+        case XI_KeyRelease:
+          return ((XIDeviceEvent *) xev)->event;
+        case XI_FocusIn:
+        case XI_FocusOut:
+        case XI_Enter:
+        case XI_Leave:
+          return ((XIEnterEvent *) xev)->event;
+        }
+    }
+
   switch (event->type)
     {
-    case KeyPress:
-    case KeyRelease:
-    case ButtonPress:
-    case ButtonRelease:
-    case MotionNotify:
-    case FocusIn:
-    case FocusOut:
     case KeymapNotify:
     case Expose:
     case GraphicsExpose:
@@ -2963,19 +2993,13 @@ static guint32
 event_get_time (MetaDisplay *display,
                 XEvent      *event)
 {
+  XIEvent *xev = get_input_event (display, event);
+
+  if (xev)
+    return xev->time;
+
   switch (event->type)
     {
-    case KeyPress:
-    case KeyRelease:
-      return event->xkey.time;
-      
-    case ButtonPress:
-    case ButtonRelease:
-      return event->xbutton.time;
-      
-    case MotionNotify:
-      return event->xmotion.time;
-
     case PropertyNotify:
       return event->xproperty.time;
 
@@ -2984,10 +3008,6 @@ event_get_time (MetaDisplay *display,
     case SelectionNotify:
       return event->xselection.time;
 
-    case EnterNotify:
-    case LeaveNotify:
-      return event->xcrossing.time;
-
     case FocusIn:
     case FocusOut:
     case KeymapNotify:      
diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h
index 7be9c24..1f2723a 100644
--- a/src/core/keybindings-private.h
+++ b/src/core/keybindings-private.h
@@ -66,9 +66,9 @@ gboolean meta_window_grab_all_keys          (MetaWindow  *window,
                                              guint32      timestamp);
 void     meta_window_ungrab_all_keys        (MetaWindow  *window,
                                              guint32      timestamp);
-gboolean meta_display_process_key_event     (MetaDisplay *display,
-                                             MetaWindow  *window,
-                                             XEvent      *event);
+gboolean meta_display_process_key_event     (MetaDisplay   *display,
+                                             MetaWindow    *window,
+                                             XIDeviceEvent *xev);
 void     meta_set_keybindings_disabled      (gboolean     setting);
 void     meta_display_process_mapping_event (MetaDisplay *display,
                                              XEvent      *event);
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 63b0e13..f88f6ae 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -109,36 +109,36 @@ meta_key_binding_is_builtin (MetaKeyBinding *binding)
 static void handle_workspace_switch  (MetaDisplay    *display,
                                       MetaScreen     *screen,
                                       MetaWindow     *window,
-                                      XEvent         *event,
+                                      XIDeviceEvent  *xev,
                                       MetaKeyBinding *binding,
                                       gpointer        dummy);
 
 static gboolean process_mouse_move_resize_grab (MetaDisplay *display,
                                                 MetaScreen  *screen,
                                                 MetaWindow  *window,
-                                                XEvent      *event,
+                                                XIDeviceEvent *xev,
                                                 KeySym       keysym);
 
 static gboolean process_keyboard_move_grab (MetaDisplay *display,
                                             MetaScreen  *screen,
                                             MetaWindow  *window,
-                                            XEvent      *event,
+                                            XIDeviceEvent *xev,
                                             KeySym       keysym);
 
 static gboolean process_keyboard_resize_grab (MetaDisplay *display,
                                               MetaScreen  *screen,
                                               MetaWindow  *window,
-                                              XEvent      *event,
+                                              XIDeviceEvent *xev,
                                               KeySym       keysym);
 
 static gboolean process_tab_grab           (MetaDisplay *display,
                                             MetaScreen  *screen,
-                                            XEvent      *event,
+                                            XIDeviceEvent *xev,
                                             KeySym       keysym);
 
 static gboolean process_workspace_switch_grab (MetaDisplay *display,
                                                MetaScreen  *screen,
-                                               XEvent      *event,
+                                               XIDeviceEvent *xev,
                                                KeySym       keysym);
 
 static void regrab_key_bindings         (MetaDisplay *display);
@@ -1356,7 +1356,7 @@ invoke_handler (MetaDisplay    *display,
                 MetaScreen     *screen,
                 MetaKeyHandler *handler,
                 MetaWindow     *window,
-                XEvent         *event,
+                XIDeviceEvent *xev,
                 MetaKeyBinding *binding)
 
 {
@@ -1364,14 +1364,14 @@ invoke_handler (MetaDisplay    *display,
     (* handler->func) (display, screen,
                        handler->flags & META_KEY_BINDING_PER_WINDOW ?
                            window : NULL,
-                       event,
+                       xev,
                        binding,
                        handler->user_data);
   else
     (* handler->default_func) (display, screen,
                                handler->flags & META_KEY_BINDING_PER_WINDOW ?
                                    window: NULL,
-                               event,
+                               xev,
                                binding,
                                NULL);
 }
@@ -1381,13 +1381,13 @@ invoke_handler_by_name (MetaDisplay    *display,
                         MetaScreen     *screen,
                         const char     *handler_name,
                         MetaWindow     *window,
-                        XEvent         *event)
+                        XIDeviceEvent  *xev)
 {
   MetaKeyHandler *handler;
 
   handler = HANDLER (handler_name);
   if (handler)
-    invoke_handler (display, screen, handler, window, event, NULL);
+    invoke_handler (display, screen, handler, window, xev, NULL);
 }
 
 /* now called from only one place, may be worth merging */
@@ -1397,14 +1397,14 @@ process_event (MetaKeyBinding       *bindings,
                MetaDisplay          *display,
                MetaScreen           *screen,
                MetaWindow           *window,
-               XEvent               *event,
+               XIDeviceEvent        *xev,
                KeySym                keysym,
                gboolean              on_window)
 {
   int i;
 
   /* we used to have release-based bindings but no longer. */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return FALSE;
 
   /*
@@ -1416,9 +1416,9 @@ process_event (MetaKeyBinding       *bindings,
       MetaKeyHandler *handler = bindings[i].handler;
 
       if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) ||
-          event->type != KeyPress ||
-          bindings[i].keycode != event->xkey.keycode ||
-          ((event->xkey.state & 0xff & ~(display->ignored_modifier_mask)) !=
+          xev->evtype != XI_KeyPress ||
+          bindings[i].keycode != xev->detail ||
+          ((xev->mods.effective & 0xff & ~(display->ignored_modifier_mask)) !=
            bindings[i].mask) ||
           meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i]))
         continue;
@@ -1432,7 +1432,7 @@ process_event (MetaKeyBinding       *bindings,
       meta_topic (META_DEBUG_KEYBINDINGS,
                   "Binding keycode 0x%x mask 0x%x matches event 0x%x state 0x%x\n",
                   bindings[i].keycode, bindings[i].mask,
-                  event->xkey.keycode, event->xkey.state);
+                  xev->detail, xev->mods.effective);
 
       if (handler == NULL)
         meta_bug ("Binding %s has no handler\n", bindings[i].name);
@@ -1447,7 +1447,7 @@ process_event (MetaKeyBinding       *bindings,
        */
       display->allow_terminal_deactivation = TRUE;
 
-      invoke_handler (display, screen, handler, window, event, &bindings[i]);
+      invoke_handler (display, screen, handler, window, xev, &bindings[i]);
 
       return TRUE;
     }
@@ -1460,12 +1460,12 @@ process_event (MetaKeyBinding       *bindings,
 static gboolean
 process_overlay_key (MetaDisplay *display,
                      MetaScreen *screen,
-                     XEvent *event,
+                     XIDeviceEvent *xev,
                      KeySym keysym)
 {
   if (display->overlay_key_only_pressed)
     {
-      if (event->xkey.keycode != display->overlay_key_combo.keycode)
+      if (xev->detail != display->overlay_key_combo.keycode)
         {
           display->overlay_key_only_pressed = FALSE;
 
@@ -1483,28 +1483,31 @@ process_overlay_key (MetaDisplay *display,
            */
           if (process_event (display->key_bindings,
                              display->n_key_bindings,
-                             display, screen, NULL, event, keysym,
+                             display, screen, NULL, xev, keysym,
                              FALSE))
             {
               /* As normally, after we've handled a global key
                * binding, we unfreeze the keyboard but keep the grab
                * (this is important for something like cycling
                * windows */
-              XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time);
+              XIAllowEvents (display->xdisplay, xev->deviceid,
+                             AsyncKeyboard, xev->time);
             }
           else
             {
               /* Replay the event so it gets delivered to our
                * per-window key bindings or to the application */
-              XAllowEvents (display->xdisplay, ReplayKeyboard, event->xkey.time);
+              XIAllowEvents (display->xdisplay, xev->deviceid,
+                             ReplayKeyboard, xev->time);
             }
         }
-      else if (event->xkey.type == KeyRelease)
+      else if (xev->evtype == XI_KeyRelease)
         {
           display->overlay_key_only_pressed = FALSE;
           /* We want to unfreeze events, but keep the grab so that if the user
            * starts typing into the overlay we get all the keys */
-          XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time);
+          XIAllowEvents (display->xdisplay, xev->deviceid,
+                         AsyncKeyboard, xev->time);
 
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             {
@@ -1522,13 +1525,14 @@ process_overlay_key (MetaDisplay *display,
 
       return TRUE;
     }
-  else if (event->xkey.type == KeyPress &&
-           event->xkey.keycode == display->overlay_key_combo.keycode)
+  else if (xev->evtype == XI_KeyPress &&
+           xev->detail == display->overlay_key_combo.keycode)
     {
       display->overlay_key_only_pressed = TRUE;
       /* We keep the keyboard frozen - this allows us to use ReplayKeyboard
        * on the next event if it's not the release of the overlay key */
-      XAllowEvents (display->xdisplay, SyncKeyboard, event->xkey.time);
+      XIAllowEvents (display->xdisplay, xev->deviceid,
+                     SyncKeyboard, xev->time);
 
       return TRUE;
     }
@@ -1551,9 +1555,9 @@ process_overlay_key (MetaDisplay *display,
  * (and help us solve the other fixmes).
  */
 gboolean
-meta_display_process_key_event (MetaDisplay *display,
-                                MetaWindow  *window,
-                                XEvent      *event)
+meta_display_process_key_event (MetaDisplay   *display,
+                                MetaWindow    *window,
+                                XIDeviceEvent *xev)
 {
   KeySym keysym;
   gboolean keep_grab;
@@ -1572,47 +1576,48 @@ meta_display_process_key_event (MetaDisplay *display,
        * poorly defined how this mode is supposed to interact with
        * plugins.
        */
-      XAllowEvents (display->xdisplay, ReplayKeyboard, event->xkey.time);
+      XIAllowEvents (display->xdisplay, xev->deviceid,
+                     ReplayKeyboard, xev->time);
       return FALSE;
     }
 
   /* if key event was on root window, we have a shortcut */
-  screen = meta_display_screen_for_root (display, event->xkey.window);
+  screen = meta_display_screen_for_root (display, xev->event);
   
   /* else round-trip to server */
   if (screen == NULL)
-    screen = meta_display_screen_for_xwindow (display,
-                                              event->xany.window);
+    screen = meta_display_screen_for_xwindow (display, xev->event);
 
   if (screen == NULL)
     return FALSE; /* event window is destroyed */
   
   /* ignore key events on popup menus and such. */
-  if (meta_ui_window_is_widget (screen->ui, event->xany.window))
+  if (meta_ui_window_is_widget (screen->ui, xev->event))
     return FALSE;
   
   /* window may be NULL */
   
-  keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
+  keysym = XKeycodeToKeysym (display->xdisplay, xev->detail, 0);
 
   str = XKeysymToString (keysym);
   
   /* was topic */
   meta_topic (META_DEBUG_KEYBINDINGS,
               "Processing key %s event, keysym: %s state: 0x%x window: %s\n",
-              event->type == KeyPress ? "press" : "release",
-              str ? str : "none", event->xkey.state,
+              xev->evtype == XI_KeyPress ? "press" : "release",
+              str ? str : "none", xev->mods.effective,
               window ? window->desc : "(no window)");
 
   all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
   if (!all_keys_grabbed)
     {
-      handled = process_overlay_key (display, screen, event, keysym);
+      handled = process_overlay_key (display, screen, xev, keysym);
       if (handled)
         return TRUE;
     }
 
-  XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time);
+  XIAllowEvents (display->xdisplay, xev->deviceid,
+                 AsyncKeyboard, xev->time);
 
   keep_grab = TRUE;
   if (all_keys_grabbed)
@@ -1641,7 +1646,7 @@ meta_display_process_key_event (MetaDisplay *display,
                           "Processing event for mouse-only move/resize\n");
               g_assert (window != NULL);
               keep_grab = process_mouse_move_resize_grab (display, screen,
-                                                          window, event, keysym);
+                                                          window, xev, keysym);
               break;
  
             case META_GRAB_OP_KEYBOARD_MOVING:
@@ -1649,7 +1654,7 @@ meta_display_process_key_event (MetaDisplay *display,
                           "Processing event for keyboard move\n");
               g_assert (window != NULL);
               keep_grab = process_keyboard_move_grab (display, screen,
-                                                      window, event, keysym);
+                                                      window, xev, keysym);
               break;
               
             case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
@@ -1665,7 +1670,7 @@ meta_display_process_key_event (MetaDisplay *display,
                           "Processing event for keyboard resize\n");
               g_assert (window != NULL);
               keep_grab = process_keyboard_resize_grab (display, screen,
-                                                        window, event, keysym);
+                                                        window, xev, keysym);
               break;
  
             case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
@@ -1676,13 +1681,13 @@ meta_display_process_key_event (MetaDisplay *display,
             case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
               meta_topic (META_DEBUG_KEYBINDINGS,
                           "Processing event for keyboard tabbing/cycling\n");
-              keep_grab = process_tab_grab (display, screen, event, keysym);
+              keep_grab = process_tab_grab (display, screen, xev, keysym);
               break;
               
             case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
               meta_topic (META_DEBUG_KEYBINDINGS,
                           "Processing event for keyboard workspace switching\n");
-              keep_grab = process_workspace_switch_grab (display, screen, event, keysym);
+              keep_grab = process_workspace_switch_grab (display, screen, xev, keysym);
               break;
  
             default:
@@ -1694,7 +1699,7 @@ meta_display_process_key_event (MetaDisplay *display,
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Ending grab op %u on key event sym %s\n",
                       display->grab_op, XKeysymToString (keysym));
-          meta_display_end_grab_op (display, event->xkey.time);
+          meta_display_end_grab_op (display, xev->time);
         }
 
       return TRUE;
@@ -1703,7 +1708,7 @@ meta_display_process_key_event (MetaDisplay *display,
   /* Do the normal keybindings */
   return process_event (display->key_bindings,
                         display->n_key_bindings,
-                        display, screen, window, event, keysym,
+                        display, screen, window, xev, keysym,
                         !all_keys_grabbed && window);
 }
 
@@ -1711,11 +1716,11 @@ static gboolean
 process_mouse_move_resize_grab (MetaDisplay *display,
                                 MetaScreen  *screen,
                                 MetaWindow  *window,
-                                XEvent      *event,
+                                XIDeviceEvent *xev,
                                 KeySym       keysym)
 {
   /* don't care about releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return TRUE;
 
   if (keysym == XK_Escape)
@@ -1758,7 +1763,7 @@ static gboolean
 process_keyboard_move_grab (MetaDisplay *display,
                             MetaScreen  *screen,
                             MetaWindow  *window,
-                            XEvent      *event,
+                            XIDeviceEvent *xev,
                             KeySym       keysym)
 {
   gboolean handled;
@@ -1769,23 +1774,23 @@ process_keyboard_move_grab (MetaDisplay *display,
   handled = FALSE;
 
   /* don't care about releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, xev->detail))
     return TRUE;
 
   meta_window_get_position (window, &x, &y);
 
-  smart_snap = (event->xkey.state & ShiftMask) != 0;
+  smart_snap = (xev->mods.effective & ShiftMask) != 0;
   
 #define SMALL_INCREMENT 1
 #define NORMAL_INCREMENT 10
 
   if (smart_snap)
     incr = 1;
-  else if (event->xkey.state & ControlMask)
+  else if (xev->mods.effective & ControlMask)
     incr = SMALL_INCREMENT;
   else
     incr = NORMAL_INCREMENT;
@@ -1880,7 +1885,7 @@ static gboolean
 process_keyboard_resize_grab_op_change (MetaDisplay *display,
                                         MetaScreen  *screen,
                                         MetaWindow  *window,
-                                        XEvent      *event,
+                                        XIDeviceEvent *xev,
                                         KeySym       keysym)
 {
   gboolean handled;
@@ -2002,7 +2007,7 @@ static gboolean
 process_keyboard_resize_grab (MetaDisplay *display,
                               MetaScreen  *screen,
                               MetaWindow  *window,
-                              XEvent      *event,
+                              XIDeviceEvent *xev,
                               KeySym       keysym)
 {
   gboolean handled;
@@ -2015,11 +2020,11 @@ process_keyboard_resize_grab (MetaDisplay *display,
   handled = FALSE;
 
   /* don't care about releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, xev->detail))
     return TRUE;
 
   if (keysym == XK_Escape)
@@ -2036,7 +2041,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
     }
 
   if (process_keyboard_resize_grab_op_change (display, screen, window, 
-                                              event, keysym))
+                                              xev, keysym))
     return TRUE;
 
   width = window->rect.width;
@@ -2044,7 +2049,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
 
   gravity = meta_resize_gravity_from_grab_op (display->grab_op);
 
-  smart_snap = (event->xkey.state & ShiftMask) != 0;
+  smart_snap = (xev->mods.effective & ShiftMask) != 0;
   
 #define SMALL_INCREMENT 1
 #define NORMAL_INCREMENT 10
@@ -2054,7 +2059,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
       height_inc = 1;
       width_inc = 1;
     }
-  else if (event->xkey.state & ControlMask)
+  else if (xev->mods.effective & ControlMask)
     {
       width_inc = SMALL_INCREMENT;
       height_inc = SMALL_INCREMENT;
@@ -2264,7 +2269,7 @@ end_keyboard_grab (MetaDisplay *display,
 static gboolean
 process_tab_grab (MetaDisplay *display,
                   MetaScreen  *screen,
-                  XEvent      *event,
+                  XIDeviceEvent *xev,
                   KeySym       keysym)
 {
   MetaKeyBinding *binding;
@@ -2279,7 +2284,7 @@ process_tab_grab (MetaDisplay *display,
 
   binding = display_get_keybinding (display,
                                     keysym,
-                                    event->xkey.keycode,
+                                    xev->detail,
                                     display->grab_mask);
   if (binding)
     action = meta_prefs_get_keybinding_action (binding->name);
@@ -2293,11 +2298,11 @@ process_tab_grab (MetaDisplay *display,
    */
   if (!screen->tab_popup)
     {
-      if (event->type == KeyRelease)
+      if (xev->evtype == XI_KeyRelease)
         {
-          if (end_keyboard_grab (display, event->xkey.keycode))
+          if (end_keyboard_grab (display, xev->detail))
             {
-              invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event);
+              invoke_handler_by_name (display, screen, "tab-popup-select", NULL, xev);
 
               /* We return FALSE to end the grab; if the handler ended the grab itself
                * that will be a noop. If the handler didn't end the grab, then it's a
@@ -2334,7 +2339,7 @@ process_tab_grab (MetaDisplay *display,
               binding->handler->func &&
               binding->handler->func != binding->handler->default_func)
             {
-              invoke_handler (display, screen, binding->handler, NULL, event, binding);
+              invoke_handler (display, screen, binding->handler, NULL, xev, binding);
               return TRUE;
             }
           break;
@@ -2344,7 +2349,7 @@ process_tab_grab (MetaDisplay *display,
              * If this is simply user pressing the Shift key, we do not want
              * to cancel the grab.
              */
-            if (is_modifier (display, event->xkey.keycode))
+            if (is_modifier (display, xev->detail))
               return TRUE;
           }
 
@@ -2353,12 +2358,12 @@ process_tab_grab (MetaDisplay *display,
         }
 
       /* Some unhandled key press */
-      invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event);
+      invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, xev);
       return FALSE;
     }
 
-  if (event->type == KeyRelease &&
-      end_keyboard_grab (display, event->xkey.keycode))
+  if (xev->evtype == XI_KeyRelease &&
+      end_keyboard_grab (display, xev->detail))
     {
       /* We're done, move to the new window. */
       MetaWindow *target_window;
@@ -2379,11 +2384,11 @@ process_tab_grab (MetaDisplay *display,
                       "selection and turning mouse_mode off\n",
                       target_window->desc);
           display->mouse_mode = FALSE;
-          meta_window_activate (target_window, event->xkey.time);
+          meta_window_activate (target_window, xev->time);
 
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Ending grab early so we can focus the target window\n");
-          meta_display_end_grab_op (display, event->xkey.time);
+          meta_display_end_grab_op (display, xev->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2392,11 +2397,11 @@ process_tab_grab (MetaDisplay *display,
     }
   
   /* don't care about other releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, xev->detail))
     return TRUE;
 
   prev_window = meta_screen_tab_popup_get_selected (screen);
@@ -2515,7 +2520,7 @@ process_tab_grab (MetaDisplay *display,
       meta_topic (META_DEBUG_KEYBINDINGS,
                   "Key pressed, moving tab focus in popup\n");
 
-      if (event->xkey.state & ShiftMask)
+      if (xev->mods.effective & ShiftMask)
         backward = !backward;
 
       if (backward)
@@ -2574,7 +2579,7 @@ static void
 handle_switch_to_workspace (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *event_window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2593,7 +2598,7 @@ handle_switch_to_workspace (MetaDisplay    *display,
        * Note that we're the only caller of that function, so perhaps
        * we should merge with it.
        */
-      handle_workspace_switch (display, screen, event_window, event, binding,
+      handle_workspace_switch (display, screen, event_window, xev, binding,
                                dummy);
       return;
     }
@@ -2602,7 +2607,7 @@ handle_switch_to_workspace (MetaDisplay    *display,
   
   if (workspace)
     {
-      meta_workspace_activate (workspace, event->xkey.time);
+      meta_workspace_activate (workspace, xev->time);
     }
   else
     {
@@ -2615,7 +2620,7 @@ static void
 handle_maximize_vertically (MetaDisplay    *display,
                       MetaScreen     *screen,
                       MetaWindow     *window,
-                      XEvent         *event,
+                      XIDeviceEvent *xev,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -2632,7 +2637,7 @@ static void
 handle_maximize_horizontally (MetaDisplay    *display,
                        MetaScreen     *screen,
                        MetaWindow     *window,
-                       XEvent         *event,
+                       XIDeviceEvent *xev,
                        MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -2696,7 +2701,7 @@ static void
 handle_move_to_corner_nw  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2707,7 +2712,7 @@ static void
 handle_move_to_corner_ne  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2718,7 +2723,7 @@ static void
 handle_move_to_corner_sw  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2729,7 +2734,7 @@ static void
 handle_move_to_corner_se  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2740,7 +2745,7 @@ static void
 handle_move_to_side_n     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2751,7 +2756,7 @@ static void
 handle_move_to_side_s     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2762,7 +2767,7 @@ static void
 handle_move_to_side_e     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2773,7 +2778,7 @@ static void
 handle_move_to_side_w     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2784,7 +2789,7 @@ static void
 handle_move_to_center  (MetaDisplay    *display,
                         MetaScreen     *screen,
                         MetaWindow     *window,
-                        XEvent         *event,
+                        XIDeviceEvent *xev,
                         MetaKeyBinding *binding,
                         gpointer        dummy)
 {
@@ -2811,7 +2816,7 @@ handle_move_to_center  (MetaDisplay    *display,
 static gboolean
 process_workspace_switch_grab (MetaDisplay *display,
                                MetaScreen  *screen,
-                               XEvent      *event,
+                               XIDeviceEvent *xev,
                                KeySym       keysym)
 {
   MetaWorkspace *workspace;
@@ -2819,8 +2824,8 @@ process_workspace_switch_grab (MetaDisplay *display,
   if (screen != display->grab_screen || !screen->ws_popup)
     return FALSE;
 
-  if (event->type == KeyRelease &&
-      end_keyboard_grab (display, event->xkey.keycode))
+  if (xev->evtype == XI_KeyRelease &&
+      end_keyboard_grab (display, xev->detail))
     {
       /* We're done, move to the new workspace. */
       MetaWorkspace *target_workspace;
@@ -2834,14 +2839,14 @@ process_workspace_switch_grab (MetaDisplay *display,
         {
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Ending grab so we can focus on the target workspace\n");
-          meta_display_end_grab_op (display, event->xkey.time);
+          meta_display_end_grab_op (display, xev->time);
 
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Focusing default window on target workspace\n");
 
           meta_workspace_focus_default_window (target_workspace, 
                                                NULL,
-                                               event->xkey.time);
+                                               xev->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2853,11 +2858,11 @@ process_workspace_switch_grab (MetaDisplay *display,
     }
   
   /* don't care about other releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (xev->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, xev->detail))
     return TRUE;
 
   /* select the next workspace in the popup */
@@ -2869,7 +2874,7 @@ process_workspace_switch_grab (MetaDisplay *display,
       MetaKeyBindingAction action;
 
       action = meta_display_get_keybinding_action (display,
-                                                   event->xkey.keycode,
+                                                   xev->detail,
                                                    display->grab_mask);
 
       switch (action)
@@ -2908,7 +2913,7 @@ process_workspace_switch_grab (MetaDisplay *display,
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Activating target workspace\n");
 
-          meta_workspace_activate (target_workspace, event->xkey.time);
+          meta_workspace_activate (target_workspace, xev->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2918,7 +2923,7 @@ process_workspace_switch_grab (MetaDisplay *display,
   meta_topic (META_DEBUG_KEYBINDINGS,
               "Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
   workspace = meta_screen_workspace_popup_get_selected (screen);
-  meta_workspace_focus_default_window (workspace, NULL, event->xkey.time);
+  meta_workspace_focus_default_window (workspace, NULL, xev->time);
   return FALSE;
 }
 
@@ -2926,7 +2931,7 @@ static void
 handle_show_desktop (MetaDisplay    *display,
                        MetaScreen     *screen,
                        MetaWindow     *window,
-                       XEvent         *event,
+                       XIDeviceEvent *xev,
                        MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -2935,17 +2940,17 @@ handle_show_desktop (MetaDisplay    *display,
       meta_screen_unshow_desktop (screen);
       meta_workspace_focus_default_window (screen->active_workspace, 
                                            NULL,
-                                           event->xkey.time);
+                                           xev->time);
     }
   else
-    meta_screen_show_desktop (screen, event->xkey.time);
+    meta_screen_show_desktop (screen, xev->time);
 }
 
 static void
 handle_panel (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *xev,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -2972,17 +2977,17 @@ handle_panel (MetaDisplay    *display,
   ev.message_type = display->atom__GNOME_PANEL_ACTION;
   ev.format = 32;
   ev.data.l[0] = action_atom;
-  ev.data.l[1] = event->xkey.time;
+  ev.data.l[1] = xev->time;
 
   meta_topic (META_DEBUG_KEYBINDINGS,
               "Sending panel message with timestamp %lu, and turning mouse_mode "
-              "off due to keybinding press\n", event->xkey.time);
+              "off due to keybinding press\n", xev->time);
   display->mouse_mode = FALSE;
 
   meta_error_trap_push (display);
 
   /* Release the grab for the panel before sending the event */
-  XUngrabKeyboard (display->xdisplay, event->xkey.time);
+  XUngrabKeyboard (display->xdisplay, xev->time);
 
   XSendEvent (display->xdisplay,
 	      screen->xroot,
@@ -2997,7 +3002,7 @@ static void
 handle_activate_window_menu (MetaDisplay    *display,
                       MetaScreen     *screen,
                       MetaWindow     *event_window,
-                      XEvent         *event,
+                      XIDeviceEvent *xev,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -3014,7 +3019,7 @@ handle_activate_window_menu (MetaDisplay    *display,
       meta_window_show_menu (display->focus_window,
                              x, y,
                              0,
-                             event->xkey.time);
+                             xev->time);
     }
 }
 
@@ -3062,7 +3067,7 @@ static void
 do_choose_window (MetaDisplay    *display,
                   MetaScreen     *screen,
                   MetaWindow     *event_window,
-                  XEvent         *event,
+                  XIDeviceEvent *xev,
                   MetaKeyBinding *binding,
                   gboolean        backward,
                   gboolean        show_popup)
@@ -3074,7 +3079,7 @@ do_choose_window (MetaDisplay    *display,
               "Tab list = %u show_popup = %d\n", type, show_popup);
   
   /* reverse direction if shift is down */
-  if (event->xkey.state & ShiftMask)
+  if (xev->mods.effective & ShiftMask)
     backward = !backward;
   
   initial_selection = meta_display_get_tab_next (display,
@@ -3107,7 +3112,7 @@ do_choose_window (MetaDisplay    *display,
                   "switch/cycle windows with no modifiers\n",
                   initial_selection->desc);
       display->mouse_mode = FALSE;
-      meta_window_activate (initial_selection, event->xkey.time);
+      meta_window_activate (initial_selection, xev->time);
       return;
     }
 
@@ -3127,7 +3132,7 @@ do_choose_window (MetaDisplay    *display,
                                    FALSE,
                                    0,
                                    binding->mask,
-                                   event->xkey.time,
+                                   xev->time,
                                    0, 0))
     return;
 
@@ -3142,9 +3147,9 @@ do_choose_window (MetaDisplay    *display,
                   "mouse_mode due to switch/cycle windows where "
                   "modifier was released prior to grab\n",
                   initial_selection->desc);
-      meta_display_end_grab_op (display, event->xkey.time);
+      meta_display_end_grab_op (display, xev->time);
       display->mouse_mode = FALSE;
-      meta_window_activate (initial_selection, event->xkey.time);
+      meta_window_activate (initial_selection, xev->time);
       return;
     }
 
@@ -3166,13 +3171,13 @@ static void
 handle_switch (MetaDisplay    *display,
                     MetaScreen     *screen,
                     MetaWindow     *event_window,
-                    XEvent         *event,
+                    XIDeviceEvent *xev,
                     MetaKeyBinding *binding,
                     gpointer        dummy)
 {
   gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
 
-  do_choose_window (display, screen, event_window, event, binding,
+  do_choose_window (display, screen, event_window, xev, binding,
                     backwards, TRUE);
 }
 
@@ -3180,13 +3185,13 @@ static void
 handle_cycle (MetaDisplay    *display,
                     MetaScreen     *screen,
                     MetaWindow     *event_window,
-                    XEvent         *event,
+                    XIDeviceEvent *xev,
                     MetaKeyBinding *binding,
                     gpointer        dummy)
 {
   gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
 
-  do_choose_window (display, screen, event_window, event, binding,
+  do_choose_window (display, screen, event_window, xev, binding,
                     backwards, FALSE);
 }
 
@@ -3194,7 +3199,7 @@ static void
 handle_tab_popup_select (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *xev,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -3205,7 +3210,7 @@ static void
 handle_tab_popup_cancel (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *xev,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -3216,7 +3221,7 @@ static void
 handle_toggle_fullscreen  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3230,7 +3235,7 @@ static void
 handle_toggle_above       (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3244,7 +3249,7 @@ static void
 handle_toggle_tiled (MetaDisplay    *display,
                      MetaScreen     *screen,
                      MetaWindow     *window,
-                     XEvent         *event,
+                     XIDeviceEvent *xev,
                      MetaKeyBinding *binding,
                      gpointer        dummy)
 {
@@ -3284,7 +3289,7 @@ static void
 handle_toggle_maximized    (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3302,7 +3307,7 @@ static void
 handle_maximize           (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3316,7 +3321,7 @@ static void
 handle_unmaximize         (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3330,33 +3335,33 @@ static void
 handle_toggle_shaded      (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
   if (window->shaded)
-    meta_window_unshade (window, event->xkey.time);
+    meta_window_unshade (window, xev->time);
   else if (window->has_shade_func)
-    meta_window_shade (window, event->xkey.time);
+    meta_window_shade (window, xev->time);
 }
 
 static void
 handle_close              (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
   if (window->has_close_func)
-    meta_window_delete (window, event->xkey.time);
+    meta_window_delete (window, xev->time);
 }
 
 static void
 handle_minimize        (MetaDisplay    *display,
                         MetaScreen     *screen,
                         MetaWindow     *window,
-                        XEvent         *event,
+                        XIDeviceEvent *xev,
                         MetaKeyBinding *binding,
                         gpointer        dummy)
 {
@@ -3368,7 +3373,7 @@ static void
 handle_begin_move         (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3377,7 +3382,7 @@ handle_begin_move         (MetaDisplay    *display,
       meta_window_begin_grab_op (window,
                                  META_GRAB_OP_KEYBOARD_MOVING,
                                  FALSE,
-                                 event->xkey.time);
+                                 xev->time);
     }
 }
 
@@ -3385,7 +3390,7 @@ static void
 handle_begin_resize       (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3394,7 +3399,7 @@ handle_begin_resize       (MetaDisplay    *display,
       meta_window_begin_grab_op (window,
                                  META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
                                  FALSE,
-                                 event->xkey.time);
+                                 xev->time);
     }
 }
 
@@ -3402,7 +3407,7 @@ static void
 handle_toggle_on_all_workspaces (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3416,7 +3421,7 @@ static void
 handle_move_to_workspace  (MetaDisplay    *display,
                               MetaScreen     *screen,
                               MetaWindow     *window,
-                              XEvent         *event,
+                              XIDeviceEvent *xev,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3458,7 +3463,7 @@ handle_move_to_workspace  (MetaDisplay    *display,
           meta_display_clear_mouse_mode (workspace->screen->display);
           meta_workspace_activate_with_focus (workspace,
                                               window,
-                                              event->xkey.time);
+                                              xev->time);
         }
     }
   else
@@ -3471,7 +3476,7 @@ static void
 handle_raise_or_lower (MetaDisplay    *display,
                        MetaScreen     *screen,
 		       MetaWindow     *window,
-		       XEvent         *event,
+		       XIDeviceEvent *xev,
 		       MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -3518,7 +3523,7 @@ static void
 handle_raise (MetaDisplay    *display,
               MetaScreen     *screen,
               MetaWindow     *window,
-              XEvent         *event,
+              XIDeviceEvent *xev,
               MetaKeyBinding *binding,
               gpointer        dummy)
 {
@@ -3529,7 +3534,7 @@ static void
 handle_lower (MetaDisplay    *display,
               MetaScreen     *screen,
               MetaWindow     *window,
-              XEvent         *event,
+              XIDeviceEvent *xev,
               MetaKeyBinding *binding,
               gpointer        dummy)
 {
@@ -3540,7 +3545,7 @@ static void
 handle_workspace_switch  (MetaDisplay    *display,
                           MetaScreen     *screen,
                           MetaWindow     *window,
-                          XEvent         *event,
+                          XIDeviceEvent  *xev,
                           MetaKeyBinding *binding,
                           gpointer        dummy)
 {
@@ -3555,7 +3560,7 @@ handle_workspace_switch  (MetaDisplay    *display,
               "Starting tab between workspaces, showing popup\n");
 
   /* FIXME should we use binding->mask ? */
-  grab_mask = event->xkey.state & ~(display->ignored_modifier_mask);
+  grab_mask = xev->mods.effective & ~(display->ignored_modifier_mask);
   
   if (!meta_display_begin_grab_op (display,
                                    screen,
@@ -3565,7 +3570,7 @@ handle_workspace_switch  (MetaDisplay    *display,
                                    FALSE,
                                    0,
                                    grab_mask,
-                                   event->xkey.time,
+                                   xev->time,
                                    0, 0))
     return;
 
@@ -3583,10 +3588,10 @@ handle_workspace_switch  (MetaDisplay    *display,
        * release event. Must end grab before we can switch
        * spaces.
        */
-      meta_display_end_grab_op (display, event->xkey.time);
+      meta_display_end_grab_op (display, xev->time);
     }
 
-  meta_workspace_activate (next, event->xkey.time);
+  meta_workspace_activate (next, xev->time);
 
   if (grabbed_before_release && !meta_prefs_get_no_tab_popup ())
     meta_screen_workspace_popup_create (screen, next);
@@ -3596,7 +3601,7 @@ static void
 handle_set_spew_mark (MetaDisplay    *display,
                   MetaScreen     *screen,
                   MetaWindow     *window,
-                  XEvent         *event,
+                  XIDeviceEvent *xev,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -3653,12 +3658,12 @@ void
 meta_keybindings_switch_window (MetaDisplay    *display,
                                 MetaScreen     *screen,
                                 MetaWindow     *event_window,
-                                XEvent         *event,
+                                XIDeviceEvent  *xev,
                                 MetaKeyBinding *binding)
 {
   gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
 
-  do_choose_window (display, screen, event_window, event, binding,
+  do_choose_window (display, screen, event_window, xev, binding,
                     backwards, FALSE);
 }
 
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 33fff73..f9d1674 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -562,7 +562,8 @@ gboolean meta_window_property_notify   (MetaWindow *window,
 gboolean meta_window_client_message    (MetaWindow *window,
                                         XEvent     *event);
 gboolean meta_window_notify_focus      (MetaWindow *window,
-                                        XEvent     *event);
+                                        XIEnterEvent *xev);
+void     meta_window_unmap_notify      (MetaWindow *window);
 
 void     meta_window_set_current_workspace_hint (MetaWindow *window);
 
@@ -586,7 +587,7 @@ void meta_window_handle_mouse_grab_op_sync_event (MetaWindow *window,
 #endif /* HAVE_XSYNC */
 
 void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
-                                             XEvent     *event);
+                                             XIDeviceEvent *xev);
 
 GList* meta_window_get_workspaces (MetaWindow *window);
 
diff --git a/src/core/window.c b/src/core/window.c
index e64c265..7a9d114 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6826,9 +6826,45 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
     }
 }
 
+void
+meta_window_unmap_notify (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 *xev)
 {
   /* note the event can be on either the window or the frame,
    * we focus the frame for shaded windows
@@ -6851,20 +6887,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" :
+              xev->evtype == XI_FocusIn ? "in" :
+              xev->evtype == XI_FocusOut ? "out" :
               "???",
-              window->desc, event->xany.window,
-              event->xany.window == window->xwindow ?
+              window->desc, xev->event,
+              xev->event == window->xwindow ?
               "client window" :
-              (window->frame && event->xany.window == window->frame->xwindow) ?
+              (window->frame && xev->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 (xev->mode),
+              meta_event_detail_to_string (xev->detail));
 
   /* FIXME our pointer tracking is broken; see how
    * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c
@@ -6885,19 +6918,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 ((xev->evtype == XI_FocusIn ||
+       xev->evtype == XI_FocusOut) &&
+      (xev->mode == NotifyGrab ||
+       xev->mode == NotifyUngrab ||
        /* From WindowMaker, ignore all funky pointer root events */
-       event->xfocus.detail > NotifyNonlinearVirtual))
+       xev->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 (xev->evtype == XI_FocusIn)
     {
       if (window->override_redirect)
         {
@@ -6977,11 +7010,9 @@ meta_window_notify_focus (MetaWindow *window,
           meta_window_propagate_focus_appearance (window, TRUE);
         }
     }
-  else if (event->type == FocusOut ||
-           event->type == UnmapNotify)
+  else if (xev->evtype == XI_FocusOut)
     {
-      if (event->type == FocusOut &&
-          event->xfocus.detail == NotifyInferior)
+      if (xev->detail == NotifyInferior)
         {
           /* This event means the client moved focus to a subwindow */
           meta_topic (META_DEBUG_FOCUS,
@@ -6989,38 +7020,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_unmap_notify (window);
+        }
     }
 
   /* Now set _NET_ACTIVE_WINDOW hint */
@@ -9145,31 +9148,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;
@@ -9180,11 +9198,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;
@@ -9193,7 +9211,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;
 
@@ -9290,14 +9308,14 @@ meta_window_handle_mouse_grab_op_sync_event (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
@@ -9309,17 +9327,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);
@@ -9335,35 +9355,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);
             }
         }
diff --git a/src/meta/keybindings.h b/src/meta/keybindings.h
index 2cd2a37..c7707cc 100644
--- a/src/meta/keybindings.h
+++ b/src/meta/keybindings.h
@@ -38,7 +38,7 @@ gboolean meta_keybindings_set_custom_handler (const gchar        *name,
 void meta_keybindings_switch_window (MetaDisplay    *display,
 				     MetaScreen     *screen,
 				     MetaWindow     *event_window,
-				     XEvent         *event,
+                                     XIDeviceEvent  *event,
 				     MetaKeyBinding *binding);
 
 
diff --git a/src/meta/prefs.h b/src/meta/prefs.h
index f480f58..b7c0717 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -252,7 +252,7 @@ typedef struct
 typedef void (* MetaKeyHandlerFunc) (MetaDisplay    *display,
                                      MetaScreen     *screen,
                                      MetaWindow     *window,
-                                     XEvent         *event,
+                                     XIDeviceEvent  *event,
                                      MetaKeyBinding *binding,
                                      gpointer        user_data);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]