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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel