mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Handle commit signal
wlr_surface can change during xwayland map/unmap, so let's only update view width and height after commit signal has been received.
This commit is contained in:
		
							parent
							
								
									9d408aad73
								
							
						
					
					
						commit
						127eddfd96
					
				
					 4 changed files with 57 additions and 25 deletions
				
			
		| 
						 | 
					@ -111,17 +111,19 @@ struct view {
 | 
				
			||||||
	struct wlr_xdg_surface *xdg_surface;
 | 
						struct wlr_xdg_surface *xdg_surface;
 | 
				
			||||||
	struct wlr_xwayland_surface *xwayland_surface;
 | 
						struct wlr_xwayland_surface *xwayland_surface;
 | 
				
			||||||
	struct wlr_surface *surface;
 | 
						struct wlr_surface *surface;
 | 
				
			||||||
	struct wl_listener map;
 | 
					 | 
				
			||||||
	struct wl_listener unmap;
 | 
					 | 
				
			||||||
	struct wl_listener destroy;
 | 
					 | 
				
			||||||
	struct wl_listener request_move;
 | 
					 | 
				
			||||||
	struct wl_listener request_resize;
 | 
					 | 
				
			||||||
	struct wl_listener request_configure;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool mapped;
 | 
						bool mapped;
 | 
				
			||||||
	bool been_mapped;
 | 
						bool been_mapped;
 | 
				
			||||||
	int x, y;
 | 
						int x, y, w, h;
 | 
				
			||||||
	bool show_server_side_deco;
 | 
						bool show_server_side_deco;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener map;
 | 
				
			||||||
 | 
						struct wl_listener unmap;
 | 
				
			||||||
 | 
						struct wl_listener destroy;
 | 
				
			||||||
 | 
						struct wl_listener commit;
 | 
				
			||||||
 | 
						struct wl_listener request_move;
 | 
				
			||||||
 | 
						struct wl_listener request_resize;
 | 
				
			||||||
 | 
						struct wl_listener request_configure;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct keyboard {
 | 
					struct keyboard {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/deco.c
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/deco.c
									
										
									
									
									
								
							| 
						 | 
					@ -17,9 +17,8 @@ struct wlr_box deco_max_extents(struct view *view)
 | 
				
			||||||
	struct wlr_box box = {
 | 
						struct wlr_box box = {
 | 
				
			||||||
		.x = view->x - BORDER_WIDTH,
 | 
							.x = view->x - BORDER_WIDTH,
 | 
				
			||||||
		.y = view->y - rc.title_height - BORDER_WIDTH,
 | 
							.y = view->y - rc.title_height - BORDER_WIDTH,
 | 
				
			||||||
		.width = view->surface->current.width + 2 * BORDER_WIDTH,
 | 
							.width = view->w + 2 * BORDER_WIDTH,
 | 
				
			||||||
		.height = view->surface->current.height + rc.title_height +
 | 
							.height = view->h + rc.title_height + 2 * BORDER_WIDTH,
 | 
				
			||||||
			  2 * BORDER_WIDTH,
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	return box;
 | 
						return box;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -35,8 +34,7 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
 | 
				
			||||||
		return box;
 | 
							return box;
 | 
				
			||||||
	BUG_ON(!view->been_mapped);
 | 
						BUG_ON(!view->been_mapped);
 | 
				
			||||||
	BUG_ON(!view->show_server_side_deco);
 | 
						BUG_ON(!view->show_server_side_deco);
 | 
				
			||||||
	if ((view->surface->current.width < 1) ||
 | 
						if ((view->w < 1) || (view->h < 1)) {
 | 
				
			||||||
	    (view->surface->current.height < 1)) {
 | 
					 | 
				
			||||||
		warn("view (%p) has no width/height", view);
 | 
							warn("view (%p) has no width/height", view);
 | 
				
			||||||
		return box;
 | 
							return box;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -45,55 +43,52 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
 | 
				
			||||||
		wlr_texture_get_size(theme.xbm_close_active_unpressed,
 | 
							wlr_texture_get_size(theme.xbm_close_active_unpressed,
 | 
				
			||||||
				     &box.width, &box.height);
 | 
									     &box.width, &box.height);
 | 
				
			||||||
		margin = (rc.title_height - box.height) / 2;
 | 
							margin = (rc.title_height - box.height) / 2;
 | 
				
			||||||
		box.x = view->x + view->surface->current.width + margin -
 | 
							box.x = view->x + view->w + margin - rc.title_height;
 | 
				
			||||||
			rc.title_height;
 | 
					 | 
				
			||||||
		box.y = view->y - rc.title_height + margin;
 | 
							box.y = view->y - rc.title_height + margin;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_BUTTON_MAXIMIZE:
 | 
						case LAB_DECO_BUTTON_MAXIMIZE:
 | 
				
			||||||
		wlr_texture_get_size(theme.xbm_maximize_active_unpressed,
 | 
							wlr_texture_get_size(theme.xbm_maximize_active_unpressed,
 | 
				
			||||||
				     &box.width, &box.height);
 | 
									     &box.width, &box.height);
 | 
				
			||||||
		margin = (rc.title_height - box.height) / 2;
 | 
							margin = (rc.title_height - box.height) / 2;
 | 
				
			||||||
		box.x = view->x + view->surface->current.width + margin -
 | 
							box.x = view->x + view->w + margin - rc.title_height * 2;
 | 
				
			||||||
			rc.title_height * 2;
 | 
					 | 
				
			||||||
		box.y = view->y - rc.title_height + margin;
 | 
							box.y = view->y - rc.title_height + margin;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_BUTTON_ICONIFY:
 | 
						case LAB_DECO_BUTTON_ICONIFY:
 | 
				
			||||||
		wlr_texture_get_size(theme.xbm_iconify_active_unpressed,
 | 
							wlr_texture_get_size(theme.xbm_iconify_active_unpressed,
 | 
				
			||||||
				     &box.width, &box.height);
 | 
									     &box.width, &box.height);
 | 
				
			||||||
		margin = (rc.title_height - box.height) / 2;
 | 
							margin = (rc.title_height - box.height) / 2;
 | 
				
			||||||
		box.x = view->x + view->surface->current.width + margin -
 | 
							box.x = view->x + view->w + margin - rc.title_height * 3;
 | 
				
			||||||
			rc.title_height * 3;
 | 
					 | 
				
			||||||
		box.y = view->y - rc.title_height + margin;
 | 
							box.y = view->y - rc.title_height + margin;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_PART_TITLE:
 | 
						case LAB_DECO_PART_TITLE:
 | 
				
			||||||
		box.x = view->x;
 | 
							box.x = view->x;
 | 
				
			||||||
		box.y = view->y - rc.title_height;
 | 
							box.y = view->y - rc.title_height;
 | 
				
			||||||
		box.width = view->surface->current.width;
 | 
							box.width = view->w;
 | 
				
			||||||
		box.height = rc.title_height;
 | 
							box.height = rc.title_height;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_PART_TOP:
 | 
						case LAB_DECO_PART_TOP:
 | 
				
			||||||
		box.x = view->x - BORDER_WIDTH;
 | 
							box.x = view->x - BORDER_WIDTH;
 | 
				
			||||||
		box.y = view->y - rc.title_height - BORDER_WIDTH;
 | 
							box.y = view->y - rc.title_height - BORDER_WIDTH;
 | 
				
			||||||
		box.width = view->surface->current.width + 2 * BORDER_WIDTH;
 | 
							box.width = view->w + 2 * BORDER_WIDTH;
 | 
				
			||||||
		box.height = BORDER_WIDTH;
 | 
							box.height = BORDER_WIDTH;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_PART_RIGHT:
 | 
						case LAB_DECO_PART_RIGHT:
 | 
				
			||||||
		box.x = view->x + view->surface->current.width;
 | 
							box.x = view->x + view->w;
 | 
				
			||||||
		box.y = view->y - rc.title_height;
 | 
							box.y = view->y - rc.title_height;
 | 
				
			||||||
		box.width = BORDER_WIDTH;
 | 
							box.width = BORDER_WIDTH;
 | 
				
			||||||
		box.height = view->surface->current.height + rc.title_height;
 | 
							box.height = view->h + rc.title_height;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_PART_BOTTOM:
 | 
						case LAB_DECO_PART_BOTTOM:
 | 
				
			||||||
		box.x = view->x - BORDER_WIDTH;
 | 
							box.x = view->x - BORDER_WIDTH;
 | 
				
			||||||
		box.y = view->y + view->surface->current.height;
 | 
							box.y = view->y + view->h;
 | 
				
			||||||
		box.width = view->surface->current.width + 2 * BORDER_WIDTH;
 | 
							box.width = view->w + 2 * BORDER_WIDTH;
 | 
				
			||||||
		box.height = +BORDER_WIDTH;
 | 
							box.height = +BORDER_WIDTH;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LAB_DECO_PART_LEFT:
 | 
						case LAB_DECO_PART_LEFT:
 | 
				
			||||||
		box.x = view->x - BORDER_WIDTH;
 | 
							box.x = view->x - BORDER_WIDTH;
 | 
				
			||||||
		box.y = view->y - rc.title_height;
 | 
							box.y = view->y - rc.title_height;
 | 
				
			||||||
		box.width = BORDER_WIDTH;
 | 
							box.width = BORDER_WIDTH;
 | 
				
			||||||
		box.height = view->surface->current.height + rc.title_height;
 | 
							box.height = view->h + rc.title_height;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/xdg.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/xdg.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,4 +1,6 @@
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
 | 
					#include "common/log.h"
 | 
				
			||||||
 | 
					#include "common/bug-on.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct xdg_deco {
 | 
					struct xdg_deco {
 | 
				
			||||||
	struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
 | 
						struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
 | 
				
			||||||
| 
						 | 
					@ -63,6 +65,14 @@ static bool has_ssd(struct view *view)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_commit(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct view *view = wl_container_of(listener, view, commit);
 | 
				
			||||||
 | 
						BUG_ON(!view->surface);
 | 
				
			||||||
 | 
						view->w = view->surface->current.width;
 | 
				
			||||||
 | 
						view->h = view->surface->current.height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void xdg_surface_map(struct wl_listener *listener, void *data)
 | 
					void xdg_surface_map(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct view *view = wl_container_of(listener, view, map);
 | 
						struct view *view = wl_container_of(listener, view, map);
 | 
				
			||||||
| 
						 | 
					@ -73,6 +83,9 @@ void xdg_surface_map(struct wl_listener *listener, void *data)
 | 
				
			||||||
		view_init_position(view);
 | 
							view_init_position(view);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	view->been_mapped = true;
 | 
						view->been_mapped = true;
 | 
				
			||||||
 | 
						wl_signal_add(&view->xdg_surface->surface->events.commit,
 | 
				
			||||||
 | 
							      &view->commit);
 | 
				
			||||||
 | 
						view->commit.notify = handle_commit;
 | 
				
			||||||
	view_focus(view);
 | 
						view_focus(view);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,6 +93,7 @@ void xdg_surface_unmap(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct view *view = wl_container_of(listener, view, unmap);
 | 
						struct view *view = wl_container_of(listener, view, unmap);
 | 
				
			||||||
	view->mapped = false;
 | 
						view->mapped = false;
 | 
				
			||||||
 | 
						wl_list_remove(&view->commit.link);
 | 
				
			||||||
	view_focus(next_toplevel(view));
 | 
						view_focus(next_toplevel(view));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								src/xwl.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								src/xwl.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
#include "common/log.h"
 | 
					#include "common/log.h"
 | 
				
			||||||
 | 
					#include "common/bug-on.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool has_ssd(struct view *view)
 | 
					static bool has_ssd(struct view *view)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -11,6 +12,16 @@ static bool has_ssd(struct view *view)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_commit(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct view *view = wl_container_of(listener, view, commit);
 | 
				
			||||||
 | 
						BUG_ON(!view->surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Must receive commit signal before accessing surface->current* */
 | 
				
			||||||
 | 
						view->w = view->surface->current.width;
 | 
				
			||||||
 | 
						view->h = view->surface->current.height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void xwl_surface_map(struct wl_listener *listener, void *data)
 | 
					void xwl_surface_map(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct view *view = wl_container_of(listener, view, map);
 | 
						struct view *view = wl_container_of(listener, view, map);
 | 
				
			||||||
| 
						 | 
					@ -23,6 +34,15 @@ void xwl_surface_map(struct wl_listener *listener, void *data)
 | 
				
			||||||
		view_init_position(view);
 | 
							view_init_position(view);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	view->been_mapped = true;
 | 
						view->been_mapped = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Add commit listener here, because xwayland map/unmap can change
 | 
				
			||||||
 | 
						 * the wlr_surface
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						wl_signal_add(&view->xwayland_surface->surface->events.commit,
 | 
				
			||||||
 | 
							      &view->commit);
 | 
				
			||||||
 | 
						view->commit.notify = handle_commit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view_focus(view);
 | 
						view_focus(view);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +50,7 @@ void xwl_surface_unmap(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct view *view = wl_container_of(listener, view, unmap);
 | 
						struct view *view = wl_container_of(listener, view, unmap);
 | 
				
			||||||
	view->mapped = false;
 | 
						view->mapped = false;
 | 
				
			||||||
 | 
						wl_list_remove(&view->commit.link);
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Note that if 'view' is not a toplevel view, the 'front' toplevel view
 | 
						 * Note that if 'view' is not a toplevel view, the 'front' toplevel view
 | 
				
			||||||
	 * will be focussed on; but if 'view' is a toplevel view, the 'next'
 | 
						 * will be focussed on; but if 'view' is a toplevel view, the 'next'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue