diff --git a/clutter/clutter/clutter-keymap-private.h b/clutter/clutter/clutter-keymap-private.h new file mode 100644 index 000000000..2268e63f2 --- /dev/null +++ b/clutter/clutter/clutter-keymap-private.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef CLUTTER_KEYMAP_PRIVATE_H +#define CLUTTER_KEYMAP_PRIVATE_H + +#include "clutter/clutter-keymap.h" + +CLUTTER_EXPORT +void clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap, + gboolean caps_lock_state, + gboolean num_lock_state); + +#endif /* CLUTTER_KEYMAP_PRIVATE_H */ diff --git a/clutter/clutter/clutter-keymap.c b/clutter/clutter/clutter-keymap.c index cdeb8f257..1f1041fe0 100644 --- a/clutter/clutter/clutter-keymap.c +++ b/clutter/clutter/clutter-keymap.c @@ -21,10 +21,29 @@ #include "clutter-build-config.h" -#include "clutter-keymap.h" +#include "clutter-keymap-private.h" #include "clutter-private.h" -G_DEFINE_ABSTRACT_TYPE (ClutterKeymap, clutter_keymap, G_TYPE_OBJECT) +enum +{ + PROP_0, + + PROP_CAPS_LOCK_STATE, + PROP_NUM_LOCK_STATE, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _ClutterKeymapPrivate +{ + gboolean caps_lock_state; + gboolean num_lock_state; +} ClutterKeymapPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterKeymap, clutter_keymap, + G_TYPE_OBJECT) enum { @@ -34,9 +53,76 @@ enum static guint signals[N_SIGNALS] = { 0, }; +static void +clutter_keymap_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterKeymap *keymap = CLUTTER_KEYMAP (object); + ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); + + switch (prop_id) + { + case PROP_CAPS_LOCK_STATE: + g_value_set_boolean (value, priv->caps_lock_state); + break; + case PROP_NUM_LOCK_STATE: + g_value_set_boolean (value, priv->num_lock_state); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_keymap_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterKeymap *keymap = CLUTTER_KEYMAP (object); + ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); + + switch (prop_id) + { + case PROP_CAPS_LOCK_STATE: + priv->caps_lock_state = g_value_get_boolean (value); + break; + case PROP_NUM_LOCK_STATE: + priv->num_lock_state = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void clutter_keymap_class_init (ClutterKeymapClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = clutter_keymap_get_property; + object_class->set_property = clutter_keymap_set_property; + + obj_props[PROP_CAPS_LOCK_STATE] = + g_param_spec_boolean ("caps-lock-state", + "Caps lock state", + "Caps lock state", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_NUM_LOCK_STATE] = + g_param_spec_boolean ("num-lock-state", + "Num lock state", + "Num lock state", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); + signals[STATE_CHANGED] = g_signal_new (I_("state-changed"), G_TYPE_FROM_CLASS (klass), @@ -54,13 +140,17 @@ clutter_keymap_init (ClutterKeymap *keymap) gboolean clutter_keymap_get_num_lock_state (ClutterKeymap *keymap) { - return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_num_lock_state (keymap); + ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); + + return priv->num_lock_state; } gboolean clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap) { - return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_caps_lock_state (keymap); + ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); + + return priv->caps_lock_state; } PangoDirection @@ -68,3 +158,35 @@ clutter_keymap_get_direction (ClutterKeymap *keymap) { return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap); } + +void +clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap, + gboolean caps_lock_state, + gboolean num_lock_state) +{ + ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); + + if (priv->caps_lock_state == caps_lock_state && + priv->num_lock_state == num_lock_state) + return; + + if (priv->caps_lock_state != caps_lock_state) + { + priv->caps_lock_state = caps_lock_state; + g_object_notify_by_pspec (G_OBJECT (keymap), + obj_props[PROP_CAPS_LOCK_STATE]); + } + + if (priv->num_lock_state != num_lock_state) + { + priv->num_lock_state = num_lock_state; + g_object_notify_by_pspec (G_OBJECT (keymap), + obj_props[PROP_NUM_LOCK_STATE]); + } + + g_debug ("Locks state changed - Num: %s, Caps: %s", + priv->num_lock_state ? "set" : "unset", + priv->caps_lock_state ? "set" : "unset"); + + g_signal_emit (keymap, signals[STATE_CHANGED], 0); +} diff --git a/clutter/clutter/clutter-keymap.h b/clutter/clutter/clutter-keymap.h index 40be12ea3..3e317f6a1 100644 --- a/clutter/clutter/clutter-keymap.h +++ b/clutter/clutter/clutter-keymap.h @@ -38,8 +38,6 @@ struct _ClutterKeymapClass { GObjectClass parent_class; - gboolean (* get_num_lock_state) (ClutterKeymap *keymap); - gboolean (* get_caps_lock_state) (ClutterKeymap *keymap); PangoDirection (* get_direction) (ClutterKeymap *keymap); }; diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index 9f20d7ba3..a3bbfc113 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -204,6 +204,7 @@ clutter_private_headers = [ 'clutter-input-focus-private.h', 'clutter-input-method-private.h', 'clutter-input-pointer-a11y-private.h', + 'clutter-keymap-private.h', 'clutter-offscreen-effect-private.h', 'clutter-paint-context-private.h', 'clutter-paint-node-private.h', diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c index 8db24f883..500bb1012 100644 --- a/src/backends/native/meta-keymap-native.c +++ b/src/backends/native/meta-keymap-native.c @@ -23,7 +23,9 @@ #include "backends/meta-keymap-utils.h" #include "backends/native/meta-input-thread.h" +#include "backends/native/meta-seat-impl.h" #include "backends/native/meta-seat-native.h" +#include "clutter/clutter-keymap-private.h" static const char *option_xkb_layout = "us"; static const char *option_xkb_variant = ""; @@ -53,22 +55,6 @@ meta_keymap_native_finalize (GObject *object) G_OBJECT_CLASS (meta_keymap_native_parent_class)->finalize (object); } -static gboolean -meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap) -{ - MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap); - - return keymap_native->num_lock; -} - -static gboolean -meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap) -{ - MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap); - - return keymap_native->caps_lock; -} - static PangoDirection meta_keymap_native_get_direction (ClutterKeymap *keymap) { @@ -83,8 +69,6 @@ meta_keymap_native_class_init (MetaKeymapNativeClass *klass) object_class->finalize = meta_keymap_native_finalize; - keymap_class->get_num_lock_state = meta_keymap_native_get_num_lock_state; - keymap_class->get_caps_lock_state = meta_keymap_native_get_caps_lock_state; keymap_class->get_direction = meta_keymap_native_get_direction; } @@ -123,18 +107,46 @@ meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap) return keymap->keymap; } +typedef struct +{ + MetaKeymapNative *keymap_native; + gboolean num_lock_state; + gboolean caps_lock_state; +} UpdateLockedModifierStateData; + +static gboolean +update_locked_modifier_state_in_main (gpointer user_data) +{ + UpdateLockedModifierStateData *data = user_data; + + clutter_keymap_set_lock_modifier_state (CLUTTER_KEYMAP (data->keymap_native), + data->caps_lock_state, + data->num_lock_state); + + return G_SOURCE_REMOVE; +} + void -meta_keymap_native_update_in_impl (MetaKeymapNative *keymap, +meta_keymap_native_update_in_impl (MetaKeymapNative *keymap_native, + MetaSeatImpl *seat_impl, struct xkb_state *xkb_state) { - keymap->num_lock = + UpdateLockedModifierStateData *data; + + data = g_new0 (UpdateLockedModifierStateData, 1); + data->keymap_native = keymap_native; + data->num_lock_state = xkb_state_mod_name_is_active (xkb_state, XKB_MOD_NAME_NUM, XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED); - keymap->caps_lock = + data->caps_lock_state = xkb_state_mod_name_is_active (xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED); + + meta_seat_impl_queue_main_thread_idle (seat_impl, + update_locked_modifier_state_in_main, + data, g_free); } diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h index 456f8850f..0aa62d085 100644 --- a/src/backends/native/meta-keymap-native.h +++ b/src/backends/native/meta-keymap-native.h @@ -37,6 +37,7 @@ void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap, struct xkb_keymap *xkb_keymap); struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap); void meta_keymap_native_update_in_impl (MetaKeymapNative *keymap, + MetaSeatImpl *seat_impl, struct xkb_state *xkb_state); #endif /* META_KEYMAP_NATIVE_H */ diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index e88285419..1ffc9e685 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -434,8 +434,9 @@ meta_seat_impl_notify_key_in_impl (MetaSeatImpl *seat_impl, MetaInputDeviceNative *keyboard_native; gboolean numlock_active; - meta_keymap_native_update_in_impl (seat_impl->keymap, seat_impl->xkb); - emit_signal (seat_impl, signals[MODS_STATE_CHANGED], NULL, 0); + meta_keymap_native_update_in_impl (seat_impl->keymap, + seat_impl, + seat_impl->xkb); meta_seat_impl_sync_leds_in_impl (seat_impl); numlock_active = @@ -2646,7 +2647,9 @@ meta_seat_impl_set_keyboard_numlock_in_impl (MetaSeatImpl *seat_impl, group_mods); meta_seat_impl_sync_leds_in_impl (seat_impl); - meta_keymap_native_update_in_impl (seat_impl->keymap, seat_impl->xkb); + meta_keymap_native_update_in_impl (seat_impl->keymap, + seat_impl, + seat_impl->xkb); } static gpointer @@ -3158,7 +3161,9 @@ meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl) xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); meta_seat_impl_sync_leds_in_impl (seat_impl); - meta_keymap_native_update_in_impl (seat_impl->keymap, seat_impl->xkb); + meta_keymap_native_update_in_impl (seat_impl->keymap, + seat_impl, + seat_impl->xkb); g_rw_lock_writer_unlock (&seat_impl->state_lock); } @@ -3319,7 +3324,9 @@ set_keyboard_layout_index (GTask *task) locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); - meta_keymap_native_update_in_impl (seat_impl->keymap, seat_impl->xkb); + meta_keymap_native_update_in_impl (seat_impl->keymap, + seat_impl, + seat_impl->xkb); seat_impl->layout_idx = idx; diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c index d30b46e98..da5d064e7 100644 --- a/src/backends/x11/meta-keymap-x11.c +++ b/src/backends/x11/meta-keymap-x11.c @@ -30,6 +30,7 @@ #include "backends/meta-input-settings-private.h" #include "backends/x11/meta-keymap-x11.h" #include "clutter/clutter.h" +#include "clutter/clutter-keymap-private.h" #include "clutter/clutter-mutter.h" #include "clutter/x11/clutter-x11.h" @@ -80,8 +81,6 @@ struct _MetaKeymapX11 uint32_t keymap_serial; - uint32_t caps_lock_state : 1; - uint32_t num_lock_state : 1; uint32_t has_direction : 1; uint32_t use_xkb : 1; @@ -205,23 +204,20 @@ static void update_locked_mods (MetaKeymapX11 *keymap_x11, int locked_mods) { - gboolean old_caps_lock_state, old_num_lock_state; + ClutterKeymap *keymap = CLUTTER_KEYMAP (keymap_x11); + gboolean caps_lock_state; + gboolean num_lock_state; + gboolean old_num_lock_state; - old_caps_lock_state = keymap_x11->caps_lock_state; - old_num_lock_state = keymap_x11->num_lock_state; + caps_lock_state = !!(locked_mods & CLUTTER_LOCK_MASK); + num_lock_state = !!(locked_mods & keymap_x11->num_lock_mask); - keymap_x11->caps_lock_state = (locked_mods & CLUTTER_LOCK_MASK) != 0; - keymap_x11->num_lock_state = (locked_mods & keymap_x11->num_lock_mask) != 0; + old_num_lock_state = clutter_keymap_get_num_lock_state (keymap); + clutter_keymap_set_lock_modifier_state (CLUTTER_KEYMAP (keymap_x11), + caps_lock_state, + num_lock_state); - g_debug ("Locks state changed - Num: %s, Caps: %s", - keymap_x11->num_lock_state ? "set" : "unset", - keymap_x11->caps_lock_state ? "set" : "unset"); - - if ((keymap_x11->caps_lock_state != old_caps_lock_state) || - (keymap_x11->num_lock_state != old_num_lock_state)) - g_signal_emit_by_name (keymap_x11, "state-changed"); - - if (keymap_x11->num_lock_state != old_num_lock_state) + if (num_lock_state != old_num_lock_state) { MetaBackend *backend; MetaInputSettings *input_settings; @@ -232,7 +228,7 @@ update_locked_mods (MetaKeymapX11 *keymap_x11, if (input_settings) { meta_input_settings_maybe_save_numlock_state (input_settings, - keymap_x11->num_lock_state); + num_lock_state); } } } @@ -516,22 +512,6 @@ meta_keymap_x11_finalize (GObject *object) G_OBJECT_CLASS (meta_keymap_x11_parent_class)->finalize (object); } -static gboolean -meta_keymap_x11_get_num_lock_state (ClutterKeymap *keymap) -{ - MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap); - - return keymap_x11->num_lock_state; -} - -static gboolean -meta_keymap_x11_get_caps_lock_state (ClutterKeymap *keymap) -{ - MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap); - - return keymap_x11->caps_lock_state; -} - static PangoDirection meta_keymap_x11_get_direction (ClutterKeymap *keymap) { @@ -577,8 +557,6 @@ meta_keymap_x11_class_init (MetaKeymapX11Class *klass) gobject_class->set_property = meta_keymap_x11_set_property; gobject_class->finalize = meta_keymap_x11_finalize; - keymap_class->get_num_lock_state = meta_keymap_x11_get_num_lock_state; - keymap_class->get_caps_lock_state = meta_keymap_x11_get_caps_lock_state; keymap_class->get_direction = meta_keymap_x11_get_direction; g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);