[mutter] wayland: save/restore numlock state
- From: Olivier Fourdan <ofourdan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland: save/restore numlock state
- Date: Fri, 9 Sep 2016 17:47:17 +0000 (UTC)
commit 4c106a9c9bc743fb83bfe3759fcbbea883a8a260
Author: Olivier Fourdan <ofourdan redhat com>
Date: Thu Sep 8 09:55:44 2016 +0200
wayland: save/restore numlock state
Save the state on NumLock so that is can be (optionally) restored on
next login.
bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=757943
.../clutter/evdev/clutter-device-manager-evdev.c | 54 ++++++++
clutter/clutter/evdev/clutter-evdev.h | 4 +
src/backends/meta-backend-private.h | 3 +
src/backends/meta-backend.c | 8 +
src/backends/native/meta-backend-native.c | 9 ++
src/backends/x11/meta-backend-x11.c | 9 ++
src/meta/meta-backend.h | 3 +
src/wayland/meta-wayland-keyboard.c | 140 ++++++++++++++++++++
src/wayland/meta-wayland-keyboard.h | 1 +
9 files changed, 231 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c
b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index b42b576..c03c68c 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -2531,6 +2531,60 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
}
/**
+ * clutter_evdev_set_keyboard_numlock: (skip)
+ * @evdev: the #ClutterDeviceManager created by the evdev backend
+ * @numlock_set: TRUE to set NumLock ON, FALSE otherwise.
+ *
+ * Sets the NumLock state on the backend's #xkb_state .
+ *
+ * Stability: unstable
+ */
+void
+clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
+ gboolean numlock_state)
+{
+ ClutterDeviceManagerEvdev *manager_evdev;
+ ClutterDeviceManagerEvdevPrivate *priv;
+ GSList *iter;
+ xkb_mod_mask_t numlock;
+
+ g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
+
+ manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
+ priv = manager_evdev->priv;
+ numlock = (1 << xkb_keymap_mod_get_index(priv->keymap, "Mod2"));
+
+ for (iter = priv->seats; iter; iter = iter->next)
+ {
+ ClutterSeatEvdev *seat = iter->data;
+ xkb_mod_mask_t depressed_mods;
+ xkb_mod_mask_t latched_mods;
+ xkb_mod_mask_t locked_mods;
+ xkb_mod_mask_t group_mods;
+
+ depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
+ latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED);
+ locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED);
+ group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE);
+
+ if (numlock_state)
+ locked_mods |= numlock;
+ else
+ locked_mods &= ~numlock;
+
+ xkb_state_update_mask (seat->xkb,
+ depressed_mods,
+ latched_mods,
+ locked_mods,
+ 0, 0,
+ group_mods);
+
+ clutter_seat_evdev_sync_leds (seat);
+ }
+}
+
+
+/**
* clutter_evdev_set_pointer_constrain_callback:
* @evdev: the #ClutterDeviceManager created by the evdev backend
* @callback: the callback
diff --git a/clutter/clutter/evdev/clutter-evdev.h b/clutter/clutter/evdev/clutter-evdev.h
index be8748f..1f5485c 100644
--- a/clutter/clutter/evdev/clutter-evdev.h
+++ b/clutter/clutter/evdev/clutter-evdev.h
@@ -105,6 +105,10 @@ CLUTTER_AVAILABLE_IN_1_20
void clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
xkb_layout_index_t idx);
+CLUTTER_AVAILABLE_IN_1_26
+void clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
+ gboolean numlock_state);
+
CLUTTER_AVAILABLE_IN_1_18
void clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
gboolean repeat,
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index ee85e8a..b8abccf 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -103,6 +103,9 @@ struct _MetaBackendClass
double *dy,
double *dx_unaccel,
double *dy_unaccel);
+ void (* set_numlock) (MetaBackend *backend,
+ gboolean numlock_state);
+
};
void meta_init_backend (MetaBackendType backend_type);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 8c97765..872d0d3 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -542,6 +542,14 @@ meta_backend_lock_layout_group (MetaBackend *backend,
META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
}
+void
+meta_backend_set_numlock (MetaBackend *backend,
+ gboolean numlock_state)
+{
+ META_BACKEND_GET_CLASS (backend)->set_numlock (backend, numlock_state);
+}
+
+
/**
* meta_backend_get_stage:
* @backend: A #MetaBackend
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index 385122c..09b235b 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -368,6 +368,14 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0);
}
+static void
+meta_backend_native_set_numlock (MetaBackend *backend,
+ gboolean numlock_state)
+{
+ ClutterDeviceManager *manager = clutter_device_manager_get_default ();
+ clutter_evdev_set_keyboard_numlock (manager, numlock_state);
+}
+
static gboolean
meta_backend_native_get_relative_motion_deltas (MetaBackend *backend,
const ClutterEvent *event,
@@ -421,6 +429,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
backend_class->get_relative_motion_deltas = meta_backend_native_get_relative_motion_deltas;
backend_class->update_screen_size = meta_backend_native_update_screen_size;
+ backend_class->set_numlock = meta_backend_native_set_numlock;
}
static void
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index c9a6b9a..a0b196e 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -806,6 +806,14 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend,
}
static void
+meta_backend_x11_set_numlock (MetaBackend *backend,
+ gboolean numlock_state)
+{
+ /* TODO: Currently handled by gnome-settings-deamon */
+}
+
+
+static void
meta_backend_x11_update_screen_size (MetaBackend *backend,
int width, int height)
{
@@ -897,6 +905,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->lock_layout_group = meta_backend_x11_lock_layout_group;
backend_class->update_screen_size = meta_backend_x11_update_screen_size;
backend_class->select_stage_events = meta_backend_x11_select_stage_events;
+ backend_class->set_numlock = meta_backend_x11_set_numlock;
}
static void
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
index c50429a..fad8f55 100644
--- a/src/meta/meta-backend.h
+++ b/src/meta/meta-backend.h
@@ -44,6 +44,9 @@ void meta_backend_set_keymap (MetaBackend *backend,
void meta_backend_lock_layout_group (MetaBackend *backend,
guint idx);
+void meta_backend_set_numlock (MetaBackend *backend,
+ gboolean numlock_state);
+
ClutterActor *meta_backend_get_stage (MetaBackend *backend);
void meta_clutter_init (void);
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index d505783..7f267b1 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -65,9 +65,19 @@
#include "backends/native/meta-backend-native.h"
#endif
+#define GSD_KEYBOARD_SCHEMA "org.gnome.settings-daemon.peripherals.keyboard"
+typedef enum
+{
+ GSD_KEYBOARD_NUM_LOCK_STATE_UNKNOWN,
+ GSD_KEYBOARD_NUM_LOCK_STATE_ON,
+ GSD_KEYBOARD_NUM_LOCK_STATE_OFF
+} GsdKeyboardNumLockState;
+
G_DEFINE_TYPE (MetaWaylandKeyboard, meta_wayland_keyboard, G_TYPE_OBJECT);
static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
+static void meta_wayland_keyboard_set_numlock (MetaWaylandKeyboard *keyboard,
+ gboolean numlock_state);
static void notify_modifiers (MetaWaylandKeyboard *keyboard);
static guint evdev_code (const ClutterKeyEvent *event);
@@ -362,6 +372,107 @@ notify_modifiers (MetaWaylandKeyboard *keyboard)
}
static void
+numlock_set_xkb_state (MetaWaylandKeyboard *keyboard,
+ GsdKeyboardNumLockState state)
+{
+ MetaBackend *backend = meta_get_backend ();
+ gboolean numlock_state;
+
+ if (state != GSD_KEYBOARD_NUM_LOCK_STATE_ON &&
+ state != GSD_KEYBOARD_NUM_LOCK_STATE_OFF)
+ return;
+
+ numlock_state = (state == GSD_KEYBOARD_NUM_LOCK_STATE_ON);
+ meta_verbose ("set numlock state %s\n", (numlock_state ? "ON" : "OFF"));
+ meta_backend_set_numlock (backend, numlock_state);
+ meta_wayland_keyboard_set_numlock (keyboard, numlock_state);
+}
+
+static void
+maybe_restore_numlock_state (MetaWaylandKeyboard *keyboard)
+{
+ gboolean remember_numlock;
+
+ if (!keyboard->gsd_settings)
+ return;
+
+ /* We are cheating for now, we use g-s-d settings... */
+ remember_numlock = g_settings_get_boolean (keyboard->gsd_settings,
+ "remember-numlock-state");
+
+ if (remember_numlock)
+ {
+ GsdKeyboardNumLockState state;
+
+ state = g_settings_get_enum (keyboard->gsd_settings, "numlock-state");
+ numlock_set_xkb_state (keyboard, state);
+ }
+}
+
+static void
+maybe_save_numlock_state (MetaWaylandKeyboard *keyboard)
+{
+ MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
+ GDesktopKeyboardNumLockState numlock_state;
+ int numlock_active;
+
+ if (!META_IS_BACKEND_NATIVE (meta_get_backend ()))
+ return;
+
+ if (!xkb_info->state)
+ return;
+
+ if (!keyboard->gsd_settings)
+ return;
+
+ if (!g_settings_get_boolean (keyboard->gsd_settings, "remember-numlock-state"))
+ return;
+
+ numlock_active = xkb_state_mod_name_is_active(xkb_info->state,
+ "Mod2",
+ XKB_STATE_MODS_LOCKED);
+ switch (numlock_active)
+ {
+ case -1:
+ numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_UNKNOWN;
+ break;
+ case 0:
+ numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_OFF;
+ break;
+ default:
+ numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_ON;
+ break;
+ }
+ g_settings_set_enum (keyboard->gsd_settings, "numlock-state", numlock_state);
+}
+
+static void
+meta_wayland_keyboard_set_numlock (MetaWaylandKeyboard *keyboard,
+ gboolean numlock_state)
+{
+ MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
+ xkb_mod_mask_t latched, locked, group, depressed;
+ xkb_mod_mask_t numlock;
+
+ meta_verbose ("backend numlock state %s\n", (numlock_state ? "ON" : "OFF"));
+
+ latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
+ locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
+ group = xkb_state_serialize_layout (xkb_info->state, XKB_STATE_LAYOUT_EFFECTIVE);
+ depressed = xkb_state_serialize_mods(xkb_info->state, XKB_STATE_DEPRESSED);
+ numlock = (1 << xkb_keymap_mod_get_index(xkb_info->keymap, "Mod2"));
+
+ if (numlock_state == TRUE)
+ locked |= numlock;
+ else
+ locked &= ~numlock;
+
+ xkb_state_update_mask (xkb_info->state, depressed, latched, locked, 0, 0, group);
+
+ notify_modifiers (keyboard);
+}
+
+static void
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
@@ -431,6 +542,16 @@ notify_key_repeat (MetaWaylandKeyboard *keyboard)
}
static void
+remember_numlock_state_changed (GSettings *settings,
+ const char *key,
+ gpointer data)
+{
+ MetaWaylandKeyboard *keyboard = data;
+
+ maybe_save_numlock_state (keyboard);
+}
+
+static void
settings_changed (GSettings *settings,
const char *key,
gpointer data)
@@ -484,6 +605,7 @@ meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard,
MetaWaylandSeat *seat)
{
MetaBackend *backend = meta_get_backend ();
+ GSettingsSchema *schema;
keyboard->seat = seat;
@@ -502,11 +624,25 @@ meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard,
g_signal_connect (keyboard->settings, "changed",
G_CALLBACK (settings_changed), keyboard);
+ /* We are cheating for now, we use g-s-d settings... Check if available */
+ schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
+ GSD_KEYBOARD_SCHEMA,
+ TRUE);
+ if (schema)
+ {
+ keyboard->gsd_settings = g_settings_new_full (schema, NULL, NULL);
+ g_settings_schema_unref (schema);
+ g_signal_connect (keyboard->gsd_settings, "changed::remember-numlock-state",
+ G_CALLBACK (remember_numlock_state_changed), keyboard);
+ }
+
g_signal_connect (backend, "keymap-changed",
G_CALLBACK (on_keymap_changed), keyboard);
g_signal_connect (backend, "keymap-layout-group-changed",
G_CALLBACK (on_keymap_layout_group_changed), keyboard);
meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
+
+ maybe_restore_numlock_state (keyboard);
}
static void
@@ -538,6 +674,8 @@ meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard)
/* XXX: What about keyboard->resource_list? */
g_clear_object (&keyboard->settings);
+ if (keyboard->gsd_settings)
+ g_object_unref (keyboard->gsd_settings);
keyboard->seat = NULL;
}
@@ -593,6 +731,8 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
if (keyboard->mods_changed != 0)
{
+ if (keyboard->mods_changed & XKB_STATE_MODS_LOCKED)
+ maybe_save_numlock_state (keyboard);
notify_modifiers (keyboard);
keyboard->mods_changed = 0;
}
diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h
index 5f7d15c..5e7d84b 100644
--- a/src/wayland/meta-wayland-keyboard.h
+++ b/src/wayland/meta-wayland-keyboard.h
@@ -100,6 +100,7 @@ struct _MetaWaylandKeyboard
MetaWaylandKeyboardGrab default_grab;
GSettings *settings;
+ GSettings *gsd_settings;
};
void meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]