mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Fix crash when closing last child of a tabbed container
The crash only occurs if the mouse cursor is above the tabbed container
when the last child is closed.
Introduced in 03d49490cc, over a week ago
and unnoticed until now :O
The above commit changes the behaviour of a focus change. When you
change focus, it sends pointer motion which makes the client set a new
cursor image. We already had this behaviour for workspace switching, but
this commit adds it for view switching too, such as in a tabbed
container or when closing a view.
The sequence of events that leads to the crash is:
* The last child of a tabbed container unmaps, which triggers a
`destroy` event before we've cleaned up the child or reaped the tabbed
container.
* The seat code listens to the `destroy` event and removes the seat
container from the focus stack. As part of this, it decides to set focus
to the parent (my fix alters this decision).
* When setting focus to the new parent, the container motion is sent as
per the previously mentioned commit.
* The motion code uses `container_at`, which encounters the tabbed
container and its child in a half destroyed state, and everything blows
up from there.
`con->parent` is needed because scratchpad containers don't have parents
if they're hidden, so this probably fixes a crash when a hidden
scratchpad container closes too.
The `con->parent->children->length > 1` check should catch any cases
where the parent is about to be reaped.
			
			
This commit is contained in:
		
							parent
							
								
									cdc4ad2b4f
								
							
						
					
					
						commit
						b14bd1b0b1
					
				
					 1 changed files with 1 additions and 0 deletions
				
			
		| 
						 | 
					@ -181,6 +181,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
 | 
				
			||||||
	bool set_focus =
 | 
						bool set_focus =
 | 
				
			||||||
		focus != NULL &&
 | 
							focus != NULL &&
 | 
				
			||||||
		(focus == con || container_has_child(con, focus)) &&
 | 
							(focus == con || container_has_child(con, focus)) &&
 | 
				
			||||||
 | 
							con->parent && con->parent->children->length > 1 &&
 | 
				
			||||||
		con->type != C_WORKSPACE;
 | 
							con->type != C_WORKSPACE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seat_container_destroy(seat_con);
 | 
						seat_container_destroy(seat_con);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue