[gnome-settings-daemon/gnome-3-6] keyboard: Add combos with Caps Lock to the input sources switcher
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon/gnome-3-6] keyboard: Add combos with Caps Lock to the input sources switcher
- Date: Mon, 12 Nov 2012 14:05:53 +0000 (UTC)
commit 8c7df76addcfc3cb8f28276bbb3da3e4f8e536be
Author: Rui Matos <tiagomatos gmail com>
Date: Fri Nov 2 19:51:34 2012 +0100
keyboard: Add combos with Caps Lock to the input sources switcher
When using Caps Lock as a shortcut we need to undo the modifier
locking that occurs in the X server.
https://bugzilla.gnome.org/show_bug.cgi?id=686613
data/gsd-enums.h | 4 +
plugins/keyboard/gsd-input-sources-switcher.c | 82 +++++++++++++++++++++++++
2 files changed, 86 insertions(+), 0 deletions(-)
---
diff --git a/data/gsd-enums.h b/data/gsd-enums.h
index 49e07db..99d9fba 100644
--- a/data/gsd-enums.h
+++ b/data/gsd-enums.h
@@ -140,6 +140,10 @@ typedef enum
GSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT,
GSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT,
GSD_INPUT_SOURCES_SWITCHER_ALT_CTRL,
+ GSD_INPUT_SOURCES_SWITCHER_CAPS,
+ GSD_INPUT_SOURCES_SWITCHER_SHIFT_CAPS,
+ GSD_INPUT_SOURCES_SWITCHER_ALT_CAPS,
+ GSD_INPUT_SOURCES_SWITCHER_CTRL_CAPS,
} GsdInputSourcesSwitcher;
#endif /* __gsd_enums_h__ */
diff --git a/plugins/keyboard/gsd-input-sources-switcher.c b/plugins/keyboard/gsd-input-sources-switcher.c
index 233d491..b48f37e 100644
--- a/plugins/keyboard/gsd-input-sources-switcher.c
+++ b/plugins/keyboard/gsd-input-sources-switcher.c
@@ -23,6 +23,8 @@
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
+#include <X11/XKBlib.h>
+
#include "gsd-enums.h"
#include "gsd-keygrab.h"
@@ -40,6 +42,9 @@ static guint n_keys = 0;
static guint master_keyboard_id = 0;
+static gboolean includes_caps = FALSE;
+static Time caps_press_time = 0;
+
static void
do_switch (void)
{
@@ -254,6 +259,58 @@ init_keys (void)
the_keys[6].keysym = GDK_KEY_ISO_Level3_Shift;
the_keys[6].state = GDK_CONTROL_MASK;
break;
+
+ case GSD_INPUT_SOURCES_SWITCHER_CAPS:
+ includes_caps = TRUE;
+ n_keys = 1;
+ the_keys = g_new0 (Key, n_keys);
+
+ the_keys[0].keysym = GDK_KEY_Caps_Lock;
+ the_keys[0].state = 0;
+ break;
+
+ case GSD_INPUT_SOURCES_SWITCHER_SHIFT_CAPS:
+ includes_caps = TRUE;
+ n_keys = 3;
+ the_keys = g_new0 (Key, n_keys);
+
+ the_keys[0].keysym = GDK_KEY_Caps_Lock;
+ the_keys[0].state = GDK_SHIFT_MASK;
+ the_keys[1].keysym = GDK_KEY_Shift_L;
+ the_keys[1].state = GDK_LOCK_MASK;
+ the_keys[2].keysym = GDK_KEY_Shift_R;
+ the_keys[2].state = GDK_LOCK_MASK;
+ break;
+
+ case GSD_INPUT_SOURCES_SWITCHER_ALT_CAPS:
+ includes_caps = TRUE;
+ n_keys = 5;
+ the_keys = g_new0 (Key, n_keys);
+
+ the_keys[0].keysym = GDK_KEY_Caps_Lock;
+ the_keys[0].state = GDK_MOD1_MASK;
+ the_keys[1].keysym = GDK_KEY_Caps_Lock;
+ the_keys[1].state = GDK_MOD5_MASK;
+ the_keys[2].keysym = GDK_KEY_Alt_L;
+ the_keys[2].state = GDK_LOCK_MASK;
+ the_keys[3].keysym = GDK_KEY_Alt_R;
+ the_keys[3].state = GDK_LOCK_MASK;
+ the_keys[4].keysym = GDK_KEY_ISO_Level3_Shift;
+ the_keys[4].state = GDK_LOCK_MASK;
+ break;
+
+ case GSD_INPUT_SOURCES_SWITCHER_CTRL_CAPS:
+ includes_caps = TRUE;
+ n_keys = 3;
+ the_keys = g_new0 (Key, n_keys);
+
+ the_keys[0].keysym = GDK_KEY_Caps_Lock;
+ the_keys[0].state = GDK_CONTROL_MASK;
+ the_keys[1].keysym = GDK_KEY_Control_L;
+ the_keys[1].state = GDK_LOCK_MASK;
+ the_keys[2].keysym = GDK_KEY_Control_R;
+ the_keys[2].state = GDK_LOCK_MASK;
+ break;
}
g_object_unref (settings);
@@ -271,11 +328,29 @@ free_keys (void)
}
static gboolean
+match_caps_locked (const Key *key,
+ XIDeviceEvent *xev)
+{
+ if (key->state & xev->mods.effective &&
+ key->keysym == XkbKeycodeToKeysym (xev->display, xev->detail, 0, 0))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
match_modifier (const Key *key,
XIEvent *xiev)
{
Key meta;
+ /* When the grab is established with Caps Lock as the modifier
+ (i.e. key->state == GDK_LOCK_MASK) we can't use match_xi2_key()
+ as this modifier is black listed there, so we do the match
+ ourselves. */
+ if (key->state == GDK_LOCK_MASK)
+ return match_caps_locked (key, (XIDeviceEvent *) xiev);
+
meta = *key;
switch (key->keysym)
@@ -372,6 +447,8 @@ filter (XEvent *xevent,
&evmask,
1,
&mods);
+ if (includes_caps)
+ caps_press_time = xev->time;
}
else
{
@@ -385,6 +462,11 @@ filter (XEvent *xevent,
xev->root,
1,
&mods);
+ if (includes_caps && caps_press_time < xev->time)
+ {
+ XkbLockModifiers (xev->display, XkbUseCoreKbd, LockMask, 0);
+ caps_press_time = xev->time;
+ }
}
}
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]