mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	xwayland: set _NET_WORKAREA property based on usable area
XWayland clients use the _NET_WORKAREA root window property to determine how much of the screen is not covered by panels/docks. The property is used for example by Qt to determine areas of the screen that popup menus should not overlap (see QScreen::availableVirtualGeometry). Depends on wlroots MR: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4406 v2: prevent calling wlr_xwayland_set_workareas() too early v3: fix segfault at exit (server->xwayland == NULL)
This commit is contained in:
		
							parent
							
								
									5a2df57363
								
							
						
					
					
						commit
						6b8c79748a
					
				
					 3 changed files with 89 additions and 0 deletions
				
			
		| 
						 | 
					@ -58,5 +58,7 @@ void xwayland_server_init(struct server *server,
 | 
				
			||||||
	struct wlr_compositor *compositor);
 | 
						struct wlr_compositor *compositor);
 | 
				
			||||||
void xwayland_server_finish(struct server *server);
 | 
					void xwayland_server_finish(struct server *server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void xwayland_update_workarea(struct server *server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* HAVE_XWAYLAND */
 | 
					#endif /* HAVE_XWAYLAND */
 | 
				
			||||||
#endif /* LABWC_XWAYLAND_H */
 | 
					#endif /* LABWC_XWAYLAND_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@
 | 
				
			||||||
#include "node.h"
 | 
					#include "node.h"
 | 
				
			||||||
#include "regions.h"
 | 
					#include "regions.h"
 | 
				
			||||||
#include "view.h"
 | 
					#include "view.h"
 | 
				
			||||||
 | 
					#include "xwayland.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
output_frame_notify(struct wl_listener *listener, void *data)
 | 
					output_frame_notify(struct wl_listener *listener, void *data)
 | 
				
			||||||
| 
						 | 
					@ -610,6 +611,9 @@ output_update_usable_area(struct output *output)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (update_usable_area(output)) {
 | 
						if (update_usable_area(output)) {
 | 
				
			||||||
		regions_update_geometry(output);
 | 
							regions_update_geometry(output);
 | 
				
			||||||
 | 
					#if HAVE_XWAYLAND
 | 
				
			||||||
 | 
							xwayland_update_workarea(output->server);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		desktop_arrange_all_views(output->server);
 | 
							desktop_arrange_all_views(output->server);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -629,6 +633,9 @@ output_update_all_usable_areas(struct server *server, bool layout_changed)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (usable_area_changed || layout_changed) {
 | 
						if (usable_area_changed || layout_changed) {
 | 
				
			||||||
 | 
					#if HAVE_XWAYLAND
 | 
				
			||||||
 | 
							xwayland_update_workarea(server);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		desktop_arrange_all_views(server);
 | 
							desktop_arrange_all_views(server);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -839,6 +839,7 @@ handle_ready(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct server *server =
 | 
						struct server *server =
 | 
				
			||||||
		wl_container_of(listener, server, xwayland_ready);
 | 
							wl_container_of(listener, server, xwayland_ready);
 | 
				
			||||||
	wlr_xwayland_set_seat(server->xwayland, server->seat.seat);
 | 
						wlr_xwayland_set_seat(server->xwayland, server->seat.seat);
 | 
				
			||||||
 | 
						xwayland_update_workarea(server);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -928,3 +929,82 @@ xwayland_server_finish(struct server *server)
 | 
				
			||||||
	server->xwayland = NULL;
 | 
						server->xwayland = NULL;
 | 
				
			||||||
	wlr_xwayland_destroy(xwayland);
 | 
						wlr_xwayland_destroy(xwayland);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					xwayland_update_workarea(struct server *server)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Do nothing if called during destroy or before xwayland is ready.
 | 
				
			||||||
 | 
						 * This function will be called again from the ready signal handler.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!server->xwayland || !server->xwayland->xwm) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_box lb;
 | 
				
			||||||
 | 
						wlr_output_layout_get_box(server->output_layout, NULL, &lb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Compute outer edges of layout (excluding negative regions) */
 | 
				
			||||||
 | 
						int layout_left = MAX(0, lb.x);
 | 
				
			||||||
 | 
						int layout_right = MAX(0, lb.x + lb.width);
 | 
				
			||||||
 | 
						int layout_top = MAX(0, lb.y);
 | 
				
			||||||
 | 
						int layout_bottom = MAX(0, lb.y + lb.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Workarea is initially the entire layout */
 | 
				
			||||||
 | 
						int workarea_left = layout_left;
 | 
				
			||||||
 | 
						int workarea_right = layout_right;
 | 
				
			||||||
 | 
						int workarea_top = layout_top;
 | 
				
			||||||
 | 
						int workarea_bottom = layout_bottom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct output *output;
 | 
				
			||||||
 | 
						wl_list_for_each(output, &server->outputs, link) {
 | 
				
			||||||
 | 
							if (!output_is_usable(output)) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_box ob;
 | 
				
			||||||
 | 
							wlr_output_layout_get_box(server->output_layout,
 | 
				
			||||||
 | 
								output->wlr_output, &ob);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Compute edges of output */
 | 
				
			||||||
 | 
							int output_left = ob.x;
 | 
				
			||||||
 | 
							int output_right = ob.x + ob.width;
 | 
				
			||||||
 | 
							int output_top = ob.y;
 | 
				
			||||||
 | 
							int output_bottom = ob.y + ob.height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Compute edges of usable area */
 | 
				
			||||||
 | 
							int usable_left = output_left + output->usable_area.x;
 | 
				
			||||||
 | 
							int usable_right = usable_left + output->usable_area.width;
 | 
				
			||||||
 | 
							int usable_top = output_top + output->usable_area.y;
 | 
				
			||||||
 | 
							int usable_bottom = usable_top + output->usable_area.height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Only adjust workarea edges for output edges that are
 | 
				
			||||||
 | 
							 * aligned with outer edges of layout
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (output_left == layout_left) {
 | 
				
			||||||
 | 
								workarea_left = MAX(workarea_left, usable_left);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (output_right == layout_right) {
 | 
				
			||||||
 | 
								workarea_right = MIN(workarea_right, usable_right);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (output_top == layout_top) {
 | 
				
			||||||
 | 
								workarea_top = MAX(workarea_top, usable_top);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (output_bottom == layout_bottom) {
 | 
				
			||||||
 | 
								workarea_bottom = MIN(workarea_bottom, usable_bottom);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Set _NET_WORKAREA property. We don't report virtual desktops
 | 
				
			||||||
 | 
						 * to XWayland, so we set only one workarea.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct wlr_box workarea = {
 | 
				
			||||||
 | 
							.x = workarea_left,
 | 
				
			||||||
 | 
							.y = workarea_top,
 | 
				
			||||||
 | 
							.width = workarea_right - workarea_left,
 | 
				
			||||||
 | 
							.height = workarea_bottom - workarea_top,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						wlr_xwayland_set_workareas(server->xwayland, &workarea, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue