1
--- a/plugins/common/gsd-keygrab.c
2
+++ b/plugins/common/gsd-keygrab.c
4
key->keysym != GDK_KEY_Pause &&
5
key->keysym != GDK_KEY_Print &&
6
key->keysym != GDK_KEY_Scroll_Lock &&
7
+ key->keysym != GDK_KEY_Caps_Lock &&
8
key->keysym != GDK_KEY_Pause &&
9
key->keysym != GDK_KEY_Break &&
10
key->keysym != GDK_KEY_Menu) {
11
@@ -239,19 +240,277 @@
12
g_array_free (all_mods, TRUE);
16
+get_keys_for_bit (guint bit,
26
+ right = &right_dummy;
32
+ case GDK_SHIFT_MASK:
33
+ *left = GDK_KEY_Shift_L;
34
+ *right = GDK_KEY_Shift_R;
36
+ case GDK_CONTROL_MASK:
37
+ *left = GDK_KEY_Control_L;
38
+ *right = GDK_KEY_Control_R;
41
+ *left = GDK_KEY_Caps_Lock;
42
+ *right = GDK_KEY_Shift_Lock;
46
+ *left = GDK_KEY_Alt_L;
47
+ *right = GDK_KEY_Alt_R;
49
+ case GDK_SUPER_MASK:
50
+ *left = GDK_KEY_Super_L;
51
+ *right = GDK_KEY_Super_R;
57
+get_mask_for_key (guint key)
60
+ case GDK_KEY_Shift_L:
61
+ case GDK_KEY_Shift_R:
62
+ return GDK_SHIFT_MASK;
63
+ case GDK_KEY_Control_L:
64
+ case GDK_KEY_Control_R:
65
+ return GDK_CONTROL_MASK;
66
+ case GDK_KEY_Caps_Lock:
67
+ case GDK_KEY_Shift_Lock:
68
+ return GDK_LOCK_MASK;
69
+ case GDK_KEY_Meta_L:
70
+ case GDK_KEY_Meta_R:
73
+ return GDK_MOD1_MASK;
74
+ case GDK_KEY_Super_L:
75
+ case GDK_KEY_Super_R:
76
+ return GDK_SUPER_MASK;
83
+get_mirrored_key (guint key)
86
+ case GDK_KEY_Shift_L:
87
+ return GDK_KEY_Shift_R;
88
+ case GDK_KEY_Shift_R:
89
+ return GDK_KEY_Shift_L;
90
+ case GDK_KEY_Control_L:
91
+ return GDK_KEY_Control_R;
92
+ case GDK_KEY_Control_R:
93
+ return GDK_KEY_Control_L;
94
+ case GDK_KEY_Meta_L:
95
+ return GDK_KEY_Meta_R;
96
+ case GDK_KEY_Meta_R:
97
+ return GDK_KEY_Meta_L;
99
+ return GDK_KEY_Alt_R;
100
+ case GDK_KEY_Alt_R:
101
+ return GDK_KEY_Alt_L;
102
+ case GDK_KEY_Super_L:
103
+ return GDK_KEY_Super_R;
104
+ case GDK_KEY_Super_R:
105
+ return GDK_KEY_Super_L;
106
+ case GDK_KEY_Hyper_L:
107
+ return GDK_KEY_Hyper_R;
108
+ case GDK_KEY_Hyper_R:
109
+ return GDK_KEY_Hyper_L;
116
grab_key_unsafe (Key *key,
117
GsdKeygrabFlags flags,
120
+ guint key_mask = get_mask_for_key (key->keysym);
122
grab_key_internal (key, TRUE, flags, screens);
124
+ if (key_mask != 0) {
128
+ if ((key->state & key_mask) != 0) {
129
+ guint mirror = get_mirrored_key (key->keysym);
132
+ gint mirror_keys_len;
133
+ GdkKeymapKey *mirror_keys;
135
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
140
+ copy.keysym = mirror;
141
+ copy.state = key->state;
142
+ copy.keycodes = g_new0 (guint, mirror_keys_len + 1);
144
+ for (j = 0; j < mirror_keys_len; j++)
145
+ copy.keycodes[j] = mirror_keys[j].keycode;
147
+ grab_key_internal (©, TRUE, flags, screens);
149
+ g_free (copy.keycodes);
150
+ g_free (mirror_keys);
154
+ for (i = 0; i < 8 * sizeof (guint); i++) {
156
+ gint left_keys_len, right_keys_len;
157
+ GdkKeymapKey *left_keys, *right_keys;
159
+ if (1 << i == key_mask || (key->state & 1 << i) == 0)
162
+ get_keys_for_bit (i, &left, &right);
164
+ if (left == 0 && right == 0)
168
+ right_keys_len = 0;
173
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
179
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
184
+ copy.keysym = left != 0 ? left : right;
185
+ copy.state = (key->state | key_mask) & ~(1 << i);
186
+ copy.keycodes = g_new0 (guint, left_keys_len + right_keys_len + 1);
188
+ for (j = 0; j < left_keys_len; j++)
189
+ copy.keycodes[j] = left_keys[j].keycode;
190
+ for (j = 0; j < right_keys_len; j++)
191
+ copy.keycodes[left_keys_len + j] = right_keys[j].keycode;
193
+ grab_key_internal (©, TRUE, flags, screens);
195
+ g_free (copy.keycodes);
196
+ g_free (right_keys);
197
+ g_free (left_keys);
203
ungrab_key_unsafe (Key *key,
206
+ guint key_mask = get_mask_for_key (key->keysym);
208
grab_key_internal (key, FALSE, 0, screens);
210
+ if (key_mask != 0) {
214
+ if ((key->state & key_mask) != 0) {
215
+ guint mirror = get_mirrored_key (key->keysym);
218
+ gint mirror_keys_len;
219
+ GdkKeymapKey *mirror_keys;
221
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
226
+ copy.keysym = mirror;
227
+ copy.state = key->state;
228
+ copy.keycodes = g_new0 (guint, mirror_keys_len + 1);
230
+ for (j = 0; j < mirror_keys_len; j++)
231
+ copy.keycodes[j] = mirror_keys[j].keycode;
233
+ grab_key_internal (©, FALSE, 0, screens);
235
+ g_free (copy.keycodes);
236
+ g_free (mirror_keys);
240
+ for (i = 0; i < 8 * sizeof (guint); i++) {
242
+ gint left_keys_len, right_keys_len;
243
+ GdkKeymapKey *left_keys, *right_keys;
245
+ if (1 << i == key_mask || (key->state & 1 << i) == 0)
248
+ get_keys_for_bit (i, &left, &right);
250
+ if (left == 0 && right == 0)
254
+ right_keys_len = 0;
259
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
265
+ gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
270
+ copy.keysym = left != 0 ? left : right;
271
+ copy.state = (key->state | key_mask) & ~(1 << i);
272
+ copy.keycodes = g_new0 (guint, left_keys_len + right_keys_len + 1);
274
+ for (j = 0; j < left_keys_len; j++)
275
+ copy.keycodes[j] = left_keys[j].keycode;
276
+ for (j = 0; j < right_keys_len; j++)
277
+ copy.keycodes[left_keys_len + j] = right_keys[j].keycode;
279
+ grab_key_internal (©, FALSE, 0, screens);
281
+ g_free (copy.keycodes);
282
+ g_free (right_keys);
283
+ g_free (left_keys);
290
if (gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), keycode,
292
&keyval, NULL, NULL, &consumed)) {
293
+ guint key_bit, event_bit;
296
+ guint mask, full_mask;
298
/* HACK: we don't want to use SysRq as a keybinding, so we avoid
299
* its translation from Alt+Print. */
300
@@ -346,20 +606,33 @@
302
/* The Key structure contains virtual modifiers, whereas
303
* the XEvent will be using the real modifier, so translate those */
304
+ key_bit = get_mask_for_key (key->keysym);
305
+ event_bit = get_mask_for_key (keyval);
307
+ full_mask = mask | key_bit;
308
gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mask);
309
+ gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &full_mask);
310
mask &= ~(GDK_META_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK);
311
+ full_mask &= ~(GDK_META_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK);
313
gdk_keyval_convert_case (keyval, &lower, &upper);
315
/* If we are checking against the lower version of the
316
* keysym, we might need the Shift state for matching,
317
* so remove it from the consumed modifiers */
318
- if (lower == key->keysym)
319
+ if (lower == key->keysym || event_bit != 0)
320
consumed &= ~GDK_SHIFT_MASK;
322
- return ((lower == key->keysym || upper == key->keysym)
323
- && (state & ~consumed & gsd_used_mods) == mask);
324
+ state &= ~consumed & gsd_used_mods;
326
+ if (key_bit != 0 && event_bit != 0) {
327
+ state |= event_bit;
328
+ gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &state);
329
+ state &= ~(GDK_META_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK);
330
+ return state == full_mask;
333
+ return (lower == key->keysym || upper == key->keysym) && state == mask;
336
/* The key we passed doesn't have a keysym, so try with just the keycode */
337
--- a/plugins/keyboard/gsd-keyboard-manager.c
338
+++ b/plugins/keyboard/gsd-keyboard-manager.c
340
* and doesn't call us so we can't set the group switching XKB
341
* option in the first place otherwise the X server's switch
342
* will take effect and we get a broken configuration. */
344
+ if (n_sources < 2 || g_strcmp0 (g_getenv ("XDG_CURRENT_DESKTOP"), "Unity") == 0)
345
strip_xkb_option (options, "grp:");
347
options_str = build_xkb_options_string (options);
348
@@ -1006,6 +1006,8 @@
350
gnome_xkb_info_free_var_defs (xkb_var_defs);
351
g_free (rules_file_path);
353
+ XkbLockModifiers (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XkbUseCoreKbd, LockMask, 0);
357
--- a/plugins/media-keys/gsd-media-keys-manager.c
358
+++ b/plugins/media-keys/gsd-media-keys-manager.c
359
@@ -2559,6 +2559,8 @@
361
GsdMediaKeysManager *manager)
363
+ static gboolean ok_to_switch = TRUE;
367
XGenericEventCookie *cookie;
368
@@ -2582,6 +2584,9 @@
370
deviceid = xev->sourceid;
372
+ if (xiev->evtype == XI_KeyPress)
373
+ ok_to_switch = TRUE;
375
for (i = 0; i < manager->priv->keys->len; i++) {
378
@@ -2614,6 +2619,15 @@
379
return GDK_FILTER_REMOVE;
382
+ if (key->key_type == SWITCH_INPUT_SOURCE_KEY || key->key_type == SWITCH_INPUT_SOURCE_BACKWARD_KEY) {
383
+ if (ok_to_switch) {
384
+ do_action (manager, deviceid, key->key_type, xev->time);
385
+ ok_to_switch = FALSE;
388
+ return GDK_FILTER_CONTINUE;
391
if (do_action (manager, deviceid, key->key_type, xev->time) == FALSE) {
392
return GDK_FILTER_REMOVE;