xdg-surface: add pending state
struct wlr_xdg_surface_state is introduced to hold the geometry and configure serial to be applied on next wl_surface.commit. This commit fixes our handling for ack_configure: instead of making the request mutate our current state, it mutates the pending state only. Co-authored-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
		
							parent
							
								
									3d0848daae
								
							
						
					
					
						commit
						db4afc2408
					
				|  | @ -161,6 +161,11 @@ struct wlr_xdg_surface_configure { | |||
| 	struct wlr_xdg_toplevel_configure *toplevel_configure; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_xdg_surface_state { | ||||
| 	uint32_t configure_serial; | ||||
| 	struct wlr_box geometry; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * An xdg-surface is a user interface element requiring management by the | ||||
|  * compositor. An xdg-surface alone isn't useful, a role should be assigned to | ||||
|  | @ -191,10 +196,10 @@ struct wlr_xdg_surface { | |||
| 	uint32_t configure_next_serial; | ||||
| 	struct wl_list configure_list; | ||||
| 
 | ||||
| 	bool has_next_geometry; | ||||
| 	struct wlr_box next_geometry; | ||||
| 	struct wlr_box geometry; | ||||
| 
 | ||||
| 	struct wlr_xdg_surface_state pending; | ||||
| 
 | ||||
| 	struct wl_listener surface_destroy; | ||||
| 	struct wl_listener surface_commit; | ||||
| 
 | ||||
|  |  | |||
|  | @ -88,12 +88,10 @@ void unmap_xdg_surface(struct wlr_xdg_surface *surface) { | |||
| 	} | ||||
| 	surface->configure_next_serial = 0; | ||||
| 
 | ||||
| 	surface->has_next_geometry = false; | ||||
| 	memset(&surface->geometry, 0, sizeof(struct wlr_box)); | ||||
| 	memset(&surface->next_geometry, 0, sizeof(struct wlr_box)); | ||||
| 	memset(&surface->pending, 0, sizeof(struct wlr_xdg_surface_state)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void xdg_surface_handle_ack_configure(struct wl_client *client, | ||||
| 		struct wl_resource *resource, uint32_t serial) { | ||||
| 	struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource); | ||||
|  | @ -144,7 +142,7 @@ static void xdg_surface_handle_ack_configure(struct wl_client *client, | |||
| 	} | ||||
| 
 | ||||
| 	surface->configured = true; | ||||
| 	surface->configure_serial = serial; | ||||
| 	surface->pending.configure_serial = serial; | ||||
| 
 | ||||
| 	wlr_signal_emit_safe(&surface->events.ack_configure, configure); | ||||
| 	xdg_surface_configure_destroy(configure); | ||||
|  | @ -252,11 +250,10 @@ static void xdg_surface_handle_set_window_geometry(struct wl_client *client, | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	surface->has_next_geometry = true; | ||||
| 	surface->next_geometry.height = height; | ||||
| 	surface->next_geometry.width = width; | ||||
| 	surface->next_geometry.x = x; | ||||
| 	surface->next_geometry.y = y; | ||||
| 	surface->pending.geometry.x = x; | ||||
| 	surface->pending.geometry.y = y; | ||||
| 	surface->pending.geometry.width = width; | ||||
| 	surface->pending.geometry.height = height; | ||||
| } | ||||
| 
 | ||||
| static void xdg_surface_handle_destroy(struct wl_client *client, | ||||
|  | @ -313,6 +310,14 @@ static void xdg_surface_handle_surface_commit(struct wl_listener *listener, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void surface_commit_state(struct wlr_xdg_surface *surface, | ||||
| 		struct wlr_xdg_surface_state *state) { | ||||
| 	surface->configure_serial = state->configure_serial; | ||||
| 	if (!wlr_box_empty(&state->geometry)) { | ||||
| 		surface->geometry = state->geometry; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void handle_xdg_surface_commit(struct wlr_surface *wlr_surface) { | ||||
| 	struct wlr_xdg_surface *surface = | ||||
| 		wlr_xdg_surface_from_wlr_surface(wlr_surface); | ||||
|  | @ -320,13 +325,7 @@ void handle_xdg_surface_commit(struct wlr_surface *wlr_surface) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (surface->has_next_geometry) { | ||||
| 		surface->has_next_geometry = false; | ||||
| 		surface->geometry.x = surface->next_geometry.x; | ||||
| 		surface->geometry.y = surface->next_geometry.y; | ||||
| 		surface->geometry.width = surface->next_geometry.width; | ||||
| 		surface->geometry.height = surface->next_geometry.height; | ||||
| 	} | ||||
| 	surface_commit_state(surface, &surface->pending); | ||||
| 
 | ||||
| 	switch (surface->role) { | ||||
| 	case WLR_XDG_SURFACE_ROLE_NONE: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue