From 50c4f500b44bdf377ff8ff300fd2c862613bfc5d Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Fri, 20 Aug 2021 12:04:58 +0200 Subject: [PATCH] render floating clients above tiled ones This first renders all fullscren clients, then floating clients, then tiled ones. xytoclient also needs to be modified to look for fullscreen and floating clients first. --- dwl.c | 97 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/dwl.c b/dwl.c index b898537..5973e24 100644 --- a/dwl.c +++ b/dwl.c @@ -263,6 +263,7 @@ static void printstatus(void); static void quit(const Arg *arg); static void quitsignal(int signo); static void render(struct wlr_surface *surface, int sx, int sy, void *data); +static void renderclient(Client *c, Monitor *m, struct timespec *now); static void renderclients(Monitor *m, struct timespec *now); static void renderlayer(struct wl_list *layer_surfaces, struct timespec *now); static void rendermon(struct wl_listener *listener, void *data); @@ -1040,6 +1041,7 @@ setfullscreen(Client *c, int fullscreen) resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0); arrange(c->mon); } + motionnotify(0); } void @@ -1661,54 +1663,72 @@ render(struct wlr_surface *surface, int sx, int sy, void *data) } void -renderclients(Monitor *m, struct timespec *now) +renderclient(Client *c, Monitor *m, struct timespec *now) { - Client *c, *sel = selclient(); + Client *sel = selclient(); const float *color; double ox, oy; int i, w, h; struct render_data rdata; struct wlr_box *borders; struct wlr_surface *surface; - /* Each subsequent window we render is rendered on top of the last. Because - * our stacking list is ordered front-to-back, we iterate over it backwards. */ - wl_list_for_each_reverse(c, &stack, slink) { - /* Only render visible clients which show on this monitor */ - if (!VISIBLEON(c, c->mon) || !wlr_output_layout_intersects( - output_layout, m->wlr_output, &c->geom)) - continue; - surface = client_surface(c); - ox = c->geom.x, oy = c->geom.y; - wlr_output_layout_output_coords(output_layout, m->wlr_output, - &ox, &oy); + /* Only render visible clients which show on this monitor */ + if (!VISIBLEON(c, c->mon) || !wlr_output_layout_intersects( + output_layout, m->wlr_output, &c->geom)) + return; - if (c->bw) { - w = surface->current.width; - h = surface->current.height; - borders = (struct wlr_box[4]) { - {ox, oy, w + 2 * c->bw, c->bw}, /* top */ + surface = client_surface(c); + ox = c->geom.x, oy = c->geom.y; + wlr_output_layout_output_coords(output_layout, m->wlr_output, + &ox, &oy); + + if (c->bw) { + w = surface->current.width; + h = surface->current.height; + borders = (struct wlr_box[4]) { + {ox, oy, w + 2 * c->bw, c->bw}, /* top */ {ox, oy + c->bw, c->bw, h}, /* left */ {ox + c->bw + w, oy + c->bw, c->bw, h}, /* right */ {ox, oy + c->bw + h, w + 2 * c->bw, c->bw}, /* bottom */ - }; + }; - /* Draw window borders */ - color = (c == sel) ? focuscolor : bordercolor; - for (i = 0; i < 4; i++) { - scalebox(&borders[i], m->wlr_output->scale); - wlr_render_rect(drw, &borders[i], color, - m->wlr_output->transform_matrix); - } + /* Draw window borders */ + color = (c == sel) ? focuscolor : bordercolor; + for (i = 0; i < 4; i++) { + scalebox(&borders[i], m->wlr_output->scale); + wlr_render_rect(drw, &borders[i], color, + m->wlr_output->transform_matrix); } + } - /* This calls our render function for each surface among the - * xdg_surface's toplevel and popups. */ - rdata.output = m->wlr_output; - rdata.when = now; - rdata.x = c->geom.x + c->bw; - rdata.y = c->geom.y + c->bw; - client_for_each_surface(c, render, &rdata); + /* This calls our render function for each surface among the + * xdg_surface's toplevel and popups. */ + rdata.output = m->wlr_output; + rdata.when = now; + rdata.x = c->geom.x + c->bw; + rdata.y = c->geom.y + c->bw; + client_for_each_surface(c, render, &rdata); +} + +void +renderclients(Monitor *m, struct timespec *now) +{ + Client *c; + + /* Each subsequent window we render is rendered on top of the last. Because + * our stacking list is ordered front-to-back, we iterate over it backwards. */ + wl_list_for_each_reverse(c, &stack, slink) { + if (!c->isfloating && !c->isfullscreen) + renderclient(c, m, now); + } + wl_list_for_each_reverse(c, &stack, slink) { + if (c->isfloating && !c->isfullscreen) + renderclient(c, m, now); + } + wl_list_for_each_reverse(c, &stack, slink) { + if (c->isfullscreen) + renderclient(c, m, now); } } @@ -2389,7 +2409,16 @@ xytoclient(double x, double y) * borders. This relies on stack being ordered from top to bottom. */ Client *c; wl_list_for_each(c, &stack, slink) - if (VISIBLEON(c, c->mon) && wlr_box_contains_point(&c->geom, x, y)) + if (c->isfullscreen && VISIBLEON(c, c->mon) + && wlr_box_contains_point(&c->geom, x, y)) + return c; + wl_list_for_each(c, &stack, slink) + if (c->isfloating && VISIBLEON(c, c->mon) + && wlr_box_contains_point(&c->geom, x, y)) + return c; + wl_list_for_each(c, &stack, slink) + if (!c->isfloating && VISIBLEON(c, c->mon) + && wlr_box_contains_point(&c->geom, x, y)) return c; return NULL; }