From 0c8cc199dc5a56af2b74e5aef77255aa6c105fec Mon Sep 17 00:00:00 2001 From: sewn Date: Sun, 14 Apr 2024 07:46:05 +0300 Subject: [PATCH] bar: update 2024-04-14 --- bar/bar.patch | 440 +++++++++++++++++++++++++++++++------------------- 1 file changed, 274 insertions(+), 166 deletions(-) diff --git a/bar/bar.patch b/bar/bar.patch index 07be2d8..53c579d 100644 --- a/bar/bar.patch +++ b/bar/bar.patch @@ -1,16 +1,81 @@ -From 6659e96800bd5697462c769cbe039840fcdcc5d1 Mon Sep 17 00:00:00 2001 +From ba2a5fe24ff9856682bee1b93695d75d70d333e5 Mon Sep 17 00:00:00 2001 From: sewn -Date: Tue, 9 Apr 2024 11:06:24 +0300 +Date: Sun, 14 Apr 2024 07:45:57 +0300 Subject: [PATCH] Implement dwm bar clone --- - Makefile | 2 +- - config.def.h | 29 +++- - dwl.c | 449 ++++++++++++++++++++++++++++++++++++++++++--------- - utf8.h | 55 +++++++ - 4 files changed, 453 insertions(+), 82 deletions(-) + LICENSE.drwl | 22 +++ + LICENSE.utf8dec | 25 ++++ + Makefile | 2 +- + config.def.h | 29 +++- + drwl.h | 136 ++++++++++++++++++ + dwl.c | 364 ++++++++++++++++++++++++++++++++++++++---------- + utf8.h | 55 ++++++++ + 7 files changed, 552 insertions(+), 81 deletions(-) + create mode 100644 LICENSE.drwl + create mode 100644 LICENSE.utf8dec + create mode 100644 drwl.h create mode 100644 utf8.h +diff --git a/LICENSE.drwl b/LICENSE.drwl +new file mode 100644 +index 0000000..35f0ad3 +--- /dev/null ++++ b/LICENSE.drwl +@@ -0,0 +1,22 @@ ++Copyright (C) 2023-2024 sewn ++ ++See also the file LICENSE.utf8dec. ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice shall be ++included in all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +diff --git a/LICENSE.utf8dec b/LICENSE.utf8dec +new file mode 100644 +index 0000000..a11589b +--- /dev/null ++++ b/LICENSE.utf8dec +@@ -0,0 +1,25 @@ ++drwl uses the flexible and economical UTF-8 Decoder made by Bjoern Hoehrmann, ++which is used under the following license: ++ ++--- ++ ++Copyright (c) 2008-2009 Bjoern Hoehrmann ++See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy ++of this software and associated documentation files (the "Software"), to deal ++in the Software without restriction, including without limitation the rights ++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++copies of the Software, and to permit persons to whom the Software is ++furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in ++all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++SOFTWARE. diff --git a/Makefile b/Makefile index a67fdd3..5578ae2 100644 --- a/Makefile @@ -83,8 +148,150 @@ index 8847e58..0be3ad0 100644 + { ClkTagBar, MODKEY, BTN_LEFT, tag, {0} }, + { ClkTagBar, MODKEY, BTN_RIGHT, toggletag, {0} }, }; +diff --git a/drwl.h b/drwl.h +new file mode 100644 +index 0000000..3aa3d9d +--- /dev/null ++++ b/drwl.h +@@ -0,0 +1,136 @@ ++/* ++ * drwl - https://codeberg.org/sewn/drwl ++ * See LICENSE file for copyright and license details. ++ */ ++#include ++#include ++ ++#define UTF8_ACCEPT 0 ++#define UTF8_REJECT 1 ++ ++static const uint8_t utf8d[] = { ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f ++ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf ++ 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df ++ 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef ++ 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff ++ 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 ++ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 ++ 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 ++ 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 ++ 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 ++}; ++ ++static inline uint32_t ++utf8decode(uint32_t *state, uint32_t *codep, uint8_t byte) ++{ ++ uint32_t type = utf8d[byte]; ++ ++ *codep = (*state != UTF8_ACCEPT) ? ++ (byte & 0x3fu) | (*codep << 6) : ++ (0xff >> type) & (byte); ++ ++ *state = utf8d[256 + *state*16 + type]; ++ return *state; ++} ++ ++static void ++drwl_rect(pixman_image_t *pix, ++ int16_t x, int16_t y, uint16_t w, uint16_t h, ++ int filled, pixman_color_t *bg) ++{ ++ if (filled) ++ pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, bg, 1, ++ &(pixman_rectangle16_t){x, y, w, h}); ++ else ++ pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, bg, 4, ++ (pixman_rectangle16_t[4]){ ++ { x, y, w, 1 }, ++ { x, y + h - 1, w, 1 }, ++ { x, y, 1, h }, ++ { x + w - 1, y, 1, h }}); ++} ++ ++static int ++drwl_text(pixman_image_t *pix, struct fcft_font *font, ++ int x, int y, unsigned int w, unsigned int h, ++ unsigned int lpad, const char *text, ++ pixman_color_t *fg, pixman_color_t *bg) ++{ ++ int ty; ++ int render = x || y || w || h; ++ long x_kern; ++ uint32_t cp, last_cp = 0; ++ uint32_t state = UTF8_ACCEPT; ++ pixman_image_t *fg_pix = NULL; ++ const struct fcft_glyph *glyph, *eg; ++ ++ if ((render && (!fg || !w)) || !text || !font) ++ return 0; ++ ++ if (!render) { ++ w = -1; ++ } else { ++ fg_pix = pixman_image_create_solid_fill(fg); ++ ++ if (bg) ++ drwl_rect(pix, x, y, w, h, 1, bg); ++ ++ x += lpad; ++ w -= lpad; ++ } ++ ++ // U+2026 == … ++ eg = fcft_rasterize_char_utf32(font, 0x2026, FCFT_SUBPIXEL_NONE); ++ ++ for (const char *p = text; *p; p++) { ++ if (utf8decode(&state, &cp, *p)) ++ continue; ++ ++ glyph = fcft_rasterize_char_utf32(font, cp, FCFT_SUBPIXEL_NONE); ++ if (!glyph) ++ continue; ++ ++ x_kern = 0; ++ if (last_cp) ++ fcft_kerning(font, last_cp, cp, &x_kern, NULL); ++ last_cp = cp; ++ ++ ty = y + (h - font->height) / 2 + font->ascent; ++ ++ /* only ellipsis if we haven't reached the end */ ++ if (x_kern + glyph->advance.x + eg->advance.x > w && *(p + 1) != '\0') { ++ w -= eg->advance.x; ++ pixman_image_composite32( ++ PIXMAN_OP_OVER, fg_pix, eg->pix, pix, 0, 0, 0, 0, ++ x + eg->x, ty - eg->y, eg->width, eg->height); ++ } ++ ++ if ((x_kern + glyph->advance.x) > w) ++ break; ++ ++ x += x_kern; ++ ++ if (render && pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) ++ // pre-rendered glyphs (eg. emoji) ++ pixman_image_composite32( ++ PIXMAN_OP_OVER, glyph->pix, NULL, pix, 0, 0, 0, 0, ++ x + glyph->x, ty - glyph->y, glyph->width, glyph->height); ++ else if (render) ++ pixman_image_composite32( ++ PIXMAN_OP_OVER, fg_pix, glyph->pix, pix, 0, 0, 0, 0, ++ x + glyph->x, ty - glyph->y, glyph->width, glyph->height); ++ ++ x += glyph->advance.x; ++ w -= glyph->advance.x; ++ } ++ ++ if (render) ++ pixman_image_unref(fg_pix); ++ ++ return x + (render ? w : 0); ++} diff --git a/dwl.c b/dwl.c -index bf763df..20c8801 100644 +index bf763df..54273ae 100644 --- a/dwl.c +++ b/dwl.c @@ -4,6 +4,7 @@ @@ -111,7 +318,7 @@ index bf763df..20c8801 100644 #endif #include "util.h" -+#include "utf8.h" ++#include "drwl.h" /* macros */ #define MAX(A, B) ((A) > (B) ? (A) : (B)) @@ -123,7 +330,7 @@ index bf763df..20c8801 100644 +#define TAGMASK ((1u << LENGTH(tags)) - 1) #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) #define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0) -+#define TEXTW(text) (draw_text(NULL, 0, 0, 0, 0, 0, text, NULL) + lrpad) ++#define TEXTW(text) (drwl_text(NULL, font, 0, 0, 0, 0, 0, text, NULL, NULL) + lrpad) /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ @@ -185,18 +392,16 @@ index bf763df..20c8801 100644 static void buttonpress(struct wl_listener *listener, void *data); static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); -@@ -278,6 +299,10 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data); +@@ -278,6 +299,8 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); +static void drawbar(Monitor *m); +static void drawbars(void); -+static uint32_t draw_text(pixman_image_t *pix, int x, int y, unsigned int w, unsigned int h, -+ unsigned int lpad, const char *text, pixman_color_t *clr); static void focusclient(Client *c, int lift); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); -@@ -306,7 +331,6 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int +@@ -306,7 +329,6 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); @@ -204,7 +409,7 @@ index bf763df..20c8801 100644 static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); -@@ -327,9 +351,11 @@ static void setsel(struct wl_listener *listener, void *data); +@@ -327,9 +349,11 @@ static void setsel(struct wl_listener *listener, void *data); static void setup(void); static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); @@ -216,7 +421,7 @@ index bf763df..20c8801 100644 static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); static void toggletag(const Arg *arg); -@@ -338,6 +364,7 @@ static void unlocksession(struct wl_listener *listener, void *data); +@@ -338,6 +362,7 @@ static void unlocksession(struct wl_listener *listener, void *data); static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); static void unmapnotify(struct wl_listener *listener, void *data); static void updatemons(struct wl_listener *listener, void *data); @@ -224,7 +429,7 @@ index bf763df..20c8801 100644 static void updatetitle(struct wl_listener *listener, void *data); static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg); -@@ -405,6 +432,18 @@ static struct wlr_box sgeom; +@@ -405,6 +430,18 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; @@ -243,7 +448,7 @@ index bf763df..20c8801 100644 #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data); -@@ -531,6 +570,11 @@ arrangelayers(Monitor *m) +@@ -531,6 +568,11 @@ arrangelayers(Monitor *m) if (!m->wlr_output->enabled) return; @@ -255,7 +460,7 @@ index bf763df..20c8801 100644 /* Arrange exclusive surfaces from top->bottom */ for (i = 3; i >= 0; i--) arrangelayer(m, &m->layers[i], &usable_area, 1); -@@ -573,17 +617,77 @@ axisnotify(struct wl_listener *listener, void *data) +@@ -573,17 +615,77 @@ axisnotify(struct wl_listener *listener, void *data) event->delta_discrete, event->source); } @@ -333,7 +538,7 @@ index bf763df..20c8801 100644 switch (event->state) { case WLR_BUTTON_PRESSED: cursor_mode = CurPressed; -@@ -592,16 +696,14 @@ buttonpress(struct wl_listener *listener, void *data) +@@ -592,16 +694,14 @@ buttonpress(struct wl_listener *listener, void *data) break; /* Change focus if the button was _pressed_ over a client */ @@ -353,7 +558,7 @@ index bf763df..20c8801 100644 return; } } -@@ -675,6 +777,9 @@ cleanup(void) +@@ -675,6 +775,9 @@ cleanup(void) /* Destroy after the wayland display (when the monitors are already destroyed) to avoid destroying them with an invalid scene output. */ wlr_scene_node_destroy(&scene->tree.node); @@ -363,7 +568,7 @@ index bf763df..20c8801 100644 } void -@@ -726,7 +831,7 @@ closemon(Monitor *m) +@@ -726,7 +829,7 @@ closemon(Monitor *m) setmon(c, selmon, c->tags); } focusclient(focustop(selmon), 1); @@ -372,7 +577,7 @@ index bf763df..20c8801 100644 } void -@@ -912,8 +1017,13 @@ createmon(struct wl_listener *listener, void *data) +@@ -912,8 +1015,13 @@ createmon(struct wl_listener *listener, void *data) wlr_output_commit_state(wlr_output, &state); wlr_output_state_finish(&state); @@ -387,92 +592,10 @@ index bf763df..20c8801 100644 /* The xdg-protocol specifies: * -@@ -1233,6 +1343,179 @@ dirtomon(enum wlr_direction dir) +@@ -1233,6 +1341,99 @@ dirtomon(enum wlr_direction dir) return selmon; } -+static uint32_t -+draw_text(pixman_image_t *pix, int x, int y, unsigned int w, unsigned int h, -+ unsigned int lpad, const char *text, pixman_color_t *clr) -+{ -+ int ty; -+ int render = x || y || w || h; -+ long x_kern; -+ uint32_t cp, last_cp = 0; -+ uint32_t state = UTF8_ACCEPT; -+ pixman_image_t *clr_pix = NULL; -+ const struct fcft_glyph *glyph; -+ -+ if ((render && (!clr || !w)) || !text || !font) -+ return 0; -+ -+ if (!render) { -+ w = -1; -+ } else { -+ clr_pix = pixman_image_create_solid_fill(clr); -+ -+ x += lpad; -+ w -= lpad; -+ } -+ -+ for (const char *p = text; *p; p++) { -+ if (utf8decode(&state, &cp, *p)) -+ continue; -+ -+ glyph = fcft_rasterize_char_utf32(font, cp, FCFT_SUBPIXEL_NONE); -+ if (!glyph) -+ continue; -+ -+ x_kern = 0; -+ if (last_cp) -+ fcft_kerning(font, last_cp, cp, &x_kern, NULL); -+ last_cp = cp; -+ -+ if ((x_kern + glyph->advance.x) > w) -+ break; -+ -+ x += x_kern; -+ -+ if (render) { -+ ty = y + (h - font->height) / 2 + font->ascent; -+ pixman_image_composite32( -+ PIXMAN_OP_OVER, clr_pix, glyph->pix, pix, 0, 0, 0, 0, -+ x + glyph->x, ty - glyph->y, glyph->width, glyph->height); -+ } -+ -+ x += glyph->advance.x; -+ w -= glyph->advance.x; -+ } -+ -+ if (render) -+ pixman_image_unref(clr_pix); -+ -+ return x + (render ? w : 0); -+} -+ -+static void -+draw_rect(pixman_image_t *pix, -+ int16_t x, int16_t y, uint16_t w, uint16_t h, -+ int filled, pixman_color_t *bg) -+{ -+ /* -+ * originally, i was using PIXMAN_OP_CLEAR and drawing -+ * a clear rectangle, however that was transparent beyond -+ * the bar, so a manually drawn bordered rectangle, made -+ * out of lines (thin recthangles) had to be used. -+ */ -+ if (filled) -+ pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, bg, 1, -+ &(pixman_rectangle16_t){x, y, w, h}); -+ else -+ pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, bg, 4, -+ (pixman_rectangle16_t[4]){ -+ { x, y, w, 1 }, -+ { x, y + h - 1, w, 1 }, -+ { x, y, 1, h }, -+ { x + w - 1, y, 1, h }}); -+} -+ +void +drawbar(Monitor *mon) +{ @@ -482,7 +605,6 @@ index bf763df..20c8801 100644 + int boxw = font->height / 6 + 2; + uint32_t i, occ = 0, urg = 0; + uint32_t stride, size; -+ const char *title; + pixman_image_t *pix; + Client *c; + Buffer *buf; @@ -493,9 +615,9 @@ index bf763df..20c8801 100644 + stride = mon->b.width * 4; + size = stride * mon->b.height; + -+ buf = ecalloc(1, sizeof(Buffer) + size); ++ buf = ecalloc(1, sizeof(Buffer) + size); + buf->stride = stride; -+ wlr_buffer_init(&buf->base, &buffer_impl, mon->b.width, mon->b.height); ++ wlr_buffer_init(&buf->base, &buffer_impl, mon->b.width, mon->b.height); + + pix = pixman_image_create_bits( + PIXMAN_a8r8g8b8, mon->b.width, mon->b.height, buf->data, stride); @@ -504,9 +626,9 @@ index bf763df..20c8801 100644 + if (mon == selmon) { + if (stext[0] == '\0') + strncpy(stext, "dwl-"VERSION, sizeof(stext)); -+ draw_rect(pix, 0, 0, mon->b.width, mon->b.height, 1, &normbarbg); -+ tw = TEXTW(stext) - lrpad + 2; -+ draw_text(pix, mon->b.width - tw, 0, tw, mon->b.height, 0, stext, &normbarfg); ++ tw = TEXTW(stext) - lrpad; ++ drwl_text(pix, font, mon->b.width - tw, 0, tw, mon->b.height, 0, ++ stext, &normbarfg, &normbarbg); + } + + wl_list_for_each(c, &clients, link) { @@ -522,30 +644,33 @@ index bf763df..20c8801 100644 + w = TEXTW(tags[i]); + sel = mon->tagset[mon->seltags] & 1 << i; + -+ draw_rect(pix, x, 0, w, mon->b.height, 1, ++ drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2, tags[i], ++ urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg), + urg & 1 << i ? &selbarfg : (sel ? &selbarbg : &normbarbg)); -+ draw_text(pix, x, 0, w, mon->b.height, lrpad / 2, tags[i], -+ urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg)); + + if (occ & 1 << i) -+ draw_rect(pix, x + boxs, boxs, boxw, boxw, -+ sel, urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg)); ++ drwl_rect(pix, x + boxs, boxs, boxw, boxw, sel, ++ urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg)); + + x += w; + } ++ + w = TEXTW(mon->ltsymbol); -+ draw_rect(pix, x, 0, w, mon->b.height, 1, &normbarbg); -+ x = draw_text(pix, x, 0, w, mon->b.height, lrpad / 2, mon->ltsymbol, &normbarfg); ++ x = drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2, ++ mon->ltsymbol, &normbarfg, &normbarbg); + + if ((w = mon->b.width - tw - x) > mon->b.height) { -+ title = c ? client_get_title(c) : NULL; -+ draw_rect(pix, x, 0, w, mon->b.height, 1, -+ (mon == selmon && title) ? &selbarbg : &normbarbg); -+ draw_text(pix, x, 0, w, mon->b.height, lrpad / 2, title, -+ mon == selmon ? &selbarfg : &normbarfg); -+ if (c && c->isfloating) -+ draw_rect(pix, x + boxs, boxs, boxw, boxw, 0, -+ mon == selmon ? &selbarfg : &normbarfg); ++ if (c != NULL) { ++ drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2, ++ c ? client_get_title(c) : NULL, ++ mon == selmon ? &selbarfg : &normbarfg, ++ (mon == selmon && c) ? &selbarbg : &normbarbg); ++ if (c && c->isfloating) ++ drwl_rect(pix, x + boxs, boxs, boxw, boxw, 0, ++ mon == selmon ? &selbarfg : &normbarfg); ++ } else { ++ drwl_rect(pix, x, 0, w, mon->b.height, 1, &normbarbg); ++ } + } + + pixman_image_unref(pix); @@ -567,7 +692,7 @@ index bf763df..20c8801 100644 void focusclient(Client *c, int lift) { -@@ -1290,7 +1573,7 @@ focusclient(Client *c, int lift) +@@ -1290,7 +1491,7 @@ focusclient(Client *c, int lift) client_activate_surface(old, 0); } } @@ -576,7 +701,7 @@ index bf763df..20c8801 100644 if (!c) { /* With no client, all we have left is to clear focus */ -@@ -1618,7 +1901,7 @@ mapnotify(struct wl_listener *listener, void *data) +@@ -1618,7 +1819,7 @@ mapnotify(struct wl_listener *listener, void *data) } else { applyrules(c); } @@ -585,7 +710,7 @@ index bf763df..20c8801 100644 unset_fullscreen: m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); -@@ -1904,46 +2187,6 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, +@@ -1904,46 +2105,6 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_motion(seat, time, sx, sy); } @@ -632,7 +757,7 @@ index bf763df..20c8801 100644 void quit(const Arg *arg) -@@ -2074,23 +2317,14 @@ run(char *startup_cmd) +@@ -2074,23 +2235,14 @@ run(char *startup_cmd) /* Now that the socket exists and the backend is started, run the startup command */ if (startup_cmd) { @@ -657,7 +782,7 @@ index bf763df..20c8801 100644 /* At this point the outputs are initialized, choose initial selmon based on * cursor position, and set default cursor image */ -@@ -2155,7 +2389,7 @@ setfloating(Client *c, int floating) +@@ -2155,7 +2307,7 @@ setfloating(Client *c, int floating) (p && p->isfullscreen) ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); arrange(c->mon); @@ -666,7 +791,7 @@ index bf763df..20c8801 100644 } void -@@ -2178,7 +2412,7 @@ setfullscreen(Client *c, int fullscreen) +@@ -2178,7 +2330,7 @@ setfullscreen(Client *c, int fullscreen) resize(c, c->prev, 0); } arrange(c->mon); @@ -675,7 +800,7 @@ index bf763df..20c8801 100644 } void -@@ -2203,7 +2437,7 @@ setlayout(const Arg *arg) +@@ -2203,7 +2355,7 @@ setlayout(const Arg *arg) selmon->lt[selmon->sellt] = (Layout *)arg->v; strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); arrange(selmon); @@ -684,16 +809,7 @@ index bf763df..20c8801 100644 } /* arg > 1.0 will set mfact absolutely */ -@@ -2272,7 +2506,7 @@ setup(void) - struct xkb_context *context; - struct xkb_keymap *keymap; - -- int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; -+ int i, sig[] = {SIGCHLD, SIGINT, SIGTERM}; - struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; - sigemptyset(&sa.sa_mask); - -@@ -2506,6 +2740,17 @@ setup(void) +@@ -2506,6 +2658,17 @@ setup(void) wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); @@ -711,7 +827,7 @@ index bf763df..20c8801 100644 /* Make sure XWayland clients don't connect to the parent X server, * e.g when running in the x11 backend or the wayland backend and the * compositor has Xwayland support */ -@@ -2548,6 +2793,30 @@ startdrag(struct wl_listener *listener, void *data) +@@ -2548,6 +2711,30 @@ startdrag(struct wl_listener *listener, void *data) LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); } @@ -742,7 +858,7 @@ index bf763df..20c8801 100644 void tag(const Arg *arg) { -@@ -2558,7 +2827,7 @@ tag(const Arg *arg) +@@ -2558,7 +2745,7 @@ tag(const Arg *arg) sel->tags = arg->ui & TAGMASK; focusclient(focustop(selmon), 1); arrange(selmon); @@ -751,7 +867,7 @@ index bf763df..20c8801 100644 } void -@@ -2603,6 +2872,14 @@ tile(Monitor *m) +@@ -2603,6 +2790,14 @@ tile(Monitor *m) } } @@ -766,7 +882,7 @@ index bf763df..20c8801 100644 void togglefloating(const Arg *arg) { -@@ -2631,7 +2908,7 @@ toggletag(const Arg *arg) +@@ -2631,7 +2826,7 @@ toggletag(const Arg *arg) sel->tags = newtags; focusclient(focustop(selmon), 1); arrange(selmon); @@ -775,7 +891,7 @@ index bf763df..20c8801 100644 } void -@@ -2644,7 +2921,7 @@ toggleview(const Arg *arg) +@@ -2644,7 +2839,7 @@ toggleview(const Arg *arg) selmon->tagset[selmon->seltags] = newtagset; focusclient(focustop(selmon), 1); arrange(selmon); @@ -784,7 +900,7 @@ index bf763df..20c8801 100644 } void -@@ -2692,7 +2969,7 @@ unmapnotify(struct wl_listener *listener, void *data) +@@ -2692,7 +2887,7 @@ unmapnotify(struct wl_listener *listener, void *data) } wlr_scene_node_destroy(&c->scene->node); @@ -793,15 +909,7 @@ index bf763df..20c8801 100644 motionnotify(0, NULL, 0, 0, 0, 0); } -@@ -2728,6 +3005,7 @@ updatemons(struct wl_listener *listener, void *data) - if (m->wlr_output->enabled - && !wlr_output_layout_get(output_layout, m->wlr_output)) - wlr_output_layout_add_auto(output_layout, m->wlr_output); -+ - } - - /* Now that we update the output layout we can get its box */ -@@ -2788,6 +3066,12 @@ updatemons(struct wl_listener *listener, void *data) +@@ -2788,6 +2983,12 @@ updatemons(struct wl_listener *listener, void *data) } } @@ -814,7 +922,7 @@ index bf763df..20c8801 100644 /* FIXME: figure out why the cursor image is at 0,0 after turning all * the monitors on. * Move the cursor image where it used to be. It does not generate a -@@ -2798,12 +3082,21 @@ updatemons(struct wl_listener *listener, void *data) +@@ -2798,12 +2999,21 @@ updatemons(struct wl_listener *listener, void *data) wlr_output_manager_v1_set_configuration(output_mgr, config); } @@ -822,7 +930,7 @@ index bf763df..20c8801 100644 +updatebardims(Monitor *m) +{ + int rw, rh; -+ wlr_output_transformed_resolution(m->wlr_output, &rw, &rh); ++ wlr_output_effective_resolution(m->wlr_output, &rw, &rh); + m->b.width = rw; + m->b.height = bh; +} @@ -837,7 +945,7 @@ index bf763df..20c8801 100644 } void -@@ -2816,7 +3109,7 @@ urgent(struct wl_listener *listener, void *data) +@@ -2816,7 +3026,7 @@ urgent(struct wl_listener *listener, void *data) return; c->isurgent = 1; @@ -846,7 +954,7 @@ index bf763df..20c8801 100644 if (client_surface(c)->mapped) client_set_border_color(c, urgentcolor); -@@ -2832,7 +3125,7 @@ view(const Arg *arg) +@@ -2832,7 +3042,7 @@ view(const Arg *arg) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; focusclient(focustop(selmon), 1); arrange(selmon); @@ -855,7 +963,7 @@ index bf763df..20c8801 100644 } void -@@ -2871,6 +3164,7 @@ xytonode(double x, double y, struct wlr_surface **psurface, +@@ -2871,6 +3081,7 @@ xytonode(double x, double y, struct wlr_surface **psurface, { struct wlr_scene_node *node, *pnode; struct wlr_surface *surface = NULL; @@ -863,7 +971,7 @@ index bf763df..20c8801 100644 Client *c = NULL; LayerSurface *l = NULL; int layer; -@@ -2879,9 +3173,12 @@ xytonode(double x, double y, struct wlr_surface **psurface, +@@ -2879,9 +3090,12 @@ xytonode(double x, double y, struct wlr_surface **psurface, if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) continue; @@ -879,7 +987,7 @@ index bf763df..20c8801 100644 /* Walk the tree to find a node that knows the client */ for (pnode = node; pnode && !c; pnode = &pnode->parent->node) c = pnode->data; -@@ -3020,7 +3317,7 @@ sethints(struct wl_listener *listener, void *data) +@@ -3020,7 +3234,7 @@ sethints(struct wl_listener *listener, void *data) return; c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);