backend-x11: Re-upload keymap when new keyboard devices are added

The X server applies a default keymap to hotplugged keyboard
devices. To enforce our current settings we must re-upload the keymap
when a new keyboard shows up.

Note that setting the VCK keymap causes the server to propagate it
to all slave keyboard devices.

https://bugzilla.gnome.org/show_bug.cgi?id=737673
This commit is contained in:
Rui Matos 2014-10-02 19:07:21 +02:00
parent 492a1b244f
commit 478b75e803

View File

@ -65,9 +65,14 @@ struct _MetaBackendX11Private
uint8_t xkb_error_base; uint8_t xkb_error_base;
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
gchar *keymap_layouts;
gchar *keymap_variants;
gchar *keymap_options;
}; };
typedef struct _MetaBackendX11Private MetaBackendX11Private; typedef struct _MetaBackendX11Private MetaBackendX11Private;
static void apply_keymap (MetaBackendX11 *x11);
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND); G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
static void static void
@ -326,6 +331,17 @@ take_touch_grab (MetaBackend *backend)
False, &mask, 1, &mods); False, &mask, 1, &mods);
} }
static void
on_device_added (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
gpointer user_data)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (user_data);
if (clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE)
apply_keymap (x11);
}
static void static void
meta_backend_x11_post_init (MetaBackend *backend) meta_backend_x11_post_init (MetaBackend *backend)
{ {
@ -376,6 +392,9 @@ meta_backend_x11_post_init (MetaBackend *backend)
meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n", meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n",
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);
g_signal_connect_object (clutter_device_manager_get_default (), "device-added",
G_CALLBACK (on_device_added), backend, 0);
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend); META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
} }
@ -560,21 +579,22 @@ upload_xkb_description (Display *xdisplay,
} }
static void static void
meta_backend_x11_set_keymap (MetaBackend *backend, apply_keymap (MetaBackendX11 *x11)
const char *layouts,
const char *variants,
const char *options)
{ {
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
XkbRF_RulesRec *xkb_rules; XkbRF_RulesRec *xkb_rules;
XkbRF_VarDefsRec xkb_var_defs = { 0 }; XkbRF_VarDefsRec xkb_var_defs = { 0 };
gchar *rules_file_path; gchar *rules_file_path;
if (!priv->keymap_layouts ||
!priv->keymap_variants ||
!priv->keymap_options)
return;
get_xkbrf_var_defs (priv->xdisplay, get_xkbrf_var_defs (priv->xdisplay,
layouts, priv->keymap_layouts,
variants, priv->keymap_variants,
options, priv->keymap_options,
&rules_file_path, &rules_file_path,
&xkb_var_defs); &xkb_var_defs);
@ -598,6 +618,25 @@ meta_backend_x11_set_keymap (MetaBackend *backend,
g_free (rules_file_path); g_free (rules_file_path);
} }
static void
meta_backend_x11_set_keymap (MetaBackend *backend,
const char *layouts,
const char *variants,
const char *options)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
g_free (priv->keymap_layouts);
priv->keymap_layouts = g_strdup (layouts);
g_free (priv->keymap_variants);
priv->keymap_variants = g_strdup (variants);
g_free (priv->keymap_options);
priv->keymap_options = g_strdup (options);
apply_keymap (x11);
}
static struct xkb_keymap * static struct xkb_keymap *
meta_backend_x11_get_keymap (MetaBackend *backend) meta_backend_x11_get_keymap (MetaBackend *backend)
{ {