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;
 | 
						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
 | 
					static void
 | 
				
			||||||
keyboard_modifiers_notify(struct wl_listener *listener, void *data)
 | 
					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)) {
 | 
						if (!input_method_keyboard_grab_forward_modifiers(keyboard)) {
 | 
				
			||||||
 | 
							/* Send modifiers to focused client */
 | 
				
			||||||
		wlr_seat_keyboard_notify_modifiers(seat->seat,
 | 
							wlr_seat_keyboard_notify_modifiers(seat->seat,
 | 
				
			||||||
			&wlr_keyboard->modifiers);
 | 
								&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