[weston,3/4] input: Move seat capability update sends out of init functions

Submitted by Derek Foreman on May 5, 2015, 8:01 p.m.

Details

Message ID 1430856114-20765-4-git-send-email-derekf@osg.samsung.com
State New
Delegated to: Jonas Ådahl
Headers show

Not browsing as part of any series.

Commit Message

Derek Foreman May 5, 2015, 8:01 p.m.
This lets device_added() do additional processing before the update is
sent, which will be useful later when recognizing keyboard capabilities.

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
---
 src/compositor-headless.c |  2 ++
 src/compositor-rdp.c      |  1 +
 src/compositor-wayland.c  |  2 ++
 src/compositor-x11.c      |  2 ++
 src/compositor.h          |  4 ++++
 src/input.c               | 49 ++++++++++++++++++++++++++++-------------------
 src/libinput-seat.c       |  8 ++++++++
 src/screen-share.c        |  2 ++
 tests/weston-test.c       |  4 ++++
 9 files changed, 54 insertions(+), 20 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index 1b1d327..0ddb26e 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -184,6 +184,8 @@  headless_input_create(struct headless_compositor *c)
 	if (weston_seat_init_keyboard(&c->fake_seat, NULL) < 0)
 		return -1;
 
+	weston_seat_send_dirty_caps(&c->fake_seat);
+
 	return 0;
 }
 
diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
index 6955d49..5b50382 100644
--- a/src/compositor-rdp.c
+++ b/src/compositor-rdp.c
@@ -842,6 +842,7 @@  xf_peer_post_connect(freerdp_peer* client)
 	}
 	weston_seat_init_keyboard(&peerCtx->item.seat, keymap);
 	weston_seat_init_pointer(&peerCtx->item.seat);
+	weston_seat_send_dirty_caps(&peerCtx->item.seat);
 
 	peerCtx->item.flags |= RDP_PEER_ACTIVATED;
 
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 6a86250..53159c4 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -1463,6 +1463,8 @@  input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
 	else
 		weston_seat_init_keyboard(&input->base, keymap);
 
+	weston_seat_send_dirty_caps(&input->base);
+
 	xkb_keymap_unref(keymap);
 
 	return;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 1cbdbc4..4a3b10e 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -336,6 +336,8 @@  x11_input_create(struct x11_compositor *c, int no_input)
 		return -1;
 	xkb_keymap_unref(keymap);
 
+	weston_seat_send_dirty_caps(&c->core_seat);
+
 	x11_compositor_setup_xkb(c);
 
 	return 0;
diff --git a/src/compositor.h b/src/compositor.h
index 35c6a30..e05b262 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -449,6 +449,8 @@  weston_touch_start_drag(struct weston_touch *touch,
 			struct weston_data_source *source,
 			struct weston_surface *icon,
 			struct wl_client *client);
+void
+weston_seat_send_dirty_caps(struct weston_seat *seat);
 
 struct weston_xkb_info {
 	struct xkb_keymap *keymap;
@@ -538,6 +540,8 @@  struct weston_seat {
 	uint32_t slot_map;
 	struct input_method *input_method;
 	char *seat_name;
+
+	bool caps_dirty;
 };
 
 enum {
diff --git a/src/input.c b/src/input.c
index 3f9e267..c37bd20 100644
--- a/src/input.c
+++ b/src/input.c
@@ -599,23 +599,32 @@  weston_touch_destroy(struct weston_touch *touch)
 	free(touch);
 }
 
-static void
-seat_send_updated_caps(struct weston_seat *seat)
+/* Send seat capability updates if necessary
+ *
+ * Checks if the seat capabilities (WL_SEAT_CAPABILITY_*) have changed
+ * and propagates updates appropriately.
+ *
+ * \param seat These seat to send capabilities changes for
+ */
+WL_EXPORT void
+weston_seat_send_dirty_caps(struct weston_seat *seat)
 {
 	enum wl_seat_capability caps = 0;
 	struct wl_resource *resource;
 
-	if (seat->pointer_device_count > 0)
-		caps |= WL_SEAT_CAPABILITY_POINTER;
-	if (seat->keyboard_device_count > 0)
-		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
-	if (seat->touch_device_count > 0)
-		caps |= WL_SEAT_CAPABILITY_TOUCH;
+	if (seat->caps_dirty) {
+		if (seat->pointer_device_count > 0)
+			caps |= WL_SEAT_CAPABILITY_POINTER;
+		if (seat->keyboard_device_count > 0)
+			caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+		if (seat->touch_device_count > 0)
+			caps |= WL_SEAT_CAPABILITY_TOUCH;
 
-	wl_resource_for_each(resource, &seat->base_resource_list) {
-		wl_seat_send_capabilities(resource, caps);
+		wl_resource_for_each(resource, &seat->base_resource_list)
+			wl_seat_send_capabilities(resource, caps);
+		wl_signal_emit(&seat->updated_caps_signal, seat);
 	}
-	wl_signal_emit(&seat->updated_caps_signal, seat);
+	seat->caps_dirty = false;
 }
 
 WL_EXPORT void
@@ -2136,7 +2145,7 @@  weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 	if (seat->keyboard_resource) {
 		seat->keyboard_device_count += 1;
 		if (seat->keyboard_device_count == 1)
-			seat_send_updated_caps(seat);
+			seat->caps_dirty = true;
 		return 0;
 	}
 
@@ -2173,7 +2182,7 @@  weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 	seat->keyboard_device_count = 1;
 	keyboard->seat = seat;
 
-	seat_send_updated_caps(seat);
+	seat->caps_dirty = true;
 
 	return 0;
 
@@ -2217,7 +2226,7 @@  weston_seat_release_keyboard(struct weston_seat *seat)
 		weston_keyboard_set_focus(seat->keyboard_resource, NULL);
 		weston_keyboard_cancel_grab(seat->keyboard_resource);
 		weston_keyboard_reset_state(seat->keyboard_resource);
-		seat_send_updated_caps(seat);
+		seat->caps_dirty = true;
 	}
 }
 
@@ -2229,7 +2238,7 @@  weston_seat_init_pointer(struct weston_seat *seat)
 	if (seat->pointer_resource) {
 		seat->pointer_device_count += 1;
 		if (seat->pointer_device_count == 1)
-			seat_send_updated_caps(seat);
+			seat->caps_dirty = true;
 		return;
 	}
 
@@ -2241,7 +2250,7 @@  weston_seat_init_pointer(struct weston_seat *seat)
 	seat->pointer_device_count = 1;
 	pointer->seat = seat;
 
-	seat_send_updated_caps(seat);
+	seat->caps_dirty = true;
 }
 
 WL_EXPORT void
@@ -2261,7 +2270,7 @@  weston_seat_release_pointer(struct weston_seat *seat)
 			pointer_unmap_sprite(pointer);
 
 		weston_pointer_reset_state(pointer);
-		seat_send_updated_caps(seat);
+		seat->caps_dirty = true;
 
 		/* seat->pointer is intentionally not destroyed so that
 		 * a newly attached pointer on this seat will retain
@@ -2278,7 +2287,7 @@  weston_seat_init_touch(struct weston_seat *seat)
 	if (seat->touch_resource) {
 		seat->touch_device_count += 1;
 		if (seat->touch_device_count == 1)
-			seat_send_updated_caps(seat);
+			seat->caps_dirty = true;
 		return;
 	}
 
@@ -2290,7 +2299,7 @@  weston_seat_init_touch(struct weston_seat *seat)
 	seat->touch_device_count = 1;
 	touch->seat = seat;
 
-	seat_send_updated_caps(seat);
+	seat->caps_dirty = true;
 }
 
 WL_EXPORT void
@@ -2302,7 +2311,7 @@  weston_seat_release_touch(struct weston_seat *seat)
 		weston_touch_set_focus(seat->touch_resource, NULL);
 		weston_touch_cancel_grab(seat->touch_resource);
 		weston_touch_reset_state(seat->touch_resource);
-		seat_send_updated_caps(seat);
+		seat->caps_dirty = true;
 	}
 }
 
diff --git a/src/libinput-seat.c b/src/libinput-seat.c
index 410df0e..f0fcd51 100644
--- a/src/libinput-seat.c
+++ b/src/libinput-seat.c
@@ -102,14 +102,22 @@  device_added(struct udev_input *input, struct libinput_device *libinput_device)
 
 	if (!input->suspended)
 		weston_seat_repick(seat);
+
+	weston_seat_send_dirty_caps(seat);
 }
 
 static void
 device_removed(struct udev_input *input, struct libinput_device *libinput_device)
 {
 	struct evdev_device *device;
+	struct udev_seat *udev_seat = get_udev_seat(input, libinput_device);
+
+	if (!udev_seat)
+		return;
+
 	device = libinput_device_get_user_data(libinput_device);
 	evdev_device_destroy(device);
+	weston_seat_send_dirty_caps(&udev_seat->base);
 }
 
 static void
diff --git a/src/screen-share.c b/src/screen-share.c
index 49b8416..597ad9b 100644
--- a/src/screen-share.c
+++ b/src/screen-share.c
@@ -214,6 +214,8 @@  ss_seat_handle_keymap(void *data, struct wl_keyboard *keyboard,
 	else
 		weston_seat_init_keyboard(&seat->base, keymap);
 
+	weston_seat_send_dirty_caps(&seat->base);
+
 	xkb_keymap_unref(keymap);
 
 	return;
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 284705a..f3b2abf 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -212,6 +212,8 @@  device_release(struct wl_client *client,
 	} else {
 		assert(0 && "Unsupported device");
 	}
+
+	weston_seat_send_dirty_caps(seat);
 }
 
 static void
@@ -230,6 +232,8 @@  device_add(struct wl_client *client,
 	} else {
 		assert(0 && "Unsupported device");
 	}
+
+	weston_seat_send_dirty_caps(seat);
 }
 
 #ifdef ENABLE_EGL

Comments

On Tue, May 05, 2015 at 03:01:53PM -0500, Derek Foreman wrote:
> This lets device_added() do additional processing before the update is
> sent, which will be useful later when recognizing keyboard capabilities.

Is the point of this to unset the keyboard capability for a keyboard
device or how is it supposed to work? In anyway, not a fan of this
patch. If the actual keyboard seat capability should be recognized, then
I'd rather see it being detected correctly in the beginning instead of
having an intermediate incorrect state.

Note, this patch is quite old, and I have a vague memory discussing this
before but can't remember any conclusions, so forgive me if I ask
already answered questions.


Jonas

> 
> Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
> ---
>  src/compositor-headless.c |  2 ++
>  src/compositor-rdp.c      |  1 +
>  src/compositor-wayland.c  |  2 ++
>  src/compositor-x11.c      |  2 ++
>  src/compositor.h          |  4 ++++
>  src/input.c               | 49 ++++++++++++++++++++++++++++-------------------
>  src/libinput-seat.c       |  8 ++++++++
>  src/screen-share.c        |  2 ++
>  tests/weston-test.c       |  4 ++++
>  9 files changed, 54 insertions(+), 20 deletions(-)
> 
> diff --git a/src/compositor-headless.c b/src/compositor-headless.c
> index 1b1d327..0ddb26e 100644
> --- a/src/compositor-headless.c
> +++ b/src/compositor-headless.c
> @@ -184,6 +184,8 @@ headless_input_create(struct headless_compositor *c)
>  	if (weston_seat_init_keyboard(&c->fake_seat, NULL) < 0)
>  		return -1;
>  
> +	weston_seat_send_dirty_caps(&c->fake_seat);
> +
>  	return 0;
>  }
>  
> diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
> index 6955d49..5b50382 100644
> --- a/src/compositor-rdp.c
> +++ b/src/compositor-rdp.c
> @@ -842,6 +842,7 @@ xf_peer_post_connect(freerdp_peer* client)
>  	}
>  	weston_seat_init_keyboard(&peerCtx->item.seat, keymap);
>  	weston_seat_init_pointer(&peerCtx->item.seat);
> +	weston_seat_send_dirty_caps(&peerCtx->item.seat);
>  
>  	peerCtx->item.flags |= RDP_PEER_ACTIVATED;
>  
> diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
> index 6a86250..53159c4 100644
> --- a/src/compositor-wayland.c
> +++ b/src/compositor-wayland.c
> @@ -1463,6 +1463,8 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
>  	else
>  		weston_seat_init_keyboard(&input->base, keymap);
>  
> +	weston_seat_send_dirty_caps(&input->base);
> +
>  	xkb_keymap_unref(keymap);
>  
>  	return;
> diff --git a/src/compositor-x11.c b/src/compositor-x11.c
> index 1cbdbc4..4a3b10e 100644
> --- a/src/compositor-x11.c
> +++ b/src/compositor-x11.c
> @@ -336,6 +336,8 @@ x11_input_create(struct x11_compositor *c, int no_input)
>  		return -1;
>  	xkb_keymap_unref(keymap);
>  
> +	weston_seat_send_dirty_caps(&c->core_seat);
> +
>  	x11_compositor_setup_xkb(c);
>  
>  	return 0;
> diff --git a/src/compositor.h b/src/compositor.h
> index 35c6a30..e05b262 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -449,6 +449,8 @@ weston_touch_start_drag(struct weston_touch *touch,
>  			struct weston_data_source *source,
>  			struct weston_surface *icon,
>  			struct wl_client *client);
> +void
> +weston_seat_send_dirty_caps(struct weston_seat *seat);
>  
>  struct weston_xkb_info {
>  	struct xkb_keymap *keymap;
> @@ -538,6 +540,8 @@ struct weston_seat {
>  	uint32_t slot_map;
>  	struct input_method *input_method;
>  	char *seat_name;
> +
> +	bool caps_dirty;
>  };
>  
>  enum {
> diff --git a/src/input.c b/src/input.c
> index 3f9e267..c37bd20 100644
> --- a/src/input.c
> +++ b/src/input.c
> @@ -599,23 +599,32 @@ weston_touch_destroy(struct weston_touch *touch)
>  	free(touch);
>  }
>  
> -static void
> -seat_send_updated_caps(struct weston_seat *seat)
> +/* Send seat capability updates if necessary
> + *
> + * Checks if the seat capabilities (WL_SEAT_CAPABILITY_*) have changed
> + * and propagates updates appropriately.
> + *
> + * \param seat These seat to send capabilities changes for
> + */
> +WL_EXPORT void
> +weston_seat_send_dirty_caps(struct weston_seat *seat)
>  {
>  	enum wl_seat_capability caps = 0;
>  	struct wl_resource *resource;
>  
> -	if (seat->pointer_device_count > 0)
> -		caps |= WL_SEAT_CAPABILITY_POINTER;
> -	if (seat->keyboard_device_count > 0)
> -		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
> -	if (seat->touch_device_count > 0)
> -		caps |= WL_SEAT_CAPABILITY_TOUCH;
> +	if (seat->caps_dirty) {
> +		if (seat->pointer_device_count > 0)
> +			caps |= WL_SEAT_CAPABILITY_POINTER;
> +		if (seat->keyboard_device_count > 0)
> +			caps |= WL_SEAT_CAPABILITY_KEYBOARD;
> +		if (seat->touch_device_count > 0)
> +			caps |= WL_SEAT_CAPABILITY_TOUCH;
>  
> -	wl_resource_for_each(resource, &seat->base_resource_list) {
> -		wl_seat_send_capabilities(resource, caps);
> +		wl_resource_for_each(resource, &seat->base_resource_list)
> +			wl_seat_send_capabilities(resource, caps);
> +		wl_signal_emit(&seat->updated_caps_signal, seat);
>  	}
> -	wl_signal_emit(&seat->updated_caps_signal, seat);
> +	seat->caps_dirty = false;
>  }
>  
>  WL_EXPORT void
> @@ -2136,7 +2145,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>  	if (seat->keyboard_resource) {
>  		seat->keyboard_device_count += 1;
>  		if (seat->keyboard_device_count == 1)
> -			seat_send_updated_caps(seat);
> +			seat->caps_dirty = true;
>  		return 0;
>  	}
>  
> @@ -2173,7 +2182,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>  	seat->keyboard_device_count = 1;
>  	keyboard->seat = seat;
>  
> -	seat_send_updated_caps(seat);
> +	seat->caps_dirty = true;
>  
>  	return 0;
>  
> @@ -2217,7 +2226,7 @@ weston_seat_release_keyboard(struct weston_seat *seat)
>  		weston_keyboard_set_focus(seat->keyboard_resource, NULL);
>  		weston_keyboard_cancel_grab(seat->keyboard_resource);
>  		weston_keyboard_reset_state(seat->keyboard_resource);
> -		seat_send_updated_caps(seat);
> +		seat->caps_dirty = true;
>  	}
>  }
>  
> @@ -2229,7 +2238,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>  	if (seat->pointer_resource) {
>  		seat->pointer_device_count += 1;
>  		if (seat->pointer_device_count == 1)
> -			seat_send_updated_caps(seat);
> +			seat->caps_dirty = true;
>  		return;
>  	}
>  
> @@ -2241,7 +2250,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>  	seat->pointer_device_count = 1;
>  	pointer->seat = seat;
>  
> -	seat_send_updated_caps(seat);
> +	seat->caps_dirty = true;
>  }
>  
>  WL_EXPORT void
> @@ -2261,7 +2270,7 @@ weston_seat_release_pointer(struct weston_seat *seat)
>  			pointer_unmap_sprite(pointer);
>  
>  		weston_pointer_reset_state(pointer);
> -		seat_send_updated_caps(seat);
> +		seat->caps_dirty = true;
>  
>  		/* seat->pointer is intentionally not destroyed so that
>  		 * a newly attached pointer on this seat will retain
> @@ -2278,7 +2287,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>  	if (seat->touch_resource) {
>  		seat->touch_device_count += 1;
>  		if (seat->touch_device_count == 1)
> -			seat_send_updated_caps(seat);
> +			seat->caps_dirty = true;
>  		return;
>  	}
>  
> @@ -2290,7 +2299,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>  	seat->touch_device_count = 1;
>  	touch->seat = seat;
>  
> -	seat_send_updated_caps(seat);
> +	seat->caps_dirty = true;
>  }
>  
>  WL_EXPORT void
> @@ -2302,7 +2311,7 @@ weston_seat_release_touch(struct weston_seat *seat)
>  		weston_touch_set_focus(seat->touch_resource, NULL);
>  		weston_touch_cancel_grab(seat->touch_resource);
>  		weston_touch_reset_state(seat->touch_resource);
> -		seat_send_updated_caps(seat);
> +		seat->caps_dirty = true;
>  	}
>  }
>  
> diff --git a/src/libinput-seat.c b/src/libinput-seat.c
> index 410df0e..f0fcd51 100644
> --- a/src/libinput-seat.c
> +++ b/src/libinput-seat.c
> @@ -102,14 +102,22 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
>  
>  	if (!input->suspended)
>  		weston_seat_repick(seat);
> +
> +	weston_seat_send_dirty_caps(seat);
>  }
>  
>  static void
>  device_removed(struct udev_input *input, struct libinput_device *libinput_device)
>  {
>  	struct evdev_device *device;
> +	struct udev_seat *udev_seat = get_udev_seat(input, libinput_device);
> +
> +	if (!udev_seat)
> +		return;
> +
>  	device = libinput_device_get_user_data(libinput_device);
>  	evdev_device_destroy(device);
> +	weston_seat_send_dirty_caps(&udev_seat->base);
>  }
>  
>  static void
> diff --git a/src/screen-share.c b/src/screen-share.c
> index 49b8416..597ad9b 100644
> --- a/src/screen-share.c
> +++ b/src/screen-share.c
> @@ -214,6 +214,8 @@ ss_seat_handle_keymap(void *data, struct wl_keyboard *keyboard,
>  	else
>  		weston_seat_init_keyboard(&seat->base, keymap);
>  
> +	weston_seat_send_dirty_caps(&seat->base);
> +
>  	xkb_keymap_unref(keymap);
>  
>  	return;
> diff --git a/tests/weston-test.c b/tests/weston-test.c
> index 284705a..f3b2abf 100644
> --- a/tests/weston-test.c
> +++ b/tests/weston-test.c
> @@ -212,6 +212,8 @@ device_release(struct wl_client *client,
>  	} else {
>  		assert(0 && "Unsupported device");
>  	}
> +
> +	weston_seat_send_dirty_caps(seat);
>  }
>  
>  static void
> @@ -230,6 +232,8 @@ device_add(struct wl_client *client,
>  	} else {
>  		assert(0 && "Unsupported device");
>  	}
> +
> +	weston_seat_send_dirty_caps(seat);
>  }
>  
>  #ifdef ENABLE_EGL
> -- 
> 2.1.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
On 29/09/15 09:47 PM, Jonas Ådahl wrote:
> On Tue, May 05, 2015 at 03:01:53PM -0500, Derek Foreman wrote:
>> This lets device_added() do additional processing before the update is
>> sent, which will be useful later when recognizing keyboard capabilities.
> 
> Is the point of this to unset the keyboard capability for a keyboard
> device or how is it supposed to work? In anyway, not a fan of this
> patch. If the actual keyboard seat capability should be recognized, then
> I'd rather see it being detected correctly in the beginning instead of
> having an intermediate incorrect state.
> 
> Note, this patch is quite old, and I have a vague memory discussing this
> before but can't remember any conclusions, so forgive me if I ask
> already answered questions.

Yeah, we spoke a little on list, then I dropped the ball and the release
came up.

The idea is to allow adding/removing a physical keyboard to cause a
capabilities change other than adding/removing the whole
WL_SEAT_CAPABILITIES_KEYBOARD cap.

So I let the libinput device_add/remove functions propagate the caps
(but only if they changed) instead of in the init functions (which are
only called when the first keyboard attaches or the last disconnects)

This is ground work for the follow up patch which lets the compositor
know the difference between keyboards that can type text and ones that
can't.  If you start with no "real" keyboard, you probably still get a
wl_keyboard full of acpi power buttons and assorted goodies.  If you
plug in a real keyboard, the compositor now knows that you can type.  So
I figured caps had to change on device insert/removal instead of just at
wl_keyboard creation/destruction time.

Ultimately, I want to be able to auto-hide the vkbd based on whether any
keyboard in the seat can type - since a tablet will always have a
wl_keyboard present with power buttons, etc.

Is there a better way to get there from here?

Thanks,
Derek

> 
> 
> Jonas
> 
>>
>> Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
>> ---
>>  src/compositor-headless.c |  2 ++
>>  src/compositor-rdp.c      |  1 +
>>  src/compositor-wayland.c  |  2 ++
>>  src/compositor-x11.c      |  2 ++
>>  src/compositor.h          |  4 ++++
>>  src/input.c               | 49 ++++++++++++++++++++++++++++-------------------
>>  src/libinput-seat.c       |  8 ++++++++
>>  src/screen-share.c        |  2 ++
>>  tests/weston-test.c       |  4 ++++
>>  9 files changed, 54 insertions(+), 20 deletions(-)
>>
>> diff --git a/src/compositor-headless.c b/src/compositor-headless.c
>> index 1b1d327..0ddb26e 100644
>> --- a/src/compositor-headless.c
>> +++ b/src/compositor-headless.c
>> @@ -184,6 +184,8 @@ headless_input_create(struct headless_compositor *c)
>>  	if (weston_seat_init_keyboard(&c->fake_seat, NULL) < 0)
>>  		return -1;
>>  
>> +	weston_seat_send_dirty_caps(&c->fake_seat);
>> +
>>  	return 0;
>>  }
>>  
>> diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
>> index 6955d49..5b50382 100644
>> --- a/src/compositor-rdp.c
>> +++ b/src/compositor-rdp.c
>> @@ -842,6 +842,7 @@ xf_peer_post_connect(freerdp_peer* client)
>>  	}
>>  	weston_seat_init_keyboard(&peerCtx->item.seat, keymap);
>>  	weston_seat_init_pointer(&peerCtx->item.seat);
>> +	weston_seat_send_dirty_caps(&peerCtx->item.seat);
>>  
>>  	peerCtx->item.flags |= RDP_PEER_ACTIVATED;
>>  
>> diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
>> index 6a86250..53159c4 100644
>> --- a/src/compositor-wayland.c
>> +++ b/src/compositor-wayland.c
>> @@ -1463,6 +1463,8 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
>>  	else
>>  		weston_seat_init_keyboard(&input->base, keymap);
>>  
>> +	weston_seat_send_dirty_caps(&input->base);
>> +
>>  	xkb_keymap_unref(keymap);
>>  
>>  	return;
>> diff --git a/src/compositor-x11.c b/src/compositor-x11.c
>> index 1cbdbc4..4a3b10e 100644
>> --- a/src/compositor-x11.c
>> +++ b/src/compositor-x11.c
>> @@ -336,6 +336,8 @@ x11_input_create(struct x11_compositor *c, int no_input)
>>  		return -1;
>>  	xkb_keymap_unref(keymap);
>>  
>> +	weston_seat_send_dirty_caps(&c->core_seat);
>> +
>>  	x11_compositor_setup_xkb(c);
>>  
>>  	return 0;
>> diff --git a/src/compositor.h b/src/compositor.h
>> index 35c6a30..e05b262 100644
>> --- a/src/compositor.h
>> +++ b/src/compositor.h
>> @@ -449,6 +449,8 @@ weston_touch_start_drag(struct weston_touch *touch,
>>  			struct weston_data_source *source,
>>  			struct weston_surface *icon,
>>  			struct wl_client *client);
>> +void
>> +weston_seat_send_dirty_caps(struct weston_seat *seat);
>>  
>>  struct weston_xkb_info {
>>  	struct xkb_keymap *keymap;
>> @@ -538,6 +540,8 @@ struct weston_seat {
>>  	uint32_t slot_map;
>>  	struct input_method *input_method;
>>  	char *seat_name;
>> +
>> +	bool caps_dirty;
>>  };
>>  
>>  enum {
>> diff --git a/src/input.c b/src/input.c
>> index 3f9e267..c37bd20 100644
>> --- a/src/input.c
>> +++ b/src/input.c
>> @@ -599,23 +599,32 @@ weston_touch_destroy(struct weston_touch *touch)
>>  	free(touch);
>>  }
>>  
>> -static void
>> -seat_send_updated_caps(struct weston_seat *seat)
>> +/* Send seat capability updates if necessary
>> + *
>> + * Checks if the seat capabilities (WL_SEAT_CAPABILITY_*) have changed
>> + * and propagates updates appropriately.
>> + *
>> + * \param seat These seat to send capabilities changes for
>> + */
>> +WL_EXPORT void
>> +weston_seat_send_dirty_caps(struct weston_seat *seat)
>>  {
>>  	enum wl_seat_capability caps = 0;
>>  	struct wl_resource *resource;
>>  
>> -	if (seat->pointer_device_count > 0)
>> -		caps |= WL_SEAT_CAPABILITY_POINTER;
>> -	if (seat->keyboard_device_count > 0)
>> -		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
>> -	if (seat->touch_device_count > 0)
>> -		caps |= WL_SEAT_CAPABILITY_TOUCH;
>> +	if (seat->caps_dirty) {
>> +		if (seat->pointer_device_count > 0)
>> +			caps |= WL_SEAT_CAPABILITY_POINTER;
>> +		if (seat->keyboard_device_count > 0)
>> +			caps |= WL_SEAT_CAPABILITY_KEYBOARD;
>> +		if (seat->touch_device_count > 0)
>> +			caps |= WL_SEAT_CAPABILITY_TOUCH;
>>  
>> -	wl_resource_for_each(resource, &seat->base_resource_list) {
>> -		wl_seat_send_capabilities(resource, caps);
>> +		wl_resource_for_each(resource, &seat->base_resource_list)
>> +			wl_seat_send_capabilities(resource, caps);
>> +		wl_signal_emit(&seat->updated_caps_signal, seat);
>>  	}
>> -	wl_signal_emit(&seat->updated_caps_signal, seat);
>> +	seat->caps_dirty = false;
>>  }
>>  
>>  WL_EXPORT void
>> @@ -2136,7 +2145,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>>  	if (seat->keyboard_resource) {
>>  		seat->keyboard_device_count += 1;
>>  		if (seat->keyboard_device_count == 1)
>> -			seat_send_updated_caps(seat);
>> +			seat->caps_dirty = true;
>>  		return 0;
>>  	}
>>  
>> @@ -2173,7 +2182,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>>  	seat->keyboard_device_count = 1;
>>  	keyboard->seat = seat;
>>  
>> -	seat_send_updated_caps(seat);
>> +	seat->caps_dirty = true;
>>  
>>  	return 0;
>>  
>> @@ -2217,7 +2226,7 @@ weston_seat_release_keyboard(struct weston_seat *seat)
>>  		weston_keyboard_set_focus(seat->keyboard_resource, NULL);
>>  		weston_keyboard_cancel_grab(seat->keyboard_resource);
>>  		weston_keyboard_reset_state(seat->keyboard_resource);
>> -		seat_send_updated_caps(seat);
>> +		seat->caps_dirty = true;
>>  	}
>>  }
>>  
>> @@ -2229,7 +2238,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>>  	if (seat->pointer_resource) {
>>  		seat->pointer_device_count += 1;
>>  		if (seat->pointer_device_count == 1)
>> -			seat_send_updated_caps(seat);
>> +			seat->caps_dirty = true;
>>  		return;
>>  	}
>>  
>> @@ -2241,7 +2250,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>>  	seat->pointer_device_count = 1;
>>  	pointer->seat = seat;
>>  
>> -	seat_send_updated_caps(seat);
>> +	seat->caps_dirty = true;
>>  }
>>  
>>  WL_EXPORT void
>> @@ -2261,7 +2270,7 @@ weston_seat_release_pointer(struct weston_seat *seat)
>>  			pointer_unmap_sprite(pointer);
>>  
>>  		weston_pointer_reset_state(pointer);
>> -		seat_send_updated_caps(seat);
>> +		seat->caps_dirty = true;
>>  
>>  		/* seat->pointer is intentionally not destroyed so that
>>  		 * a newly attached pointer on this seat will retain
>> @@ -2278,7 +2287,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>>  	if (seat->touch_resource) {
>>  		seat->touch_device_count += 1;
>>  		if (seat->touch_device_count == 1)
>> -			seat_send_updated_caps(seat);
>> +			seat->caps_dirty = true;
>>  		return;
>>  	}
>>  
>> @@ -2290,7 +2299,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>>  	seat->touch_device_count = 1;
>>  	touch->seat = seat;
>>  
>> -	seat_send_updated_caps(seat);
>> +	seat->caps_dirty = true;
>>  }
>>  
>>  WL_EXPORT void
>> @@ -2302,7 +2311,7 @@ weston_seat_release_touch(struct weston_seat *seat)
>>  		weston_touch_set_focus(seat->touch_resource, NULL);
>>  		weston_touch_cancel_grab(seat->touch_resource);
>>  		weston_touch_reset_state(seat->touch_resource);
>> -		seat_send_updated_caps(seat);
>> +		seat->caps_dirty = true;
>>  	}
>>  }
>>  
>> diff --git a/src/libinput-seat.c b/src/libinput-seat.c
>> index 410df0e..f0fcd51 100644
>> --- a/src/libinput-seat.c
>> +++ b/src/libinput-seat.c
>> @@ -102,14 +102,22 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
>>  
>>  	if (!input->suspended)
>>  		weston_seat_repick(seat);
>> +
>> +	weston_seat_send_dirty_caps(seat);
>>  }
>>  
>>  static void
>>  device_removed(struct udev_input *input, struct libinput_device *libinput_device)
>>  {
>>  	struct evdev_device *device;
>> +	struct udev_seat *udev_seat = get_udev_seat(input, libinput_device);
>> +
>> +	if (!udev_seat)
>> +		return;
>> +
>>  	device = libinput_device_get_user_data(libinput_device);
>>  	evdev_device_destroy(device);
>> +	weston_seat_send_dirty_caps(&udev_seat->base);
>>  }
>>  
>>  static void
>> diff --git a/src/screen-share.c b/src/screen-share.c
>> index 49b8416..597ad9b 100644
>> --- a/src/screen-share.c
>> +++ b/src/screen-share.c
>> @@ -214,6 +214,8 @@ ss_seat_handle_keymap(void *data, struct wl_keyboard *keyboard,
>>  	else
>>  		weston_seat_init_keyboard(&seat->base, keymap);
>>  
>> +	weston_seat_send_dirty_caps(&seat->base);
>> +
>>  	xkb_keymap_unref(keymap);
>>  
>>  	return;
>> diff --git a/tests/weston-test.c b/tests/weston-test.c
>> index 284705a..f3b2abf 100644
>> --- a/tests/weston-test.c
>> +++ b/tests/weston-test.c
>> @@ -212,6 +212,8 @@ device_release(struct wl_client *client,
>>  	} else {
>>  		assert(0 && "Unsupported device");
>>  	}
>> +
>> +	weston_seat_send_dirty_caps(seat);
>>  }
>>  
>>  static void
>> @@ -230,6 +232,8 @@ device_add(struct wl_client *client,
>>  	} else {
>>  		assert(0 && "Unsupported device");
>>  	}
>> +
>> +	weston_seat_send_dirty_caps(seat);
>>  }
>>  
>>  #ifdef ENABLE_EGL
>> -- 
>> 2.1.4
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel