mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	xwayland: pass focus to previous unmanaged surface on unmap
This is necessary because some applications (e.g. Jetbrains IDEs) represent their multi-level menus as unmanaged surfaces, and when closing a submenu, the main menu should get input focus. Closes #5347.
This commit is contained in:
		
							parent
							
								
									83866558d3
								
							
						
					
					
						commit
						613abdda6f
					
				
					 1 changed files with 16 additions and 0 deletions
				
			
		| 
						 | 
					@ -94,6 +94,22 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_seat *seat = input_manager_current_seat();
 | 
						struct sway_seat *seat = input_manager_current_seat();
 | 
				
			||||||
	if (seat->wlr_seat->keyboard_state.focused_surface ==
 | 
						if (seat->wlr_seat->keyboard_state.focused_surface ==
 | 
				
			||||||
			xsurface->surface) {
 | 
								xsurface->surface) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Try to find another unmanaged surface from the same process to pass
 | 
				
			||||||
 | 
							// focus to. This is necessary because some applications (e.g. Jetbrains
 | 
				
			||||||
 | 
							// IDEs) represent their multi-level menus as unmanaged surfaces, and
 | 
				
			||||||
 | 
							// when closing a submenu, the main menu should get input focus.
 | 
				
			||||||
 | 
							struct sway_xwayland_unmanaged *current;
 | 
				
			||||||
 | 
							wl_list_for_each(current, &root->xwayland_unmanaged, link) {
 | 
				
			||||||
 | 
								struct wlr_xwayland_surface *prev_xsurface =
 | 
				
			||||||
 | 
									current->wlr_xwayland_surface;
 | 
				
			||||||
 | 
								if (prev_xsurface->pid == xsurface->pid &&
 | 
				
			||||||
 | 
										wlr_xwayland_or_surface_wants_focus(prev_xsurface)) {
 | 
				
			||||||
 | 
									seat_set_focus_surface(seat, prev_xsurface->surface, false);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Restore focus
 | 
							// Restore focus
 | 
				
			||||||
		struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
 | 
							struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
 | 
				
			||||||
		if (previous) {
 | 
							if (previous) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue