mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	xdg: support xdg-shell v3 with popup repositioning
See https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3514 which added support on the wlroots side. We now re-run popup positioning (for both xdg-shell and layer-shell popups) when the "reposition" event is received. This allows popups that change size (such as qmpanel's applications menu) to be positioned correctly. xdg-shell v3 also gives the compositor some additional "hints" for popup positioning (reactive, parent_size, and parent_configure_serial) which are available but we don't make use of currently.
This commit is contained in:
		
							parent
							
								
									45b197b8a4
								
							
						
					
					
						commit
						a98f2635ea
					
				
					 4 changed files with 27 additions and 1 deletions
				
			
		| 
						 | 
					@ -32,6 +32,7 @@ struct lab_layer_popup {
 | 
				
			||||||
	struct wl_listener commit;
 | 
						struct wl_listener commit;
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
	struct wl_listener new_popup;
 | 
						struct wl_listener new_popup;
 | 
				
			||||||
 | 
						struct wl_listener reposition;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void layers_init(struct server *server);
 | 
					void layers_init(struct server *server);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/layers.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								src/layers.c
									
										
									
									
									
								
							| 
						 | 
					@ -356,6 +356,7 @@ popup_handle_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
		wl_container_of(listener, popup, destroy);
 | 
							wl_container_of(listener, popup, destroy);
 | 
				
			||||||
	wl_list_remove(&popup->destroy.link);
 | 
						wl_list_remove(&popup->destroy.link);
 | 
				
			||||||
	wl_list_remove(&popup->new_popup.link);
 | 
						wl_list_remove(&popup->new_popup.link);
 | 
				
			||||||
 | 
						wl_list_remove(&popup->reposition.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Usually already removed unless there was no commit at all */
 | 
						/* Usually already removed unless there was no commit at all */
 | 
				
			||||||
	if (popup->commit.notify) {
 | 
						if (popup->commit.notify) {
 | 
				
			||||||
| 
						 | 
					@ -381,6 +382,15 @@ popup_handle_commit(struct wl_listener *listener, void *data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_handle_reposition(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct lab_layer_popup *popup =
 | 
				
			||||||
 | 
							wl_container_of(listener, popup, reposition);
 | 
				
			||||||
 | 
						wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup,
 | 
				
			||||||
 | 
							&popup->output_toplevel_sx_box);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
 | 
					static void popup_handle_new_popup(struct wl_listener *listener, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct lab_layer_popup *
 | 
					static struct lab_layer_popup *
 | 
				
			||||||
| 
						 | 
					@ -410,6 +420,9 @@ create_popup(struct wlr_xdg_popup *wlr_popup, struct wlr_scene_tree *parent)
 | 
				
			||||||
	popup->commit.notify = popup_handle_commit;
 | 
						popup->commit.notify = popup_handle_commit;
 | 
				
			||||||
	wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 | 
						wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup->reposition.notify = popup_handle_reposition;
 | 
				
			||||||
 | 
						wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return popup;
 | 
						return popup;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@ struct xdg_popup {
 | 
				
			||||||
	struct wl_listener commit;
 | 
						struct wl_listener commit;
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
	struct wl_listener new_popup;
 | 
						struct wl_listener new_popup;
 | 
				
			||||||
 | 
						struct wl_listener reposition;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,7 @@ handle_xdg_popup_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
 | 
						struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
 | 
				
			||||||
	wl_list_remove(&popup->destroy.link);
 | 
						wl_list_remove(&popup->destroy.link);
 | 
				
			||||||
	wl_list_remove(&popup->new_popup.link);
 | 
						wl_list_remove(&popup->new_popup.link);
 | 
				
			||||||
 | 
						wl_list_remove(&popup->reposition.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Usually already removed unless there was no commit at all */
 | 
						/* Usually already removed unless there was no commit at all */
 | 
				
			||||||
	if (popup->commit.notify) {
 | 
						if (popup->commit.notify) {
 | 
				
			||||||
| 
						 | 
					@ -69,6 +71,13 @@ handle_xdg_popup_commit(struct wl_listener *listener, void *data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					handle_xdg_popup_reposition(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct xdg_popup *popup = wl_container_of(listener, popup, reposition);
 | 
				
			||||||
 | 
						popup_unconstrain(popup);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
 | 
					popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -100,6 +109,9 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup)
 | 
				
			||||||
	popup->commit.notify = handle_xdg_popup_commit;
 | 
						popup->commit.notify = handle_xdg_popup_commit;
 | 
				
			||||||
	wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 | 
						wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popup->reposition.notify = handle_xdg_popup_reposition;
 | 
				
			||||||
 | 
						wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We must add xdg popups to the scene graph so they get rendered. The
 | 
						 * We must add xdg popups to the scene graph so they get rendered. The
 | 
				
			||||||
	 * wlroots scene graph provides a helper for this, but to use it we must
 | 
						 * wlroots scene graph provides a helper for this, but to use it we must
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@
 | 
				
			||||||
#include "window-rules.h"
 | 
					#include "window-rules.h"
 | 
				
			||||||
#include "workspaces.h"
 | 
					#include "workspaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LAB_XDG_SHELL_VERSION (2)
 | 
					#define LAB_XDG_SHELL_VERSION (3)
 | 
				
			||||||
#define CONFIGURE_TIMEOUT_MS 100
 | 
					#define CONFIGURE_TIMEOUT_MS 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct xdg_toplevel_view *
 | 
					static struct xdg_toplevel_view *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue