[PATCH weston 1/3] evdev/libinput: sync the leds of keyboards with the xkb state

Giulio Camuffo giuliocamuffo at gmail.com
Wed Aug 20 12:57:27 PDT 2014


When a new keyboard is found (including during startup) sync its leds
with the internal state of the xkb map.
It appears that by setting them immediately when getting the new device
we're racing with the kernel or something, which wants to turn all the
leds off, so we use a timer.
---

I can't say i like this timer thing, at all. If someone has batter ideas,
please share them.


 src/libinput-seat.c | 25 +++++++++++++++++++++++++
 src/udev-seat.c     | 25 +++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/src/libinput-seat.c b/src/libinput-seat.c
index 09cf7c7..76ca342 100644
--- a/src/libinput-seat.c
+++ b/src/libinput-seat.c
@@ -45,6 +45,30 @@ udev_seat_create(struct udev_input *input, const char *seat_name);
 static void
 udev_seat_destroy(struct udev_seat *seat);
 
+static int
+set_leds(void *data)
+{
+	struct weston_seat *seat = data;
+	if (seat->keyboard)
+		seat->led_update(seat, seat->keyboard->xkb_state.leds);
+	return 0;
+}
+
+/* We want to update the leds of new keyboards to reflect the state
+ * of the xkb map, the problem is that by setting them immediately
+ * on device creation we're racing with something (the kernel?) which
+ * wants to turn them all off. So use a timer with a 100ms delay. */
+static void
+schedule_leds_update(struct weston_seat *seat)
+{
+	struct wl_event_loop *loop;
+	struct wl_event_source *timer;
+
+	loop = wl_display_get_event_loop(seat->compositor->wl_display);
+	timer = wl_event_loop_add_timer(loop, set_leds, seat);
+	wl_event_source_timer_update(timer, 100);
+}
+
 static void
 device_added(struct udev_input *input, struct libinput_device *libinput_device)
 {
@@ -92,6 +116,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
 
 	if (!input->suspended)
 		weston_seat_repick(seat);
+	schedule_leds_update(seat);
 }
 
 static void
diff --git a/src/udev-seat.c b/src/udev-seat.c
index 8e7405d..5019b8c 100644
--- a/src/udev-seat.c
+++ b/src/udev-seat.c
@@ -39,6 +39,30 @@ static void
 udev_seat_destroy(struct udev_seat *seat);
 
 static int
+set_leds(void *data)
+{
+	struct weston_seat *seat = data;
+	if (seat->keyboard)
+		seat->led_update(seat, seat->keyboard->xkb_state.leds);
+	return 0;
+}
+
+/* We want to update the leds of new keyboards to reflect the state
+ * of the xkb map, the problem is that by setting them immediately
+ * on device creation we're racing with something (the kernel?) which
+ * wants to turn them all off. So use a timer with a 100ms delay. */
+static void
+schedule_leds_update(struct udev_seat *seat)
+{
+	struct wl_event_loop *loop;
+	struct wl_event_source *timer;
+
+	loop = wl_display_get_event_loop(seat->base.compositor->wl_display);
+	timer = wl_event_loop_add_timer(loop, set_leds, &seat->base);
+	wl_event_source_timer_update(timer, 100);
+}
+
+static int
 device_added(struct udev_device *udev_device, struct udev_input *input)
 {
 	struct weston_compositor *c;
@@ -133,6 +157,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input)
 
 	if (input->enabled == 1)
 		weston_seat_repick(&seat->base);
+	schedule_leds_update(seat);
 
 	return 0;
 }
-- 
2.0.4



More information about the wayland-devel mailing list