mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	keyboard: broadcast modifiers
...to all clients rather than just the one with keyboard focus on keyboard enter/create, modifer press/release and wlr_seat_set_keyboard(). This enables: - Clients such as panels to display the current keyboard layout without introducing new wayland protocols or other IPC. - Unfocused xdg-shell clients to understand button press with keyboard modifiers for example Ctrl+click. The keymap is forwarded to all clients in wlr_seat_set_keyboard(). When a keymap contains multiple layouts, the selection is made via modifiers, which previously were only sent to the client with keyboard focus. Tested with: https://github.com/johanmalm/keyboard-layout Ref: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4496 Fixes: #2271
This commit is contained in:
		
							parent
							
								
									ad2d24fb42
								
							
						
					
					
						commit
						3b00aabd93
					
				
					 1 changed files with 60 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -80,6 +80,43 @@ end_cycling(struct server *server)
 | 
			
		|||
	should_cancel_cycling_on_next_key_release = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wlr_seat_client *
 | 
			
		||||
seat_client_from_keyboard_resource(struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	return wl_resource_get_user_data(resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
broadcast_modifiers_to_unfocused_clients(struct wlr_seat *seat,
 | 
			
		||||
		const struct wlr_keyboard_modifiers *modifiers)
 | 
			
		||||
{
 | 
			
		||||
	struct wlr_seat_client *client;
 | 
			
		||||
	wl_list_for_each(client, &seat->clients, link) {
 | 
			
		||||
		if (client == seat->keyboard_state.focused_client) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * We've already notified the focused client by calling
 | 
			
		||||
			 * wlr_seat_keyboard_notify_modifiers()
 | 
			
		||||
			 */
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		uint32_t serial = wlr_seat_client_next_serial(client);
 | 
			
		||||
		struct wl_resource *resource;
 | 
			
		||||
		wl_resource_for_each(resource, &client->keyboards) {
 | 
			
		||||
			if (!seat_client_from_keyboard_resource(resource)) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (!modifiers) {
 | 
			
		||||
				wl_keyboard_send_modifiers(resource, serial, 0,
 | 
			
		||||
					0, 0, 0);
 | 
			
		||||
			} else {
 | 
			
		||||
				wl_keyboard_send_modifiers(resource, serial,
 | 
			
		||||
					modifiers->depressed, modifiers->latched,
 | 
			
		||||
					modifiers->locked, modifiers->group);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
keyboard_modifiers_notify(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -112,8 +149,31 @@ keyboard_modifiers_notify(struct wl_listener *listener, void *data)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (!input_method_keyboard_grab_forward_modifiers(keyboard)) {
 | 
			
		||||
		/* Send modifiers to focused client */
 | 
			
		||||
		wlr_seat_keyboard_notify_modifiers(seat->seat,
 | 
			
		||||
			&wlr_keyboard->modifiers);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Also broadcast them to non-keyboard-focused clients.
 | 
			
		||||
		 *
 | 
			
		||||
		 * The Wayland protocol does not specify that modifiers are
 | 
			
		||||
		 * broadcast, so this is not something clients can rely on in
 | 
			
		||||
		 * other compositors.
 | 
			
		||||
		 *
 | 
			
		||||
		 * Sway used to broadcast modifiers but stopped doing so to
 | 
			
		||||
		 * avoid waking up all clients when the modifiers change.
 | 
			
		||||
		 *
 | 
			
		||||
		 * By testing with foot and Ctrl+scroll to change font size, it
 | 
			
		||||
		 * appears that Mutter does not pass modifiers to unfocused
 | 
			
		||||
		 * clients, whereas KWin and Weston pass modifiers to clients
 | 
			
		||||
		 * with pointer-focus.
 | 
			
		||||
		 *
 | 
			
		||||
		 * This could be made configurable if there are unintended
 | 
			
		||||
		 * consequences. If so, modifiers ought to still be passed to
 | 
			
		||||
		 * clients with pointer-focus (see issue #2271)
 | 
			
		||||
		 */
 | 
			
		||||
		broadcast_modifiers_to_unfocused_clients(seat->seat,
 | 
			
		||||
			&wlr_keyboard->modifiers);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue