From 569f55401693c9d2850f056f20ca2bd5bd5977fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 19 Nov 2022 01:34:15 -0600 Subject: [PATCH 1/9] don't unfocus focused client when starting a drag this fix chromium keyboard focus loss after a drag Fix: 3cc22de712415342e4865eef099fcfde49bcf734 --- dwl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/dwl.c b/dwl.c index 5ee3c92..b884d06 100644 --- a/dwl.c +++ b/dwl.c @@ -2265,9 +2265,6 @@ void startdrag(struct wl_listener *listener, void *data) { struct wlr_drag *drag = data; - /* During drag the focus isn't sent to clients, this causes that - * we don't update border color acording the pointer coordinates */ - focusclient(NULL, 0); if (!drag->icon) return; From 88d386bfdcedb8b46d7c4c7a3ebac2476cfcf46b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 12 Nov 2022 20:05:56 -0600 Subject: [PATCH 2/9] configurex11: resize floating clients and arrange tiled clients' monitor --- dwl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 3bf5cdc..2903d9d 100644 --- a/dwl.c +++ b/dwl.c @@ -2486,8 +2486,13 @@ configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); struct wlr_xwayland_surface_configure_event *event = data; - wlr_xwayland_surface_configure(c->surface.xwayland, - event->x, event->y, event->width, event->height); + if (!c->mon) + return; + if (c->isfloating || c->type == X11Unmanaged) + resize(c, (struct wlr_box){.x = event->x, .y = event->y, + .width = event->width, .height = event->height}, 0); + else + arrange(c->mon); } void From 93a911d6e93f760a5139bfe0d1c1eb90886c414f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 13 Nov 2022 16:39:17 -0600 Subject: [PATCH 3/9] simplify `if` expression in checkidleinhibitor() --- dwl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dwl.c b/dwl.c index 2903d9d..8599764 100644 --- a/dwl.c +++ b/dwl.c @@ -588,16 +588,15 @@ chvt(const Arg *arg) void checkidleinhibitor(struct wlr_surface *exclude) { + Client *c; int inhibited = 0; struct wlr_idle_inhibitor_v1 *inhibitor; wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { - Client *c; - if (exclude == inhibitor->surface) - continue; /* In case we can't get a client from the surface assume that it is * visible, for example a layer surface */ - if (!(c = client_from_wlr_surface(inhibitor->surface)) - || VISIBLEON(c, c->mon)) { + if (exclude != inhibitor->surface + && (!(c = client_from_wlr_surface(inhibitor->surface)) + || VISIBLEON(c, c->mon))) { inhibited = 1; break; } From 60a98b87f395618be8d35c1100e019588e255d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 13 Nov 2022 16:46:43 -0600 Subject: [PATCH 4/9] inhibit idle if surface's node is enabled --- dwl.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 8599764..949f7b3 100644 --- a/dwl.c +++ b/dwl.c @@ -588,15 +588,12 @@ chvt(const Arg *arg) void checkidleinhibitor(struct wlr_surface *exclude) { - Client *c; int inhibited = 0; + struct wlr_scene_tree *tree; struct wlr_idle_inhibitor_v1 *inhibitor; wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { - /* In case we can't get a client from the surface assume that it is - * visible, for example a layer surface */ - if (exclude != inhibitor->surface - && (!(c = client_from_wlr_surface(inhibitor->surface)) - || VISIBLEON(c, c->mon))) { + if (exclude != inhibitor->surface && (tree = inhibitor->surface->data) + && tree->node.enabled) { inhibited = 1; break; } From 63d6de58669ea4ee6876e7e624fa3c3bd9e83a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 13 Nov 2022 16:57:41 -0600 Subject: [PATCH 5/9] fix set of layersurface->popups and surface->data --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 949f7b3..3f2b261 100644 --- a/dwl.c +++ b/dwl.c @@ -804,7 +804,7 @@ createlayersurface(struct wl_listener *listener, void *data) layers[wlr_layer_surface->pending.layer], wlr_layer_surface); layersurface->scene = layersurface->scene_layer->tree; layersurface->popups = wlr_layer_surface->surface->data = - &wlr_scene_tree_create(layers[wlr_layer_surface->pending.layer])->node; + wlr_scene_tree_create(layers[wlr_layer_surface->pending.layer]); layersurface->scene->node.data = layersurface; From 7eebe677879373672774c06c81c0e3eda22d03ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 15 Nov 2022 22:29:26 -0600 Subject: [PATCH 6/9] set x and y of the layersurface's geometry box --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 3f2b261..579dad1 100644 --- a/dwl.c +++ b/dwl.c @@ -466,6 +466,8 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wlr_scene_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area); wlr_scene_node_set_position(&layersurface->popups->node, layersurface->scene->node.x, layersurface->scene->node.y); + layersurface->geom.x = layersurface->scene->node.x; + layersurface->geom.y = layersurface->scene->node.y; } } From 05eca0e2d95a44a2d33959b8362a21a0f974e17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 15 Nov 2022 22:32:20 -0600 Subject: [PATCH 7/9] rename xwayland_surface to xsurface this save us 2 lines --- dwl.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/dwl.c b/dwl.c index 579dad1..88c398f 100644 --- a/dwl.c +++ b/dwl.c @@ -2496,7 +2496,7 @@ configurex11(struct wl_listener *listener, void *data) void createnotifyx11(struct wl_listener *listener, void *data) { - struct wlr_xwayland_surface *xwayland_surface = data; + struct wlr_xwayland_surface *xsurface = data; Client *c; /* TODO: why we unset fullscreen when a xwayland client is created? */ wl_list_for_each(c, &clients, link) @@ -2504,22 +2504,20 @@ createnotifyx11(struct wl_listener *listener, void *data) setfullscreen(c, 0); /* Allocate a Client for this surface */ - c = xwayland_surface->data = ecalloc(1, sizeof(*c)); - c->surface.xwayland = xwayland_surface; - c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed; + c = xsurface->data = ecalloc(1, sizeof(*c)); + c->surface.xwayland = xsurface; + c->type = xsurface->override_redirect ? X11Unmanaged : X11Managed; c->bw = borderpx; /* Listen to the various events it can emit */ - LISTEN(&xwayland_surface->events.map, &c->map, mapnotify); - LISTEN(&xwayland_surface->events.unmap, &c->unmap, unmapnotify); - LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11); - LISTEN(&xwayland_surface->events.request_configure, &c->configure, - configurex11); - LISTEN(&xwayland_surface->events.set_hints, &c->set_hints, sethints); - LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle); - LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen, - fullscreennotify); + LISTEN(&xsurface->events.map, &c->map, mapnotify); + LISTEN(&xsurface->events.unmap, &c->unmap, unmapnotify); + LISTEN(&xsurface->events.request_activate, &c->activate, activatex11); + LISTEN(&xsurface->events.request_configure, &c->configure, configurex11); + LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints); + LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle); + LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify); + LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, fullscreennotify); } Atom From caec566286b1bbef1758bcf0599677650017c5b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 11 Nov 2022 00:22:36 -0600 Subject: [PATCH 8/9] create a dedicated layer for fullscreen clients Bug: https://github.com/djpohly/dwl/issues/327 --- dwl.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/dwl.c b/dwl.c index 88c398f..aacc345 100644 --- a/dwl.c +++ b/dwl.c @@ -73,7 +73,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11Managed, X11Unmanaged }; /* client types */ -enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrDragIcon, NUM_LAYERS }; /* scene layers */ +enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrFS, LyrDragIcon, NUM_LAYERS }; /* scene layers */ #ifdef XWAYLAND enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ @@ -102,7 +102,6 @@ typedef struct { struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_tree *scene_surface; - struct wlr_scene_rect *fullscreen_bg; /* See setfullscreen() for info */ struct wl_list link; struct wl_list flink; union { @@ -171,6 +170,7 @@ struct Monitor { struct wl_list link; struct wlr_output *wlr_output; struct wlr_scene_output *scene_output; + struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ struct wl_listener frame; struct wl_listener destroy; struct wlr_box m; /* monitor area, layout-relative */ @@ -445,6 +445,9 @@ arrange(Monitor *m) if (c->mon == m) wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m)); + wlr_scene_node_set_enabled(&m->fullscreen_bg->node, + (c = focustop(m)) && c->isfullscreen); + if (m && m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); motionnotify(0); @@ -655,6 +658,7 @@ cleanupmon(struct wl_listener *listener, void *data) m->wlr_output->data = NULL; wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); + wlr_scene_node_destroy(&m->fullscreen_bg->node); closemon(m); free(m); @@ -874,6 +878,18 @@ createmon(struct wl_listener *listener, void *data) wl_list_insert(&mons, &m->link); printstatus(); + /* The xdg-protocol specifies: + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + * + */ + /* updatemons() will resize and set correct position */ + m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg); + wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); + /* Adds this to the output layout in the order it was configured in. * * The output layout utility automatically adds a wl_output global to the @@ -1724,8 +1740,6 @@ resize(Client *c, struct wlr_box geo, int interact) wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw); wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw); - if (c->fullscreen_bg) - wlr_scene_rect_set_size(c->fullscreen_bg, c->geom.width, c->geom.height); /* wlroots makes this a no-op if size hasn't changed */ c->resize = client_set_size(c, c->geom.width - 2 * c->bw, @@ -1833,32 +1847,16 @@ setfullscreen(Client *c, int fullscreen) return; c->bw = fullscreen ? 0 : borderpx; client_set_fullscreen(c, fullscreen); + wlr_scene_node_reparent(&c->scene->node, layers[fullscreen + ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); if (fullscreen) { c->prev = c->geom; resize(c, c->mon->m, 0); - /* The xdg-protocol specifies: - * - * If the fullscreened surface is not opaque, the compositor must make - * sure that other screen content not part of the same surface tree (made - * up of subsurfaces, popups or similarly coupled surfaces) are not - * visible below the fullscreened surface. - * - * For brevity we set a black background for all clients - */ - if (!c->fullscreen_bg) { - c->fullscreen_bg = wlr_scene_rect_create(c->scene, - c->geom.width, c->geom.height, fullscreen_bg); - wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node); - } } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ resize(c, c->prev, 0); - if (c->fullscreen_bg) { - wlr_scene_node_destroy(&c->fullscreen_bg->node); - c->fullscreen_bg = NULL; - } } arrange(c->mon); printstatus(); @@ -1976,6 +1974,7 @@ setup(void) layers[LyrBottom] = wlr_scene_tree_create(&scene->tree); layers[LyrTile] = wlr_scene_tree_create(&scene->tree); layers[LyrFloat] = wlr_scene_tree_create(&scene->tree); + layers[LyrFS] = wlr_scene_tree_create(&scene->tree); layers[LyrTop] = wlr_scene_tree_create(&scene->tree); layers[LyrOverlay] = wlr_scene_tree_create(&scene->tree); layers[LyrDragIcon] = wlr_scene_tree_create(&scene->tree); @@ -2342,6 +2341,9 @@ updatemons(struct wl_listener *listener, void *data) /* Don't move clients to the left output when plugging monitors */ arrange(m); + wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); + wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); + config_head->state.enabled = 1; config_head->state.mode = m->wlr_output->current_mode; config_head->state.x = m->m.x; @@ -2411,7 +2413,7 @@ xytonode(double x, double y, struct wlr_surface **psurface, Client *c = NULL; LayerSurface *l = NULL; const int *layer; - int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg }; + int focus_order[] = { LyrOverlay, LyrTop, LyrFS, LyrFloat, LyrTile, LyrBottom, LyrBg }; for (layer = focus_order; layer < END(focus_order); layer++) { if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) { From 087373698afeab0af9257358955f1c3c772d24e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 21 Nov 2022 14:44:24 -0600 Subject: [PATCH 9/9] Revert "Add a configuration option for fullscreen locking" now all fullcreen clients are rendered above tiled and floating clients This partially reverts commit 326eee14445f8a2c08e80c30778445630c75d3bb. --- config.def.h | 1 - dwl.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index b3caab3..0473b40 100644 --- a/config.def.h +++ b/config.def.h @@ -1,7 +1,6 @@ /* appearance */ static const int sloppyfocus = 1; /* focus follows mouse */ static const unsigned int borderpx = 1; /* border pixel of windows */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0}; static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0}; static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0}; diff --git a/dwl.c b/dwl.c index aacc345..c1ff934 100644 --- a/dwl.c +++ b/dwl.c @@ -1156,7 +1156,7 @@ focusstack(const Arg *arg) { /* Focus the next or previous client (in tiling order) on selmon */ Client *c, *sel = selclient(); - if (!sel || (sel->isfullscreen && lockfullscreen)) + if (!sel || sel->isfullscreen) return; if (arg->i > 0) { wl_list_for_each(c, &sel->link, link) {