mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Set focus_inactive on a sibling when a container closes in an inactive workspace
To reproduce the problem, create layout H[view V[view view view-focused]], then switch to another workspace and have the previously focused view in the vsplit close (eg. using criteria, or an mpv video finishing). Return to the workspace using `$mod+<num>` and the entire vsplit would be focused. This happens because handle_seat_node_destroy would only set a new focus if the currently focused view or a parent was being destroyed. To fix it, it needs to set a sibling of the destroying container to focus_inactive regardless of the current focus, then restore current focus if needed. This patch changes the function accordingly. Additionally: * The function now makes an early return if the node being destroyed is a workspace. * set_focus has been renamed to needs_new_focus. This variable is true if the head focus needs to be changed.
This commit is contained in:
		
							parent
							
								
									183a4b0d6b
								
							
						
					
					
						commit
						677e112733
					
				
					 1 changed files with 28 additions and 17 deletions
				
			
		| 
						 | 
					@ -144,14 +144,20 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_node *parent = node_get_parent(node);
 | 
						struct sway_node *parent = node_get_parent(node);
 | 
				
			||||||
	struct sway_node *focus = seat_get_focus(seat);
 | 
						struct sway_node *focus = seat_get_focus(seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool set_focus =
 | 
						if (node->type == N_WORKSPACE) {
 | 
				
			||||||
		focus != NULL &&
 | 
							seat_node_destroy(seat_node);
 | 
				
			||||||
		(focus == node || node_has_ancestor(focus, node)) &&
 | 
							return;
 | 
				
			||||||
		node->type == N_CONTAINER;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Even though the container being destroyed might be nowhere near the
 | 
				
			||||||
 | 
						// focused container, we still need to set focus_inactive on a sibling of
 | 
				
			||||||
 | 
						// the container being destroyed.
 | 
				
			||||||
 | 
						bool needs_new_focus = focus &&
 | 
				
			||||||
 | 
							(focus == node || node_has_ancestor(focus, node));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seat_node_destroy(seat_node);
 | 
						seat_node_destroy(seat_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (set_focus) {
 | 
						// Find new focus_inactive (ie. sibling, or workspace if no siblings left)
 | 
				
			||||||
	struct sway_node *next_focus = NULL;
 | 
						struct sway_node *next_focus = NULL;
 | 
				
			||||||
	while (next_focus == NULL) {
 | 
						while (next_focus == NULL) {
 | 
				
			||||||
		struct sway_container *con =
 | 
							struct sway_container *con =
 | 
				
			||||||
| 
						 | 
					@ -166,10 +172,15 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
		parent = node_get_parent(parent);
 | 
							parent = node_get_parent(parent);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// the structure change might have caused it to move up to the top of
 | 
						if (needs_new_focus) {
 | 
				
			||||||
 | 
							// The structure change might have caused it to move up to the top of
 | 
				
			||||||
		// the focus stack without sending focus notifications to the view
 | 
							// the focus stack without sending focus notifications to the view
 | 
				
			||||||
		seat_send_focus(next_focus, seat);
 | 
							seat_send_focus(next_focus, seat);
 | 
				
			||||||
		seat_set_focus(seat, next_focus);
 | 
							seat_set_focus(seat, next_focus);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// Setting focus_inactive
 | 
				
			||||||
 | 
							seat_set_focus_warp(seat, next_focus, false, false);
 | 
				
			||||||
 | 
							seat_set_focus_warp(seat, focus, false, false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue