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
This commit is contained in:
parent
a884e4540c
commit
4c106a9c9b
9 changed files with 231 additions and 0 deletions
|
@ -2530,6 +2530,60 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
|||
xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -805,6 +805,14 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend,
|
|||
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -361,6 +371,107 @@ notify_modifiers (MetaWaylandKeyboard *keyboard)
|
|||
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -430,6 +541,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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ struct _MetaWaylandKeyboard
|
|||
MetaWaylandKeyboardGrab default_grab;
|
||||
|
||||
GSettings *settings;
|
||||
GSettings *gsd_settings;
|
||||
};
|
||||
|
||||
void meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard,
|
||||
|
|
Loading…
Reference in a new issue