mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	seat: Create inert objects for missing capabilities
We should throw a protocol error if the relevant capability has never existed when get_(pointer|keyboard|touch) is called. Otherwise, it should succeed, even if the capability is not currently present. This follows the spec, and avoids possible races with the client when capabilities are lost. Closes: https://github.com/swaywm/wlroots/issues/2227
This commit is contained in:
		
							parent
							
								
									d66b9966e9
								
							
						
					
					
						commit
						5e0ef70cc0
					
				
					 5 changed files with 25 additions and 9 deletions
				
			
		| 
						 | 
					@ -214,6 +214,7 @@ struct wlr_seat {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
	uint32_t capabilities;
 | 
						uint32_t capabilities;
 | 
				
			||||||
 | 
						uint32_t accumulated_capabilities;
 | 
				
			||||||
	struct timespec last_event;
 | 
						struct timespec last_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_data_source *selection_source;
 | 
						struct wlr_data_source *selection_source;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,9 +19,9 @@ static void seat_handle_get_pointer(struct wl_client *client,
 | 
				
			||||||
		struct wl_resource *seat_resource, uint32_t id) {
 | 
							struct wl_resource *seat_resource, uint32_t id) {
 | 
				
			||||||
	struct wlr_seat_client *seat_client =
 | 
						struct wlr_seat_client *seat_client =
 | 
				
			||||||
		wlr_seat_client_from_resource(seat_resource);
 | 
							wlr_seat_client_from_resource(seat_resource);
 | 
				
			||||||
	if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) {
 | 
						if (!(seat_client->seat->accumulated_capabilities & WL_SEAT_CAPABILITY_POINTER)) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Client sent get_pointer on seat without the "
 | 
							wl_resource_post_error(seat_resource, 0,
 | 
				
			||||||
			"pointer capability");
 | 
									"wl_seat.get_pointer called when no pointer capability has existed");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,9 +33,9 @@ static void seat_handle_get_keyboard(struct wl_client *client,
 | 
				
			||||||
		struct wl_resource *seat_resource, uint32_t id) {
 | 
							struct wl_resource *seat_resource, uint32_t id) {
 | 
				
			||||||
	struct wlr_seat_client *seat_client =
 | 
						struct wlr_seat_client *seat_client =
 | 
				
			||||||
		wlr_seat_client_from_resource(seat_resource);
 | 
							wlr_seat_client_from_resource(seat_resource);
 | 
				
			||||||
	if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
 | 
						if (!(seat_client->seat->accumulated_capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Client sent get_keyboard on seat without the "
 | 
							wl_resource_post_error(seat_resource, 0,
 | 
				
			||||||
			"keyboard capability");
 | 
									"wl_seat.get_keyboard called when no keyboard capability has existed");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,9 +47,9 @@ static void seat_handle_get_touch(struct wl_client *client,
 | 
				
			||||||
		struct wl_resource *seat_resource, uint32_t id) {
 | 
							struct wl_resource *seat_resource, uint32_t id) {
 | 
				
			||||||
	struct wlr_seat_client *seat_client =
 | 
						struct wlr_seat_client *seat_client =
 | 
				
			||||||
		wlr_seat_client_from_resource(seat_resource);
 | 
							wlr_seat_client_from_resource(seat_resource);
 | 
				
			||||||
	if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH)) {
 | 
						if (!(seat_client->seat->accumulated_capabilities & WL_SEAT_CAPABILITY_TOUCH)) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Client sent get_touch on seat without the "
 | 
							wl_resource_post_error(seat_resource, 0,
 | 
				
			||||||
			"touch capability");
 | 
									"wl_seat.get_touch called when no touch capability has existed");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,6 +311,7 @@ struct wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat,
 | 
				
			||||||
void wlr_seat_set_capabilities(struct wlr_seat *wlr_seat,
 | 
					void wlr_seat_set_capabilities(struct wlr_seat *wlr_seat,
 | 
				
			||||||
		uint32_t capabilities) {
 | 
							uint32_t capabilities) {
 | 
				
			||||||
	wlr_seat->capabilities = capabilities;
 | 
						wlr_seat->capabilities = capabilities;
 | 
				
			||||||
 | 
						wlr_seat->accumulated_capabilities |= capabilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_seat_client *client;
 | 
						struct wlr_seat_client *client;
 | 
				
			||||||
	wl_list_for_each(client, &wlr_seat->clients, link) {
 | 
						wl_list_for_each(client, &wlr_seat->clients, link) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -410,6 +410,11 @@ void seat_client_create_keyboard(struct wlr_seat_client *seat_client,
 | 
				
			||||||
		keyboard_handle_resource_destroy);
 | 
							keyboard_handle_resource_destroy);
 | 
				
			||||||
	wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource));
 | 
						wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD) == 0) {
 | 
				
			||||||
 | 
							wl_resource_set_user_data(resource, NULL);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_keyboard *keyboard = seat_client->seat->keyboard_state.keyboard;
 | 
						struct wlr_keyboard *keyboard = seat_client->seat->keyboard_state.keyboard;
 | 
				
			||||||
	if (keyboard == NULL) {
 | 
						if (keyboard == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -410,6 +410,11 @@ void seat_client_create_pointer(struct wlr_seat_client *seat_client,
 | 
				
			||||||
		&pointer_handle_resource_destroy);
 | 
							&pointer_handle_resource_destroy);
 | 
				
			||||||
	wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource));
 | 
						wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) {
 | 
				
			||||||
 | 
							wl_resource_set_user_data(resource, NULL);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_seat_client *focused_client =
 | 
						struct wlr_seat_client *focused_client =
 | 
				
			||||||
		seat_client->seat->pointer_state.focused_client;
 | 
							seat_client->seat->pointer_state.focused_client;
 | 
				
			||||||
	struct wlr_surface *focused_surface =
 | 
						struct wlr_surface *focused_surface =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -366,6 +366,10 @@ void seat_client_create_touch(struct wlr_seat_client *seat_client,
 | 
				
			||||||
	wl_resource_set_implementation(resource, &touch_impl, seat_client,
 | 
						wl_resource_set_implementation(resource, &touch_impl, seat_client,
 | 
				
			||||||
		&touch_handle_resource_destroy);
 | 
							&touch_handle_resource_destroy);
 | 
				
			||||||
	wl_list_insert(&seat_client->touches, wl_resource_get_link(resource));
 | 
						wl_list_insert(&seat_client->touches, wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH) == 0) {
 | 
				
			||||||
 | 
							wl_resource_set_user_data(resource, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void seat_client_destroy_touch(struct wl_resource *resource) {
 | 
					void seat_client_destroy_touch(struct wl_resource *resource) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue