backend: Add API to get layout group

Add API to get the layout group (layout index) currently active. In the
native backend this is done by fetching the state directly from the
evdev backend; on X11 this works by listening for XkbStateNotify
events, caching the layout group value.

https://bugzilla.gnome.org/show_bug.cgi?id=786408
This commit is contained in:
Jonas Ådahl 2017-08-17 17:01:50 +08:00
parent 5685449e15
commit 33f1706634
4 changed files with 58 additions and 1 deletions

View File

@ -83,6 +83,8 @@ struct _MetaBackendClass
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
xkb_layout_index_t (* get_keymap_layout_group) (MetaBackend *backend);
void (* lock_layout_group) (MetaBackend *backend,
guint idx);
@ -133,6 +135,8 @@ MetaLogicalMonitor * meta_backend_get_current_logical_monitor (MetaBackend *back
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
void meta_backend_update_last_device (MetaBackend *backend,
int device_id);

View File

@ -699,6 +699,12 @@ meta_backend_get_keymap (MetaBackend *backend)
return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
}
xkb_layout_index_t
meta_backend_get_keymap_layout_group (MetaBackend *backend)
{
return META_BACKEND_GET_CLASS (backend)->get_keymap_layout_group (backend);
}
void
meta_backend_lock_layout_group (MetaBackend *backend,
guint idx)

View File

@ -507,6 +507,14 @@ meta_backend_native_get_keymap (MetaBackend *backend)
return clutter_evdev_get_keyboard_map (manager);
}
static xkb_layout_index_t
meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
return clutter_evdev_get_keyboard_layout_index (manager);
}
static void
meta_backend_native_lock_layout_group (MetaBackend *backend,
guint idx)
@ -579,6 +587,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->set_keymap = meta_backend_native_set_keymap;
backend_class->get_keymap = meta_backend_native_get_keymap;
backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group;
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;

View File

@ -67,6 +67,7 @@ struct _MetaBackendX11Private
uint8_t xkb_error_base;
struct xkb_keymap *keymap;
xkb_layout_index_t keymap_layout_group;
MetaLogicalMonitor *cached_current_logical_monitor;
};
@ -282,12 +283,18 @@ handle_host_xevent (MetaBackend *backend,
if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
{
int layout_group;
switch (xkb_ev->any.xkb_type)
{
case XkbNewKeyboardNotify:
case XkbMapNotify:
keymap_changed (backend);
break;
case XkbStateNotify:
layout_group = xkb_ev->state.locked_group;
priv->keymap_layout_group = layout_group;
break;
default:
break;
}
@ -424,7 +431,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
priv->xcb = XGetXCBConnection (priv->xdisplay);
if (!xkb_x11_setup_xkb_extension (priv->xcb,
XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION,
@ -568,6 +574,15 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
return priv->keymap;
}
static xkb_layout_index_t
meta_backend_x11_get_keymap_layout_group (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
return priv->keymap_layout_group;
}
static void
meta_backend_x11_set_numlock (MetaBackend *backend,
gboolean numlock_state)
@ -592,6 +607,25 @@ meta_backend_x11_get_xkb_event_base (MetaBackendX11 *x11)
return priv->xkb_event_base;
}
static void
init_xkb_state (MetaBackendX11 *x11)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
struct xkb_keymap *keymap;
int32_t device_id;
struct xkb_state *state;
keymap = meta_backend_get_keymap (META_BACKEND (x11));
device_id = xkb_x11_get_core_keyboard_device_id (priv->xcb);
state = xkb_x11_state_new_from_device (keymap, priv->xcb, device_id);
priv->keymap_layout_group =
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_LOCKED);
xkb_state_unref (state);
}
static gboolean
meta_backend_x11_initable_init (GInitable *initable,
GCancellable *cancellable,
@ -619,8 +653,11 @@ meta_backend_x11_initable_init (GInitable *initable,
}
priv->xdisplay = xdisplay;
priv->xcb = XGetXCBConnection (priv->xdisplay);
clutter_x11_set_display (xdisplay);
init_xkb_state (x11);
return initable_parent_iface->init (initable, cancellable, error);
}
@ -645,6 +682,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
backend_class->get_keymap = meta_backend_x11_get_keymap;
backend_class->get_keymap_layout_group = meta_backend_x11_get_keymap_layout_group;
backend_class->set_numlock = meta_backend_x11_set_numlock;
}