[PATCH] Reapply settings when external keyboard connects
Martin Kelly
martin at martingkelly.com
Fri May 9 20:05:10 CEST 2014
Signed-off-by: Martin Kelly <martin at martingkelly.com>
---
xfsettingsd/keyboards.c | 115 +++++++++++++++++++++++++++++++++++++++++++++---
xfsettingsd/keyboards.h | 12 +++++
2 files changed, 122 insertions(+), 5 deletions(-)
diff --git a/xfsettingsd/keyboards.c b/xfsettingsd/keyboards.c
index 976e2ba..e5c59de 100644
--- a/xfsettingsd/keyboards.c
+++ b/xfsettingsd/keyboards.c
@@ -54,6 +54,13 @@ static void xfce_keyboards_helper_channel_property_changed (XfconfChannel
XfceKeyboardsHelper *helper);
static void xfce_keyboards_helper_restore_numlock_state (XfconfChannel *channel);
static void xfce_keyboards_helper_save_numlock_state (XfconfChannel *channel);
+static gboolean xfce_keyboards_helper_device_is_keyboard (XID xid);
+static void xfce_keyboards_helper_set_all_settings (XfceKeyboardsHelper *helper);
+#ifdef DEVICE_HOTPLUGGING
+static GdkFilterReturn xfce_keyboards_helper_event_filter (GdkXEvent *xevent,
+ GdkEvent *gdk_event,
+ gpointer user_data);
+#endif
@@ -69,6 +76,12 @@ struct _XfceKeyboardsHelper
/* xfconf channel */
XfconfChannel *channel;
+
+#ifdef DEVICE_HOTPLUGGING
+ /* device presence event type */
+ gint device_presence_event_type;
+#endif
+
};
@@ -93,11 +106,18 @@ xfce_keyboards_helper_init (XfceKeyboardsHelper *helper)
{
gint dummy;
gint marjor_ver, minor_ver;
+ Display *xdisplay;
+#ifdef DEVICE_HOTPLUGGING
+ XEventClass event_class;
+#endif
/* init */
helper->channel = NULL;
- if (XkbQueryExtension (GDK_DISPLAY (), &dummy, &dummy, &dummy, &marjor_ver, &minor_ver))
+ /* get the default display */
+ xdisplay = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
+
+ if (XkbQueryExtension (xdisplay, &dummy, &dummy, &dummy, &marjor_ver, &minor_ver))
{
xfsettings_dbg (XFSD_DEBUG_KEYBOARDS, "initialized xkb %d.%d", marjor_ver, minor_ver);
@@ -108,10 +128,24 @@ xfce_keyboards_helper_init (XfceKeyboardsHelper *helper)
g_signal_connect (G_OBJECT (helper->channel), "property-changed",
G_CALLBACK (xfce_keyboards_helper_channel_property_changed), helper);
- /* load settings */
- xfce_keyboards_helper_set_auto_repeat_mode (helper);
- xfce_keyboards_helper_set_repeat_rate (helper);
- xfce_keyboards_helper_restore_numlock_state (helper->channel);
+#ifdef DEVICE_HOTPLUGGING
+ if (G_LIKELY (xdisplay != NULL))
+ {
+ /* monitor device changes */
+ gdk_error_trap_push ();
+ DevicePresence (xdisplay, helper->device_presence_event_type, event_class);
+ XSelectExtensionEvent (xdisplay, RootWindow (xdisplay, DefaultScreen (xdisplay)), &event_class, 1);
+
+ /* add an event filter */
+ if (gdk_error_trap_pop () == 0)
+ gdk_window_add_filter (NULL, xfce_keyboards_helper_event_filter, helper);
+ else
+ g_warning ("Failed to create device filter");
+ }
+#endif
+
+ /* load keyboard settings */
+ xfce_keyboards_helper_set_all_settings (helper);
}
else
{
@@ -271,3 +305,74 @@ xfce_keyboards_helper_save_numlock_state (XfconfChannel *channel)
xfconf_channel_set_bool (channel, "/Default/Numlock", numlock_state);
}
+
+
+
+static void
+xfce_keyboards_helper_set_all_settings (XfceKeyboardsHelper *helper)
+{
+ xfce_keyboards_helper_set_auto_repeat_mode (helper);
+ xfce_keyboards_helper_set_repeat_rate (helper);
+ xfce_keyboards_helper_restore_numlock_state (helper->channel);
+}
+
+
+
+#ifdef DEVICE_HOTPLUGGING
+static gboolean
+xfce_keyboards_helper_device_is_keyboard (XID xid)
+{
+ XDeviceInfo *device;
+ gboolean device_found;
+ XDeviceInfo *device_list;
+ Atom keyboard_type;
+ gint n, ndevices;
+ Display *xdisplay = GDK_DISPLAY ();
+
+ keyboard_type = XInternAtom (xdisplay, XI_KEYBOARD, True);
+ device_list = XListInputDevices(xdisplay, &ndevices);
+ device_found = FALSE;
+ for (n = 0; n < ndevices; n++)
+ {
+ device = &device_list[n];
+ /* look for a keyboard that matches this XID */
+ if (device->type == keyboard_type &&
+ device->id == xid)
+ {
+ device_found = TRUE;
+ break;
+ }
+ }
+ XFreeDeviceList(device_list);
+
+ return device_found;
+}
+#endif
+
+
+
+#ifdef DEVICE_HOTPLUGGING
+static GdkFilterReturn
+xfce_keyboards_helper_event_filter (GdkXEvent *xevent,
+ GdkEvent *gdk_event,
+ gpointer user_data)
+{
+ XEvent *event = xevent;
+ XDevicePresenceNotifyEvent *dpn_event = xevent;
+ XfceKeyboardsHelper *helper = XFCE_KEYBOARDS_HELPER (user_data);
+
+ if (G_UNLIKELY (event->type != helper->device_presence_event_type))
+ return GDK_FILTER_CONTINUE;
+
+ if (G_LIKELY (dpn_event->devchange != DeviceAdded))
+ return GDK_FILTER_CONTINUE;
+
+ if (!xfce_keyboards_helper_device_is_keyboard(dpn_event->deviceid))
+ return GDK_FILTER_CONTINUE;
+
+ /* New keyboard added. Need to reapply settings. */
+ xfce_keyboards_helper_set_all_settings (helper);
+
+ return GDK_FILTER_CONTINUE;
+}
+#endif
diff --git a/xfsettingsd/keyboards.h b/xfsettingsd/keyboards.h
index ff2c174..a276be3 100644
--- a/xfsettingsd/keyboards.h
+++ b/xfsettingsd/keyboards.h
@@ -19,6 +19,8 @@
* by Olivier Fourdan.
*/
+#include <X11/extensions/XInput.h>
+
#ifndef __KEYBOARDS_H__
#define __KEYBOARDS_H__
@@ -32,6 +34,16 @@ typedef struct _XfceKeyboardsHelper XfceKeyboardsHelper;
#define XFCE_IS_KEYBOARDS_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_KEYBOARDS_HELPER))
#define XFCE_KEYBOARDS_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_KEYBOARDS_HELPER, XfceKeyboardsHelperClass))
+/* test if the required version of inputproto (1.4.2) is available */
+#undef DEVICE_HOTPLUGGING
+#ifdef XI_Add_DevicePresenceNotify_Major
+# if XI_Add_DevicePresenceNotify_Major >= 1 && defined (DeviceRemoved)
+# define DEVICE_HOTPLUGGING
+# else
+# undef DEVICE_HOTPLUGGING
+# endif
+#endif
+
GType xfce_keyboards_helper_get_type (void) G_GNUC_CONST;
#endif /* !__KEYBOARDS_H__ */
--
2.0.0.rc2
More information about the Xfce4-dev
mailing list