[mutter] Port mutter to use XInput2 events instead of Core Events



commit 1d827049d6bbb369a36c4a019a11adcd91e3d2b5
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
    
    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

 src/core/display.c             |  253 ++++++++++++++++++++-----------------
 src/core/keybindings-private.h |    6 +-
 src/core/keybindings.c         |  269 ++++++++++++++++++++--------------------
 src/core/window-private.h      |    5 +-
 src/core/window.c              |  206 +++++++++++++++++--------------
 src/meta/keybindings.h         |    2 +-
 src/meta/prefs.h               |    2 +-
 7 files changed, 394 insertions(+), 349 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 8902043..a8acc9e 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1796,23 +1796,36 @@ 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->xinput_opcode)
+    {
+      XIEvent *input_event;
+
+      /* NB: GDK event filters already have generic events
+       * allocated, so no need to do XGetEventData() on our own
+       */
+      input_event = (XIEvent *) event->xcookie.data;
+
+      switch (input_event->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 input_event;
+        default:
+          break;
+        }
+    }
 
   return NULL;
 }
@@ -1842,7 +1855,7 @@ event_callback (XEvent   *event,
   gboolean frame_was_receiver;
   gboolean bypass_compositor;
   gboolean filter_out_event;
-  XEvent *input_event;
+  XIEvent *input_event;
 
   display = data;
   
@@ -1876,8 +1889,8 @@ event_callback (XEvent   *event,
         }
     }
   else if (input_event &&
-           input_event->type == LeaveNotify &&
-           input_event->xcrossing.mode == NotifyUngrab &&
+           input_event->evtype == XI_Leave &&
+           ((XILeaveEvent *)input_event)->mode == NotifyUngrab &&
            modified == display->ungrab_should_not_cause_focus_window)
     {
       meta_display_add_ignored_crossing_serial (display, event->xany.serial);
@@ -1980,8 +1993,11 @@ event_callback (XEvent   *event,
 
   if (input_event != NULL)
     {
+      XIDeviceEvent *device_event = (XIDeviceEvent *) input_event;
+      XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
+
       if (window && !window->override_redirect &&
-          ((input_event->type == KeyPress) || (input_event->type == ButtonPress)))
+          ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress)))
         {
           if (CurrentTime == display->current_time)
             {
@@ -2000,10 +2016,10 @@ event_callback (XEvent   *event,
             }
         }
   
-      switch (input_event->type)
+      switch (input_event->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
@@ -2011,22 +2027,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 *) input_event))
             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 (device_event->detail == 4 || device_event->detail == 5)
             /* Scrollwheel event, do nothing and deliver event to compositor below */
             break;
 
           if ((window &&
                meta_grab_op_is_mouse (display->grab_op) &&
-               display->grab_button != (int) event->xbutton.button &&
+               display->grab_button != device_event->detail &&
                display->grab_window == window) ||
               grab_op_is_keyboard (display->grab_op))
             {
@@ -2042,14 +2058,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, device_event->event);
 
                   if (screen!=NULL)
                     meta_stack_set_positions (screen->stack,
                                               display->grab_old_window_stacking);
                 }
               meta_display_end_grab_op (display,
-                                        event->xbutton.time);
+                                        device_event->detail);
             }
           else if (window && display->grab_op == META_GRAB_OP_NONE)
             {
@@ -2066,10 +2082,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 = (device_event->mods.effective & grab_mask) == 0;
           
               if (unmodified ||
-                  event->xbutton.button == 1)
+                  device_event->detail == 1)
                 {
                   /* don't focus if frame received, will be lowered in
                    * frames.c or special-cased if the click was on a
@@ -2090,8 +2106,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, device_event->detail);
+                          meta_window_focus (window, device_event->time);
                         }
                       else
                         /* However, do allow terminals to lose focus due to new
@@ -2106,7 +2122,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 && device_event->detail == meta_prefs_get_mouse_button_resize())
                 {
                   if (window->has_resize_func)
                     {
@@ -2117,10 +2133,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 = device_event->root_x <  (root_x + 1 * window->rect.width  / 3);
+                      east = device_event->root_x >  (root_x + 2 * window->rect.width  / 3);
+                      north = device_event->root_y < (root_y + 1 * window->rect.height / 3);
+                      south = device_event->root_y > (root_y + 2 * window->rect.height / 3);
 
                       if (north && west)
                         op = META_GRAB_OP_RESIZING_NW;
@@ -2148,22 +2164,22 @@ event_callback (XEvent   *event,
                                                     op,
                                                     TRUE,
                                                     FALSE,
-                                                    event->xbutton.button,
+                                                    device_event->detail,
                                                     0,
-                                                    event->xbutton.time,
-                                                    event->xbutton.x_root,
-                                                    event->xbutton.y_root);
+                                                    device_event->time,
+                                                    device_event->root_x,
+                                                    device_event->root_y);
                     }
                 }
-              else if (event->xbutton.button == meta_prefs_get_mouse_button_menu())
+              else if (device_event->detail == meta_prefs_get_mouse_button_menu())
                 {
                   if (meta_prefs_get_raise_on_click ())
                     meta_window_raise (window);
                   meta_window_show_menu (window,
-                                         event->xbutton.x_root,
-                                         event->xbutton.y_root,
-                                         event->xbutton.button,
-                                         event->xbutton.time);
+                                         device_event->root_x,
+                                         device_event->root_y,
+                                         device_event->detail,
+                                         device_event->time);
                 }
 
               if (!frame_was_receiver && unmodified)
@@ -2185,16 +2201,16 @@ event_callback (XEvent   *event,
                       (display->focus_window == NULL ||
                        !meta_window_same_application (window,
                                                       display->focus_window)))
-                    mode = AsyncPointer; /* eat focus click */
+                    mode = XIAsyncDevice; /* eat focus click */
                   else
-                    mode = ReplayPointer; /* give event back */
+                    mode = XIReplayDevice; /* give event back */
 
                   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)device_event->time);
+
+                  XIAllowEvents (display->xdisplay, device_event->deviceid,
+                                 mode, device_event->time);
                 }
 
               if (begin_move && window->has_move_func)
@@ -2205,15 +2221,15 @@ event_callback (XEvent   *event,
                                               META_GRAB_OP_MOVING,
                                               TRUE,
                                               FALSE,
-                                              event->xbutton.button,
+                                              device_event->detail,
                                               0,
-                                              event->xbutton.time,
-                                              event->xbutton.x_root,
-                                              event->xbutton.y_root);
+                                              device_event->time,
+                                              device_event->root_x,
+                                              device_event->root_y);
                 }
             }
           break;
-        case ButtonRelease:
+        case XI_ButtonRelease:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
@@ -2221,17 +2237,17 @@ event_callback (XEvent   *event,
 
           if (display->grab_window == window &&
               meta_grab_op_is_mouse (display->grab_op))
-            meta_window_handle_mouse_grab_op_event (window, event);
+            meta_window_handle_mouse_grab_op_event (window, device_event);
           break;
-        case MotionNotify:
+        case XI_Motion:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
           if (display->grab_window == window &&
               meta_grab_op_is_mouse (display->grab_op))
-            meta_window_handle_mouse_grab_op_event (window, event);
+            meta_window_handle_mouse_grab_op_event (window, device_event);
           break;
-        case EnterNotify:
+        case XI_Enter:
           if (display->grab_op == META_GRAB_OP_COMPOSITOR)
             break;
 
@@ -2241,21 +2257,21 @@ event_callback (XEvent   *event,
            */
           {
             MetaScreen *new_screen = 
-              meta_display_screen_for_root (display, event->xcrossing.root);
+              meta_display_screen_for_root (display, enter_event->root);
 
             if (new_screen != NULL && display->active_screen != new_screen)
               meta_workspace_focus_default_window (new_screen->active_workspace, 
                                                    NULL,
-                                                   event->xcrossing.time);
+                                                   enter_event->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 &&
+              enter_event->mode != NotifyGrab && 
+              enter_event->mode != NotifyUngrab &&
+              enter_event->detail != NotifyInferior &&
               meta_display_focus_sentinel_clear (display))
             {
               switch (meta_prefs_get_focus_mode ())
@@ -2271,15 +2287,15 @@ event_callback (XEvent   *event,
                                   "and setting display->mouse_mode to TRUE.\n",
                                   window->desc,
                                   event->xany.serial,
-                                  event->xcrossing.time);
+                                  enter_event->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);
+                                                           enter_event->root_x,
+                                                           enter_event->root_y);
                       else
                         meta_display_mouse_mode_focus (display, window,
-                                                       event->xcrossing.time);
+                                                       enter_event->time);
 
                       /* stop ignoring stuff */
                       reset_ignored_crossing_serials (display);
@@ -2293,58 +2309,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 &&
+                  enter_event->mode != NotifyGrab &&
+                  enter_event->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, enter_event);
             }
           else if (meta_display_xwindow_is_a_no_focus_window (display,
-                                                              event->xany.window))
+                                                              enter_event->event))
             {
               meta_topic (META_DEBUG_FOCUS,
                           "Focus %s event received on no_focus_window 0x%lx "
                           "mode %s detail %s\n",
-                          input_event->type == FocusIn ? "in" :
-                          input_event->type == FocusOut ? "out" :
+                          enter_event->evtype == XI_FocusIn ? "in" :
+                          enter_event->evtype == XI_FocusOut ? "out" :
                           "???",
-                          event->xany.window,
-                          meta_event_mode_to_string (event->xfocus.mode),
-                          meta_event_detail_to_string (event->xfocus.detail));
+                          enter_event->event,
+                          meta_event_mode_to_string (enter_event->mode),
+                          meta_event_detail_to_string (enter_event->detail));
             }
           else
             {
               MetaScreen *screen =
                 meta_display_screen_for_root(display,
-                                             event->xany.window);
+                                             enter_event->event);
               if (screen == NULL)
                 break;
 
               meta_topic (META_DEBUG_FOCUS,
                           "Focus %s event received on root window 0x%lx "
                           "mode %s detail %s\n",
-                          input_event->type == FocusIn ? "in" :
-                          input_event->type == FocusOut ? "out" :
+                          enter_event->evtype == XI_FocusIn ? "in" :
+                          enter_event->evtype == XI_FocusOut ? "out" :
                           "???",
-                          event->xany.window,
-                          meta_event_mode_to_string (event->xfocus.mode),
-                          meta_event_detail_to_string (event->xfocus.detail));
+                          enter_event->event,
+                          meta_event_mode_to_string (enter_event->mode),
+                          meta_event_detail_to_string (enter_event->detail));
           
-              if (input_event->type == FocusIn &&
-                  event->xfocus.detail == NotifyDetailNone)
+              if (enter_event->evtype == XI_FocusIn &&
+                  enter_event->mode == NotifyDetailNone)
                 {
                   meta_topic (META_DEBUG_FOCUS, 
                               "Focus got set to None, probably due to "
@@ -2354,9 +2370,9 @@ event_callback (XEvent   *event,
                                                        NULL,
                                                        meta_display_get_current_time_roundtrip (display));
                 }
-              else if (input_event->type == FocusIn &&
-                       event->xfocus.mode == NotifyNormal &&
-                       event->xfocus.detail == NotifyInferior)
+              else if (enter_event->evtype == XI_FocusIn &&
+                       enter_event->mode == NotifyNormal &&
+                       enter_event->detail == NotifyInferior)
                 {
                   meta_topic (META_DEBUG_FOCUS,
                               "Focus got set to root window, probably due to "
@@ -2478,7 +2494,7 @@ event_callback (XEvent   *event,
                * and move focus to another window
                */
               if (window)
-                meta_window_notify_focus (window, event);
+                meta_window_lost_focus (window);
             }
           break;
         case MapNotify:
@@ -2883,15 +2899,28 @@ static Window
 event_get_modified_window (MetaDisplay *display,
                            XEvent *event)
 {
+  XIEvent *input_event = get_input_event (display, event);
+
+  if (input_event)
+    {
+      switch (input_event->evtype)
+        {
+        case XI_Motion:
+        case XI_ButtonPress:
+        case XI_ButtonRelease:
+        case XI_KeyPress:
+        case XI_KeyRelease:
+          return ((XIDeviceEvent *) input_event)->event;
+        case XI_FocusIn:
+        case XI_FocusOut:
+        case XI_Enter:
+        case XI_Leave:
+          return ((XIEnterEvent *) input_event)->event;
+        }
+    }
+
   switch (event->type)
     {
-    case KeyPress:
-    case KeyRelease:
-    case ButtonPress:
-    case ButtonRelease:
-    case MotionNotify:
-    case FocusIn:
-    case FocusOut:
     case KeymapNotify:
     case Expose:
     case GraphicsExpose:
@@ -2962,19 +2991,13 @@ static guint32
 event_get_time (MetaDisplay *display,
                 XEvent      *event)
 {
+  XIEvent *input_event = get_input_event (display, event);
+
+  if (input_event)
+    return input_event->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;
 
@@ -2983,10 +3006,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..c8a12b1 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 *event);
 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 2ec3c89..3821790 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  *event,
                                       MetaKeyBinding *binding,
                                       gpointer        dummy);
 
 static gboolean process_mouse_move_resize_grab (MetaDisplay *display,
                                                 MetaScreen  *screen,
                                                 MetaWindow  *window,
-                                                XEvent      *event,
+                                                XIDeviceEvent *event,
                                                 KeySym       keysym);
 
 static gboolean process_keyboard_move_grab (MetaDisplay *display,
                                             MetaScreen  *screen,
                                             MetaWindow  *window,
-                                            XEvent      *event,
+                                            XIDeviceEvent *event,
                                             KeySym       keysym);
 
 static gboolean process_keyboard_resize_grab (MetaDisplay *display,
                                               MetaScreen  *screen,
                                               MetaWindow  *window,
-                                              XEvent      *event,
+                                              XIDeviceEvent *event,
                                               KeySym       keysym);
 
 static gboolean process_tab_grab           (MetaDisplay *display,
                                             MetaScreen  *screen,
-                                            XEvent      *event,
+                                            XIDeviceEvent *event,
                                             KeySym       keysym);
 
 static gboolean process_workspace_switch_grab (MetaDisplay *display,
                                                MetaScreen  *screen,
-                                               XEvent      *event,
+                                               XIDeviceEvent *event,
                                                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  *event,
                 MetaKeyBinding *binding)
 
 {
@@ -1381,7 +1381,7 @@ invoke_handler_by_name (MetaDisplay    *display,
                         MetaScreen     *screen,
                         const char     *handler_name,
                         MetaWindow     *window,
-                        XEvent         *event)
+                        XIDeviceEvent  *event)
 {
   MetaKeyHandler *handler;
 
@@ -1397,14 +1397,14 @@ process_event (MetaKeyBinding       *bindings,
                MetaDisplay          *display,
                MetaScreen           *screen,
                MetaWindow           *window,
-               XEvent               *event,
+               XIDeviceEvent        *event,
                KeySym                keysym,
                gboolean              on_window)
 {
   int i;
 
   /* we used to have release-based bindings but no longer. */
-  if (event->type == KeyRelease)
+  if (event->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)) !=
+          event->evtype != XI_KeyPress ||
+          bindings[i].keycode != event->detail ||
+          ((event->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);
+                  event->detail, event->mods.effective);
 
       if (handler == NULL)
         meta_bug ("Binding %s has no handler\n", bindings[i].name);
@@ -1460,12 +1460,12 @@ process_event (MetaKeyBinding       *bindings,
 static gboolean
 process_overlay_key (MetaDisplay *display,
                      MetaScreen *screen,
-                     XEvent *event,
+                     XIDeviceEvent *event,
                      KeySym keysym)
 {
   if (display->overlay_key_only_pressed)
     {
-      if (event->xkey.keycode != display->overlay_key_combo.keycode)
+      if (event->detail != display->overlay_key_combo.keycode)
         {
           display->overlay_key_only_pressed = FALSE;
 
@@ -1490,21 +1490,24 @@ process_overlay_key (MetaDisplay *display,
                * 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, event->deviceid,
+                             XIAsyncDevice, event->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, event->deviceid,
+                             XIReplayDevice, event->time);
             }
         }
-      else if (event->xkey.type == KeyRelease)
+      else if (event->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, event->deviceid,
+                         XIAsyncDevice, event->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 (event->evtype == XI_KeyPress &&
+           event->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, event->deviceid,
+                     XISyncDevice, event->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 *event)
 {
   KeySym keysym;
   gboolean keep_grab;
@@ -1572,36 +1576,36 @@ 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, event->deviceid,
+                     XIReplayDevice, event->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, event->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, event->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, event->event))
     return FALSE;
   
   /* window may be NULL */
   
-  keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
+  keysym = XKeycodeToKeysym (display->xdisplay, event->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,
+              event->evtype == XI_KeyPress ? "press" : "release",
+              str ? str : "none", event->mods.effective,
               window ? window->desc : "(no window)");
 
   all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
@@ -1612,7 +1616,8 @@ meta_display_process_key_event (MetaDisplay *display,
         return TRUE;
     }
 
-  XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time);
+  XIAllowEvents (display->xdisplay, event->deviceid,
+                 XIAsyncDevice, event->time);
 
   keep_grab = TRUE;
   if (all_keys_grabbed)
@@ -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, event->time);
         }
 
       return TRUE;
@@ -1711,11 +1716,11 @@ static gboolean
 process_mouse_move_resize_grab (MetaDisplay *display,
                                 MetaScreen  *screen,
                                 MetaWindow  *window,
-                                XEvent      *event,
+                                XIDeviceEvent *event,
                                 KeySym       keysym)
 {
   /* don't care about releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (event->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 *event,
                             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 (event->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, event->detail))
     return TRUE;
 
   meta_window_get_position (window, &x, &y);
 
-  smart_snap = (event->xkey.state & ShiftMask) != 0;
+  smart_snap = (event->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 (event->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 *event,
                                         KeySym       keysym)
 {
   gboolean handled;
@@ -2002,7 +2007,7 @@ static gboolean
 process_keyboard_resize_grab (MetaDisplay *display,
                               MetaScreen  *screen,
                               MetaWindow  *window,
-                              XEvent      *event,
+                              XIDeviceEvent *event,
                               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 (event->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, event->detail))
     return TRUE;
 
   if (keysym == XK_Escape)
@@ -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 = (event->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 (event->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 *event,
                   KeySym       keysym)
 {
   MetaKeyBinding *binding;
@@ -2279,7 +2284,7 @@ process_tab_grab (MetaDisplay *display,
 
   binding = display_get_keybinding (display,
                                     keysym,
-                                    event->xkey.keycode,
+                                    event->detail,
                                     display->grab_mask);
   if (binding)
     action = meta_prefs_get_keybinding_action (binding->name);
@@ -2293,9 +2298,9 @@ process_tab_grab (MetaDisplay *display,
    */
   if (!screen->tab_popup)
     {
-      if (event->type == KeyRelease)
+      if (event->evtype == XI_KeyRelease)
         {
-          if (end_keyboard_grab (display, event->xkey.keycode))
+          if (end_keyboard_grab (display, event->detail))
             {
               invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event);
 
@@ -2346,7 +2351,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, event->detail))
               return TRUE;
           }
 
@@ -2359,8 +2364,8 @@ process_tab_grab (MetaDisplay *display,
       return FALSE;
     }
 
-  if (event->type == KeyRelease &&
-      end_keyboard_grab (display, event->xkey.keycode))
+  if (event->evtype == XI_KeyRelease &&
+      end_keyboard_grab (display, event->detail))
     {
       /* We're done, move to the new window. */
       MetaWindow *target_window;
@@ -2381,11 +2386,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, event->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, event->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2394,11 +2399,11 @@ process_tab_grab (MetaDisplay *display,
     }
   
   /* don't care about other releases, but eat them, don't end grab */
-  if (event->type == KeyRelease)
+  if (event->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, event->detail))
     return TRUE;
 
   prev_window = meta_screen_tab_popup_get_selected (screen);
@@ -2521,7 +2526,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 (event->mods.effective & ShiftMask)
         backward = !backward;
 
       if (backward)
@@ -2580,7 +2585,7 @@ static void
 handle_switch_to_workspace (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *event_window,
-                           XEvent         *event,
+                           XIDeviceEvent  *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2608,7 +2613,7 @@ handle_switch_to_workspace (MetaDisplay    *display,
   
   if (workspace)
     {
-      meta_workspace_activate (workspace, event->xkey.time);
+      meta_workspace_activate (workspace, event->time);
     }
   else
     {
@@ -2621,7 +2626,7 @@ static void
 handle_maximize_vertically (MetaDisplay    *display,
                       MetaScreen     *screen,
                       MetaWindow     *window,
-                      XEvent         *event,
+                      XIDeviceEvent  *event,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -2638,7 +2643,7 @@ static void
 handle_maximize_horizontally (MetaDisplay    *display,
                        MetaScreen     *screen,
                        MetaWindow     *window,
-                       XEvent         *event,
+                       XIDeviceEvent *event,
                        MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -2702,7 +2707,7 @@ static void
 handle_move_to_corner_nw  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2713,7 +2718,7 @@ static void
 handle_move_to_corner_ne  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2724,7 +2729,7 @@ static void
 handle_move_to_corner_sw  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2735,7 +2740,7 @@ static void
 handle_move_to_corner_se  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2746,7 +2751,7 @@ static void
 handle_move_to_side_n     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2757,7 +2762,7 @@ static void
 handle_move_to_side_s     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2768,7 +2773,7 @@ static void
 handle_move_to_side_e     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2779,7 +2784,7 @@ static void
 handle_move_to_side_w     (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -2790,7 +2795,7 @@ static void
 handle_move_to_center  (MetaDisplay    *display,
                         MetaScreen     *screen,
                         MetaWindow     *window,
-                        XEvent         *event,
+                        XIDeviceEvent *event,
                         MetaKeyBinding *binding,
                         gpointer        dummy)
 {
@@ -2817,7 +2822,7 @@ handle_move_to_center  (MetaDisplay    *display,
 static gboolean
 process_workspace_switch_grab (MetaDisplay *display,
                                MetaScreen  *screen,
-                               XEvent      *event,
+                               XIDeviceEvent *event,
                                KeySym       keysym)
 {
   MetaWorkspace *workspace;
@@ -2825,8 +2830,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 (event->evtype == XI_KeyRelease &&
+      end_keyboard_grab (display, event->detail))
     {
       /* We're done, move to the new workspace. */
       MetaWorkspace *target_workspace;
@@ -2840,14 +2845,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, event->time);
 
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Focusing default window on target workspace\n");
 
           meta_workspace_focus_default_window (target_workspace, 
                                                NULL,
-                                               event->xkey.time);
+                                               event->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2859,11 +2864,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 (event->evtype == XI_KeyRelease)
     return TRUE;
 
   /* don't end grab on modifier key presses */
-  if (is_modifier (display, event->xkey.keycode))
+  if (is_modifier (display, event->detail))
     return TRUE;
 
   /* select the next workspace in the popup */
@@ -2875,7 +2880,7 @@ process_workspace_switch_grab (MetaDisplay *display,
       MetaKeyBindingAction action;
 
       action = meta_display_get_keybinding_action (display,
-                                                   event->xkey.keycode,
+                                                   event->detail,
                                                    display->grab_mask);
 
       switch (action)
@@ -2914,7 +2919,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, event->time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2924,7 +2929,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, event->time);
   return FALSE;
 }
 
@@ -2932,7 +2937,7 @@ static void
 handle_show_desktop (MetaDisplay    *display,
                        MetaScreen     *screen,
                        MetaWindow     *window,
-                       XEvent         *event,
+                       XIDeviceEvent *event,
                        MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -2941,17 +2946,17 @@ handle_show_desktop (MetaDisplay    *display,
       meta_screen_unshow_desktop (screen);
       meta_workspace_focus_default_window (screen->active_workspace, 
                                            NULL,
-                                           event->xkey.time);
+                                           event->time);
     }
   else
-    meta_screen_show_desktop (screen, event->xkey.time);
+    meta_screen_show_desktop (screen, event->time);
 }
 
 static void
 handle_panel (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *event,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -2978,17 +2983,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] = event->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", event->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, event->time);
 
   XSendEvent (display->xdisplay,
 	      screen->xroot,
@@ -3003,7 +3008,7 @@ static void
 handle_activate_window_menu (MetaDisplay    *display,
                       MetaScreen     *screen,
                       MetaWindow     *event_window,
-                      XEvent         *event,
+                      XIDeviceEvent *event,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -3020,7 +3025,7 @@ handle_activate_window_menu (MetaDisplay    *display,
       meta_window_show_menu (display->focus_window,
                              x, y,
                              0,
-                             event->xkey.time);
+                             event->time);
     }
 }
 
@@ -3068,7 +3073,7 @@ static void
 do_choose_window (MetaDisplay    *display,
                   MetaScreen     *screen,
                   MetaWindow     *event_window,
-                  XEvent         *event,
+                  XIDeviceEvent *event,
                   MetaKeyBinding *binding,
                   gboolean        backward,
                   gboolean        show_popup)
@@ -3080,7 +3085,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 (event->mods.effective & ShiftMask)
     backward = !backward;
   
   initial_selection = meta_display_get_tab_next (display,
@@ -3113,7 +3118,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, event->time);
       return;
     }
 
@@ -3133,7 +3138,7 @@ do_choose_window (MetaDisplay    *display,
                                    FALSE,
                                    0,
                                    binding->mask,
-                                   event->xkey.time,
+                                   event->time,
                                    0, 0))
     return;
 
@@ -3148,9 +3153,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, event->time);
       display->mouse_mode = FALSE;
-      meta_window_activate (initial_selection, event->xkey.time);
+      meta_window_activate (initial_selection, event->time);
       return;
     }
 
@@ -3172,7 +3177,7 @@ static void
 handle_switch (MetaDisplay    *display,
                     MetaScreen     *screen,
                     MetaWindow     *event_window,
-                    XEvent         *event,
+                    XIDeviceEvent *event,
                     MetaKeyBinding *binding,
                     gpointer        dummy)
 {
@@ -3186,7 +3191,7 @@ static void
 handle_cycle (MetaDisplay    *display,
                     MetaScreen     *screen,
                     MetaWindow     *event_window,
-                    XEvent         *event,
+                    XIDeviceEvent *event,
                     MetaKeyBinding *binding,
                     gpointer        dummy)
 {
@@ -3200,7 +3205,7 @@ static void
 handle_tab_popup_select (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *event,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -3211,7 +3216,7 @@ static void
 handle_tab_popup_cancel (MetaDisplay    *display,
                          MetaScreen     *screen,
                          MetaWindow     *window,
-                         XEvent         *event,
+                         XIDeviceEvent *event,
                          MetaKeyBinding *binding,
                          gpointer        dummy)
 {
@@ -3222,7 +3227,7 @@ static void
 handle_toggle_fullscreen  (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3236,7 +3241,7 @@ static void
 handle_toggle_above       (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3250,7 +3255,7 @@ static void
 handle_toggle_tiled (MetaDisplay    *display,
                      MetaScreen     *screen,
                      MetaWindow     *window,
-                     XEvent         *event,
+                     XIDeviceEvent *event,
                      MetaKeyBinding *binding,
                      gpointer        dummy)
 {
@@ -3290,7 +3295,7 @@ static void
 handle_toggle_maximized    (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3308,7 +3313,7 @@ static void
 handle_maximize           (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3322,7 +3327,7 @@ static void
 handle_unmaximize         (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3336,33 +3341,33 @@ static void
 handle_toggle_shaded      (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
   if (window->shaded)
-    meta_window_unshade (window, event->xkey.time);
+    meta_window_unshade (window, event->time);
   else if (window->has_shade_func)
-    meta_window_shade (window, event->xkey.time);
+    meta_window_shade (window, event->time);
 }
 
 static void
 handle_close              (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
   if (window->has_close_func)
-    meta_window_delete (window, event->xkey.time);
+    meta_window_delete (window, event->time);
 }
 
 static void
 handle_minimize        (MetaDisplay    *display,
                         MetaScreen     *screen,
                         MetaWindow     *window,
-                        XEvent         *event,
+                        XIDeviceEvent *event,
                         MetaKeyBinding *binding,
                         gpointer        dummy)
 {
@@ -3374,7 +3379,7 @@ static void
 handle_begin_move         (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3383,7 +3388,7 @@ handle_begin_move         (MetaDisplay    *display,
       meta_window_begin_grab_op (window,
                                  META_GRAB_OP_KEYBOARD_MOVING,
                                  FALSE,
-                                 event->xkey.time);
+                                 event->time);
     }
 }
 
@@ -3391,7 +3396,7 @@ static void
 handle_begin_resize       (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3400,7 +3405,7 @@ handle_begin_resize       (MetaDisplay    *display,
       meta_window_begin_grab_op (window,
                                  META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
                                  FALSE,
-                                 event->xkey.time);
+                                 event->time);
     }
 }
 
@@ -3408,7 +3413,7 @@ static void
 handle_toggle_on_all_workspaces (MetaDisplay    *display,
                            MetaScreen     *screen,
                            MetaWindow     *window,
-                           XEvent         *event,
+                           XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3422,7 +3427,7 @@ static void
 handle_move_to_workspace  (MetaDisplay    *display,
                               MetaScreen     *screen,
                               MetaWindow     *window,
-                              XEvent         *event,
+                              XIDeviceEvent *event,
                            MetaKeyBinding *binding,
                            gpointer        dummy)
 {
@@ -3464,7 +3469,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);
+                                              event->time);
         }
     }
   else
@@ -3477,7 +3482,7 @@ static void
 handle_raise_or_lower (MetaDisplay    *display,
                        MetaScreen     *screen,
 		       MetaWindow     *window,
-		       XEvent         *event,
+		       XIDeviceEvent *event,
 		       MetaKeyBinding *binding,
                        gpointer        dummy)
 {
@@ -3524,7 +3529,7 @@ static void
 handle_raise (MetaDisplay    *display,
               MetaScreen     *screen,
               MetaWindow     *window,
-              XEvent         *event,
+              XIDeviceEvent *event,
               MetaKeyBinding *binding,
               gpointer        dummy)
 {
@@ -3535,7 +3540,7 @@ static void
 handle_lower (MetaDisplay    *display,
               MetaScreen     *screen,
               MetaWindow     *window,
-              XEvent         *event,
+              XIDeviceEvent *event,
               MetaKeyBinding *binding,
               gpointer        dummy)
 {
@@ -3546,7 +3551,7 @@ static void
 handle_workspace_switch  (MetaDisplay    *display,
                           MetaScreen     *screen,
                           MetaWindow     *window,
-                          XEvent         *event,
+                          XIDeviceEvent  *event,
                           MetaKeyBinding *binding,
                           gpointer        dummy)
 {
@@ -3561,7 +3566,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 = event->mods.effective & ~(display->ignored_modifier_mask);
   
   if (!meta_display_begin_grab_op (display,
                                    screen,
@@ -3571,7 +3576,7 @@ handle_workspace_switch  (MetaDisplay    *display,
                                    FALSE,
                                    0,
                                    grab_mask,
-                                   event->xkey.time,
+                                   event->time,
                                    0, 0))
     return;
 
@@ -3589,10 +3594,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, event->time);
     }
 
-  meta_workspace_activate (next, event->xkey.time);
+  meta_workspace_activate (next, event->time);
 
   if (grabbed_before_release && !meta_prefs_get_no_tab_popup ())
     meta_screen_workspace_popup_create (screen, next);
@@ -3602,7 +3607,7 @@ static void
 handle_set_spew_mark (MetaDisplay    *display,
                   MetaScreen     *screen,
                   MetaWindow     *window,
-                  XEvent         *event,
+                  XIDeviceEvent *event,
                       MetaKeyBinding *binding,
                       gpointer        dummy)
 {
@@ -3659,7 +3664,7 @@ void
 meta_keybindings_switch_window (MetaDisplay    *display,
                                 MetaScreen     *screen,
                                 MetaWindow     *event_window,
-                                XEvent         *event,
+                                XIDeviceEvent  *event,
                                 MetaKeyBinding *binding)
 {
   gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 1c81b99..712e023 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 *event);
+void     meta_window_lost_focus        (MetaWindow *window);
 
 void     meta_window_set_current_workspace_hint (MetaWindow *window);
 
@@ -586,7 +587,7 @@ void meta_window_update_sync_request_counter (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 13c6262..2942de6 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -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);
             }
         }
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 93e1919..0545127 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -254,7 +254,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]