unconstrain layer shell popups

also unconstrain popups from monitor's usable area
This commit is contained in:
Leonardo Hernández Hernández 2022-06-20 23:46:11 -05:00
parent 79ad72413d
commit 9b84940e37
No known key found for this signature in database
GPG key ID: E538897EE11B9624
2 changed files with 21 additions and 20 deletions

View file

@ -261,15 +261,17 @@ client_from_wlr_surface(struct wlr_surface *s)
return NULL; return NULL;
} }
static inline Client * static inline void *
client_from_popup(struct wlr_xdg_popup *popup) toplevel_from_popup(struct wlr_xdg_popup *popup)
{ {
struct wlr_xdg_surface *surface = popup->base; struct wlr_xdg_surface *surface = popup->base;
while (1) { while (1) {
switch (surface->role) { switch (surface->role) {
case WLR_XDG_SURFACE_ROLE_POPUP: case WLR_XDG_SURFACE_ROLE_POPUP:
if (!wlr_surface_is_xdg_surface(surface->popup->parent)) if (wlr_surface_is_layer_surface(surface->popup->parent))
return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data;
else if (!wlr_surface_is_xdg_surface(surface->popup->parent))
return NULL; return NULL;
surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent); surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent);

33
dwl.c
View file

@ -90,8 +90,10 @@ typedef struct {
typedef struct Monitor Monitor; typedef struct Monitor Monitor;
typedef struct { typedef struct {
/* Must be first */ /* Must keep these three elements in this order */
unsigned int type; /* XDGShell or X11* */ unsigned int type; /* XDGShell or X11* */
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon;
struct wlr_scene_node *scene; struct wlr_scene_node *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_node *scene_surface; struct wlr_scene_node *scene_surface;
@ -107,8 +109,7 @@ typedef struct {
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener set_title; struct wl_listener set_title;
struct wl_listener fullscreen; struct wl_listener fullscreen;
struct wlr_box geom, prev; /* layout-relative, includes border */ struct wlr_box prev; /* layout-relative, includes border */
Monitor *mon;
#ifdef XWAYLAND #ifdef XWAYLAND
struct wl_listener activate; struct wl_listener activate;
struct wl_listener configure; struct wl_listener configure;
@ -146,19 +147,19 @@ typedef struct {
} Keyboard; } Keyboard;
typedef struct { typedef struct {
/* Must be first */ /* Must keep these three elements in this order */
unsigned int type; /* LayerShell */ unsigned int type; /* LayerShell */
int mapped; struct wlr_box geom;
Monitor *mon;
struct wlr_scene_node *scene; struct wlr_scene_node *scene;
struct wl_list link; struct wl_list link;
int mapped;
struct wlr_layer_surface_v1 *layer_surface; struct wlr_layer_surface_v1 *layer_surface;
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener map; struct wl_listener map;
struct wl_listener unmap; struct wl_listener unmap;
struct wl_listener surface_commit; struct wl_listener surface_commit;
struct wlr_box geo;
} LayerSurface; } LayerSurface;
typedef struct { typedef struct {
@ -559,7 +560,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
wlr_layer_surface_v1_destroy(wlr_layer_surface); wlr_layer_surface_v1_destroy(wlr_layer_surface);
continue; continue;
} }
layersurface->geo = box; layersurface->geom = box;
if (state->exclusive_zone > 0) if (state->exclusive_zone > 0)
applyexclusive(usable_area, state->anchor, state->exclusive_zone, applyexclusive(usable_area, state->anchor, state->exclusive_zone,
@ -835,7 +836,6 @@ createlayersurface(struct wl_listener *listener, void *data)
{ {
struct wlr_layer_surface_v1 *wlr_layer_surface = data; struct wlr_layer_surface_v1 *wlr_layer_surface = data;
LayerSurface *layersurface; LayerSurface *layersurface;
Monitor *m;
struct wlr_layer_surface_v1_state old_state; struct wlr_layer_surface_v1_state old_state;
if (!wlr_layer_surface->output) { if (!wlr_layer_surface->output) {
@ -855,14 +855,14 @@ createlayersurface(struct wl_listener *listener, void *data)
layersurface->layer_surface = wlr_layer_surface; layersurface->layer_surface = wlr_layer_surface;
wlr_layer_surface->data = layersurface; wlr_layer_surface->data = layersurface;
m = wlr_layer_surface->output->data; layersurface->mon = wlr_layer_surface->output->data;
layersurface->scene = wlr_layer_surface->surface->data = layersurface->scene = wlr_layer_surface->surface->data =
wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer], wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer],
wlr_layer_surface->surface); wlr_layer_surface->surface);
layersurface->scene->data = layersurface; layersurface->scene->data = layersurface;
wl_list_insert(&m->layers[wlr_layer_surface->pending.layer], wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->pending.layer],
&layersurface->link); &layersurface->link);
/* Temporarily set the layer's current state to pending /* Temporarily set the layer's current state to pending
@ -870,7 +870,7 @@ createlayersurface(struct wl_listener *listener, void *data)
*/ */
old_state = wlr_layer_surface->current; old_state = wlr_layer_surface->current;
wlr_layer_surface->current = wlr_layer_surface->pending; wlr_layer_surface->current = wlr_layer_surface->pending;
arrangelayers(m); arrangelayers(layersurface->mon);
wlr_layer_surface->current = old_state; wlr_layer_surface->current = old_state;
} }
@ -955,9 +955,9 @@ createnotify(struct wl_listener *listener, void *data)
struct wlr_box box; struct wlr_box box;
xdg_surface->surface->data = wlr_scene_xdg_surface_create( xdg_surface->surface->data = wlr_scene_xdg_surface_create(
xdg_surface->popup->parent->data, xdg_surface); xdg_surface->popup->parent->data, xdg_surface);
if (!(c = client_from_popup(xdg_surface->popup)) || !c->mon) if (!(c = toplevel_from_popup(xdg_surface->popup)) || !c->mon)
return; return;
box = c->mon->m; box = c->mon->w;
box.x -= c->geom.x; box.x -= c->geom.x;
box.y -= c->geom.y; box.y -= c->geom.y;
wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
@ -1055,9 +1055,8 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data)
wl_list_remove(&layersurface->surface_commit.link); wl_list_remove(&layersurface->surface_commit.link);
wlr_scene_node_destroy(layersurface->scene); wlr_scene_node_destroy(layersurface->scene);
if (layersurface->layer_surface->output) { if (layersurface->layer_surface->output) {
Monitor *m = layersurface->layer_surface->output->data; if (layersurface->mon)
if (m) arrangelayers(layersurface->mon);
arrangelayers(m);
layersurface->layer_surface->output = NULL; layersurface->layer_surface->output = NULL;
} }
free(layersurface); free(layersurface);