summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Cella <guido@guidocella.xyz>2024-01-28 18:30:36 +0100
committerLeonardo Hernández Hernández <leohdz172@proton.me>2024-02-05 16:00:28 -0600
commit298949bbc4eae8cedb9cdd11cfc9ebd139ac5d5f (patch)
tree895df4121941761002da00be4ea9db38ac62a592
parent17c5cbbf7b6c3a5373f46e6fb6e88daada325479 (diff)
place child clients above fullscreen clients
When a child window of a fullscreen client is mapped, the fullscreen is disabled, and if the previously fullscreen client is floating the child window is rendered below it and cannot be seen, causing confusion, though it is still focused and interactable. Fix this by putting children of fullscreen clients in LyrFS instead of LyrFloat, and by returning before the unset_fullscreen code is called when they are mapped. focusstack() now lets you switch focus from a fullscreen client to its child windows, otherwise if you switch focus from the child window to the fullscreen client you could not focus the child window again and the fullscreen client would stay unresponsive. Child clients are not reparented to LyrFloat after leaving fullscreen, so you could spawn a child window, focus back the fullscreen client, unfullscreen it, and the child window would still be drawn above other floating clients. Avoid dealing with this edge case to keep the line count low. These cases can be tested by pressing Ctrl+o in applications with an open file dialog.
-rw-r--r--client.h12
-rw-r--r--dwl.c13
2 files changed, 20 insertions, 5 deletions
diff --git a/client.h b/client.h
index 8a379d0..fe9dffc 100644
--- a/client.h
+++ b/client.h
@@ -183,6 +183,18 @@ client_get_parent(Client *c)
return p;
}
+static inline int
+client_has_children(Client *c)
+{
+#ifdef XWAYLAND
+ if (client_is_x11(c))
+ return !wl_list_empty(&c->surface.xwayland->children);
+#endif
+ /* surface.xdg->link is never empty because it always contains at least the
+ * surface itself. */
+ return wl_list_length(&c->surface.xdg->link) > 1;
+}
+
static inline const char *
client_get_title(Client *c)
{
diff --git a/dwl.c b/dwl.c
index b04b66a..95ebee8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1256,7 +1256,7 @@ focusstack(const Arg *arg)
{
/* Focus the next or previous client (in tiling order) on selmon */
Client *c, *sel = focustop(selmon);
- if (!sel || sel->isfullscreen)
+ if (!sel || (sel->isfullscreen && !client_has_children(sel)))
return;
if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) {
@@ -1496,7 +1496,8 @@ void
mapnotify(struct wl_listener *listener, void *data)
{
/* Called when the surface is mapped, or ready to display on-screen. */
- Client *p, *w, *c = wl_container_of(listener, c, map);
+ Client *p = NULL;
+ Client *w, *c = wl_container_of(listener, c, map);
Monitor *m;
int i;
@@ -1553,7 +1554,7 @@ mapnotify(struct wl_listener *listener, void *data)
unset_fullscreen:
m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y);
wl_list_for_each(w, &clients, link) {
- if (w != c && w->isfullscreen && m == w->mon && (w->tags & c->tags))
+ if (w != c && w != p && w->isfullscreen && m == w->mon && (w->tags & c->tags))
setfullscreen(w, 0);
}
}
@@ -2044,11 +2045,13 @@ setcursorshape(struct wl_listener *listener, void *data)
void
setfloating(Client *c, int floating)
{
+ Client *p = client_get_parent(c);
c->isfloating = floating;
if (!c->mon)
return;
- wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
- ? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
+ wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
+ (p && p->isfullscreen) ? LyrFS
+ : c->isfloating ? LyrFloat : LyrTile]);
arrange(c->mon);
printstatus();
}