From f3c4f723147b40fb1284083f3d7dac988c52d162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 1 Jan 2024 00:51:01 -0600 Subject: [PATCH 01/13] fix posible NULL-dereference in wl_surface.commit handler --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 10d5a5b..4d19357 100644 --- a/dwl.c +++ b/dwl.c @@ -731,7 +731,7 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - if (client_surface(c)->mapped) + if (client_surface(c)->mapped && c->mon) resize(c, c->geom, (c->isfloating && !c->isfullscreen)); /* mark a pending resize as completed */ From 25e34e4d0c97165eef627b70b916967852ec1f5e Mon Sep 17 00:00:00 2001 From: Ben Jargowsky Date: Sat, 6 Jan 2024 17:29:39 -0800 Subject: [PATCH 02/13] Destroy fullscreen node after moving clients off mon --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 4d19357..632dabf 100644 --- a/dwl.c +++ b/dwl.c @@ -672,9 +672,9 @@ 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); + wlr_scene_node_destroy(&m->fullscreen_bg->node); free(m); } From 6340989c8e1a178637996d293481d9366205cfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 10 Jan 2024 00:10:39 -0600 Subject: [PATCH 03/13] add acknowledgment to djpohly --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1aa5195..3b5dd0f 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ Many thanks to suckless.org and the dwm developers and community for the inspiration, and to the various contributors to the project, including: - Alexander Courtis for the XWayland implementation +- Devin J. Pohly for creating and nurturing the fledgling project - Guido Cella for the layer-shell protocol implementation, patch maintenance, and for helping to keep the project running - Stivvo for output management and fullscreen support, and patch maintenance From f5b046ce9e907a6211b9f7f5061b4d5ecac43294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 11 Oct 2023 23:26:59 -0600 Subject: [PATCH 04/13] prefer functionality over philosophy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b5dd0f..c9652d1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Or on our [Discord server]. dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is intended to fill the same space in the Wayland world that dwm does in X11, -primarily in terms of philosophy, and secondarily in terms of functionality. +primarily in terms of functionality, and secondarily in terms of philosophy. Like dwm, dwl is: - Easy to understand, hack on, and extend with patches From a73afc66abdffe2668ea27130f447ae05efb04f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 11 Oct 2023 23:40:16 -0600 Subject: [PATCH 05/13] drop SLOC limit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c9652d1..60b4845 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Like dwm, dwl is: - Easy to understand, hack on, and extend with patches - One C source file (or a very small number) configurable via `config.h` -- Limited to 2200 SLOC to promote hackability - Tied to as few external dependencies as possible dwl is not meant to provide every feature under the sun. Instead, like dwm, it @@ -34,6 +33,10 @@ given the base on which it is built. Implemented default features are: - Layer shell popups (used by Waybar) - Damage tracking provided by scenegraph API +Given the Wayland architecture, dwl has to implement features from dwm **and** +the xorg-server. Because of this, it is impossible to maintain the original project goal of 2000 +SLOC and have a reasonably complete compositor with features comparable to dwm. + Features under consideration (possibly as patches) are: - Protocols made trivial by wlroots From fd263041a00deb648c2e27daac942e86621b2855 Mon Sep 17 00:00:00 2001 From: choc Date: Wed, 10 Jan 2024 22:27:04 +0800 Subject: [PATCH 06/13] check if monitor is null before setting gamma fixes segfault on monitor disconnect when using wlsunset --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 632dabf..a20c607 100644 --- a/dwl.c +++ b/dwl.c @@ -2076,6 +2076,8 @@ setgamma(struct wl_listener *listener, void *data) { struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; Monitor *m = event->output->data; + if (!m) + return; m->gamma_lut_changed = 1; wlr_output_schedule_frame(m->wlr_output); } From ec557f253b33f156720ae8950889519ed6425685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 12 Jan 2024 22:34:09 -0600 Subject: [PATCH 07/13] clarify the code will be kept as small as possible --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 60b4845..6af019e 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,10 @@ given the base on which it is built. Implemented default features are: - Damage tracking provided by scenegraph API Given the Wayland architecture, dwl has to implement features from dwm **and** -the xorg-server. Because of this, it is impossible to maintain the original project goal of 2000 -SLOC and have a reasonably complete compositor with features comparable to dwm. +the xorg-server. Because of this, it is impossible to maintain the original +project goal of 2000 SLOC and have a reasonably complete compositor with +features comparable to dwm. However, this does not mean that the code will grow +indiscriminately. We will try to keep the code as small as possible. Features under consideration (possibly as patches) are: From 337d6ba3fbec3379162a1a287028fce363488197 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sun, 14 Jan 2024 09:01:49 -0600 Subject: [PATCH 08/13] acknowledgements refactoring --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6af019e..3d22cf3 100644 --- a/README.md +++ b/README.md @@ -157,8 +157,8 @@ possible. Many thanks to suckless.org and the dwm developers and community for the inspiration, and to the various contributors to the project, including: +- **Devin J. Pohly for creating and nurturing the fledgling project** - Alexander Courtis for the XWayland implementation -- Devin J. Pohly for creating and nurturing the fledgling project - Guido Cella for the layer-shell protocol implementation, patch maintenance, and for helping to keep the project running - Stivvo for output management and fullscreen support, and patch maintenance From 0151bd48ddef6c7679b1fd6fcce9db6340ab80d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 11 Jan 2023 12:13:53 -0600 Subject: [PATCH 09/13] turn on -Wsign-compare --- Makefile | 2 +- client.h | 6 +++--- dwl.c | 16 +++++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index f0ff805..e0a601d 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ include config.mk # flags for compiling DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND) -DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wno-sign-compare -Wshadow -Wunused-macros\ +DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wshadow -Wunused-macros\ -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types # CFLAGS / LDFLAGS diff --git a/client.h b/client.h index 1dae434..0753da8 100644 --- a/client.h +++ b/client.h @@ -339,10 +339,10 @@ client_set_size(Client *c, uint32_t width, uint32_t height) return 0; } #endif - if (width == c->surface.xdg->toplevel->current.width - && height ==c->surface.xdg->toplevel->current.height) + if ((int32_t)width == c->surface.xdg->toplevel->current.width + && (int32_t)height == c->surface.xdg->toplevel->current.height) return 0; - return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height); + return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height); } static inline void diff --git a/dwl.c b/dwl.c index a20c607..77583ee 100644 --- a/dwl.c +++ b/dwl.c @@ -415,9 +415,9 @@ applybounds(Client *c, struct wlr_box *bbox) c->geom.x = bbox->x + bbox->width - c->geom.width; if (c->geom.y >= bbox->y + bbox->height) c->geom.y = bbox->y + bbox->height - c->geom.height; - if (c->geom.x + c->geom.width + 2 * c->bw <= bbox->x) + if (c->geom.x + c->geom.width + 2 * (int)c->bw <= bbox->x) c->geom.x = bbox->x; - if (c->geom.y + c->geom.height + 2 * c->bw <= bbox->y) + if (c->geom.y + c->geom.height + 2 * (int)c->bw <= bbox->y) c->geom.y = bbox->y; } @@ -426,7 +426,8 @@ applyrules(Client *c) { /* rule matching */ const char *appid, *title; - uint32_t i, newtags = 0; + uint32_t newtags = 0; + int i; const Rule *r; Monitor *mon = selmon, *m; @@ -520,7 +521,7 @@ arrangelayers(Monitor *m) arrangelayer(m, &m->layers[i], &usable_area, 0); /* Find topmost keyboard interactive layer, if such a layer exists */ - for (i = 0; i < LENGTH(layers_above_shell); i++) { + for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped) continue; @@ -657,7 +658,7 @@ cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); LayerSurface *l, *tmp; - int i; + size_t i; /* m->layers[i] are intentionally not unlinked */ for (i = 0; i < LENGTH(m->layers); i++) { @@ -2166,7 +2167,7 @@ setup(void) struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; sigemptyset(&sa.sa_mask); - for (i = 0; i < LENGTH(sig); i++) + for (i = 0; i < (int)LENGTH(sig); i++) sigaction(sig[i], &sa, NULL); wlr_log_init(log_level, NULL); @@ -2454,7 +2455,8 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int i, n = 0, mw, my, ty; + unsigned int mw, my, ty; + int i, n = 0; Client *c; wl_list_for_each(c, &clients, link) From a1f3e25c350db7907b584aba30bf2567ca10610e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 1 Feb 2023 14:02:29 -0600 Subject: [PATCH 10/13] turn on -Wfloat-conversion --- Makefile | 2 +- config.def.h | 12 ++++++------ dwl.c | 19 ++++++++++--------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index e0a601d..0822ddc 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ include config.mk # flags for compiling DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND) DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wshadow -Wunused-macros\ - -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types + -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Wfloat-conversion # CFLAGS / LDFLAGS PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) diff --git a/config.def.h b/config.def.h index a8ed61d..9009517 100644 --- a/config.def.h +++ b/config.def.h @@ -12,7 +12,7 @@ static const float bordercolor[] = COLOR(0x444444ff); static const float focuscolor[] = COLOR(0x005577ff); static const float urgentcolor[] = COLOR(0xff0000ff); /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ -static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */ +static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ /* tagging - TAGCOUNT must be no greater than 31 */ #define TAGCOUNT (9) @@ -39,12 +39,12 @@ static const Layout layouts[] = { /* monitors */ /* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */ static const MonitorRule monrules[] = { - /* name mfact nmaster scale layout rotate/reflect x y */ + /* name mfact nmaster scale layout rotate/reflect x y */ /* example of a HiDPI laptop monitor: - { "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, + { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, */ /* defaults */ - { NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, + { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, }; /* keyboard */ @@ -126,8 +126,8 @@ static const Key keys[] = { { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, - { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} }, - { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} }, + { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} }, + { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} }, { MODKEY, XKB_KEY_Return, zoom, {0} }, { MODKEY, XKB_KEY_Tab, view, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, diff --git a/dwl.c b/dwl.c index 77583ee..449913d 100644 --- a/dwl.c +++ b/dwl.c @@ -65,6 +65,7 @@ /* macros */ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define ROUND(X) ((int)((X < 0) ? (X - 0.5) : (X + 0.5))) #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) #define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -196,7 +197,7 @@ struct Monitor { unsigned int seltags; unsigned int sellt; uint32_t tagset[2]; - double mfact; + float mfact; int gamma_lut_changed; int nmaster; char ltsymbol[16]; @@ -1621,17 +1622,17 @@ motionnotify(uint32_t time) } /* Update drag icon's position */ - wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y); + wlr_scene_node_set_position(&drag_icon->node, ROUND(cursor->x), ROUND(cursor->y)); /* If we are currently grabbing the mouse, handle and return */ if (cursor_mode == CurMove) { /* Move the grabbed client to the new position. */ - resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, + resize(grabc, (struct wlr_box){.x = ROUND(cursor->x) - grabcx, .y = ROUND(cursor->y) - grabcy, .width = grabc->geom.width, .height = grabc->geom.height}, 1); return; } else if (cursor_mode == CurResize) { resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, - .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1); + .width = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1); return; } @@ -1683,8 +1684,8 @@ moveresize(const Arg *arg) setfloating(grabc, 1); switch (cursor_mode = arg->ui) { case CurMove: - grabcx = cursor->x - grabc->geom.x; - grabcy = cursor->y - grabc->geom.y; + grabcx = ROUND(cursor->x) - grabc->geom.x; + grabcy = ROUND(cursor->y) - grabc->geom.y; wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); break; case CurResize: @@ -2105,7 +2106,7 @@ setmfact(const Arg *arg) if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; if (f < 0.1 || f > 0.9) return; selmon->mfact = f; @@ -2277,7 +2278,7 @@ setup(void) wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener); LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr); locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, - (float [4]){0.1, 0.1, 0.1, 1.0}); + (float [4]){0.1f, 0.1f, 0.1f, 1.0f}); wlr_scene_node_set_enabled(&locked_bg->node, 0); /* Use decoration protocols to negotiate server-side decorations */ @@ -2466,7 +2467,7 @@ tile(Monitor *m) return; if (n > m->nmaster) - mw = m->nmaster ? m->w.width * m->mfact : 0; + mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0; else mw = m->w.width; i = my = ty = 0; From 417e37f98877975ad19b13c9c09f0837684668e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 15 Jan 2024 02:15:54 +0000 Subject: [PATCH 11/13] request description before logs --- .gitea/issue_template/bug_report.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitea/issue_template/bug_report.yml b/.gitea/issue_template/bug_report.yml index 56f4a3e..77ce108 100644 --- a/.gitea/issue_template/bug_report.yml +++ b/.gitea/issue_template/bug_report.yml @@ -33,6 +33,14 @@ body: validations: required: false + - type: textarea + attributes: + label: Description + value: | + The steps you took to reproduce the problem. + validations: + required: false + - type: textarea id: debug_log attributes: @@ -52,11 +60,3 @@ body: - If the lines mentioning dwl or wlroots have `??`. Please compile both dwl and wlroots from source (enabling debug symbols) and try to reproduce. validations: required: false - - - type: textarea - attributes: - label: Description - value: | - The steps you took to reproduce the problem. - validations: - required: false From 6c8be38ec49273cc22faa4849295aaff5e39bfba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 15 Jan 2024 02:19:02 +0000 Subject: [PATCH 12/13] drop unused variable --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index 449913d..f25ac2f 100644 --- a/dwl.c +++ b/dwl.c @@ -1483,7 +1483,6 @@ locksession(struct wl_listener *listener, void *data) void maplayersurfacenotify(struct wl_listener *listener, void *data) { - LayerSurface *l = wl_container_of(listener, l, map); motionnotify(0); } From 26d7c9689f6e7eb699f2a63c2093c2a27e411ea3 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Fri, 21 Jul 2023 20:17:41 -0400 Subject: [PATCH 13/13] No need to call updatemons ourselves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The output manager in wlroots emits an output_layout.change event when anything changes, so updatemons will be called anyway. ΔSLOC: -1 --- dwl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/dwl.c b/dwl.c index f25ac2f..bf02a6d 100644 --- a/dwl.c +++ b/dwl.c @@ -1757,9 +1757,6 @@ apply_or_test: else wlr_output_configuration_v1_send_failed(config); wlr_output_configuration_v1_destroy(config); - - /* TODO: use a wrapper function? */ - updatemons(NULL, NULL); } void