[mutter/wayland] wayland: Update keyboard state unconditionally



commit b3364cad3ecb3e4e0967c9177732acebc0b80462
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue Mar 18 18:00:48 2014 +0100

    wayland: Update keyboard state unconditionally
    
    In particular we need to know about all key events to keep the xkb
    state reliable even if the event is then consumed by a global shortcut
    or grab and never reaches any wayland client.
    
    We also need to keep track of all pressed keys at all times so that we
    can send an updated set or pressed keys to the focused client when a
    grab ends.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722847

 src/wayland/meta-wayland-keyboard.c |   55 ++++++++++++++++-------------------
 src/wayland/meta-wayland-keyboard.h |    4 ++
 src/wayland/meta-wayland-seat.c     |   23 ++++++++++++++-
 src/wayland/meta-wayland-seat.h     |    4 +-
 src/wayland/meta-wayland.c          |   29 ++++++++++++------
 5 files changed, 72 insertions(+), 43 deletions(-)
---
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index 7964b3f..5aac8fb 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -328,29 +328,6 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
 }
 
 static void
-set_modifiers (MetaWaylandKeyboard   *keyboard,
-               guint32                serial,
-               const ClutterKeyEvent *event)
-{
-  MetaWaylandKeyboardGrab *grab = keyboard->grab;
-  struct xkb_state *state = keyboard->xkb_info.state;
-  enum xkb_state_component changed_state;
-
-  changed_state = xkb_state_update_key (state,
-                                        event->hardware_keycode,
-                                        event->type == CLUTTER_KEY_PRESS ? XKB_KEY_DOWN : XKB_KEY_UP);
-  if (changed_state == 0)
-    return;
-
-  grab->interface->modifiers (grab,
-                              serial,
-                              xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
-                              xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
-                              xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
-                              xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
-}
-
-static void
 update_pressed_keys (MetaWaylandKeyboard   *keyboard,
                     uint32_t               evdev_code,
                     gboolean               is_press)
@@ -397,12 +374,36 @@ evdev_code (const ClutterKeyEvent *event)
   return event->hardware_keycode - 8;
 }
 
+void
+meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
+                              const ClutterKeyEvent *event)
+{
+  MetaWaylandKeyboardGrab *grab = keyboard->grab;
+  gboolean is_press = event->type == CLUTTER_KEY_PRESS;
+  struct xkb_state *state = keyboard->xkb_info.state;
+  enum xkb_state_component changed_state;
+
+  update_pressed_keys (keyboard, evdev_code (event), is_press);
+
+  changed_state = xkb_state_update_key (state,
+                                        event->hardware_keycode,
+                                        is_press ? XKB_KEY_DOWN : XKB_KEY_UP);
+  if (changed_state == 0)
+    return;
+
+  grab->interface->modifiers (grab,
+                              wl_display_next_serial (keyboard->display),
+                              xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
+                              xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
+                              xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
+                              xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
+}
+
 gboolean
 meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
                                     const ClutterKeyEvent *event)
 {
   gboolean is_press = event->type == CLUTTER_KEY_PRESS;
-  uint32_t serial;
   gboolean handled;
 
   /* Synthetic key events are for autorepeat. Ignore those, as
@@ -414,12 +415,6 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
                is_press ? "press" : "release",
                event->hardware_keycode);
 
-  update_pressed_keys (keyboard, evdev_code, is_press);
-
-  serial = wl_display_next_serial (keyboard->display);
-
-  set_modifiers (keyboard, serial, event);
-
   handled = keyboard->grab->interface->key (keyboard->grab,
                                            event->time,
                                            evdev_code (event),
diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h
index 468b9ce..13fbf0a 100644
--- a/src/wayland/meta-wayland-keyboard.h
+++ b/src/wayland/meta-wayland-keyboard.h
@@ -136,4 +136,8 @@ meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
 void
 meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard);
 
+void
+meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
+                              const ClutterKeyEvent *event);
+
 #endif /* __META_WAYLAND_KEYBOARD_H__ */
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index ed2ef55..85c244b 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -347,7 +347,7 @@ count_buttons (const ClutterEvent *event)
   return count;
 }
 
-void
+static void
 meta_wayland_seat_update_pointer (MetaWaylandSeat    *seat,
                                   const ClutterEvent *event)
 {
@@ -370,6 +370,27 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat    *seat,
     }
 }
 
+void
+meta_wayland_seat_update (MetaWaylandSeat    *seat,
+                          const ClutterEvent *event)
+{
+  switch (event->type)
+    {
+    case CLUTTER_MOTION:
+    case CLUTTER_BUTTON_PRESS:
+    case CLUTTER_BUTTON_RELEASE:
+    case CLUTTER_SCROLL:
+      meta_wayland_seat_update_pointer (seat, event);
+      break;
+    case CLUTTER_KEY_PRESS:
+    case CLUTTER_KEY_RELEASE:
+      meta_wayland_keyboard_update (&seat->keyboard, (const ClutterKeyEvent *) event);
+      break;
+    default:
+      break;
+    }
+}
+
 gboolean
 meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
                                 const ClutterEvent *event)
diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h
index 4293193..a038e2e 100644
--- a/src/wayland/meta-wayland-seat.h
+++ b/src/wayland/meta-wayland-seat.h
@@ -71,8 +71,8 @@ MetaWaylandSeat *
 meta_wayland_seat_new (struct wl_display *display);
 
 void
-meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
-                                  const ClutterEvent *event);
+meta_wayland_seat_update (MetaWaylandSeat    *seat,
+                          const ClutterEvent *event);
 
 gboolean
 meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index a13a920..a01d6f9 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -508,6 +508,15 @@ stage_destroy_cb (void)
   meta_quit (META_EXIT_SUCCESS);
 }
 
+/**
+ * meta_wayland_compositor_update:
+ * @compositor: the #MetaWaylandCompositor instance
+ * @event: the #ClutterEvent used to update @seat's state
+ *
+ * This is used to update display server state like updating cursor
+ * position and keeping track of buttons and keys pressed. It must be
+ * called for all input events coming from the underlying devices.
+ */
 void
 meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
                                 const ClutterEvent    *event)
@@ -536,18 +545,18 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
       meta_idle_monitor_reset_idletime (device_monitor);
     }
 
-  switch (event->type)
-    {
-    case CLUTTER_MOTION:
-    case CLUTTER_BUTTON_PRESS:
-    case CLUTTER_BUTTON_RELEASE:
-    case CLUTTER_SCROLL:
-      meta_wayland_seat_update_pointer (compositor->seat, event);
-    default:
-      break;
-    }
+  meta_wayland_seat_update (compositor->seat, event);
 }
 
+/**
+ * meta_wayland_compositor_handle_event:
+ * @compositor: the #MetaWaylandCompositor instance
+ * @event: the #ClutterEvent to be sent
+ *
+ * This method sends events to the focused wayland client, if any.
+ *
+ * Return value: whether @event was sent to a wayland client.
+ */
 gboolean
 meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
                                       const ClutterEvent    *event)


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