diff -Nru mutter-3.28.3/debian/changelog mutter-3.28.3/debian/changelog --- mutter-3.28.3/debian/changelog 2018-08-03 12:20:10.000000000 +0800 +++ mutter-3.28.3/debian/changelog 2018-10-15 11:00:24.000000000 +0800 @@ -1,3 +1,11 @@ +mutter (3.28.3-2~ubuntu18.04.2) bionic-proposed; urgency=medium + + * d/p/clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch: + - clutter/x11: Implement keycode lookup from keysyms on virtual key + devices (LP: #1730211) + + -- Shih-Yuan Lee (FourDollars) Mon, 15 Oct 2018 11:00:24 +0800 + mutter (3.28.3-2~ubuntu18.04.1) bionic; urgency=medium * No-change backport from unstable to bionic diff -Nru mutter-3.28.3/debian/patches/clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch mutter-3.28.3/debian/patches/clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch --- mutter-3.28.3/debian/patches/clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch 1970-01-01 08:00:00.000000000 +0800 +++ mutter-3.28.3/debian/patches/clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch 2018-10-15 10:58:08.000000000 +0800 @@ -0,0 +1,315 @@ +From 85284acb000ddc70afcf716b6c198b4b5bf5741e Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 29 Jun 2018 14:31:23 +0200 +Subject: [PATCH] clutter/x11: Implement keycode lookup from keysyms on virtual + key devices + +Unfortunately XKeysymToKeycode() falls short in that it coalesces keysyms +into keycodes pertaining to the first level (i.e. lowercase). Add a +ClutterKeymapX11 method (much alike its GdkKeymap counterpart) to look up +all matches for the given keysym. + +Two other helper methods have been added so the virtual device can fetch +the current keyboard group, and latch modifiers for key emission. Combining +all this, the virtual device is now able to handle keycodes in further +levels. + +Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/135 +--- + clutter/clutter/x11/clutter-keymap-x11.c | 178 +++++++++++++++++- + clutter/clutter/x11/clutter-keymap-x11.h | 8 + + .../x11/clutter-virtual-input-device-x11.c | 22 ++- + 3 files changed, 204 insertions(+), 4 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c +index 914e31434..c34e676a4 100644 +--- a/clutter/clutter/x11/clutter-keymap-x11.c ++++ b/clutter/clutter/x11/clutter-keymap-x11.c +@@ -38,6 +38,14 @@ + + typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class; + typedef struct _DirectionCacheEntry DirectionCacheEntry; ++typedef struct _ClutterKeymapKey ClutterKeymapKey; ++ ++struct _ClutterKeymapKey ++{ ++ guint keycode; ++ guint group; ++ guint level; ++}; + + struct _DirectionCacheEntry + { +@@ -59,6 +67,7 @@ struct _ClutterKeymapX11 + + ClutterModifierType num_lock_mask; + ClutterModifierType scroll_lock_mask; ++ ClutterModifierType level3_shift_mask; + + PangoDirection current_direction; + +@@ -69,6 +78,7 @@ struct _ClutterKeymapX11 + Atom current_group_atom; + guint current_cache_serial; + DirectionCacheEntry group_direction_cache[4]; ++ int current_group; + #endif + + guint caps_lock_state : 1; +@@ -198,6 +208,9 @@ get_xkb (ClutterKeymapX11 *keymap_x11) + if (keymap_x11->scroll_lock_mask == 0) + keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy, + XK_Scroll_Lock); ++ if (keymap_x11->level3_shift_mask == 0) ++ keymap_x11->level3_shift_mask = XkbKeysymToModifiers (backend_x11->xdpy, ++ XK_ISO_Level3_Shift); + + return keymap_x11->xkb_desc; + } +@@ -469,6 +482,7 @@ static void + clutter_keymap_x11_init (ClutterKeymapX11 *keymap) + { + keymap->current_direction = PANGO_DIRECTION_NEUTRAL; ++ keymap->current_group = -1; + } + + static ClutterTranslateReturn +@@ -498,7 +512,8 @@ clutter_keymap_x11_translate_event (ClutterEventTranslator *translator, + { + case XkbStateNotify: + CLUTTER_NOTE (EVENT, "Updating keyboard state"); +- update_direction (keymap_x11, XkbStateGroup (&xkb_event->state)); ++ keymap_x11->current_group = XkbStateGroup (&xkb_event->state); ++ update_direction (keymap_x11, keymap_x11->current_group); + update_locked_mods (keymap_x11, xkb_event->state.locked_mods); + retval = CLUTTER_TRANSLATE_REMOVE; + break; +@@ -665,3 +680,164 @@ _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap) + #endif + return PANGO_DIRECTION_NEUTRAL; + } ++ ++static gboolean ++clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11, ++ guint keyval, ++ ClutterKeymapKey **keys, ++ gint *n_keys) ++{ ++#ifdef HAVE_XKB ++ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) ++ { ++ XkbDescRec *xkb = get_xkb (keymap_x11); ++ GArray *retval; ++ gint keycode; ++ ++ keycode = keymap_x11->min_keycode; ++ retval = g_array_new (FALSE, FALSE, sizeof (ClutterKeymapKey)); ++ ++ while (keycode <= keymap_x11->max_keycode) ++ { ++ gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); ++ gint group = 0; ++ gint level = 0; ++ gint total_syms = XkbKeyNumSyms (xkb, keycode); ++ gint i = 0; ++ KeySym *entry; ++ ++ /* entry is an array with all syms for group 0, all ++ * syms for group 1, etc. and for each group the ++ * shift level syms are in order ++ */ ++ entry = XkbKeySymsPtr (xkb, keycode); ++ ++ while (i < total_syms) ++ { ++ g_assert (i == (group * max_shift_levels + level)); ++ ++ if (entry[i] == keyval) ++ { ++ ClutterKeymapKey key; ++ ++ key.keycode = keycode; ++ key.group = group; ++ key.level = level; ++ ++ g_array_append_val (retval, key); ++ ++ g_assert (XkbKeySymEntry (xkb, keycode, level, group) == ++ keyval); ++ } ++ ++ ++level; ++ ++ if (level == max_shift_levels) ++ { ++ level = 0; ++ ++group; ++ } ++ ++ ++i; ++ } ++ ++ ++keycode; ++ } ++ ++ if (retval->len > 0) ++ { ++ *keys = (ClutterKeymapKey*) retval->data; ++ *n_keys = retval->len; ++ } ++ else ++ { ++ *keys = NULL; ++ *n_keys = 0; ++ } ++ ++ g_array_free (retval, retval->len > 0 ? FALSE : TRUE); ++ ++ return *n_keys > 0; ++ } ++ else ++#endif ++ { ++ return FALSE; ++ } ++} ++ ++void ++clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, ++ uint32_t level, ++ gboolean enable) ++{ ++#ifdef HAVE_XKB ++ ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); ++ uint32_t modifiers[] = { ++ 0, ++ ShiftMask, ++ keymap_x11->level3_shift_mask, ++ keymap_x11->level3_shift_mask | ShiftMask, ++ }; ++ uint32_t value = 0; ++ ++ if (!backend_x11->use_xkb) ++ return; ++ ++ level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1); ++ ++ if (enable) ++ value = modifiers[level]; ++ else ++ value = 0; ++ ++ XkbLatchModifiers (clutter_x11_get_default_display (), ++ XkbUseCoreKbd, modifiers[level], ++ value); ++#endif ++} ++ ++static uint32_t ++clutter_keymap_x11_get_current_group (ClutterKeymapX11 *keymap_x11) ++{ ++ ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); ++ XkbStateRec state_rec; ++ ++ if (keymap_x11->current_group >= 0) ++ return keymap_x11->current_group; ++ ++ XkbGetState (backend_x11->xdpy, XkbUseCoreKbd, &state_rec); ++ return XkbStateGroup (&state_rec); ++} ++ ++gboolean ++clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, ++ guint keyval, ++ guint *keycode_out, ++ guint *level_out) ++{ ++ ClutterKeymapKey *keys; ++ gint i, n_keys, group; ++ gboolean found = FALSE; ++ ++ g_return_val_if_fail (keycode_out != NULL, FALSE); ++ g_return_val_if_fail (level_out != NULL, FALSE); ++ ++ group = clutter_keymap_x11_get_current_group (keymap_x11); ++ ++ if (!clutter_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys)) ++ return FALSE; ++ ++ for (i = 0; i < n_keys && !found; i++) ++ { ++ if (keys[i].group == group) ++ { ++ *keycode_out = keys[i].keycode; ++ *level_out = keys[i].level; ++ found = TRUE; ++ } ++ } ++ ++ g_free (keys); ++ return found; ++} +diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h +index ad673a2a7..4b5b403c8 100644 +--- a/clutter/clutter/x11/clutter-keymap-x11.h ++++ b/clutter/clutter/x11/clutter-keymap-x11.h +@@ -51,6 +51,14 @@ gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap, + + PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap); + ++gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, ++ guint keyval, ++ guint *keycode_out, ++ guint *level_out); ++void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, ++ uint32_t level, ++ gboolean enable); ++ + G_END_DECLS + + #endif /* __CLUTTER_KEYMAP_X11_H__ */ +diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c +index 416c944b3..b86ded0d0 100644 +--- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c ++++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c +@@ -32,6 +32,8 @@ + + #include "clutter-virtual-input-device.h" + #include "x11/clutter-virtual-input-device-x11.h" ++#include "x11/clutter-backend-x11.h" ++#include "x11/clutter-keymap-x11.h" + + struct _ClutterVirtualInputDeviceX11 + { +@@ -135,11 +137,25 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu + uint32_t keyval, + ClutterKeyState key_state) + { +- KeyCode keycode; ++ ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); ++ ClutterKeymapX11 *keymap = backend_x11->keymap; ++ uint32_t keycode, level; ++ ++ if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) ++ { ++ g_warning ("No keycode found for keyval %x in current group", keyval); ++ return; ++ } ++ ++ if (key_state == CLUTTER_KEY_STATE_PRESSED) ++ clutter_keymap_x11_latch_modifiers (keymap, level, TRUE); + +- keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval); + XTestFakeKeyEvent (clutter_x11_get_default_display (), +- keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0); ++ (KeyCode) keycode, ++ key_state == CLUTTER_KEY_STATE_PRESSED, 0); ++ ++ if (key_state == CLUTTER_KEY_STATE_RELEASED) ++ clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); + } + + static void +-- +2.17.1 + diff -Nru mutter-3.28.3/debian/patches/series mutter-3.28.3/debian/patches/series --- mutter-3.28.3/debian/patches/series 2018-08-03 12:20:10.000000000 +0800 +++ mutter-3.28.3/debian/patches/series 2018-10-15 11:00:19.000000000 +0800 @@ -8,6 +8,7 @@ theme-use-gtk_render_icon_suface-to-paint-button-icon.patch theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch clutter-Smooth-out-master-clock-to-smooth-visuals.patch +clutter-x11-Implement-keycode-lookup-from-keysyms-on.patch core-Return-1-if-meta_window_get_monitor-is-called-on-an-.patch bgo768531_workaround-startup-notifications.patch debian/synaptics-support.patch