FreeBSD Bugzilla – Attachment 222886 Details for
Bug 244290
x11-wm/xfce4 does not see up arrow after reinstall
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Upstream patch requiring testing
libxfce4.diff (text/plain), 49.96 KB, created by
Guido Falsi
on 2021-02-28 19:18:25 UTC
(
hide
)
Description:
Upstream patch requiring testing
Filename:
MIME Type:
Creator:
Guido Falsi
Created:
2021-02-28 19:18:25 UTC
Size:
49.96 KB
patch
obsolete
>Index: Makefile >=================================================================== >--- Makefile (revision 566798) >+++ Makefile (working copy) >@@ -3,7 +3,7 @@ > > PORTNAME= libxfce4menu > PORTVERSION= 4.16.0 >-PORTREVISION= 1 >+PORTREVISION= 2 > CATEGORIES= x11 xfce > MASTER_SITES= XFCE > DISTNAME= libxfce4ui-${DISTVERSIONFULL} >Index: files/patch-libxfce4kbd-private_xfce-shortcuts-grabber.c >=================================================================== >--- files/patch-libxfce4kbd-private_xfce-shortcuts-grabber.c (revision 566798) >+++ files/patch-libxfce4kbd-private_xfce-shortcuts-grabber.c (nonexistent) >@@ -1,21 +0,0 @@ >---- libxfce4kbd-private/xfce-shortcuts-grabber.c.orig 2020-11-23 10:16:17 UTC >-+++ libxfce4kbd-private/xfce-shortcuts-grabber.c >-@@ -22,6 +22,8 @@ >- #include <config.h> >- #endif >- >-+#include <sys/param.h> >-+ >- #include <glib.h> >- #include <glib-object.h> >- >-@@ -180,6 +182,9 @@ xfce_shortcuts_grabber_keys_changed (GdkKeymap >- >- TRACE ("Keys changed, regrabbing"); >- >-+#ifdef __FreeBSD__ >-+ xfce_shortcuts_grabber_ungrab_all (grabber); >-+#endif >- xfce_shortcuts_grabber_grab_all (grabber); >- } >- > >Property changes on: files/patch-libxfce4kbd-private_xfce-shortcuts-grabber.c >___________________________________________________________________ >Deleted: fbsd:nokeywords >## -1 +0,0 ## >-yes >\ No newline at end of property >Deleted: svn:eol-style >## -1 +0,0 ## >-native >\ No newline at end of property >Deleted: svn:mime-type >## -1 +0,0 ## >-text/plain >\ No newline at end of property >Index: files/patch-shortcuts-grabber-fix-PR27 >=================================================================== >--- files/patch-shortcuts-grabber-fix-PR27 (revision 566798) >+++ files/patch-shortcuts-grabber-fix-PR27 (working copy) >@@ -1,21 +1,1324 @@ >---- libxfce4kbd-private/xfce-shortcuts-grabber.c.orig 2020-11-23 10:16:17 UTC >+From 7c1e0e71899d13f75fe4177454656049d3f35d54 Mon Sep 17 00:00:00 2001 >+From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> >+Date: Mon, 4 Jan 2021 17:01:04 +0100 >+Subject: [PATCH 1/5] shortcuts-grabber: Record xkb state group (Bug #33) >+ >+XkbGroupForCoreState(xevent->xkey.state) returns 0 even after a keyboard >+layout switch. Instead of using the XkbGroupForCoreState() function, this >+patch watches for XkbStateNotify events from which it obtains the xkb state >+group. >+ >+Closes: https://gitlab.xfce.org/xfce/libxfce4ui/-/issues/33 >+See also: https://gitlab.xfce.org/xfce/libxfce4ui/-/merge_requests/33 >+--- >+ libxfce4kbd-private/xfce-shortcuts-grabber.c | 38 ++++++++++++++++---- >+ 1 file changed, 31 insertions(+), 7 deletions(-) >+ >+diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c >+index 60ddfd7..9df45c3 100644 >+--- libxfce4kbd-private/xfce-shortcuts-grabber.c > +++ libxfce4kbd-private/xfce-shortcuts-grabber.c >-@@ -22,6 +22,8 @@ >- #include <config.h> >- #endif >+@@ -61,13 +61,14 @@ static void xfce_shortcuts_grabber_grab (XfceShortcutsGra >+ gboolean grab); >+ static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ GdkEvent *event, >+- XfceShortcutsGrabber *grabber); >++ gpointer data); > >-+#include <sys/param.h> >+ >+ >+ struct _XfceShortcutsGrabberPrivate >+ { >+ GHashTable *keys; >++ gint xkbEventType, xkbStateGroup; >+ }; >+ >+ typedef enum >+@@ -141,20 +142,26 @@ static void >+ xfce_shortcuts_grabber_constructed (GObject *object) >+ { >+ GdkDisplay *display; >++ Display *xdisplay; >+ GdkKeymap *keymap; >+ >+ XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object); >+ >+ display = gdk_display_get_default (); >++ xdisplay = GDK_DISPLAY_XDISPLAY (display); >+ keymap = gdk_keymap_get_for_display (display); >+ g_signal_connect (keymap, "keys-changed", G_CALLBACK (xfce_shortcuts_grabber_keys_changed), >+ grabber); >+ >++ if (G_UNLIKELY (!XkbQueryExtension (xdisplay, 0, &grabber->priv->xkbEventType, 0, 0, 0))) >++ grabber->priv->xkbEventType = -1; >++ grabber->priv->xkbStateGroup = -1; > + >- #include <glib.h> >- #include <glib-object.h> >+ /* Flush events before adding the event filter */ >+- XAllowEvents (GDK_DISPLAY_XDISPLAY (display), AsyncBoth, CurrentTime); >++ XAllowEvents (xdisplay, AsyncBoth, CurrentTime); > >-@@ -180,6 +182,9 @@ xfce_shortcuts_grabber_keys_changed (GdkKeymap >+ /* Add event filter */ >+- gdk_window_add_filter (NULL, (GdkFilterFunc) xfce_shortcuts_grabber_event_filter, grabber); >++ gdk_window_add_filter (NULL, xfce_shortcuts_grabber_event_filter, grabber); >+ } > >+ >+@@ -417,10 +424,11 @@ find_event_key (const gchar *shortcut, >+ >+ >+ static GdkFilterReturn >+-xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+- GdkEvent *event, >+- XfceShortcutsGrabber *grabber) >++xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >++ GdkEvent *event, >++ gpointer data) >+ { >++ XfceShortcutsGrabber *const grabber = data; >+ struct EventKeyFindContext context; >+ GdkKeymap *keymap; >+ GdkModifierType consumed, modifiers; >+@@ -434,6 +442,22 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ >+ xevent = (XEvent *) gdk_xevent; >+ >++ if (xevent->type == grabber->priv->xkbEventType) >++ { >++ const XkbEvent *e = (const XkbEvent*) xevent; >++ TRACE ("xkb event: any.xkb_type=%d", e->any.xkb_type); >++ if (e->any.xkb_type == XkbStateNotify) >++ { >++ TRACE ("xkb event: any.xkb_type=XkbStateNotify, state.group=%d", e->state.group); >++ if (grabber->priv->xkbStateGroup != e->state.group) >++ { >++ grabber->priv->xkbStateGroup = e->state.group; >++ xfce_shortcuts_grabber_ungrab_all (grabber); >++ xfce_shortcuts_grabber_grab_all (grabber); >++ } >++ } >++ } >++ >+ if (xevent->type != KeyPress) >+ return GDK_FILTER_CONTINUE; >+ >+@@ -450,7 +474,7 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ >+ gdk_keymap_translate_keyboard_state (keymap, xevent->xkey.keycode, >+ modifiers, >+- XkbGroupForCoreState (xevent->xkey.state), >++ grabber->priv->xkbStateGroup, >+ &keyval, NULL, NULL, &consumed); >+ >+ /* We want Alt + Print to be Alt + Print not SysReq. See bug #7897 */ >+-- >+GitLab >+ >+ >+From 5d34aac693e160de3d22d1700b89664dcac12394 Mon Sep 17 00:00:00 2001 >+From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> >+Date: Fri, 26 Feb 2021 05:27:16 +0100 >+Subject: [PATCH 2/5] shortcuts: Fix a memory leak >+ >+--- >+ libxfce4kbd-private/xfce-shortcuts-provider.c | 1 + >+ 1 file changed, 1 insertion(+) >+ >+diff --git a/libxfce4kbd-private/xfce-shortcuts-provider.c b/libxfce4kbd-private/xfce-shortcuts-provider.c >+index b7f7a47..83ab6c0 100644 >+--- libxfce4kbd-private/xfce-shortcuts-provider.c >++++ libxfce4kbd-private/xfce-shortcuts-provider.c >+@@ -711,6 +711,7 @@ void >+ xfce_shortcuts_free (GList *shortcuts) >+ { >+ g_list_foreach (shortcuts, (GFunc) (void (*)(void)) xfce_shortcut_free, NULL); >++ g_list_free (shortcuts); >+ } >+ >+ >+-- >+GitLab >+ >+ >+From c18f068ab2bd69647af6519e389d76728c1f924e Mon Sep 17 00:00:00 2001 >+From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> >+Date: Fri, 26 Feb 2021 05:57:42 +0100 >+Subject: [PATCH 3/5] shortcuts-grabber: Stop search when the first match is >+ found >+ >+--- >+ libxfce4kbd-private/xfce-shortcuts-grabber.c | 14 ++++++-------- >+ 1 file changed, 6 insertions(+), 8 deletions(-) >+ >+diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c >+index 9df45c3..61f8ef8 100644 >+--- libxfce4kbd-private/xfce-shortcuts-grabber.c >++++ libxfce4kbd-private/xfce-shortcuts-grabber.c >+@@ -391,10 +391,9 @@ xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, >+ >+ struct EventKeyFindContext >+ { >+- XfceShortcutsGrabber *grabber; >+- GdkModifierType modifiers; >+- guint keyval; >+- const gchar *result; >++ GdkModifierType modifiers; >++ guint keyval; >++ const gchar *result; >+ }; >+ >+ >+@@ -461,7 +460,6 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ if (xevent->type != KeyPress) >+ return GDK_FILTER_CONTINUE; >+ >+- context.grabber = grabber; >+ context.result = NULL; >+ timestamp = xevent->xkey.time; >+ >+@@ -520,9 +518,9 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ TRACE ("Looking for %s", raw_shortcut_name); >+ g_free (raw_shortcut_name); >+ >+- g_hash_table_foreach (grabber->priv->keys, >+- (GHFunc) (void (*)(void)) find_event_key, >+- &context); >++ g_hash_table_find (grabber->priv->keys, >++ (GHRFunc) (void (*)(void)) find_event_key, >++ &context); >+ >+ if (G_LIKELY (context.result != NULL)) >+ /* We had a positive match */ >+-- >+GitLab >+ >+ >+From 51deff8231b94f040060f663bcdb1c65d090884e Mon Sep 17 00:00:00 2001 >+From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> >+Date: Fri, 26 Feb 2021 06:52:04 +0100 >+Subject: [PATCH 4/5] shortcuts-grabber: Redesign shortcut regrabbing (Bug #33) >+MIME-Version: 1.0 >+Content-Type: text/plain; charset=UTF-8 >+Content-Transfer-Encoding: 8bit >+ >+This patch hopes to fix shortcut grabbing issues related to keyboard >+layouts while maintaining high performance. >+ >+The implementation uses a new hash-table for tracking the keycodes grabbed >+from the X server. The grabbed X11/Xorg keys are reference counted: >+X11 XGrabKey() is called once per a keycode+modifiers combination and >+X11 XUngrabKey() is called when the reference count of the combination >+drops to zero. It is common for the reference counts to, for example, >+reach the value of 4 if the user is using 4 keyboard layouts, in which >+case the new implementation will use a single XGrabKey() call compared >+to 4 such calls in previous implementations. >+ >+The grab_all() function has been removed and has been replaced by an >+optimized regrab_all() function which is more efficient than the sequence >+ungrab_all()+grab_all(). >+ >+Tested keyboard layouts: >+ - English >+ - English (Colemak) >+ - French (BÃPO) >+ - Slovak (QWERTY) >+ >+Test environments: >+ - Arch Linux (FR-BÃPO) >+ - FreeBSD (basic testing) >+ - Gentoo Linux (EN, EN-Colemak, SK-QWERTY) >+ - Xubuntu (basic testing) >+ >+Closes: https://gitlab.xfce.org/xfce/libxfce4ui/-/issues/33 >+--- >+ libxfce4kbd-private/xfce-shortcuts-grabber.c | 598 ++++++++++++++----- >+ 1 file changed, 449 insertions(+), 149 deletions(-) >+ >+diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c >+index 61f8ef8..1de5929 100644 >+--- libxfce4kbd-private/xfce-shortcuts-grabber.c >++++ libxfce4kbd-private/xfce-shortcuts-grabber.c >+@@ -54,11 +54,13 @@ static void xfce_shortcuts_grabber_constructed (GObject >+ static void xfce_shortcuts_grabber_finalize (GObject *object); >+ static void xfce_shortcuts_grabber_keys_changed (GdkKeymap *keymap, >+ XfceShortcutsGrabber *grabber); >+-static void xfce_shortcuts_grabber_grab_all (XfceShortcutsGrabber *grabber); >++static void xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber); >+ static void xfce_shortcuts_grabber_ungrab_all (XfceShortcutsGrabber *grabber); >+ static void xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, >++ XfceKey *key); >++static void xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, >+ XfceKey *key, >+- gboolean grab); >++ gboolean trace); >+ static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ GdkEvent *event, >+ gpointer data); >+@@ -67,25 +69,37 @@ static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent >+ >+ struct _XfceShortcutsGrabberPrivate >+ { >++ /* Maps a shortcut string to a pointer to XfceKey */ >+ GHashTable *keys; >+- gint xkbEventType, xkbStateGroup; >+-}; >+ >+-typedef enum >+-{ >+- UNDEFINED_GRAB_STATE = 0, /* Initial value after g_new0(XfceKey) */ >+- NOT_GRABBED, >+- GRABBED, >+-} XfceKeyGrabState; >++ /* Maps an XfceXGrab to a reference count. >++ * The reference count tracks the number of shortcuts that grab the XfceXGrab. */ >++ GHashTable *grabbed_keycodes; >++ >++ gint xkbEventType, xkbStateGroup; >++}; >+ >+ struct _XfceKey >+ { >+ guint keyval; >+- guint modifiers; >+- GArray *keycodes; >+- XfceKeyGrabState grab_state; >++ GdkModifierType modifiers; >++ >++ /* Information about how the key has been grabbed */ >++ guint n_keys; /* Equals 0 if the key isn't grabbed */ >++ GdkKeymapKey *keys; >++ GdkModifierType non_virtual_modifiers; >++ guint numlock_modifier; >+ }; >+ >++typedef struct >++{ >++ guint keycode; >++ GdkModifierType non_virtual_modifiers; >++ guint numlock_modifier; >++} XfceXGrab; >++ >++typedef guint XfceXGrabRefcount; >++ >+ >+ >+ G_DEFINE_TYPE (XfceShortcutsGrabber, xfce_shortcuts_grabber, G_TYPE_OBJECT) >+@@ -117,6 +131,45 @@ xfce_shortcuts_grabber_class_init (XfceShortcutsGrabberClass *klass) >+ >+ >+ >++static void >++free_key (gpointer data) >++{ >++ XfceKey *key = data; >++ g_free (key->keys); >++ g_free (key); >++} >++ >++static gboolean >++xgrab_equal (gconstpointer data1, gconstpointer data2) >++{ >++ const XfceXGrab *a = data1; >++ const XfceXGrab *b = data2; >++ >++ if (a == b) >++ return TRUE; >++ >++ return a->keycode == b->keycode && >++ a->non_virtual_modifiers == b->non_virtual_modifiers && >++ a->numlock_modifier == b->numlock_modifier; >++} >++ >++static void >++xgrab_free (gpointer data) >++{ >++ XfceXGrab *g = data; >++ g_free (g); >++} >++ >++static guint >++xgrab_hash (gconstpointer data) >++{ >++ const XfceXGrab *g = data; >++ return g->keycode ^ g->non_virtual_modifiers ^ g->numlock_modifier; >++} >++ >++ >++ >++ >+ static void >+ xfce_shortcuts_grabber_init (XfceShortcutsGrabber *grabber) >+ { >+@@ -124,7 +177,8 @@ xfce_shortcuts_grabber_init (XfceShortcutsGrabber *grabber) >+ GdkKeymap *keymap; >+ >+ grabber->priv = XFCE_SHORTCUTS_GRABBER_GET_PRIVATE (grabber); >+- grabber->priv->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); >++ grabber->priv->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_key); >++ grabber->priv->grabbed_keycodes = g_hash_table_new_full (xgrab_hash, xgrab_equal, xgrab_free, g_free); >+ >+ /* Workaround: Make sure modmap is up to date >+ * There is possibly a bug in GTK+ where virtual modifiers are not >+@@ -173,6 +227,7 @@ xfce_shortcuts_grabber_finalize (GObject *object) >+ >+ xfce_shortcuts_grabber_ungrab_all (grabber); >+ g_hash_table_unref (grabber->priv->keys); >++ g_hash_table_unref (grabber->priv->grabbed_keycodes); >+ >+ (*G_OBJECT_CLASS (xfce_shortcuts_grabber_parent_class)->finalize) (object); >+ } >+@@ -187,29 +242,73 @@ xfce_shortcuts_grabber_keys_changed (GdkKeymap *keymap, >+ > TRACE ("Keys changed, regrabbing"); > >-+#ifdef __FreeBSD__ >-+ xfce_shortcuts_grabber_ungrab_all (grabber); >+- xfce_shortcuts_grabber_grab_all (grabber); >++ xfce_shortcuts_grabber_regrab_all (grabber); >+ } >+ >+ >+ >+ static gboolean >+-grab_key (const gchar *shortcut, >+- XfceKey *key, >+- XfceShortcutsGrabber *grabber) >++xfce_shortcuts_grabber_xgrab (XfceXGrab g, gboolean grab) >+ { >+- xfce_shortcuts_grabber_grab (grabber, key, TRUE); >+- return FALSE; >+-} >++ GdkDisplay *display = gdk_display_get_default (); >++ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); >++ Window root_window; >++ guint k; >++ gboolean success = TRUE; >++ >++ /* Ignorable modifiers */ >++ const guint mod_masks [] = { >++ 0, >++ GDK_MOD2_MASK, >++ g.numlock_modifier | GDK_MOD2_MASK, >++ GDK_LOCK_MASK, >++ g.numlock_modifier | GDK_LOCK_MASK, >++ GDK_MOD5_MASK, >++ g.numlock_modifier | GDK_MOD5_MASK, >++ GDK_MOD2_MASK | GDK_LOCK_MASK, >++ g.numlock_modifier | GDK_MOD2_MASK | GDK_LOCK_MASK, >++ GDK_MOD2_MASK | GDK_MOD5_MASK, >++ g.numlock_modifier | GDK_MOD2_MASK | GDK_MOD5_MASK, >++ GDK_LOCK_MASK | GDK_MOD5_MASK, >++ g.numlock_modifier | GDK_LOCK_MASK | GDK_MOD5_MASK, >++ GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD5_MASK, >++ g.numlock_modifier | GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD5_MASK, >++ }; >++ >++ /* Retrieve the root window of the screen */ >++ root_window = GDK_WINDOW_XID (gdk_screen_get_root_window (gdk_display_get_default_screen (display))); >++ >++ TRACE ("%s keycode %u, non_virtual_modifiers 0x%x", >++ grab ? "Grabbing" : "Ungrabbing", >++ g.keycode, g.non_virtual_modifiers); >+ >++ gdk_x11_display_error_trap_push (display); >+ >++ for (k = 0; k < G_N_ELEMENTS (mod_masks); k++) >++ { >++ /* Take ignorable modifiers into account when grabbing/ungrabbing */ >++ if (grab) >++ XGrabKey (xdisplay, >++ g.keycode, >++ g.non_virtual_modifiers | mod_masks [k], >++ root_window, >++ False, GrabModeAsync, GrabModeAsync); >++ else >++ XUngrabKey (xdisplay, >++ g.keycode, >++ g.non_virtual_modifiers | mod_masks [k], >++ root_window); >++ } >+ >+-static void >+-xfce_shortcuts_grabber_grab_all (XfceShortcutsGrabber *grabber) >+-{ >+- g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber)); >+- g_hash_table_foreach (grabber->priv->keys, >+- (GHFunc) (void (*)(void)) grab_key, >+- grabber); >++ gdk_display_flush (display); >++ if (gdk_x11_display_error_trap_pop (display)) >++ { >++ g_warning ("Failed to %s keycode %u", >++ grab ? "grab" : "ungrab", g.keycode); >++ success = FALSE; >++ } >++ >++ return success; >+ } >+ >+ >+@@ -219,7 +318,7 @@ ungrab_key (const gchar *shortcut, >+ XfceKey *key, >+ XfceShortcutsGrabber *grabber) >+ { >+- xfce_shortcuts_grabber_grab (grabber, key, FALSE); >++ xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >+ return FALSE; >+ } >+ >+@@ -236,155 +335,358 @@ xfce_shortcuts_grabber_ungrab_all (XfceShortcutsGrabber *grabber) >+ >+ >+ >++static gboolean >++get_entries_for_keyval (GdkKeymap *keymap, >++ guint keyval, >++ GdkKeymapKey **keys, >++ gint *n_keys) >++{ >++ /* Get all keys generating keyval */ >++ if (!gdk_keymap_get_entries_for_keyval (keymap, keyval, keys, n_keys)) >++ { >++ TRACE ("Got no keys for keyval"); >++ return FALSE; >++ } >++ >++ if (G_UNLIKELY (*n_keys <= 0)) >++ { >++ g_free (*keys); >++ return FALSE; >++ } >++ >++ return TRUE; >++} >++ >++ >++ >++static gboolean >++map_virtual_modifiers (GdkKeymap *keymap, >++ GdkModifierType virtual_modifiers, >++ GdkModifierType *non_virtual_modifiers) >++{ >++ /* Map virtual modifiers to non-virtual modifiers */ >++ GdkModifierType non_virtual = virtual_modifiers; >++ if (!gdk_keymap_map_virtual_modifiers (keymap, &non_virtual)) >++ return FALSE; >++ >++ if (non_virtual == virtual_modifiers && >++ (GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK) & non_virtual) >++ { >++ TRACE ("Failed to map virtual modifiers"); >++ return FALSE; >++ } >++ >++ *non_virtual_modifiers = non_virtual; >++ return TRUE; >++} >++ >++ >++ >++ >+ static void >+-xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, >+- XfceKey *key, >+- gboolean grab) >++xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ { >+- GdkModifierType numlock_modifier; >+- GdkKeymapKey *keys; >+- GdkDisplay *display; >+- GdkKeymap *keymap; >+- gchar *shortcut_name; >+- guint modifiers; >+- guint k; >+- gint i; >+- gint j; >+- gint n_keys; >+- gint screens; >++ GdkDisplay *display; >++ Display *xdisplay; >++ GdkKeymap *keymap; >++ guint numlock_modifier; >++ GHashTable *grabbed_keycodes; >++ GHashTableIter iter; >++ gpointer hash_value; >++ guint n_already_grabbed = 0; >++ guint n_regrab = 0; >++ XfceKey **regrab; /* list of keys to re-grab */ >++ guint i; >+ >+ g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber)); >+- g_return_if_fail (key != NULL); >+- >+- if (key->grab_state == (grab ? GRABBED : NOT_GRABBED)) { >+- TRACE (grab ? "Key already grabbed" : "Key already ungrabbed"); >+- return; >+- } >+- key->grab_state = UNDEFINED_GRAB_STATE; >+ >+ display = gdk_display_get_default (); >+- screens = 1; >++ xdisplay = GDK_DISPLAY_XDISPLAY (display); >+ keymap = gdk_keymap_get_for_display (display); >++ numlock_modifier = XkbKeysymToModifiers (xdisplay, GDK_KEY_Num_Lock); >++ grabbed_keycodes = grabber->priv->grabbed_keycodes; >++ >++ regrab = g_malloc (g_hash_table_size (grabber->priv->keys) * sizeof (*regrab)); >++ >++ /* Phase 1: Ungrab all keys that need to be re-grabbed >++ * and collect them into the 'regrab' list */ >++ g_hash_table_iter_init (&iter, grabber->priv->keys); >++ while (g_hash_table_iter_next (&iter, NULL, &hash_value)) >++ { >++ XfceKey *const key = hash_value; >++ GdkKeymapKey *keys; >++ GdkModifierType non_virtual_modifiers; >++ gint n_keys; >++ gboolean already_grabbed; >++ >++ if (!map_virtual_modifiers (keymap, key->modifiers, &non_virtual_modifiers)) >++ continue; >++ if (!get_entries_for_keyval (keymap, key->keyval, &keys, &n_keys)) >++ continue; >++ >++ already_grabbed = TRUE; >++ if (key->n_keys == (guint) n_keys && >++ key->non_virtual_modifiers == non_virtual_modifiers && >++ key->numlock_modifier == numlock_modifier) >++ { >++ gint j; >++ for (j = 0; j < n_keys; j++) >++ if (memcmp (&key->keys[j], &keys[j], sizeof(*keys)) != 0) >++ { >++ already_grabbed = FALSE; >++ break; >++ } >++ } >++ else >++ already_grabbed = FALSE; >++ >++ if (already_grabbed) >++ { >++ n_already_grabbed++; >++ g_free (keys); >++ } >++ else >++ { >++ /* Undo current X11 grabs of the key */ >++ xfce_shortcuts_grabber_ungrab (grabber, key, FALSE); >++ >++ /* Set key->keys to the keycodes that need to be grabbed in phase 2 */ >++ if (G_UNLIKELY (key->keys)) >++ { >++ g_free (key->keys); >++ key->keys = NULL; >++ } >++ key->n_keys = n_keys; >++ if (n_keys != 0) >++ key->keys = keys; >++ else >++ g_free (keys); >++ key->non_virtual_modifiers = non_virtual_modifiers; >++ key->numlock_modifier = numlock_modifier; >++ >++ /* Remember to grab the key in phase 2 */ >++ regrab[n_regrab++] = key; >++ } >++ } >+ >+- /* Map virtual modifiers to non-virtual modifiers */ >+- modifiers = key->modifiers; >+- gdk_keymap_map_virtual_modifiers (keymap, &modifiers); >++ TRACE ("n_already_grabbed=%u, n_regrab=%u", n_already_grabbed, n_regrab); >++ >++ /* Phase 2: Grab all keys that have been stored in the 'regrab' list */ >++ for (i = 0; i < n_regrab; i++) >++ { >++ XfceKey *const key = regrab[i]; >++ guint j; >++ >++#ifdef DEBUG_TRACE >++ gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >++ TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >++ TRACE (" key->n_keys: %d", key->n_keys); >++ g_free (shortcut_name); >++ shortcut_name = NULL; > +#endif >- xfce_shortcuts_grabber_grab_all (grabber); >+ >+- /* Debugging information */ >+- shortcut_name = gtk_accelerator_name (key->keyval, modifiers); >++ /* Grab all hardware keys generating keyval */ >++ for (j = 0; j < key->n_keys;) >++ { >++ XfceXGrab g; >++ gpointer refcount; >++ >++ g.keycode = key->keys[j].keycode; >++ g.non_virtual_modifiers = key->non_virtual_modifiers; >++ g.numlock_modifier = key->numlock_modifier; >++ if (!g_hash_table_lookup_extended (grabbed_keycodes, &g, NULL, &refcount)) >++ { >++ if (xfce_shortcuts_grabber_xgrab (g, TRUE)) >++ { >++ XfceXGrab *g1 = g_new (XfceXGrab, 1); >++ XfceXGrabRefcount *refcount1 = g_new (XfceXGrabRefcount, 1); >++ *g1 = g; >++ *refcount1 = 1; >++ g_hash_table_insert (grabbed_keycodes, g1, refcount1); >++ j++; >++ } >++ else >++ /* Failed to grab key->keys[j], remove it from key->keys */ >++ key->keys[j] = key->keys[--key->n_keys]; >++ } >++ else >++ { >++ // 'g' has already been grabbed, increment its refcount only >++ XfceXGrabRefcount *refcount1 = refcount; >++ (*refcount1)++; >++ TRACE ("keycode %u, non_virtual_modifiers 0x%x: ++refcount = %u", >++ g.keycode, g.non_virtual_modifiers, *refcount1); >++ j++; >++ } >++ } >++ >++ if (key->n_keys == 0 && key->keys != NULL) >++ { >++ g_free (key->keys); >++ key->keys = NULL; >++ } >++ } >+ >+- TRACE (grab ? "Grabbing %s" : "Ungrabbing %s", shortcut_name); >+- TRACE ("Keyval: %d", key->keyval); >+- TRACE ("Modifiers: 0x%x", modifiers); >++ g_free (regrab); >++} >+ >++ >++ >++static void >++xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, XfceKey *key) >++{ >++ GdkDisplay *display; >++ Display *xdisplay; >++ GdkKeymap *keymap; >++ guint numlock_modifier; >++ GHashTable *grabbed_keycodes; >++ GdkKeymapKey *keys; >++ GdkModifierType non_virtual_modifiers; >++ gint i, n_keys; >++#ifdef DEBUG_TRACE >++ gchar *shortcut_name; >++#endif >++ >++ display = gdk_display_get_default (); >++ xdisplay = GDK_DISPLAY_XDISPLAY (display); >++ keymap = gdk_keymap_get_for_display (display); >++ numlock_modifier = XkbKeysymToModifiers (xdisplay, GDK_KEY_Num_Lock); >++ grabbed_keycodes = grabber->priv->grabbed_keycodes; >++ >++ if (!map_virtual_modifiers (keymap, key->modifiers, &non_virtual_modifiers)) >++ return; >++ if (!get_entries_for_keyval (keymap, key->keyval, &keys, &n_keys)) >++ return; >++ >++#ifdef DEBUG_TRACE >++ shortcut_name = gtk_accelerator_name (key->keyval, non_virtual_modifiers); >++ TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" non_virtual_modifiers: 0x%x", non_virtual_modifiers); >++ TRACE (" n_keys: %d", n_keys); >+ g_free (shortcut_name); >++ shortcut_name = NULL; >++#endif >+ >+- if (modifiers == key->modifiers && >+- (GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK) & modifiers) >++ /* Undo old grabs (just in case there are some old grabs) */ >++ if (G_UNLIKELY (key->n_keys != 0)) >+ { >+- TRACE ("Failed to map virtual modifiers"); >+- return; >++ g_warning ("keyval %u already grabbed", key->keyval); >++ xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >+ } >+ >+- /* Get all keys generating keyval */ >+- if (!gdk_keymap_get_entries_for_keyval (keymap,key->keyval, >+- &keys, &n_keys)) >++ /* Grab all hardware keys generating keyval */ >++ for (i = 0; i < n_keys;) >+ { >+- TRACE ("Got no keys for keyval"); >+- return; >++ XfceXGrab g; >++ gpointer refcount; >++ >++ g.keycode = keys[i].keycode; >++ g.non_virtual_modifiers = non_virtual_modifiers; >++ g.numlock_modifier = numlock_modifier; >++ if (!g_hash_table_lookup_extended (grabbed_keycodes, &g, NULL, &refcount)) >++ { >++ if (xfce_shortcuts_grabber_xgrab (g, TRUE)) >++ { >++ XfceXGrab *g1 = g_new (XfceXGrab, 1); >++ XfceXGrabRefcount *refcount1 = g_new (XfceXGrabRefcount, 1); >++ *g1 = g; >++ *refcount1 = 1; >++ g_hash_table_insert (grabbed_keycodes, g1, refcount1); >++ TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: refcount := %u", >++ keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >++ i++; >++ } >++ else >++ /* Failed to grab keys[i], remove it from keys */ >++ keys[i] = keys[--n_keys]; >++ } >++ else >++ { >++ // 'g' has already been grabbed, increment its refcount only >++ XfceXGrabRefcount *refcount1 = refcount; >++ (*refcount1)++; >++ TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: ++refcount = %u", >++ keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >++ i++; >++ } >+ } >+ >+- if (n_keys == 0) >+- { >+- g_free (keys); >++ /* Set key->keys to the list of keys that been succesfully grabbed */ >++ g_free (key->keys); >++ key->keys = NULL; >++ key->n_keys = n_keys; >++ if (n_keys != 0) >++ key->keys = keys; >++ else >++ g_free (keys); >++ key->non_virtual_modifiers = non_virtual_modifiers; >++ key->numlock_modifier = numlock_modifier; >++} >+ >+- TRACE ("Got 0 keys for keyval"); >+- return; >+- } >++static void >++xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, XfceKey *key, >++ gboolean trace) >++{ >++ GHashTable *grabbed_keycodes; >++ guint i; >+ >+- numlock_modifier = >+- XkbKeysymToModifiers (GDK_DISPLAY_XDISPLAY (display), GDK_KEY_Num_Lock); >++ grabbed_keycodes = grabber->priv->grabbed_keycodes; >+ >+- key->grab_state = (grab ? GRABBED : NOT_GRABBED); >+- for (i = 0; i < n_keys; i ++) >++ if (trace) >+ { >+- /* Grab all hardware keys generating keyval */ >++ gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >++ TRACE ("Ungrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >++ TRACE (" key->n_keys: %u", key->n_keys); >++ g_free (shortcut_name); >++ } >+ >+- TRACE ("Keycode: %d", keys[i].keycode); >++ for (i = 0; i < key->n_keys; i++) >++ { >++ XfceXGrab g; >++ gpointer refcount; >+ >+- for (j = 0; j < screens; j++) >++ g.keycode = key->keys[i].keycode; >++ g.non_virtual_modifiers = key->non_virtual_modifiers; >++ g.numlock_modifier = key->numlock_modifier; >++ if (G_LIKELY (g_hash_table_lookup_extended (grabbed_keycodes, &g, NULL, &refcount))) >+ { >+- /* Do the grab on all screens */ >+- Window root_window; >+- >+- /* Ignorable modifiers */ >+- guint mod_masks [] = { >+- 0, >+- GDK_MOD2_MASK, >+- numlock_modifier | GDK_MOD2_MASK, >+- GDK_LOCK_MASK, >+- numlock_modifier | GDK_LOCK_MASK, >+- GDK_MOD5_MASK, >+- numlock_modifier | GDK_MOD5_MASK, >+- GDK_MOD2_MASK | GDK_LOCK_MASK, >+- numlock_modifier | GDK_MOD2_MASK | GDK_LOCK_MASK, >+- GDK_MOD2_MASK | GDK_MOD5_MASK, >+- numlock_modifier | GDK_MOD2_MASK | GDK_MOD5_MASK, >+- GDK_LOCK_MASK | GDK_MOD5_MASK, >+- numlock_modifier | GDK_LOCK_MASK | GDK_MOD5_MASK, >+- GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD5_MASK, >+- numlock_modifier | GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD5_MASK, >+- }; >+- >+- /* Retrieve the root window of the screen */ >+- root_window = GDK_WINDOW_XID (gdk_screen_get_root_window (gdk_display_get_default_screen (display))); >+- gdk_x11_display_error_trap_push (display); >+- >+- for (k = 0; k < G_N_ELEMENTS (mod_masks); k++) >++ XfceXGrabRefcount *refcount1 = refcount; >++ if (G_LIKELY (*refcount1 != 0)) >+ { >+- /* Take ignorable modifiers into account when grabbing */ >+- if (grab) >+- XGrabKey (GDK_DISPLAY_XDISPLAY (display), >+- keys[i].keycode, >+- modifiers | mod_masks [k], >+- root_window, >+- False, >+- GrabModeAsync, >+- GrabModeAsync); >+- else >++ (*refcount1)--; >++ if (trace) >++ TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: --refcount = %u", >++ key->keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >++ if(*refcount1 == 0) >+ { >+- if (i >= (gint) key->keycodes->len) >+- break; >+- XUngrabKey (GDK_DISPLAY_XDISPLAY (display), >+- g_array_index (key->keycodes, guint, i), >+- modifiers | mod_masks [k], >+- root_window); >++ xfce_shortcuts_grabber_xgrab (g, FALSE); >++ g_hash_table_remove (grabbed_keycodes, &g); >+ } >+ } >+- >+- gdk_display_flush (display); >+- >+- if (gdk_x11_display_error_trap_pop (display)) >++ else >+ { >+- TRACE (grab ? "Failed to grab" : "Failed to ungrab"); >+- key->grab_state = UNDEFINED_GRAB_STATE; >++ g_warning ("corrupted refcount"); >+ } >+ } >+- /* Remember the old keycode, as we need it to ungrab. */ >+- if (grab) >+- g_array_append_val (key->keycodes, keys[i].keycode); >+ else >+- g_array_index (key->keycodes, guint, i) = UINT_MAX; >+- } >+- >+- /* Cleanup elements containing UINT_MAX from the key->keycodes array */ >+- for (i = key->keycodes->len - 1; i >= 0; i --) >+- { >+- if (g_array_index (key->keycodes, guint, i) == UINT_MAX) >+- g_array_remove_index_fast (key->keycodes, i); >++ { >++ g_warning ("corrupted hashtable"); >++ } >+ } >+ >+- g_free (keys); >++ g_free (key->keys); >++ key->keys = NULL; >++ key->n_keys = 0; >++ key->non_virtual_modifiers = 0; >++ key->numlock_modifier = 0; > } > >+ >+@@ -451,8 +753,7 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ if (grabber->priv->xkbStateGroup != e->state.group) >+ { >+ grabber->priv->xkbStateGroup = e->state.group; >+- xfce_shortcuts_grabber_ungrab_all (grabber); >+- xfce_shortcuts_grabber_grab_all (grabber); >++ xfce_shortcuts_grabber_regrab_all (grabber); >+ } >+ } >+ } >+@@ -553,19 +854,18 @@ xfce_shortcuts_grabber_add (XfceShortcutsGrabber *grabber, >+ g_return_if_fail (shortcut != NULL); >+ >+ key = g_new0 (XfceKey, 1); >+- key->keycodes = g_array_new (FALSE, TRUE, sizeof (guint)); >+ >+ gtk_accelerator_parse (shortcut, &key->keyval, &key->modifiers); >++ TRACE ("parse %s -> keyval=0x%x, modifiers=0x%x", shortcut, key->keyval, key->modifiers); >+ >+ if (G_LIKELY (key->keyval != 0)) >+ { >+- xfce_shortcuts_grabber_grab (grabber, key, TRUE); >++ xfce_shortcuts_grabber_grab (grabber, key); >+ g_hash_table_insert (grabber->priv->keys, g_strdup (shortcut), key); >+ } >+ else >+ { >+- g_array_free (key->keycodes, TRUE); >+- g_free (key); >++ free_key (key); >+ } >+ } >+ >+@@ -584,7 +884,7 @@ xfce_shortcuts_grabber_remove (XfceShortcutsGrabber *grabber, >+ >+ if (G_LIKELY (key != NULL)) >+ { >+- xfce_shortcuts_grabber_grab (grabber, key, FALSE); >++ xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >+ g_hash_table_remove (grabber->priv->keys, shortcut); >+ } >+ } >+-- >+GitLab >+ >+ >+From 609b60be1ea7db9140a1d96ad4dccf7d9512b7fd Mon Sep 17 00:00:00 2001 >+From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> >+Date: Sat, 27 Feb 2021 17:34:41 +0100 >+Subject: [PATCH 5/5] shortcuts-grabber: Filter grabbing by key group >+ >+Closes: https://gitlab.xfce.org/xfce/libxfce4ui/-/issues/33 >+--- >+ libxfce4kbd-private/xfce-shortcuts-grabber.c | 162 ++++++++++++------- >+ 1 file changed, 106 insertions(+), 56 deletions(-) >+ >+diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c >+index 1de5929..4d21e4a 100644 >+--- libxfce4kbd-private/xfce-shortcuts-grabber.c >++++ libxfce4kbd-private/xfce-shortcuts-grabber.c >+@@ -59,8 +59,7 @@ static void xfce_shortcuts_grabber_ungrab_all (XfceShortcutsGra >+ static void xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, >+ XfceKey *key); >+ static void xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, >+- XfceKey *key, >+- gboolean trace); >++ XfceKey *key); >+ static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ GdkEvent *event, >+ gpointer data); >+@@ -318,7 +317,7 @@ ungrab_key (const gchar *shortcut, >+ XfceKey *key, >+ XfceShortcutsGrabber *grabber) >+ { >+- xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >++ xfce_shortcuts_grabber_ungrab (grabber, key); >+ return FALSE; >+ } >+ >+@@ -337,23 +336,67 @@ xfce_shortcuts_grabber_ungrab_all (XfceShortcutsGrabber *grabber) >+ >+ static gboolean >+ get_entries_for_keyval (GdkKeymap *keymap, >++ gint group, >+ guint keyval, >+ GdkKeymapKey **keys, >+- gint *n_keys) >++ guint *n_keys) >+ { >+- /* Get all keys generating keyval */ >+- if (!gdk_keymap_get_entries_for_keyval (keymap, keyval, keys, n_keys)) >++ GdkKeymapKey *keys1; >++ gint n_keys1; >++ >++ *keys = NULL; >++ *n_keys = 0; >++ >++ /* Get all keys generating keyval */ >++ if (!gdk_keymap_get_entries_for_keyval (keymap, keyval, &keys1, &n_keys1)) >+ { >+ TRACE ("Got no keys for keyval"); >+ return FALSE; >+ } >+ >+- if (G_UNLIKELY (*n_keys <= 0)) >++ if (G_UNLIKELY (n_keys1 <= 0)) >+ { >+- g_free (*keys); >++ g_free (keys1); >+ return FALSE; >+ } >+ >++ /* Filter keys by group */ >++ { >++ gboolean group0_only; >++ gint i, n_matches; >++ >++ /* For keys such as F12: >++ * keys1[i].group is always 0 (even if n_keys1 >= 2) >++ * and thus n_matches will be zero if group != 0 */ >++ >++ group0_only = TRUE; >++ n_matches = 0; >++ for (i = 0; i < n_keys1; i++) >++ { >++ group0_only &= (keys1[i].group == 0) ? TRUE : FALSE; >++ if (keys1[i].group == group) >++ n_matches++; >++ } >++ >++ if (!group0_only || n_matches != 0) >++ { >++ /* Remove keys that do not match the group*/ >++ for (i = 0; i < n_keys1;) >++ if (keys1[i].group == group) >++ i++; >++ else >++ keys1[i] = keys1[--n_keys1]; >++ } >++ } >++ >++ if (G_UNLIKELY (n_keys1 == 0)) >++ { >++ g_free (keys1); >++ keys1 = NULL; >++ } >++ >++ *keys = keys1; >++ *n_keys = n_keys1; >+ return TRUE; >+ } >+ >+@@ -397,6 +440,7 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ guint n_regrab = 0; >+ XfceKey **regrab; /* list of keys to re-grab */ >+ guint i; >++ gint group; >+ >+ g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber)); >+ >+@@ -405,6 +449,9 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ keymap = gdk_keymap_get_for_display (display); >+ numlock_modifier = XkbKeysymToModifiers (xdisplay, GDK_KEY_Num_Lock); >+ grabbed_keycodes = grabber->priv->grabbed_keycodes; >++ group = grabber->priv->xkbStateGroup; >++ if (G_UNLIKELY (group == -1)) >++ group = 0; >+ >+ regrab = g_malloc (g_hash_table_size (grabber->priv->keys) * sizeof (*regrab)); >+ >+@@ -416,20 +463,20 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ XfceKey *const key = hash_value; >+ GdkKeymapKey *keys; >+ GdkModifierType non_virtual_modifiers; >+- gint n_keys; >++ guint n_keys; >+ gboolean already_grabbed; >+ >+ if (!map_virtual_modifiers (keymap, key->modifiers, &non_virtual_modifiers)) >+ continue; >+- if (!get_entries_for_keyval (keymap, key->keyval, &keys, &n_keys)) >++ if (!get_entries_for_keyval (keymap, group, key->keyval, &keys, &n_keys)) >+ continue; >+ >+ already_grabbed = TRUE; >+- if (key->n_keys == (guint) n_keys && >++ if (key->n_keys == n_keys && >+ key->non_virtual_modifiers == non_virtual_modifiers && >+ key->numlock_modifier == numlock_modifier) >+ { >+- gint j; >++ guint j; >+ for (j = 0; j < n_keys; j++) >+ if (memcmp (&key->keys[j], &keys[j], sizeof(*keys)) != 0) >+ { >+@@ -448,7 +495,8 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ else >+ { >+ /* Undo current X11 grabs of the key */ >+- xfce_shortcuts_grabber_ungrab (grabber, key, FALSE); >++ if (key->n_keys != 0) >++ xfce_shortcuts_grabber_ungrab (grabber, key); >+ >+ /* Set key->keys to the keycodes that need to be grabbed in phase 2 */ >+ if (G_UNLIKELY (key->keys)) >+@@ -465,7 +513,8 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ key->numlock_modifier = numlock_modifier; >+ >+ /* Remember to grab the key in phase 2 */ >+- regrab[n_regrab++] = key; >++ if (n_keys != 0) >++ regrab[n_regrab++] = key; >+ } >+ } >+ >+@@ -478,14 +527,15 @@ xfce_shortcuts_grabber_regrab_all (XfceShortcutsGrabber *grabber) >+ guint j; >+ >+ #ifdef DEBUG_TRACE >+- gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >+- TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >+- TRACE (" key->keyval: %d", key->keyval); >+- TRACE (" key->modifiers: 0x%x", key->modifiers); >+- TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >+- TRACE (" key->n_keys: %d", key->n_keys); >+- g_free (shortcut_name); >+- shortcut_name = NULL; >++ { >++ gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >++ TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >++ TRACE (" key->n_keys: %u", key->n_keys); >++ g_free (shortcut_name); >++ } >+ #endif >+ >+ /* Grab all hardware keys generating keyval */ >+@@ -545,38 +595,40 @@ xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, XfceKey *key) >+ GHashTable *grabbed_keycodes; >+ GdkKeymapKey *keys; >+ GdkModifierType non_virtual_modifiers; >+- gint i, n_keys; >+-#ifdef DEBUG_TRACE >+- gchar *shortcut_name; >+-#endif >++ guint i, n_keys; >++ gint group; >+ >+ display = gdk_display_get_default (); >+ xdisplay = GDK_DISPLAY_XDISPLAY (display); >+ keymap = gdk_keymap_get_for_display (display); >+ numlock_modifier = XkbKeysymToModifiers (xdisplay, GDK_KEY_Num_Lock); >+ grabbed_keycodes = grabber->priv->grabbed_keycodes; >++ group = grabber->priv->xkbStateGroup; >++ if (G_UNLIKELY (group == -1)) >++ group = 0; >+ >+ if (!map_virtual_modifiers (keymap, key->modifiers, &non_virtual_modifiers)) >+ return; >+- if (!get_entries_for_keyval (keymap, key->keyval, &keys, &n_keys)) >++ if (!get_entries_for_keyval (keymap, group, key->keyval, &keys, &n_keys)) >+ return; >+ >+ #ifdef DEBUG_TRACE >+- shortcut_name = gtk_accelerator_name (key->keyval, non_virtual_modifiers); >+- TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >+- TRACE (" key->keyval: %d", key->keyval); >+- TRACE (" key->modifiers: 0x%x", key->modifiers); >+- TRACE (" non_virtual_modifiers: 0x%x", non_virtual_modifiers); >+- TRACE (" n_keys: %d", n_keys); >+- g_free (shortcut_name); >+- shortcut_name = NULL; >++ { >++ char *shortcut_name = gtk_accelerator_name (key->keyval, non_virtual_modifiers); >++ TRACE (key->n_keys==0 ? "Grabbing %s" : "Regrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" non_virtual_modifiers: 0x%x", non_virtual_modifiers); >++ TRACE (" n_keys: %u", n_keys); >++ g_free (shortcut_name); >++ } >+ #endif >+ >+ /* Undo old grabs (just in case there are some old grabs) */ >+ if (G_UNLIKELY (key->n_keys != 0)) >+ { >+ g_warning ("keyval %u already grabbed", key->keyval); >+- xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >++ xfce_shortcuts_grabber_ungrab (grabber, key); >+ } >+ >+ /* Grab all hardware keys generating keyval */ >+@@ -597,7 +649,7 @@ xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, XfceKey *key) >+ *g1 = g; >+ *refcount1 = 1; >+ g_hash_table_insert (grabbed_keycodes, g1, refcount1); >+- TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: refcount := %u", >++ TRACE ("group %d, keycode %u, non_virtual_modifiers 0x%x: refcount := %u", >+ keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >+ i++; >+ } >+@@ -610,7 +662,7 @@ xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, XfceKey *key) >+ // 'g' has already been grabbed, increment its refcount only >+ XfceXGrabRefcount *refcount1 = refcount; >+ (*refcount1)++; >+- TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: ++refcount = %u", >++ TRACE ("group %d, keycode %u, non_virtual_modifiers 0x%x: ++refcount = %u", >+ keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >+ i++; >+ } >+@@ -629,24 +681,24 @@ xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber, XfceKey *key) >+ } >+ >+ static void >+-xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, XfceKey *key, >+- gboolean trace) >++xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, XfceKey *key) >+ { >+ GHashTable *grabbed_keycodes; >+ guint i; >+ >+ grabbed_keycodes = grabber->priv->grabbed_keycodes; >+ >+- if (trace) >+- { >+- gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >+- TRACE ("Ungrabbing %s", shortcut_name); >+- TRACE (" key->keyval: %d", key->keyval); >+- TRACE (" key->modifiers: 0x%x", key->modifiers); >+- TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >+- TRACE (" key->n_keys: %u", key->n_keys); >+- g_free (shortcut_name); >+- } >++#ifdef DEBUG_TRACE >++ { >++ gchar *shortcut_name = gtk_accelerator_name (key->keyval, key->non_virtual_modifiers); >++ TRACE ("Ungrabbing %s", shortcut_name); >++ TRACE (" key->keyval: %d", key->keyval); >++ TRACE (" key->modifiers: 0x%x", key->modifiers); >++ TRACE (" key->non_virtual_modifiers: 0x%x", key->non_virtual_modifiers); >++ TRACE (" key->n_keys: %u", key->n_keys); >++ g_free (shortcut_name); >++ } >++#endif >+ >+ for (i = 0; i < key->n_keys; i++) >+ { >+@@ -662,9 +714,8 @@ xfce_shortcuts_grabber_ungrab (XfceShortcutsGrabber *grabber, XfceKey *key, >+ if (G_LIKELY (*refcount1 != 0)) >+ { >+ (*refcount1)--; >+- if (trace) >+- TRACE ("[group %d] keycode %u, non_virtual_modifiers 0x%x: --refcount = %u", >+- key->keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >++ TRACE ("group %d, keycode %u, non_virtual_modifiers 0x%x: --refcount = %u", >++ key->keys[i].group, g.keycode, g.non_virtual_modifiers, *refcount1); >+ if(*refcount1 == 0) >+ { >+ xfce_shortcuts_grabber_xgrab (g, FALSE); >+@@ -746,12 +797,11 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, >+ if (xevent->type == grabber->priv->xkbEventType) >+ { >+ const XkbEvent *e = (const XkbEvent*) xevent; >+- TRACE ("xkb event: any.xkb_type=%d", e->any.xkb_type); >+ if (e->any.xkb_type == XkbStateNotify) >+ { >+- TRACE ("xkb event: any.xkb_type=XkbStateNotify, state.group=%d", e->state.group); >+ if (grabber->priv->xkbStateGroup != e->state.group) >+ { >++ TRACE ("xkb event: any.xkb_type=XkbStateNotify, state.group=%d", e->state.group); >+ grabber->priv->xkbStateGroup = e->state.group; >+ xfce_shortcuts_grabber_regrab_all (grabber); >+ } >+@@ -884,7 +934,7 @@ xfce_shortcuts_grabber_remove (XfceShortcutsGrabber *grabber, >+ >+ if (G_LIKELY (key != NULL)) >+ { >+- xfce_shortcuts_grabber_ungrab (grabber, key, TRUE); >++ xfce_shortcuts_grabber_ungrab (grabber, key); >+ g_hash_table_remove (grabber->priv->keys, shortcut); >+ } >+ } >+-- >+GitLab >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 244290
:
214538
|
215420
|
221942
|
222475
| 222886