From 859aaf903d8e6ad5ca93c3205771edadfc24969c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 29 Sep 2008 20:40:45 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20107000=20=E2=80=93=20Add=20signals=20to?= =?UTF-8?q?=20GdkKeymap=20for=20monitoring=20caps=5Flock,=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-09-29 Matthias Clasen Bug 107000 – Add signals to GdkKeymap for monitoring caps_lock, etc. * gdk/gdk.symbols: * gdk/gdkkeys.[ch]: Add a new GdkKeymap::state-changed signal, and a gdk_keymap_get_caps_lock_state function. * gdk/x11/gdkkeys-x11.c: Implement it here. For now, only emit state-changed when caps lock lockedness changes. * gdk/x11/gdkdisplay-x11.c: Also select for modifier lock status changes in the XkbSelectEventDetails call. svn path=/trunk/; revision=21545 --- ChangeLog | 14 +++++++ docs/reference/ChangeLog | 4 ++ docs/reference/gdk/gdk-sections.txt | 1 + gdk/gdk.symbols | 1 + gdk/gdkkeys.c | 21 ++++++++++ gdk/gdkkeys.h | 2 + gdk/x11/gdkdisplay-x11.c | 2 +- gdk/x11/gdkkeys-x11.c | 65 +++++++++++++++++++++++------ 8 files changed, 97 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f45c7297d..f0a981019e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-09-29 Matthias Clasen + + Bug 107000 – Add signals to GdkKeymap for monitoring caps_lock, etc. + + * gdk/gdk.symbols: + * gdk/gdkkeys.[ch]: Add a new GdkKeymap::state-changed signal, and + a gdk_keymap_get_caps_lock_state function. + + * gdk/x11/gdkkeys-x11.c: Implement it here. For now, only emit + state-changed when caps lock lockedness changes. + + * gdk/x11/gdkdisplay-x11.c: Also select for modifier lock status + changes in the XkbSelectEventDetails call. + 2008-09-29 Kristian Rietveld Bug 487624 - Tooltips doesn't get updated if ther's no mouse motion diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index a658c54076..2ce71413a6 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2008-09-29 Matthias Clasen + + * gdk/gdk-sections.txt: Add gdk_keymap_get_caps_locks_state. + 2008-09-17 Matthias Clasen * === Released 2.14.2 === diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index bedd5ae802..ce37ae1399 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -992,6 +992,7 @@ gdk_keymap_get_entries_for_keyval gdk_keymap_get_entries_for_keycode gdk_keymap_get_direction gdk_keymap_have_bidi_layouts +gdk_keymap_get_caps_lock_state gdk_keyval_name diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 30c77b74b8..b96f7922a8 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -829,6 +829,7 @@ gdk_keymap_get_entries_for_keycode gdk_keymap_get_entries_for_keyval gdk_keymap_get_for_display gdk_keymap_have_bidi_layouts +gdk_keymap_get_caps_lock_state gdk_keymap_lookup_key gdk_keymap_translate_keyboard_state gdk_keyval_convert_case diff --git a/gdk/gdkkeys.c b/gdk/gdkkeys.c index b01d6398c3..d3e4d1b8f3 100644 --- a/gdk/gdkkeys.c +++ b/gdk/gdkkeys.c @@ -33,6 +33,7 @@ enum { DIRECTION_CHANGED, KEYS_CHANGED, + STATE_CHANGED, LAST_SIGNAL }; @@ -81,6 +82,26 @@ gdk_keymap_class_init (GdkKeymapClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * GdkKeymap::state-changed: + * @keymap: the object on which the signal is emitted + * + * The ::state-changed signal is emitted when the state of the + * keyboard changes, e.g when the Caps Lock is turned on or off. + * See gdk_keyboard_get_caps_lock_state(). + * + * Since: 2.16 + */ + signals[STATE_CHANGED] = + g_signal_new ("state_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkKeymapClass, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } static void diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h index 839cbe765b..63a226620b 100644 --- a/gdk/gdkkeys.h +++ b/gdk/gdkkeys.h @@ -75,6 +75,7 @@ struct _GdkKeymapClass void (*direction_changed) (GdkKeymap *keymap); void (*keys_changed) (GdkKeymap *keymap); + void (*state_changed) (GdkKeymap *keymap); }; GType gdk_keymap_get_type (void) G_GNUC_CONST; @@ -106,6 +107,7 @@ gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, gint *n_entries); PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap); gboolean gdk_keymap_have_bidi_layouts (GdkKeymap *keymap); +gboolean gdk_keymap_get_caps_lock_state (GdkKeymap *keymap); /* Key values */ diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index e48c16cb41..cbef9ea439 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -356,7 +356,7 @@ gdk_display_open (const gchar *display_name) XkbSelectEventDetails (display_x11->xdisplay, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, - XkbGroupLockMask); + XkbGroupLockMask|XkbModifierLockMask); XkbSetDetectableAutoRepeat (display_x11->xdisplay, True, diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index 018613adbf..fdf041122f 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -82,9 +82,10 @@ struct _GdkKeymapX11 GdkModifierType group_switch_mask; GdkModifierType num_lock_mask; GdkModifierType modmap[8]; - gboolean sun_keypad; PangoDirection current_direction; - gboolean have_direction; + guint sun_keypad : 1; + guint have_direction : 1; + guint caps_lock_state : 1; guint current_serial; #ifdef HAVE_XKB @@ -656,12 +657,17 @@ get_num_groups (GdkKeymap *keymap, return xkb->ctrls->num_groups; } -static void +static gboolean update_direction (GdkKeymapX11 *keymap_x11, gint group) { XkbDescPtr xkb = get_xkb (keymap_x11); Atom group_atom; + gboolean had_direction; + PangoDirection old_direction; + + had_direction = keymap_x11->have_direction; + old_direction = keymap_x11->current_direction; group_atom = xkb->names->groups[group]; @@ -672,6 +678,21 @@ update_direction (GdkKeymapX11 *keymap_x11, keymap_x11->current_group_atom = group_atom; keymap_x11->have_direction = TRUE; } + + return !had_direction || old_direction != keymap_x11->current_direction; +} + +static gboolean +update_lock_state (GdkKeymapX11 *keymap_x11, + gint locked_mods) +{ + gboolean caps_lock_state; + + caps_lock_state = keymap_x11->caps_lock_state; + + keymap_x11->caps_lock_state = (locked_mods & GDK_LOCK_MASK) != 0; + + return caps_lock_state != keymap_x11->caps_lock_state; } /* keep this in sync with the XkbSelectEventDetails() call @@ -684,19 +705,16 @@ _gdk_keymap_state_changed (GdkDisplay *display, GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); XkbEvent *xkb_event = (XkbEvent *)xevent; + g_print ("keymap state changed\n"); if (display_x11->keymap) { GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (display_x11->keymap); - gboolean had_direction; - PangoDirection direction; - had_direction = keymap_x11->have_direction; - direction = keymap_x11->current_direction; - - update_direction (keymap_x11, XkbStateGroup (&xkb_event->state)); - - if (!had_direction || direction != keymap_x11->current_direction) - g_signal_emit_by_name (keymap_x11, "direction_changed"); + if (update_direction (keymap_x11, XkbStateGroup (&xkb_event->state))) + g_signal_emit_by_name (keymap_x11, "direction-changed"); + + if (update_lock_state (keymap_x11, xkb_event->state.locked_mods)) + g_signal_emit_by_name (keymap_x11, "state-changed"); } } @@ -792,6 +810,29 @@ gdk_keymap_have_bidi_layouts (GdkKeymap *keymap) return FALSE; } +/** + * gdk_keymap_get_caps_lock_state: + * @keymap: a #GdkKeymap + * + * Returns wether the Caps Lock modifer is locked. + * + * Returns: %TRUE if Caps Lock is on + * + * Since: 2.16 + */ +gboolean +gdk_keymap_get_caps_lock_state (GdkKeymap *keymap) +{ + GdkKeymapX11 *keymap_x11; + + keymap = GET_EFFECTIVE_KEYMAP (keymap); + + keymap_x11 = GDK_KEYMAP_X11 (keymap); + + return keymap_x11->caps_lock_state; +} + + /** * gdk_keymap_get_entries_for_keyval: * @keymap: a #GdkKeymap, or %NULL to use the default keymap