Author: jannis
Date: 2008-08-31 23:48:13 +0000 (Sun, 31 Aug 2008)
New Revision: 27632

Modified:
   xfce4-settings/trunk/ChangeLog
   xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
   xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c
Log:
        * dialogs/keyboard-settings/shortcuts-dialog.c,
          xfce4-settings-helper/keyboard-shortcuts.c: Add two new functions
          called get_modifier_masks() and get_ignore_mask(). The first
          determines to which of the Mod2-Mod5 modifiers CapsLock, NumLock and
          ScrollLock are mapped and generates a modifier mask for them. The
          latter combines this mask with the IGNORED_MODIFIERS mask which we
          already used before and which includes GDK_HYPER_MASK etc.. This
          mask is then used in several places to avoid these modifiers to
          appear in the result of gtk_accelerator_name() and to properly grab
          the shortcuts. This should fix bug #4304.


Modified: xfce4-settings/trunk/ChangeLog
===================================================================
--- xfce4-settings/trunk/ChangeLog      2008-08-31 19:02:51 UTC (rev 27631)
+++ xfce4-settings/trunk/ChangeLog      2008-08-31 23:48:13 UTC (rev 27632)
@@ -1,3 +1,16 @@
+2008-09-01     Jannis Pohlmann <[EMAIL PROTECTED]>
+
+       * dialogs/keyboard-settings/shortcuts-dialog.c,
+         xfce4-settings-helper/keyboard-shortcuts.c: Add two new functions
+         called get_modifier_masks() and get_ignore_mask(). The first
+         determines to which of the Mod2-Mod5 modifiers CapsLock, NumLock and
+         ScrollLock are mapped and generates a modifier mask for them. The
+         latter combines this mask with the IGNORED_MODIFIERS mask which we
+         already used before and which includes GDK_HYPER_MASK etc.. This
+         mask is then used in several places to avoid these modifiers to
+         appear in the result of gtk_accelerator_name() and to properly grab
+         the shortcuts. This should fix bug #4304.
+.
 2008-08-31     Jannis Pohlmann <[EMAIL PROTECTED]>
 
        * dialogs/keyboard-settings/shortcut-dialog.c: Ignore

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c    
2008-08-31 19:02:51 UTC (rev 27631)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c    
2008-08-31 23:48:13 UTC (rev 27632)
@@ -23,6 +23,8 @@
 #include <config.h>
 #endif
 
+#include <gdk/gdkkeysyms.h>
+
 #include <gtk/gtk.h>
 
 #include <libxfce4util/libxfce4util.h>
@@ -32,15 +34,6 @@
 
 
 
-/* Modifiers to be ignored (0x2000 is an Xkb modifier) */
-#define IGNORED_MODIFIERS (0x2000 | GDK_LOCK_MASK | GDK_HYPER_MASK | 
GDK_SUPER_MASK | GDK_META_MASK)
-
-/* Modifiers to be used */
-#define USED_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | 
GDK_MOD2_MASK | \
-                        GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK)
-
-
-
 static void     shortcut_dialog_class_init       (ShortcutDialogClass *klass);
 static void     shortcut_dialog_init             (ShortcutDialog      *dialog);
 static void     shortcut_dialog_dispose          (GObject             *object);
@@ -49,6 +42,11 @@
                                                   const gchar         *action);
 static gboolean shortcut_dialog_key_released     (ShortcutDialog      *dialog,
                                                   GdkEventKey         *event);
+static gboolean get_modmap_masks                 (Display             *display,
+                                                  gint                
*caps_lock_mask,
+                                                  gint                
*num_lock_mask,
+                                                  gint                
*scroll_lock_mask);
+static gint     get_ignore_mask                  (Display             
*display);
 
 
 
@@ -308,13 +306,18 @@
 shortcut_dialog_key_released (ShortcutDialog *dialog,
                               GdkEventKey    *event)
 {
+  Display *display;
   gboolean event_handled = FALSE;
   gboolean shortcut_accepted = FALSE;
   gchar   *shortcut;
   gint     modifiers;
+  gint     ignore_mask;
 
+  /* Determine mask of ignored modifiers */
+  ignore_mask = get_ignore_mask (GDK_DISPLAY_XDISPLAY (gdk_display_get_default 
()));
+
   /* Strip ignored modifiers from the event mask */
-  modifiers = event->state & ~IGNORED_MODIFIERS & GDK_MODIFIER_MASK;
+  modifiers = event->state & ~ignore_mask;
 
   /* Get GTK+ accelerator string */
   shortcut = gtk_accelerator_name (event->keyval, modifiers);
@@ -352,3 +355,117 @@
   g_return_val_if_fail (IS_SHORTCUT_DIALOG (dialog), NULL);
   return dialog->shortcut;
 }
+
+
+
+/* The following code appears again in 
xfce4-settings-helper/keyboard-shortcuts-helper.c: */
+
+/* Modifiers to be ignored (0x2000 is an Xkb modifier) */
+#define IGNORED_MODIFIERS (0x2000 | GDK_LOCK_MASK | GDK_HYPER_MASK | 
GDK_SUPER_MASK | GDK_META_MASK)
+
+/* Modifiers to be used */
+#define USED_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | 
GDK_MOD2_MASK | \
+                        GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK)
+
+
+
+static gboolean
+get_modmap_masks (Display *display,
+                  gint    *caps_lock_mask,
+                  gint    *num_lock_mask,
+                  gint    *scroll_lock_mask)
+{
+  XModifierKeymap *modmap;
+  const KeySym    *keysyms;
+  KeyCode          keycode;
+  KeySym          *keymap;
+  gint             keysyms_per_keycode = 0;
+  gint             min_keycode = 0;
+  gint             max_keycode = 0;
+  gint             mask;
+  gint             i;
+  gint             j;
+
+  /* Clear the masks */
+  *caps_lock_mask = 0;
+  *num_lock_mask = 0;
+  *scroll_lock_mask = 0;
+
+  gdk_error_trap_push ();
+
+  /* Determine minimum and maximum number of keycodes */
+  XDisplayKeycodes (display, &min_keycode, &max_keycode);
+
+  /* Determine symbols for all keycodes */
+  keymap = XGetKeyboardMapping (display, min_keycode, max_keycode - 
min_keycode + 1, &keysyms_per_keycode);
+
+  if (G_UNLIKELY (keymap == NULL))
+    return FALSE;
+
+  /* Determine modifier mappign */
+  modmap = XGetModifierMapping (display);
+
+  if (G_UNLIKELY (modmap == NULL))
+    {
+      XFree (keymap);
+      return FALSE;
+    }
+
+  /* Iterate over all modifier keycodes */
+  for (i = 0; i < 8 * modmap->max_keypermod; ++i)
+    {
+      /* Get the current keycode */
+      keycode = modmap->modifiermap[i];
+
+      /* Ignore invalid codes */
+      if (keycode == 0 || keycode < min_keycode || keycode > max_keycode)
+        continue;
+
+      /* Determine all keysyms for the current keycode */
+      keysyms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
+
+      /* Create modifier mask for the current modifier */
+      mask = 1 << (i / modmap->max_keypermod);
+
+      /* Iterate over all keysyms of the current keycode and modify the 
resulting 
+       * masks according to which keysyms belong to which X modifiers */
+      for (j = 0; j < keysyms_per_keycode; ++j)
+        {
+          if (keysyms[j] == GDK_Caps_Lock) 
+            *caps_lock_mask |= mask;
+          else if (keysyms[j] == GDK_Num_Lock)
+            *num_lock_mask |= mask;
+          else if (keysyms[j] == GDK_Scroll_Lock)
+            *scroll_lock_mask |= mask;
+        }
+    }
+  
+  /* Free mappings */
+  XFreeModifiermap (modmap);
+  XFree (keymap);
+
+  gdk_flush ();
+  gdk_error_trap_pop ();
+
+  return TRUE;
+}
+
+
+
+static gint
+get_ignore_mask (Display *display)
+{
+  gint caps_lock_mask;
+  gint num_lock_mask;
+  gint scroll_lock_mask;
+  gint ignore_mask;
+
+  ignore_mask = IGNORED_MODIFIERS & GDK_MODIFIER_MASK;
+
+  if (G_LIKELY (get_modmap_masks (display, &caps_lock_mask, &num_lock_mask, 
&scroll_lock_mask)))
+    ignore_mask |= caps_lock_mask | num_lock_mask | scroll_lock_mask;
+
+  return ignore_mask;
+}
+
+/* End of the duplicated code */

Modified: xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c
===================================================================
--- xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c     
2008-08-31 19:02:51 UTC (rev 27631)
+++ xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c     
2008-08-31 23:48:13 UTC (rev 27632)
@@ -31,6 +31,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
 
 #include <xfconf/xfconf.h>
 #include <libxfcegui4/libxfcegui4.h>
@@ -40,16 +41,6 @@
 
 
 
-/* Modifiers to be ignored (0x2000 is an Xkb modifier) */
-#define IGNORED_MODIFIERS (0x2000 | GDK_LOCK_MASK | GDK_HYPER_MASK)
-
-/* Modifiers to be used */
-#define USED_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_SUPER_MASK | 
GDK_META_MASK | \
-                        GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | 
GDK_MOD4_MASK | GDK_MOD5_MASK)
-
-
-
-
 /* Property identifiers */
 enum
 {
@@ -103,10 +94,14 @@
                                                                         const 
GValue                     *value,
                                                                         gchar  
                         **shortcut,
                                                                         gchar  
                         **action);
+static gboolean        get_modmap_masks                                
(Display                          *display,
+                                                                        gint   
                          *caps_lock_mask,
+                                                                        gint   
                          *num_lock_mask,
+                                                                        gint   
                          *scroll_lock_mask);
+static gint            get_ignore_mask                                 
(Display                          *display);
 
 
 
-
 struct _XfceKeyboardShortcutsHelperClass
 {
   GObjectClass __parent__;
@@ -389,11 +384,11 @@
       return FALSE ;
     }
 
-  /* Create mask containing ignored modifier bits set which are not set in the 
grab_mask already */
-  ignore_mask = IGNORED_MODIFIERS & ~grab_mask & GDK_MODIFIER_MASK;
+  /* Determine mask containing ignored modifier bits */
+  ignore_mask = get_ignore_mask (xdisplay);
 
   /* Store indices of all set bits of the ignore mask in an array */
-  for (i = 0, n_bits = 0; ignore_mask != 0; ++i, ignore_mask >>= 1)
+  for (i = 0, n_bits = 0; i < 32; ++i, ignore_mask >>= 1)
     if ((ignore_mask & 0x1) != 0)
       bits[n_bits++] = i;
 
@@ -496,6 +491,7 @@
   const gchar *value;
   gint         monitor;
   gint         modifiers;
+  gint         ignore_mask;
 
   g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
 
@@ -509,12 +505,17 @@
   /* Convert event keycode to keysym */
   keysym = XKeycodeToKeysym (GDK_DISPLAY_XDISPLAY (display), xevent->keycode, 
0);
 
+  /* Determine ignored modifiers mask */
+  ignore_mask = get_ignore_mask (GDK_DISPLAY_XDISPLAY (display));
+
   /* Remove ignored modifiers and non-modifier keys from the event state mask 
*/
-  modifiers = xevent->state & ~IGNORED_MODIFIERS & GDK_MODIFIER_MASK;
+  modifiers = xevent->state & ~ignore_mask & GDK_MODIFIER_MASK;
 
   /* Get accelerator string for the pressed keys */
   accelerator_name = gtk_accelerator_name (keysym, modifiers);
 
+  g_message ("accelerator_name = %s", accelerator_name);
+
   /* Perform accelerator lookup */
   if (G_LIKELY (g_hash_table_lookup_extended (helper->shortcuts, 
accelerator_name, (gpointer) &key, (gpointer) &value)))
     {
@@ -641,3 +642,117 @@
 
   return result;
 }
+
+
+
+/* The following code appears again in 
dialogs/keyboard-settings/shortcut-dialog.c: */
+
+/* Modifiers to be ignored (0x2000 is an Xkb modifier) */
+#define IGNORED_MODIFIERS (0x2000 | GDK_LOCK_MASK | GDK_HYPER_MASK | 
GDK_SUPER_MASK | GDK_META_MASK)
+
+/* Modifiers to be used */
+#define USED_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | 
GDK_MOD2_MASK | \
+                        GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK)
+
+
+
+static gboolean
+get_modmap_masks (Display *display,
+                  gint    *caps_lock_mask,
+                  gint    *num_lock_mask,
+                  gint    *scroll_lock_mask)
+{
+  XModifierKeymap *modmap;
+  const KeySym    *keysyms;
+  KeyCode          keycode;
+  KeySym          *keymap;
+  gint             keysyms_per_keycode = 0;
+  gint             min_keycode = 0;
+  gint             max_keycode = 0;
+  gint             mask;
+  gint             i;
+  gint             j;
+
+  /* Clear the masks */
+  *caps_lock_mask = 0;
+  *num_lock_mask = 0;
+  *scroll_lock_mask = 0;
+
+  gdk_error_trap_push ();
+
+  /* Determine minimum and maximum number of keycodes */
+  XDisplayKeycodes (display, &min_keycode, &max_keycode);
+
+  /* Determine symbols for all keycodes */
+  keymap = XGetKeyboardMapping (display, min_keycode, max_keycode - 
min_keycode + 1, &keysyms_per_keycode);
+
+  if (G_UNLIKELY (keymap == NULL))
+    return FALSE;
+
+  /* Determine modifier mappign */
+  modmap = XGetModifierMapping (display);
+
+  if (G_UNLIKELY (modmap == NULL))
+    {
+      XFree (keymap);
+      return FALSE;
+    }
+
+  /* Iterate over all modifier keycodes */
+  for (i = 0; i < 8 * modmap->max_keypermod; ++i)
+    {
+      /* Get the current keycode */
+      keycode = modmap->modifiermap[i];
+
+      /* Ignore invalid codes */
+      if (keycode == 0 || keycode < min_keycode || keycode > max_keycode)
+        continue;
+
+      /* Determine all keysyms for the current keycode */
+      keysyms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
+
+      /* Create modifier mask for the current modifier */
+      mask = 1 << (i / modmap->max_keypermod);
+
+      /* Iterate over all keysyms of the current keycode and modify the 
resulting 
+       * masks according to which keysyms belong to which X modifiers */
+      for (j = 0; j < keysyms_per_keycode; ++j)
+        {
+          if (keysyms[j] == GDK_Caps_Lock) 
+            *caps_lock_mask |= mask;
+          else if (keysyms[j] == GDK_Num_Lock)
+            *num_lock_mask |= mask;
+          else if (keysyms[j] == GDK_Scroll_Lock)
+            *scroll_lock_mask |= mask;
+        }
+    }
+  
+  /* Free mappings */
+  XFreeModifiermap (modmap);
+  XFree (keymap);
+
+  gdk_flush ();
+  gdk_error_trap_pop ();
+
+  return TRUE;
+}
+
+
+
+static gint
+get_ignore_mask (Display *display)
+{
+  gint caps_lock_mask;
+  gint num_lock_mask;
+  gint scroll_lock_mask;
+  gint ignore_mask;
+
+  ignore_mask = IGNORED_MODIFIERS & GDK_MODIFIER_MASK;
+
+  if (G_LIKELY (get_modmap_masks (display, &caps_lock_mask, &num_lock_mask, 
&scroll_lock_mask)))
+    ignore_mask |= caps_lock_mask | num_lock_mask | scroll_lock_mask;
+
+  return ignore_mask;
+}
+
+/* End of the duplicated code */

_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to