From 057d50af8cd54647933021ae20e975a54ecf4408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 23 Nov 2023 10:56:01 -0600 Subject: [PATCH 01/58] pass wl_display to wlr_output_layout_create (wlroots!4310) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4310 --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 69da91d..de336b7 100644 --- a/dwl.c +++ b/dwl.c @@ -631,7 +631,6 @@ cleanup(void) waitpid(child_pid, NULL, 0); } wlr_xcursor_manager_destroy(cursor_mgr); - wlr_output_layout_destroy(output_layout); wl_display_destroy(dpy); /* Destroy after the wayland display (when the monitors are already destroyed) to avoid destroying them with an invalid scene output. */ @@ -2232,7 +2231,7 @@ setup(void) /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ - output_layout = wlr_output_layout_create(); + output_layout = wlr_output_layout_create(dpy); LISTEN_STATIC(&output_layout->events.change, updatemons); wlr_xdg_output_manager_v1_create(dpy, output_layout); From 3fe3581a5986be10e0736ea6c8ded59c7f44db5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 23 Nov 2023 14:19:10 -0600 Subject: [PATCH 02/58] chase wlr_layer_shell_v1.new_surface changes (wlroots!4265) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4265 --- dwl.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/dwl.c b/dwl.c index de336b7..7b13087 100644 --- a/dwl.c +++ b/dwl.c @@ -707,7 +707,17 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) LayerSurface *l = wl_container_of(listener, l, surface_commit); struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->current.layer]]; + struct wlr_layer_surface_v1_state old_state; + if (l->layer_surface->initial_commit) { + /* Temporarily set the layer's current state to pending + * so that we can easily arrange it */ + old_state = l->layer_surface->current; + l->layer_surface->current = l->layer_surface->pending; + arrangelayers(l->mon); + l->layer_surface->current = old_state; + return; + } if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped) return; @@ -794,7 +804,6 @@ createlayersurface(struct wl_listener *listener, void *data) LayerSurface *l; struct wlr_surface *surface = layer_surface->surface; struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->pending.layer]]; - struct wlr_layer_surface_v1_state old_state; if (!layer_surface->output && !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { @@ -819,15 +828,6 @@ createlayersurface(struct wl_listener *listener, void *data) wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); wlr_surface_send_enter(surface, layer_surface->output); - - /* Temporarily set the layer's current state to pending - * so that we can easily arrange it - */ - old_state = layer_surface->current; - layer_surface->current = layer_surface->pending; - l->mapped = 1; - arrangelayers(l->mon); - layer_surface->current = old_state; } void @@ -1484,7 +1484,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 70c5fcc23d3702544c978e81b8f067de596f06d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 23 Nov 2023 14:06:45 -0600 Subject: [PATCH 03/58] chase xdg-shell events update (wlroots!4345) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4345 --- dwl.c | 80 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/dwl.c b/dwl.c index 7b13087..aa3f1b9 100644 --- a/dwl.c +++ b/dwl.c @@ -251,6 +251,7 @@ static void createlocksurface(struct wl_listener *listener, void *data); static void createmon(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data); static void createpointer(struct wlr_pointer *pointer); +static void createpopup(struct wl_listener *listener, void *data); static void cursorframe(struct wl_listener *listener, void *data); static void destroydragicon(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data); @@ -739,6 +740,9 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); + if (c->surface.xdg->initial_commit) + wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + if (client_surface(c)->mapped) resize(c, c->geom, (c->isfloating && !c->isfullscreen)); @@ -926,49 +930,22 @@ createmon(struct wl_listener *listener, void *data) void createnotify(struct wl_listener *listener, void *data) { - /* This event is raised when wlr_xdg_shell receives a new xdg surface from a - * client, either a toplevel (application window) or popup, - * or when wlr_layer_shell receives a new popup from a layer. - * If you want to do something tricky with popups you should check if - * its parent is wlr_xdg_shell or wlr_layer_shell */ - struct wlr_xdg_surface *xdg_surface = data; + /* This event is raised when a client creates a new toplevel (application window). */ + struct wlr_xdg_toplevel *toplevel = data; Client *c = NULL; - LayerSurface *l = NULL; - - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - struct wlr_box box; - int type = toplevel_from_wlr_surface(xdg_surface->surface, &c, &l); - if (!xdg_surface->popup->parent || type < 0) - return; - xdg_surface->surface->data = wlr_scene_xdg_surface_create( - xdg_surface->popup->parent->data, xdg_surface); - if ((l && !l->mon) || (c && !c->mon)) - return; - box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->geom.x : c->geom.x); - box.y -= (type == LayerShell ? l->geom.y : c->geom.y); - wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); - return; - } else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) - return; /* Allocate a Client for this surface */ - c = xdg_surface->data = ecalloc(1, sizeof(*c)); - c->surface.xdg = xdg_surface; + c = toplevel->base->data = ecalloc(1, sizeof(*c)); + c->surface.xdg = toplevel->base; c->bw = borderpx; - wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel, - WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - - LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); - LISTEN(&xdg_surface->surface->events.map, &c->map, mapnotify); - LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmapnotify); - LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle); - LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen, - fullscreennotify); - LISTEN(&xdg_surface->toplevel->events.request_maximize, &c->maximize, - maximizenotify); + LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify); + LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify); + LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify); + LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify); + LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen, fullscreennotify); + LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify); + LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle); } void @@ -1015,6 +992,30 @@ createpointer(struct wlr_pointer *pointer) wlr_cursor_attach_input_device(cursor, &pointer->base); } +void +createpopup(struct wl_listener *listener, void *data) +{ + /* This event is raised when a client (either xdg-shell or layer-shell) + * creates a new popup. */ + struct wlr_xdg_popup *popup = data; + LayerSurface *l = NULL; + Client *c = NULL; + struct wlr_box box; + + int type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); + if (!popup->parent || type < 0) + return; + popup->base->surface->data = wlr_scene_xdg_surface_create( + popup->parent->data, popup->base); + if ((l && !l->mon) || (c && !c->mon)) + return; + box = type == LayerShell ? l->mon->m : c->mon->w; + box.x -= (type == LayerShell ? l->geom.x : c->geom.x); + box.y -= (type == LayerShell ? l->geom.y : c->geom.y); + /* FIXME: this send a configure event to a uninitialized wlr_xdg_surface */ + wlr_xdg_popup_unconstrain_from_box(popup, &box); +} + void cursorframe(struct wl_listener *listener, void *data) { @@ -2249,7 +2250,8 @@ setup(void) wl_list_init(&fstack); xdg_shell = wlr_xdg_shell_create(dpy, 6); - LISTEN_STATIC(&xdg_shell->events.new_surface, createnotify); + LISTEN_STATIC(&xdg_shell->events.new_toplevel, createnotify); + LISTEN_STATIC(&xdg_shell->events.new_popup, createpopup); layer_shell = wlr_layer_shell_v1_create(dpy, 3); LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface); From 05c263de45f9f4ab2262e6bba111e7b95c153556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 27 Dec 2023 11:45:36 -0600 Subject: [PATCH 04/58] only create wlr_presentation (wlroots!4482) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4482 --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index ec2b1c1..d0ac38a 100644 --- a/dwl.c +++ b/dwl.c @@ -2231,6 +2231,7 @@ setup(void) wlr_viewporter_create(dpy); wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_fractional_scale_manager_v1_create(dpy, 1); + wlr_presentation_create(dpy, backend); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); @@ -2385,8 +2386,6 @@ setup(void) LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply); LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); - wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); - /* 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 */ From c222468887b25fa21c34c02ae605d002de218d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 5 Jan 2024 10:01:16 -0600 Subject: [PATCH 05/58] don't send configure events to uninitialized xdg-popups --- dwl.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/dwl.c b/dwl.c index d0ac38a..5ab5a0a 100644 --- a/dwl.c +++ b/dwl.c @@ -245,6 +245,7 @@ static void cleanupmon(struct wl_listener *listener, void *data); static void closemon(Monitor *m); static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); +static void commitpopup(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data); static void createidleinhibitor(struct wl_listener *listener, void *data); static void createkeyboard(struct wlr_keyboard *keyboard); @@ -753,6 +754,33 @@ commitnotify(struct wl_listener *listener, void *data) c->resize = 0; } +void +commitpopup(struct wl_listener *listener, void *data) +{ + struct wlr_surface *surface = data; + struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface); + LayerSurface *l = NULL; + Client *c = NULL; + struct wlr_box box; + int type = -1; + + if (!popup->base->initial_commit) + return; + + type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); + if (!popup->parent || type < 0) + return; + popup->base->surface->data = wlr_scene_xdg_surface_create( + popup->parent->data, popup->base); + if ((l && !l->mon) || (c && !c->mon)) + return; + box = type == LayerShell ? l->mon->m : c->mon->w; + box.x -= (type == LayerShell ? l->geom.x : c->geom.x); + box.y -= (type == LayerShell ? l->geom.y : c->geom.y); + wlr_xdg_popup_unconstrain_from_box(popup, &box); + wl_list_remove(&listener->link); +} + void createdecoration(struct wl_listener *listener, void *data) { @@ -989,22 +1017,7 @@ createpopup(struct wl_listener *listener, void *data) /* This event is raised when a client (either xdg-shell or layer-shell) * creates a new popup. */ struct wlr_xdg_popup *popup = data; - LayerSurface *l = NULL; - Client *c = NULL; - struct wlr_box box; - - int type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); - if (!popup->parent || type < 0) - return; - popup->base->surface->data = wlr_scene_xdg_surface_create( - popup->parent->data, popup->base); - if ((l && !l->mon) || (c && !c->mon)) - return; - box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->geom.x : c->geom.x); - box.y -= (type == LayerShell ? l->geom.y : c->geom.y); - /* FIXME: this send a configure event to a uninitialized wlr_xdg_surface */ - wlr_xdg_popup_unconstrain_from_box(popup, &box); + LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); } void From 668022bc906fc7ba4d2092d260fbd10304fec29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 5 Jan 2024 11:12:34 -0600 Subject: [PATCH 06/58] don't send configure events to uninitialized xdg-toplevels --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 5ab5a0a..7fb1b88 100644 --- a/dwl.c +++ b/dwl.c @@ -1578,8 +1578,9 @@ maximizenotify(struct wl_listener *listener, void *data) * protocol version * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ Client *c = wl_container_of(listener, c, maximize); - if (wl_resource_get_version(c->surface.xdg->toplevel->resource) - < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + if (c->surface.xdg->initialized + && wl_resource_get_version(c->surface.xdg->toplevel->resource) + < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) wlr_xdg_surface_schedule_configure(c->surface.xdg); } From facbe57fcbe74d27809eefdfe6aaac5150fbb954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 5 Jan 2024 11:16:16 -0600 Subject: [PATCH 07/58] drop wl_drm (wlroots!4397) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4397 --- dwl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index 7fb1b88..c992cbf 100644 --- a/dwl.c +++ b/dwl.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -2216,11 +2215,9 @@ setup(void) * with wlr_scene. */ wlr_renderer_init_wl_shm(drw, dpy); - if (wlr_renderer_get_dmabuf_texture_formats(drw)) { - wlr_drm_create(dpy, drw); + if (wlr_renderer_get_dmabuf_texture_formats(drw)) wlr_scene_set_linux_dmabuf_v1(scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); - } /* Autocreates an allocator for us. * The allocator is the bridge between the renderer and the backend. It From f136aa088ab0f439c151b34fb1465abd85ca97ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 24 Jan 2024 12:09:55 -0600 Subject: [PATCH 08/58] Revert "drop wl_drm (wlroots!4397)" There still a lot software that uses this protocol This reverts commit facbe57fcbe74d27809eefdfe6aaac5150fbb954. --- dwl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index b899dbb..6d29ec0 100644 --- a/dwl.c +++ b/dwl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -2216,9 +2217,11 @@ setup(void) * with wlr_scene. */ wlr_renderer_init_wl_shm(drw, dpy); - if (wlr_renderer_get_dmabuf_texture_formats(drw)) + if (wlr_renderer_get_dmabuf_texture_formats(drw)) { + wlr_drm_create(dpy, drw); wlr_scene_set_linux_dmabuf_v1(scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); + } /* Autocreates an allocator for us. * The allocator is the bridge between the renderer and the backend. It From b3f33e91479d795436b2c6937d58754eaf18192e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 24 Jan 2024 12:10:54 -0600 Subject: [PATCH 09/58] add support for axis_relative_direction event (wlroots!4003) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4003 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 6d29ec0..a4e4983 100644 --- a/dwl.c +++ b/dwl.c @@ -549,7 +549,7 @@ axisnotify(struct wl_listener *listener, void *data) /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(seat, event->time_msec, event->orientation, event->delta, - event->delta_discrete, event->source); + event->delta_discrete, event->source, event->relative_direction); } void From 4043fc3093a73174cb63653ba9e742b4738f2ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 24 Jan 2024 12:12:09 -0600 Subject: [PATCH 10/58] do not arrange monitor if it's disabled (wlroots!4520) This causes us to send negative values to xdg-configures (e.g a bug in our end) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4520 --- dwl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dwl.c b/dwl.c index a4e4983..b70d818 100644 --- a/dwl.c +++ b/dwl.c @@ -460,6 +460,10 @@ void arrange(Monitor *m) { Client *c; + + if (!m->wlr_output->enabled) + return; + wl_list_for_each(c, &clients, link) { if (c->mon == m) { wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m)); From 5fec98b17ac398070ca05ba12fab7c22ea56a753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 25 Jan 2024 11:11:40 -0600 Subject: [PATCH 11/58] pass wl_event_loop to wlr_backend_autocreate (wlroots!4443) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4443 --- dwl.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dwl.c b/dwl.c index b70d818..95a6e82 100644 --- a/dwl.c +++ b/dwl.c @@ -341,6 +341,7 @@ static pid_t child_pid = -1; static int locked; static void *exclusive_focus; static struct wl_display *dpy; +static struct wl_event_loop *event_loop; static struct wlr_backend *backend; static struct wlr_scene *scene; static struct wlr_scene_tree *layers[NUM_LAYERS]; @@ -653,6 +654,10 @@ cleanup(void) wl_event_source_remove(kb_group.key_repeat_source); wl_event_source_remove(vkb_group.key_repeat_source); + /* If it's not destroyed manually it will cause a use-after-free of wlr_seat. + * Destroy it until it's fixed in the wlroots side */ + wlr_backend_destroy(backend); + wl_display_destroy(dpy); /* Destroy after the wayland display (when the monitors are already destroyed) to avoid destroying them with an invalid scene output. */ @@ -2191,12 +2196,13 @@ setup(void) /* The Wayland display is managed by libwayland. It handles accepting * clients from the Unix socket, manging Wayland globals, and so on. */ dpy = wl_display_create(); + event_loop = wl_display_get_event_loop(dpy); /* The backend is a wlroots feature which abstracts the underlying input and * output hardware. The autocreate option will choose the most suitable * backend based on the current environment, such as opening an X11 window * if an X11 server is running. */ - if (!(backend = wlr_backend_autocreate(dpy, &session))) + if (!(backend = wlr_backend_autocreate(event_loop, &session))) die("couldn't create backend"); /* Initialize the scene graph used to lay out windows */ @@ -2389,10 +2395,8 @@ setup(void) LISTEN(&vkb_group.wlr_group->keyboard.events.key, &vkb_group.key, keypress); LISTEN(&vkb_group.wlr_group->keyboard.events.modifiers, &vkb_group.modifiers, keypressmod); - kb_group.key_repeat_source = wl_event_loop_add_timer( - wl_display_get_event_loop(dpy), keyrepeat, &kb_group); - vkb_group.key_repeat_source = wl_event_loop_add_timer( - wl_display_get_event_loop(dpy), keyrepeat, &vkb_group); + kb_group.key_repeat_source = wl_event_loop_add_timer(event_loop, keyrepeat, &kb_group); + vkb_group.key_repeat_source = wl_event_loop_add_timer(event_loop, keyrepeat, &vkb_group); /* A seat can only have one keyboard, but this is a limitation of the * Wayland protocol - not wlroots. We assign all connected keyboards to the From c215e8a3e1dae6c3f4789dd404d6266c39d9d2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 6 Feb 2024 20:30:40 -0600 Subject: [PATCH 12/58] send initial configure to xdg-toplevels (wlroots!4396) We still need to fix xdg-popups References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4396 --- dwl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index e9cf506..ac5b19d 100644 --- a/dwl.c +++ b/dwl.c @@ -756,8 +756,11 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - if (c->surface.xdg->initial_commit) + if (c->surface.xdg->initial_commit) { wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); + return; + } if (client_surface(c)->mapped && c->mon) resize(c, c->geom, (c->isfloating && !c->isfullscreen)); From 7b3eb7050186d477889b78afa36079fdb7a8ea3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 6 Feb 2024 20:37:36 -0600 Subject: [PATCH 13/58] misc fixes to xdg-toplevel-decoration --- dwl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index ac5b19d..e8557ce 100644 --- a/dwl.c +++ b/dwl.c @@ -759,6 +759,8 @@ commitnotify(struct wl_listener *listener, void *data) if (c->surface.xdg->initial_commit) { wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); + if (c->decoration) + requestdecorationmode(&c->set_decoration_mode, c->decoration); return; } @@ -1052,6 +1054,7 @@ void destroydecoration(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, destroy_decoration); + c->decoration = NULL; wl_list_remove(&c->destroy_decoration.link); wl_list_remove(&c->set_decoration_mode.link); @@ -1929,8 +1932,9 @@ void requestdecorationmode(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, set_decoration_mode); - wlr_xdg_toplevel_decoration_v1_set_mode(c->decoration, - WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + if (c->surface.xdg->initialized) + wlr_xdg_toplevel_decoration_v1_set_mode(c->decoration, + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } void From a0117eea76ce5ca5e6660f5a6f0057e29f268d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 29 Feb 2024 14:05:09 -0600 Subject: [PATCH 14/58] use enums from the wayland protocol (wlroots!4575) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4575 --- dwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index e8557ce..dfb3a27 100644 --- a/dwl.c +++ b/dwl.c @@ -571,7 +571,7 @@ buttonpress(struct wl_listener *listener, void *data) wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); switch (event->state) { - case WLR_BUTTON_PRESSED: + case WL_POINTER_BUTTON_STATE_PRESSED: cursor_mode = CurPressed; held_grab = seat->pointer_state.focused_surface; if (locked) @@ -592,7 +592,7 @@ buttonpress(struct wl_listener *listener, void *data) } } break; - case WLR_BUTTON_RELEASED: + case WL_POINTER_BUTTON_STATE_RELEASED: held_grab = NULL; /* If you released any buttons, we exit interactive move/resize mode. */ /* TODO should reset to the pointer focus's current setcursor */ From bb734816627b3bad7ea231bfb454777a1c5177ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 21 Apr 2024 15:53:59 -0600 Subject: [PATCH 15/58] use wlr_renderer_get_texture_formats (wlroots!4644) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4644 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 1ebc3d4..589b187 100644 --- a/dwl.c +++ b/dwl.c @@ -2341,7 +2341,7 @@ setup(void) * with wlr_scene. */ wlr_renderer_init_wl_shm(drw, dpy); - if (wlr_renderer_get_dmabuf_texture_formats(drw)) { + if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) { wlr_drm_create(dpy, drw); wlr_scene_set_linux_dmabuf_v1(scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); From 3b1f0a8a88d0b535c76d2f0e919fd68e3a4c3b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 30 Apr 2024 12:36:10 -0600 Subject: [PATCH 16/58] add support for alpha-modifier-v1 (wlroots!4616) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4616 --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 589b187..06db9f4 100644 --- a/dwl.c +++ b/dwl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -2371,6 +2372,7 @@ setup(void) wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_fractional_scale_manager_v1_create(dpy, 1); wlr_presentation_create(dpy, backend); + wlr_alpha_modifier_v1_create(dpy); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); From bf81a128ecddaa63a904c2b08b80ed03619e0eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 27 May 2024 23:10:40 -0600 Subject: [PATCH 17/58] wlroots now allows parallel installs --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a67fdd3..82f23b3 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unu -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) +PKGS = wlroots-0.18 wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) From 57b5e41063d27087d3a651b28f1ae6c7d9e2a6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 30 May 2024 15:00:05 -0600 Subject: [PATCH 18/58] use enum headers when possible --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 82f23b3..29f24b4 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,13 @@ WAYLAND_SCANNER = `$(PKG_CONFIG) --variable=wayland_scanner wayland-scanner` WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols` cursor-shape-v1-protocol.h: - $(WAYLAND_SCANNER) server-header \ + $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@ pointer-constraints-unstable-v1-protocol.h: - $(WAYLAND_SCANNER) server-header \ + $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@ wlr-layer-shell-unstable-v1-protocol.h: - $(WAYLAND_SCANNER) server-header \ + $(WAYLAND_SCANNER) enum-header \ protocols/wlr-layer-shell-unstable-v1.xml $@ xdg-shell-protocol.h: $(WAYLAND_SCANNER) server-header \ From 7a46fccdba35b46d91226d10c1c9b90e43418c09 Mon Sep 17 00:00:00 2001 From: Peter Hofmann Date: Tue, 18 Jun 2024 19:09:32 +0200 Subject: [PATCH 19/58] Run startup_cmd in new session and kill the entire group When a user's startup_cmd is a little more complex, e.g. a shell script, and forks off several processes, then killing only the main child pid might leave unwanted processes behind on exit. Not all children will notice when their parent or the compositor has quit. To fix this, put startup_cmd into its own session and process group, and kill the entire group on exit. --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 5a31aee..79ccb34 100644 --- a/dwl.c +++ b/dwl.c @@ -674,7 +674,7 @@ cleanup(void) #endif wl_display_destroy_clients(dpy); if (child_pid > 0) { - kill(child_pid, SIGTERM); + kill(-child_pid, SIGTERM); waitpid(child_pid, NULL, 0); } wlr_xcursor_manager_destroy(cursor_mgr); @@ -2141,6 +2141,7 @@ run(char *startup_cmd) if ((child_pid = fork()) < 0) die("startup: fork:"); if (child_pid == 0) { + setsid(); dup2(piperw[0], STDIN_FILENO); close(piperw[0]); close(piperw[1]); From a8403d7b4d54e30699424586784cc0265b29d08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 3 May 2024 11:03:18 -0600 Subject: [PATCH 20/58] handle gpu resets Fixes: https://codeberg.org/dwl/dwl/issues/601 --- dwl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dwl.c b/dwl.c index 9890a6c..7b61ba2 100644 --- a/dwl.c +++ b/dwl.c @@ -289,6 +289,7 @@ static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); static Client *focustop(Monitor *m); static void fullscreennotify(struct wl_listener *listener, void *data); +static void gpureset(struct wl_listener *listener, void *data); static void handlesig(int signo); static void incnmaster(const Arg *arg); static void inputdevice(struct wl_listener *listener, void *data); @@ -1454,6 +1455,30 @@ fullscreennotify(struct wl_listener *listener, void *data) setfullscreen(c, client_wants_fullscreen(c)); } +void +gpureset(struct wl_listener *listener, void *data) +{ + struct wlr_renderer *old_drw = drw; + struct wlr_allocator *old_alloc = alloc; + struct Monitor *m; + if (!(drw = wlr_renderer_autocreate(backend))) + die("couldn't recreate renderer"); + + if (!(alloc = wlr_allocator_autocreate(backend, drw))) + die("couldn't recreate allocator"); + + LISTEN_STATIC(&drw->events.lost, gpureset); + + wlr_compositor_set_renderer(compositor, drw); + + wl_list_for_each(m, &mons, link) { + wlr_output_init_render(m->wlr_output, alloc, drw); + } + + wlr_allocator_destroy(old_alloc); + wlr_renderer_destroy(old_drw); +} + void handlesig(int signo) { @@ -2394,6 +2419,7 @@ setup(void) * supports for shared memory, this configures that for clients. */ if (!(drw = wlr_renderer_autocreate(backend))) die("couldn't create renderer"); + LISTEN_STATIC(&drw->events.lost, gpureset); /* Create shm, drm and linux_dmabuf interfaces by ourselves. * The simplest way is call: From 16076ec5a40ed708b99f27100036a4a92b4fdd59 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 4 May 2024 20:59:51 +0200 Subject: [PATCH 21/58] fix: make sure selmon doesn't get set to disabled mon --- dwl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dwl.c b/dwl.c index 79ccb34..83bdbe4 100644 --- a/dwl.c +++ b/dwl.c @@ -727,6 +727,9 @@ closemon(Monitor *m) do /* don't switch to disabled mons */ selmon = wl_container_of(mons.next, selmon, link); while (!selmon->wlr_output->enabled && i++ < nmons); + + if (!selmon->wlr_output->enabled) + selmon = NULL; } wl_list_for_each(c, &clients, link) { @@ -2789,6 +2792,10 @@ updatemons(struct wl_listener *listener, void *data) config_head->state.x = m->m.x; config_head->state.y = m->m.y; + + if (!selmon) { + selmon = m; + } } if (selmon && selmon->wlr_output->enabled) { From 11baacbec0b75dff34abf52d5172687e4ae2cc4f Mon Sep 17 00:00:00 2001 From: Rutherther Date: Tue, 14 May 2024 17:57:59 +0200 Subject: [PATCH 22/58] Add output to layout after enabled state is committed --- dwl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dwl.c b/dwl.c index 83bdbe4..60b74ae 100644 --- a/dwl.c +++ b/dwl.c @@ -1906,11 +1906,6 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) config_head->state.custom_mode.height, config_head->state.custom_mode.refresh); - /* Don't move monitors if position wouldn't change, this to avoid - * wlroots marking the output as manually configured */ - if (m->m.x != config_head->state.x || m->m.y != config_head->state.y) - wlr_output_layout_add(output_layout, wlr_output, - config_head->state.x, config_head->state.y); wlr_output_state_set_transform(&state, config_head->state.transform); wlr_output_state_set_scale(&state, config_head->state.scale); wlr_output_state_set_adaptive_sync_enabled(&state, @@ -1920,6 +1915,13 @@ apply_or_test: ok &= test ? wlr_output_test_state(wlr_output, &state) : wlr_output_commit_state(wlr_output, &state); + /* Don't move monitors if position wouldn't change, this to avoid + * wlroots marking the output as manually configured. + * wlr_output_layout_add does not like disabled outputs */ + if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) + wlr_output_layout_add(output_layout, wlr_output, + config_head->state.x, config_head->state.y); + wlr_output_state_finish(&state); } From 784b047b3825b0c784de85034e9b215134250e3c Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 31 May 2024 16:00:50 +0200 Subject: [PATCH 23/58] Check for null monitor in resize function --- dwl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 60b74ae..3dba2bf 100644 --- a/dwl.c +++ b/dwl.c @@ -2100,8 +2100,14 @@ requestmonstate(struct wl_listener *listener, void *data) void resize(Client *c, struct wlr_box geo, int interact) { - struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; + struct wlr_box *bbox; struct wlr_box clip; + + if (!c->mon) + return; + + bbox = interact ? &sgeom : &c->mon->w; + client_set_bounds(c, geo.width, geo.height); c->geom = geo; applybounds(c, bbox); From 92d1c286b8041bcdf5c335a63f5c060460e2a0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 20 Jun 2024 18:38:59 -0600 Subject: [PATCH 24/58] default CC to gcc posix c99 does not accept `-pedantic` Fixes: https://codeberg.org/dwl/dwl/issues/584 --- config.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.mk b/config.mk index 906f403..259bd0f 100644 --- a/config.mk +++ b/config.mk @@ -13,3 +13,5 @@ XLIBS = # Uncomment to build XWayland support #XWAYLAND = -DXWAYLAND #XLIBS = xcb xcb-icccm + +CC = gcc From 9b1f35e42bf435b212dfcdcc510439ef8b4f2e31 Mon Sep 17 00:00:00 2001 From: Emil Miler Date: Wed, 17 Jan 2024 09:45:03 +0100 Subject: [PATCH 25/58] Implement support for output power management This patch is based on the original stale patch by Guido Cella @guidocella. It has been modified to apply cleanly to the latest v5.0 tag. Since the SLOC limit is now lifted, this core feature should be merged into dwl upstream. Thanks to Dima Krasner @dimkr for the cherry-pick. Closes: #559, #525 --- Makefile | 5 +- dwl.c | 14 ++ ...lr-output-power-management-unstable-v1.xml | 128 ++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 protocols/wlr-output-power-management-unstable-v1.xml diff --git a/Makefile b/Makefile index e3e6426..8375772 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) all: dwl dwl: dwl.o util.o $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ -dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h +dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h wlr-output-power-management-unstable-v1-protocol.h util.o: util.c util.h # wayland-scanner is a tool which generates C headers and rigging for Wayland @@ -37,6 +37,9 @@ wlr-layer-shell-unstable-v1-protocol.h: xdg-shell-protocol.h: $(WAYLAND_SCANNER) server-header \ $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ +wlr-output-power-management-unstable-v1-protocol.h: + $(WAYLAND_SCANNER) server-header \ + protocols/wlr-output-power-management-unstable-v1.xml $@ config.h: cp config.def.h $@ diff --git a/dwl.c b/dwl.c index 3dba2bf..7a2920e 100644 --- a/dwl.c +++ b/dwl.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -310,6 +311,7 @@ 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); static void printstatus(void); +static void powermgrsetmodenotify(struct wl_listener *listener, void *data); static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); @@ -381,6 +383,7 @@ static struct wlr_gamma_control_manager_v1 *gamma_control_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; +static struct wlr_output_power_manager_v1 *power_mgr; static struct wlr_pointer_constraints_v1 *pointer_constraints; static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; @@ -2011,6 +2014,14 @@ printstatus(void) fflush(stdout); } +void +powermgrsetmodenotify(struct wl_listener *listener, void *data) +{ + struct wlr_output_power_v1_set_mode_event *event = data; + wlr_output_enable(event->output, event->mode); + wlr_output_commit(event->output); +} + void quit(const Arg *arg) { @@ -2422,6 +2433,9 @@ setup(void) gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); + power_mgr = wlr_output_power_manager_v1_create(dpy); + LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmodenotify); + /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(); diff --git a/protocols/wlr-output-power-management-unstable-v1.xml b/protocols/wlr-output-power-management-unstable-v1.xml new file mode 100644 index 0000000..a977839 --- /dev/null +++ b/protocols/wlr-output-power-management-unstable-v1.xml @@ -0,0 +1,128 @@ + + + + Copyright © 2019 Purism SPC + + 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 (including the next + paragraph) 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. + + + + This protocol allows clients to control power management modes + of outputs that are currently part of the compositor space. The + intent is to allow special clients like desktop shells to power + down outputs when the system is idle. + + To modify outputs not currently part of the compositor space see + wlr-output-management. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + This interface is a manager that allows creating per-output power + management mode controls. + + + + + Create a output power management mode control that can be used to + adjust the power management mode for a given output. + + + + + + + + All objects created by the manager will still remain valid, until their + appropriate destroy request has been called. + + + + + + + This object offers requests to set the power management mode of + an output. + + + + + + + + + + + + + + Set an output's power save mode to the given mode. The mode change + is effective immediately. If the output does not support the given + mode a failed event is sent. + + + + + + + Report the power management mode change of an output. + + The mode event is sent after an output changed its power + management mode. The reason can be a client using set_mode or the + compositor deciding to change an output's mode. + This event is also sent immediately when the object is created + so the client is informed about the current power management mode. + + + + + + + This event indicates that the output power management mode control + is no longer valid. This can happen for a number of reasons, + including: + - The output doesn't support power management + - Another client already has exclusive power management mode control + for this output + - The output disappeared + + Upon receiving this event, the client should destroy this object. + + + + + + Destroys the output power management mode control object. + + + + From 2902df94d6e3da04b7abc92f846b0da7d40ff4ea Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sat, 6 Apr 2024 11:29:14 -0600 Subject: [PATCH 26/58] Prevent updatemons() from removing monitors that have been put to sleep from the layout --- dwl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 7a2920e..4867760 100644 --- a/dwl.c +++ b/dwl.c @@ -207,6 +207,7 @@ struct Monitor { int gamma_lut_changed; int nmaster; char ltsymbol[16]; + int asleep; }; typedef struct { @@ -962,6 +963,8 @@ createmon(struct wl_listener *listener, void *data) LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); + m->asleep = 0; + wlr_output_state_set_enabled(&state, 1); wlr_output_commit_state(wlr_output, &state); wlr_output_state_finish(&state); @@ -2018,8 +2021,11 @@ void powermgrsetmodenotify(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; + wlr_output_enable(event->output, event->mode); wlr_output_commit(event->output); + + ((Monitor *)(event->output->data))->asleep = !event->mode; } void @@ -2755,7 +2761,7 @@ updatemons(struct wl_listener *listener, void *data) /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled) + if (m->wlr_output->enabled || m->asleep) continue; config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); config_head->state.enabled = 0; From 650a918010ac5769787d461812392cff786e4d3b Mon Sep 17 00:00:00 2001 From: thanatos Date: Thu, 20 Jun 2024 18:48:47 -0600 Subject: [PATCH 27/58] Updated power management handling to address issues raised in the PR --- Makefile | 8 ++++---- dwl.c | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 8375772..fdc581a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) all: dwl dwl: dwl.o util.o $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ -dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h wlr-output-power-management-unstable-v1-protocol.h +dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h util.o: util.c util.h # wayland-scanner is a tool which generates C headers and rigging for Wayland @@ -34,12 +34,12 @@ pointer-constraints-unstable-v1-protocol.h: wlr-layer-shell-unstable-v1-protocol.h: $(WAYLAND_SCANNER) server-header \ protocols/wlr-layer-shell-unstable-v1.xml $@ -xdg-shell-protocol.h: - $(WAYLAND_SCANNER) server-header \ - $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ wlr-output-power-management-unstable-v1-protocol.h: $(WAYLAND_SCANNER) server-header \ protocols/wlr-output-power-management-unstable-v1.xml $@ +xdg-shell-protocol.h: + $(WAYLAND_SCANNER) server-header \ + $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ config.h: cp config.def.h $@ diff --git a/dwl.c b/dwl.c index 4867760..2cdc819 100644 --- a/dwl.c +++ b/dwl.c @@ -312,7 +312,7 @@ 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); static void printstatus(void); -static void powermgrsetmodenotify(struct wl_listener *listener, void *data); +static void powermgrsetmode(struct wl_listener *listener, void *data); static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); @@ -963,8 +963,6 @@ createmon(struct wl_listener *listener, void *data) LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); - m->asleep = 0; - wlr_output_state_set_enabled(&state, 1); wlr_output_commit_state(wlr_output, &state); wlr_output_state_finish(&state); @@ -1899,6 +1897,10 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) Monitor *m = wlr_output->data; struct wlr_output_state state; + /* Ensure displays previously disabled by wlr-output-power-management-v1 + * are properly handled*/ + m->asleep = 0; + wlr_output_state_init(&state); wlr_output_state_set_enabled(&state, config_head->state.enabled); if (!config_head->state.enabled) @@ -2018,12 +2020,16 @@ printstatus(void) } void -powermgrsetmodenotify(struct wl_listener *listener, void *data) +powermgrsetmode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; + struct wlr_output_state state = {0}; - wlr_output_enable(event->output, event->mode); - wlr_output_commit(event->output); + if (!event->output->data) + return; + + wlr_output_state_set_enabled(&state, event->mode); + wlr_output_commit_state(event->output, &state); ((Monitor *)(event->output->data))->asleep = !event->mode; } @@ -2440,7 +2446,7 @@ setup(void) LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); power_mgr = wlr_output_power_manager_v1_create(dpy); - LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmodenotify); + LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ From 9cdce1b8ff6e50affd0c20696b2dd8048e45b3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 20 Jun 2024 23:09:03 -0600 Subject: [PATCH 28/58] try to limit (79 characters) the line lenght in the Makefile --- Makefile | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fdc581a..9308656 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,12 @@ 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 -Wfloat-conversion +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 \ + -Wfloat-conversion # CFLAGS / LDFLAGS PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) @@ -16,7 +19,9 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) all: dwl dwl: dwl.o util.o $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ -dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h +dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \ + pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \ + wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h util.o: util.c util.h # wayland-scanner is a tool which generates C headers and rigging for Wayland @@ -48,8 +53,8 @@ clean: dist: clean mkdir -p dwl-$(VERSION) - cp -R LICENSE* Makefile CHANGELOG.md README.md client.h config.def.h\ - config.mk protocols dwl.1 dwl.c util.c util.h dwl.desktop\ + cp -R LICENSE* Makefile CHANGELOG.md README.md client.h config.def.h \ + config.mk protocols dwl.1 dwl.c util.c util.h dwl.desktop \ dwl-$(VERSION) tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION) rm -rf dwl-$(VERSION) @@ -65,7 +70,8 @@ install: dwl cp -f dwl.desktop $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop chmod 644 $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1 $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop + rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1 \ + $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop .SUFFIXES: .c .o .c.o: From 845d3c47bd5dc8c7c7966e835579f10e69c5d92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 20 Jun 2024 23:28:14 -0600 Subject: [PATCH 29/58] Reapply gamma LUT when re-enabling an output using wlr-output-power-management --- dwl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 2cdc819..d48bf40 100644 --- a/dwl.c +++ b/dwl.c @@ -2024,14 +2024,16 @@ powermgrsetmode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; struct wlr_output_state state = {0}; + Monitor *m = event->output->data; - if (!event->output->data) + if (!m) return; + m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */ wlr_output_state_set_enabled(&state, event->mode); - wlr_output_commit_state(event->output, &state); + wlr_output_commit_state(m->wlr_output, &state); - ((Monitor *)(event->output->data))->asleep = !event->mode; + m->asleep = !event->mode; } void From 4a7d1bebf5c706109c92bd0415ab62825a7556ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 22 Jun 2024 00:21:17 -0600 Subject: [PATCH 30/58] add bugref for negative x,y monitor position and xwayland --- config.def.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index a784eb4..646a3d6 100644 --- a/config.def.h +++ b/config.def.h @@ -36,8 +36,10 @@ static const Layout layouts[] = { }; /* monitors */ -/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator */ -/* WARNING: negative values other than (-1, -1) cause problems with xwayland clients' menus */ +/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator + * WARNING: negative values other than (-1, -1) cause problems with Xwayland clients + * https://gitlab.freedesktop.org/xorg/xserver/-/issues/899 +*/ /* 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 */ From 13925eb1da8af2c1d23ee9d01efd03c3626081b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 23 Jun 2024 14:42:50 -0600 Subject: [PATCH 31/58] correctly report position to xwayland clients Previously we didn't take into account their borders requiring us to add `borderpx` to override_redirect clients. Fixes: https://codeberg.org/dwl/dwl/issues/651 --- client.h | 2 +- dwl.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client.h b/client.h index 19861b9..42f225f 100644 --- a/client.h +++ b/client.h @@ -350,7 +350,7 @@ client_set_size(Client *c, uint32_t width, uint32_t height) #ifdef XWAYLAND if (client_is_x11(c)) { wlr_xwayland_surface_configure(c->surface.xwayland, - c->geom.x, c->geom.y, width, height); + c->geom.x + c->bw, c->geom.y + c->bw, width, height); return 0; } #endif diff --git a/dwl.c b/dwl.c index d48bf40..00e9cc1 100644 --- a/dwl.c +++ b/dwl.c @@ -1651,8 +1651,7 @@ mapnotify(struct wl_listener *listener, void *data) if (client_is_unmanaged(c)) { /* Unmanaged clients always are floating */ wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); - wlr_scene_node_set_position(&c->scene->node, c->geom.x + borderpx, - c->geom.y + borderpx); + wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); if (client_wants_focus(c)) { focusclient(c, 1); exclusive_focus = c; @@ -3038,7 +3037,7 @@ createnotifyx11(struct wl_listener *listener, void *data) c = xsurface->data = ecalloc(1, sizeof(*c)); c->surface.xwayland = xsurface; c->type = X11; - c->bw = borderpx; + c->bw = client_is_unmanaged(c) ? 0 : borderpx; /* Listen to the various events it can emit */ LISTEN(&xsurface->events.associate, &c->associate, associatex11); From 46ae075430017ccd4a58d63a166fe1e696d3f379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 5 Jun 2024 00:42:43 -0600 Subject: [PATCH 32/58] set preferred scale on creation (LayerShell) --- dwl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dwl.c b/dwl.c index 00e9cc1..521b07a 100644 --- a/dwl.c +++ b/dwl.c @@ -71,6 +71,7 @@ #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 CEIL(X) ((int)((X < 0) ? (X) : ((int)X == X) ? (X) : ((int)X + 1))) #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]) @@ -884,6 +885,8 @@ createlayersurface(struct wl_listener *listener, void *data) wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); wlr_surface_send_enter(surface, layer_surface->output); + wlr_fractional_scale_v1_notify_scale(surface, l->mon->wlr_output->scale); + wlr_surface_set_preferred_buffer_scale(surface, CEIL(l->mon->wlr_output->scale)); /* Temporarily set the layer's current state to pending * so that we can easily arrange it From 1002ea04fa45fba46755478044bc4828f8e19b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 25 Jun 2024 22:22:43 -0600 Subject: [PATCH 33/58] add bugref about why we call updatemons in outputmgrapplyortest --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 521b07a..9fb50a7 100644 --- a/dwl.c +++ b/dwl.c @@ -1941,7 +1941,7 @@ apply_or_test: wlr_output_configuration_v1_send_failed(config); wlr_output_configuration_v1_destroy(config); - /* TODO: use a wrapper function? */ + /* https://codeberg.org/dwl/dwl/issues/577 */ updatemons(NULL, NULL); } From 2b4893a0ad57fb5234c48615a2e531401efcf69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 29 Jun 2024 18:31:01 -0600 Subject: [PATCH 34/58] add a note about having at least a dummy rule for `rules[]` Closes: https://codeberg.org/dwl/dwl/issues/656 --- config.def.h | 1 + 1 file changed, 1 insertion(+) diff --git a/config.def.h b/config.def.h index 646a3d6..22d2171 100644 --- a/config.def.h +++ b/config.def.h @@ -20,6 +20,7 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca /* logging */ static int log_level = WLR_ERROR; +/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ static const Rule rules[] = { /* app_id title tags mask isfloating monitor */ /* examples: */ From 71f11e6cf63289d51f152469a0da81a85fe2608c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 27 Jun 2024 13:19:16 -0600 Subject: [PATCH 35/58] set O_NONBLOCK flag to stdout --- dwl.c | 6 ++++++ util.c | 16 ++++++++++++++++ util.h | 1 + 3 files changed, 23 insertions(+) diff --git a/dwl.c b/dwl.c index 9fb50a7..3175e79 100644 --- a/dwl.c +++ b/dwl.c @@ -2190,6 +2190,12 @@ run(char *startup_cmd) close(piperw[1]); close(piperw[0]); } + + /* Mark stdout as non-blocking to avoid people who does not close stdin + * nor consumes it in their startup script getting dwl frozen */ + if (fd_set_nonblock(STDOUT_FILENO) < 0) + close(STDOUT_FILENO); + printstatus(); /* At this point the outputs are initialized, choose initial selmon based on diff --git a/util.c b/util.c index cca7c19..51130af 100644 --- a/util.c +++ b/util.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "util.h" @@ -33,3 +34,18 @@ ecalloc(size_t nmemb, size_t size) die("calloc:"); return p; } + +int +fd_set_nonblock(int fd) { + int flags = fcntl(fd, F_GETFL); + if (flags < 0) { + perror("fcntl(F_GETFL):"); + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + perror("fcntl(F_SETFL):"); + return -1; + } + + return 0; +} diff --git a/util.h b/util.h index 4c94117..226980d 100644 --- a/util.h +++ b/util.h @@ -2,3 +2,4 @@ void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size); +int fd_set_nonblock(int fd); From b4638fef296cc7fa7ce51fa8ac07ecad17985226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 3 Jul 2024 13:20:51 -0600 Subject: [PATCH 36/58] drop useless maplayersurfacenotify() --- dwl.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dwl.c b/dwl.c index 3175e79..a0f26bf 100644 --- a/dwl.c +++ b/dwl.c @@ -177,7 +177,6 @@ typedef struct { struct wlr_layer_surface_v1 *layer_surface; struct wl_listener destroy; - struct wl_listener map; struct wl_listener unmap; struct wl_listener surface_commit; } LayerSurface; @@ -298,7 +297,6 @@ static void keypressmod(struct wl_listener *listener, void *data); static int keyrepeat(void *data); static void killclient(const Arg *arg); static void locksession(struct wl_listener *listener, void *data); -static void maplayersurfacenotify(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); @@ -871,7 +869,6 @@ createlayersurface(struct wl_listener *listener, void *data) l = layer_surface->data = ecalloc(1, sizeof(*l)); l->type = LayerShell; LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify); - LISTEN(&surface->events.map, &l->map, maplayersurfacenotify); LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); LISTEN(&layer_surface->events.destroy, &l->destroy, destroylayersurfacenotify); @@ -1170,7 +1167,6 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) wl_list_remove(&l->link); wl_list_remove(&l->destroy.link); - wl_list_remove(&l->map.link); wl_list_remove(&l->unmap.link); wl_list_remove(&l->surface_commit.link); wlr_scene_node_destroy(&l->scene->node); @@ -1625,12 +1621,6 @@ locksession(struct wl_listener *listener, void *data) wlr_session_lock_v1_send_locked(session_lock); } -void -maplayersurfacenotify(struct wl_listener *listener, void *data) -{ - motionnotify(0, NULL, 0, 0, 0, 0); -} - void mapnotify(struct wl_listener *listener, void *data) { From ab5c554d096ebca8446b7b1354c49be014b8b747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 5 Jun 2024 00:43:14 -0600 Subject: [PATCH 37/58] set preferred scale after the first commit (XDGshell) --- dwl.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index a0f26bf..ee24044 100644 --- a/dwl.c +++ b/dwl.c @@ -773,6 +773,19 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); + if (c->surface.xdg->initial_commit) { + /* + * Get the monitor this client will be rendered on + * Note that if the user set a rule in which the client is placed on + * a different monitor based on its title this will likely select + * a wrong monitor. + */ + applyrules(c); + wlr_surface_set_preferred_buffer_scale(client_surface(c), CEIL(c->mon->wlr_output->scale)); + wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ + } + if (client_surface(c)->mapped && c->mon) resize(c, c->geom, (c->isfloating && !c->isfullscreen)); @@ -2120,7 +2133,7 @@ resize(Client *c, struct wlr_box geo, int interact) struct wlr_box *bbox; struct wlr_box clip; - if (!c->mon) + if (!c->mon || !c->scene) return; bbox = interact ? &sgeom : &c->mon->w; @@ -2246,7 +2259,7 @@ setfloating(Client *c, int floating) Client *p = client_get_parent(c); c->isfloating = floating; /* If in floating layout do not change the client's layer */ - if (!c->mon || !c->mon->lt[c->mon->sellt]->arrange) + if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange) return; wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || (p && p->isfullscreen) ? LyrFS @@ -2259,7 +2272,7 @@ void setfullscreen(Client *c, int fullscreen) { c->isfullscreen = fullscreen; - if (!c->mon) + if (!c->mon || !client_surface(c)->mapped) return; c->bw = fullscreen ? 0 : borderpx; client_set_fullscreen(c, fullscreen); From 2db0a2e8ef57acceeb3331a312dc3388a1710b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 25 Jun 2024 11:38:01 -0600 Subject: [PATCH 38/58] use round(3) and ceilf(3) from the math library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ΔSLOC: -1 --- Makefile | 2 +- dwl.c | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 9308656..0d651e7 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ # CFLAGS / LDFLAGS PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) -LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) +LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) all: dwl dwl: dwl.o util.o diff --git a/dwl.c b/dwl.c index ee24044..9d8317e 100644 --- a/dwl.c +++ b/dwl.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -70,8 +71,6 @@ /* 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 CEIL(X) ((int)((X < 0) ? (X) : ((int)X == X) ? (X) : ((int)X + 1))) #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]) @@ -781,7 +780,7 @@ commitnotify(struct wl_listener *listener, void *data) * a wrong monitor. */ applyrules(c); - wlr_surface_set_preferred_buffer_scale(client_surface(c), CEIL(c->mon->wlr_output->scale)); + wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ } @@ -896,7 +895,7 @@ createlayersurface(struct wl_listener *listener, void *data) wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); wlr_surface_send_enter(surface, layer_surface->output); wlr_fractional_scale_v1_notify_scale(surface, l->mon->wlr_output->scale); - wlr_surface_set_preferred_buffer_scale(surface, CEIL(l->mon->wlr_output->scale)); + wlr_surface_set_preferred_buffer_scale(surface, (int32_t)ceilf(l->mon->wlr_output->scale)); /* Temporarily set the layer's current state to pending * so that we can easily arrange it @@ -1812,17 +1811,17 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d } /* Update drag icon's position */ - wlr_scene_node_set_position(&drag_icon->node, ROUND(cursor->x), ROUND(cursor->y)); + wlr_scene_node_set_position(&drag_icon->node, (int)round(cursor->x), (int)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 = ROUND(cursor->x) - grabcx, .y = ROUND(cursor->y) - grabcy, + resize(grabc, (struct wlr_box){.x = (int)round(cursor->x) - grabcx, .y = (int)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 = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1); + .width = (int)round(cursor->x) - grabc->geom.x, .height = (int)round(cursor->y) - grabc->geom.y}, 1); return; } @@ -1863,8 +1862,8 @@ moveresize(const Arg *arg) setfloating(grabc, 1); switch (cursor_mode = arg->ui) { case CurMove: - grabcx = ROUND(cursor->x) - grabc->geom.x; - grabcy = ROUND(cursor->y) - grabc->geom.y; + grabcx = (int)round(cursor->x) - grabc->geom.x; + grabcy = (int)round(cursor->y) - grabc->geom.y; wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); break; case CurResize: @@ -2649,7 +2648,7 @@ tile(Monitor *m) return; if (n > m->nmaster) - mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0; + mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0; else mw = m->w.width; i = my = ty = 0; From 7d8c3ea3695de248aa1975def5839b0ffd34d198 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Tue, 7 May 2024 19:14:32 +0200 Subject: [PATCH 39/58] feat: focus empty monitor when clicked --- dwl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dwl.c b/dwl.c index 9d8317e..e2fd223 100644 --- a/dwl.c +++ b/dwl.c @@ -604,6 +604,7 @@ buttonpress(struct wl_listener *listener, void *data) switch (event->state) { case WLR_BUTTON_PRESSED: cursor_mode = CurPressed; + selmon = xytomon(cursor->x, cursor->y); if (locked) break; From aede3b294b1b78afb1ceaf2214b8cc024a775974 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 30 Jun 2024 21:42:05 +0200 Subject: [PATCH 40/58] Fix applybounds Applybounds doesn't move client when it overlays only with border with monitor to the right. Apparently, c->geom.width already includes the border as well. --- dwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index e2fd223..dc0437e 100644 --- a/dwl.c +++ b/dwl.c @@ -439,9 +439,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 * (int)c->bw <= bbox->x) + if (c->geom.x + c->geom.width <= bbox->x) c->geom.x = bbox->x; - if (c->geom.y + c->geom.height + 2 * (int)c->bw <= bbox->y) + if (c->geom.y + c->geom.height <= bbox->y) c->geom.y = bbox->y; } From 043ab3ac1335d7a1cd84fe0f9cea8056977211a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 12 Jul 2024 21:08:48 -0600 Subject: [PATCH 41/58] Revert "place child clients above fullscreen clients" This does not work as intended. Lets revert it temporarily and add it back after the release. This reverts commit 298949bbc4eae8cedb9cdd11cfc9ebd139ac5d5f. --- client.h | 12 ------------ dwl.c | 13 +++++-------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/client.h b/client.h index 42f225f..f0e5445 100644 --- a/client.h +++ b/client.h @@ -183,18 +183,6 @@ 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 dc0437e..145fd01 100644 --- a/dwl.c +++ b/dwl.c @@ -1404,7 +1404,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 && !client_has_children(sel))) + if (!sel || sel->isfullscreen) return; if (arg->i > 0) { wl_list_for_each(c, &sel->link, link) { @@ -1638,8 +1638,7 @@ void mapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p = NULL; - Client *w, *c = wl_container_of(listener, c, map); + Client *p, *w, *c = wl_container_of(listener, c, map); Monitor *m; int i; @@ -1695,7 +1694,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 != p && w->isfullscreen && m == w->mon && (w->tags & c->tags)) + if (w != c && w->isfullscreen && m == w->mon && (w->tags & c->tags)) setfullscreen(w, 0); } } @@ -2256,14 +2255,12 @@ setcursorshape(struct wl_listener *listener, void *data) void setfloating(Client *c, int floating) { - Client *p = client_get_parent(c); c->isfloating = floating; /* If in floating layout do not change the client's layer */ if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange) return; - wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || - (p && p->isfullscreen) ? LyrFS - : c->isfloating ? LyrFloat : LyrTile]); + wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen + ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); arrange(c->mon); printstatus(); } From bd5001b7801b694b8bfb13215848e56113708917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 13 Jul 2024 01:14:26 -0600 Subject: [PATCH 42/58] prepare CHANGELOG.md for 0.6 --- CHANGELOG.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 366728d..89de0ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,79 @@ ## Unreleased + ### Added + +* Add `rootcolor` to change the default background color ([#544][544]). +* Implement the wlr-virtual-pointer-unstable-v1 protocol ([#574][574]). +* Implement the pointer-constraints and relative-pointer protocols ([#317][317]) +* Implement the wlr-output-power-management protocol ([#599][599]) + +[544]: https://codeberg.org/dwl/dwl/pulls/544 +[574]: https://codeberg.org/dwl/dwl/pulls/574 +[317]: https://codeberg.org/dwl/dwl/issues/317 +[599]: https://codeberg.org/dwl/dwl/issues/559 + + ### Changed -### Deprecated + +* Keyboards are now managed through keyboard groups ([#549][549]). +* Only the first matched keybinding is executed. +* Allow toggling the layout before selecting a different one ([#570][570]). +* Fullscreen clients are now rendered above wlr_layer_surfaces in the top layer + ([#609][609]). +* The default menu was changed from `bemenu-run` to `wmenu-run` ([#553][553]). +* The option `sloppyfocus` now replicates the dwm behavior ([#599][599]). +* Allow configure position of monitors with negative values. (-1, -1) is + used to auto-configure them ([#635][635]). +* dwl now kills the entire process group of `startup_cmd` +* The O_NONBLOCK flag is set for stdout. + +[549]: https://codeberg.org/dwl/dwl/pulls/549 +[570]: https://codeberg.org/dwl/dwl/pulls/570 +[609]: https://codeberg.org/dwl/dwl/pulls/609 +[553]: https://codeberg.org/dwl/dwl/issues/553 +[599]: https://codeberg.org/dwl/dwl/pulls/599 +[635]: https://codeberg.org/dwl/dwl/pulls/635 + + ### Removed + +* The SLOC limit is now removed ([#497][497]). + +[497]: https://codeberg.org/dwl/dwl/pulls/497 + + ### Fixed -### Security + +* Clients not having the correct border color when mapping. +* Compliance with the xdg-decoration-unstable-v1 ([#546][546]). +* dwl no longer sends negative values in xdg_toplevel.configure events. +* Crashes with disabled monitors ([#472][472]). + +[546]: https://codeberg.org/dwl/dwl/pulls/546 +[472]: https://codeberg.org/dwl/dwl/issues/472 + + ### Contributors +Ben Jargowsky +Benjamin Chausse +David Donahue +Devin J. Pohly +Dima Krasner +Emil Miler +Forrest Bushstone +Guido Cella +Peter Hofmann +Rutherther +Squibid +choc +fictitiousexistence +korei999 +sewn +thanatos + ## 0.5 From 5a4839b1c8e1b171441a86a379ef30ddfb687421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 13 Jul 2024 16:34:01 -0600 Subject: [PATCH 43/58] bump version to 0.6 --- CHANGELOG.md | 2 +- config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89de0ca..6ef3d96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -* [Unreleased](#unreleased) +* [0.6](#0.6) * [0.5](#0.5) diff --git a/config.mk b/config.mk index 259bd0f..6fb4fb3 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -_VERSION = 0.5 +_VERSION = 0.6 VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` PKG_CONFIG = pkg-config From 12b44421c84367a67461f81cacf13297ae673c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 13 Jul 2024 20:23:04 -0600 Subject: [PATCH 44/58] bump to linux-dmabuf version 5 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 39b2d31..70d99ca 100644 --- a/dwl.c +++ b/dwl.c @@ -2468,7 +2468,7 @@ setup(void) if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) { wlr_drm_create(dpy, drw); wlr_scene_set_linux_dmabuf_v1(scene, - wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); + wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); } /* Autocreates an allocator for us. From 9a962ce136536689b289ac126a0ad3525a13f682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:01:36 -0600 Subject: [PATCH 45/58] Reapply "place child clients above fullscreen clients" This reverts commit 043ab3ac1335d7a1cd84fe0f9cea8056977211a4. --- client.h | 12 ++++++++++++ dwl.c | 13 ++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/client.h b/client.h index f0e5445..42f225f 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 4a1267b..2dbc5da 100644 --- a/dwl.c +++ b/dwl.c @@ -1427,7 +1427,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) { @@ -1685,7 +1685,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; @@ -1741,7 +1742,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); } } @@ -2304,12 +2305,14 @@ setcursorshape(struct wl_listener *listener, void *data) void setfloating(Client *c, int floating) { + Client *p = client_get_parent(c); c->isfloating = floating; /* If in floating layout do not change the client's layer */ if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange) 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(); } From efe10ea655de409d76e08b21913bf7cab72d4fec Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sun, 14 Jul 2024 21:02:45 -0600 Subject: [PATCH 46/58] use the parent scene node to determine if move clients out of LyrFloat [sevz: commit message is mine] --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 2dbc5da..5bf995e 100644 --- a/dwl.c +++ b/dwl.c @@ -504,7 +504,7 @@ arrange(Monitor *m) /* We move all clients (except fullscreen and unmanaged) to LyrTile while * in floating layout to avoid "real" floating clients be always on top */ wl_list_for_each(c, &clients, link) { - if (c->mon != m || c->isfullscreen) + if (c->mon != m || c->scene->node.parent == layers[LyrFS]) continue; wlr_scene_node_reparent(&c->scene->node, From c709b09e10ad6b4ccb63e7f75b17f0fdd488d4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:13:20 -0600 Subject: [PATCH 47/58] changelog: add new 'unreleased' section --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef3d96..62cccc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,21 @@ # Changelog +* [Unreleased](#unreleased) * [0.6](#0.6) * [0.5](#0.5) ## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors + + +## 0.6 ### Added From 0060e1922d600f7f2378b82477ec053654560267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:16:25 -0600 Subject: [PATCH 48/58] prepare CHANGELOG.md for 0.7 --- CHANGELOG.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62cccc6..c8e7a19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,22 @@ ## Unreleased + +This version is just 0.6 with wlroots 0.18 compatibility. + ### Added -### Changed -### Deprecated -### Removed -### Fixed -### Security + +* Add support for the alpha-modifier-v1 protocol ([wlroots!4616][wlroots!4616]). +* dwl now will survive GPU resets ([#601][601]). + +[wlroots!4616]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4616 +[601]: https://codeberg.org/dwl/dwl/issues/601 + + ### Contributors +Guido Cella + ## 0.6 From bd59573f07f27fff7870a1e1a70e72493bb42453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:22:08 -0600 Subject: [PATCH 49/58] bump version to 0.7-rc1 --- CHANGELOG.md | 4 ++-- config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e7a19..cc3edb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,11 @@ # Changelog -* [Unreleased](#unreleased) +* [0.7](#0.7) * [0.6](#0.6) * [0.5](#0.5) -## Unreleased +## 0.7 This version is just 0.6 with wlroots 0.18 compatibility. diff --git a/config.mk b/config.mk index 6fb4fb3..c5e3b4c 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -_VERSION = 0.6 +_VERSION = 0.7-rc1 VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` PKG_CONFIG = pkg-config From 7328e5691cb09c5a6937c9beea239743aed9ffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:33:37 -0600 Subject: [PATCH 50/58] changelog: add new 'unreleased' section --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc3edb5..3aefd6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,21 @@ # Changelog +* [Unreleased](#unreleased) * [0.7](#0.7) * [0.6](#0.6) * [0.5](#0.5) +## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors + + ## 0.7 This version is just 0.6 with wlroots 0.18 compatibility. From 51881da27bc95f303ec249ccc51eb9a8e0ee6ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:34:28 -0600 Subject: [PATCH 51/58] bump version to 0.8-dev --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index c5e3b4c..1d5ac38 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -_VERSION = 0.7-rc1 +_VERSION = 0.8-dev VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` PKG_CONFIG = pkg-config From 2553111aa39445f0d5e50963ab689ef677a3ad81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:34:44 -0600 Subject: [PATCH 52/58] bump wlroots version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3358bae..f955e7b 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wlroots-0.18 wayland-server xkbcommon libinput $(XLIBS) +PKGS = wlroots-0.19 wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) From da6de7c4d7a2858d463945dc185abc5ae7796960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:37:03 -0600 Subject: [PATCH 53/58] update wlr_xwayland_surface names (wlroots!2434) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/2434 --- client.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client.h b/client.h index 42f225f..c43dbfd 100644 --- a/client.h +++ b/client.h @@ -391,8 +391,8 @@ client_wants_focus(Client *c) { #ifdef XWAYLAND return client_is_unmanaged(c) - && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) - && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; + && wlr_xwayland_surface_override_redirect_wants_focus(c->surface.xwayland) + && wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; #endif return 0; } From 452a314faa18573fe100a03a154fdd0a0ad54ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:55:58 -0600 Subject: [PATCH 54/58] update README.md to mention the main branch now requires wlroots-git Closes: https://codeberg.org/dwl/dwl/issues/646 --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d91923..6161a53 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,9 @@ Xwayland (runtime only) ``` Simply install these (and their `-devel` versions if your distro has separate -development packages) and run `make`. If you wish to build against a Git -version of wlroots, check out the [wlroots-next branch]. +development packages) and run `make`. You need to use the Git version of +wlroots to build the `main` branch. If you wish to build against a released +version of wlroots, use a release or a [0.x branch]. To enable XWayland, you should uncomment its flags in `config.mk`. @@ -168,7 +169,7 @@ inspiration, and to the various contributors to the project, including: [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl [Wayland]: https://wayland.freedesktop.org/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next +[0.x branch]: https://codeberg.org/dwl/dwl/branches [patches repository]: https://codeberg.org/dwl/dwl-patches [s6]: https://skarnet.org/software/s6/ [anopa]: https://jjacky.com/anopa/ From ad30ca910b9da45835523af5c24ac353b7d13e9f Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Tue, 16 Jul 2024 23:02:22 -0500 Subject: [PATCH 55/58] Documentation restructuring Modified documentation to make clear the change in development (main) branch versus releases. --- README.md | 236 +++++++++++++++++++++++++++++------------------------- 1 file changed, 125 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 6161a53..cec84f5 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,132 @@ 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 functionality, and secondarily in terms of philosophy. -Like dwm, dwl is: +primarily in terms of functionality, and secondarily in terms of +philosophy. 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` - Tied to as few external dependencies as possible +## Getting Started: + +### Latest semi-stable [release] +This is probably where you want to start. This builds against the dependent +packages' versions currently shipping in major distributions. If your +distribution's wlroots version is older, use an earlier dwl [release] or [0.x +branch]. + +### Development branch [main] +Active development progresses on the `main` branch. The `main` branch is built +against a late (and often changing) git commit of wlroots. While the adventurous +are welcome to use `main`, it is a rocky road. Using `main` requires that the +user be willing to chase git commits of wlroots. Testing development pull +requests may involve merging unmerged pull requests in [wlroots]' git repository +and/or git commits of wayland. + +### Building dwl +dwl has the following dependencies: +- libinput +- wayland +- wlroots (compiled with the libinput backend) +- xkbcommon +- wayland-protocols (compile-time only) +- pkg-config (compile-time only) + +dwl has the following additional dependencies if XWayland support is enabled: +- libxcb +- libxcb-wm +- wlroots (compiled with X11 support) +- Xwayland (runtime only) + +Install these (and their `-devel` versions if your distro has separate +development packages) and run `make`. If you wish to build against a released +version of wlroots (*you probably do*), use a [release] or a [0.x branch]. If +you want to use the unstable development `main` branch, you need to use the git +version of [wlroots]. + +To enable XWayland, you should uncomment its flags in `config.mk`. + +## Configuration + +All configuration is done by editing `config.h` and recompiling, in the same +manner as dwm. There is no way to separately restart the window manager in +Wayland without restarting the entire display server, so any changes will take +effect the next time dwl is executed. + +As in the dwm community, we encourage users to share patches they have +created. Check out the [dwl-patches] repository! + +## Running dwl + +dwl can be run on any of the backends supported by wlroots. This means you can +run it as a separate window inside either an X11 or Wayland session, as well as +directly from a VT console. Depending on your distro's setup, you may need to +add your user to the `video` and `input` groups before you can run dwl on a +VT. If you are using `elogind` or `systemd-logind` you need to install polkit; +otherwise you need to add yourself in the `seat` group and enable/start the +seatd daemon. + +When dwl is run with no arguments, it will launch the server and begin handling +any shortcuts configured in `config.h`. There is no status bar or other +decoration initially; these are instead clients that can be run within the +Wayland session. Do note that the default background color is black. This can be +modified in `config.h`. + +If you would like to run a script or command automatically at startup, you can +specify the command using the `-s` option. This command will be executed as a +shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`, +but differs in that the display server will not shut down when this process +terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait +for it to terminate (if it hasn't already). This makes it ideal for execing into +a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd +--user`]. + +Note: The `-s` command is run as a *child process* of dwl, which means that it +does not have the ability to affect the environment of dwl or of any processes +that it spawns. If you need to set environment variables that affect the entire +dwl session, these must be set prior to running dwl. For example, Wayland +requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager +such as `elogind` or `systemd-logind`. If your system doesn't do this +automatically, you will need to configure it prior to launching `dwl`, e.g.: + + export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u) + mkdir -p $XDG_RUNTIME_DIR + dwl + +### Status information + +Information about selected layouts, current window title, app-id, and +selected/occupied/urgent tags is written to the stdin of the `-s` command (see +the `printstatus()` function for details). This information can be used to +populate an external status bar with a script that parses the +information. Failing to read this information will cause dwl to block, so if you +do want to run a startup command that does not consume the status information, +you can close standard input with the `<&-` shell redirection, for example: + + dwl -s 'foot --server <&-' + +If your startup command is a shell script, you can achieve the same inside the +script with the line + + exec <&- + +To get a list of status bars that work with dwl consult our [wiki]. + +## Replacements for X applications + +You can find a [list of useful resources on our wiki]. + +## Background + dwl is not meant to provide every feature under the sun. Instead, like dwm, it sticks to features which are necessary, simple, and straightforward to implement given the base on which it is built. Implemented default features are: - Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an - exception to this goal, to avoid dependencies on font rendering and/or - drawing libraries when an external bar could work well. + exception to this goal, to avoid dependencies on font rendering and/or drawing + libraries when an external bar could work well. - Configurable multi-monitor layout support, including position and rotation - Configurable HiDPI/multi-DPI support - Idle-inhibit protocol which lets applications such as mpv disable idle @@ -53,101 +164,6 @@ Feature *non-goals* for the main codebase include: be done through the compositor - Animations and visual effects -## Building dwl - -dwl has the following dependencies: -``` -libinput -wayland -wlroots (compiled with the libinput backend) -xkbcommon -wayland-protocols (compile-time only) -pkg-config (compile-time only) -``` -If you enable X11 support: -``` -libxcb -libxcb-wm -wlroots (compiled with X11 support) -Xwayland (runtime only) -``` - -Simply install these (and their `-devel` versions if your distro has separate -development packages) and run `make`. You need to use the Git version of -wlroots to build the `main` branch. If you wish to build against a released -version of wlroots, use a release or a [0.x branch]. - -To enable XWayland, you should uncomment its flags in `config.mk`. - -## Configuration - -All configuration is done by editing `config.h` and recompiling, in the same -manner as dwm. There is no way to separately restart the window manager in -Wayland without restarting the entire display server, so any changes will take -effect the next time dwl is executed. - -As in the dwm community, we encourage users to share patches they have created. -Check out the dwl [patches repository]! - -## Running dwl - -dwl can be run on any of the backends supported by wlroots. This means you can -run it as a separate window inside either an X11 or Wayland session, as well -as directly from a VT console. Depending on your distro's setup, you may need -to add your user to the `video` and `input` groups before you can run dwl on -a VT. If you are using `elogind` or `systemd-logind` you need to install -polkit; otherwise you need to add yourself in the `seat` group and -enable/start the seatd daemon. - -When dwl is run with no arguments, it will launch the server and begin handling -any shortcuts configured in `config.h`. There is no status bar or other -decoration initially; these are instead clients that can be run within -the Wayland session. -Do note that the background color is black. - -If you would like to run a script or command automatically at startup, you can -specify the command using the `-s` option. This command will be executed as a -shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`, -but differs in that the display server will not shut down when this process -terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait -for it to terminate (if it hasn't already). This makes it ideal for execing into -a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd --user`]. - -Note: The `-s` command is run as a *child process* of dwl, which means that it -does not have the ability to affect the environment of dwl or of any processes -that it spawns. If you need to set environment variables that affect the entire -dwl session, these must be set prior to running dwl. For example, Wayland -requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager -such as `elogind` or `systemd-logind`. If your system doesn't do this -automatically, you will need to configure it prior to launching `dwl`, e.g.: - - export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u) - mkdir -p $XDG_RUNTIME_DIR - dwl - -### Status information - -Information about selected layouts, current window title, app-id, and -selected/occupied/urgent tags is written to the stdin of the `-s` command (see -the `printstatus()` function for details). This information can be used to -populate an external status bar with a script that parses the information. -Failing to read this information will cause dwl to block, so if you do want to -run a startup command that does not consume the status information, you can -close standard input with the `<&-` shell redirection, for example: - - dwl -s 'foot --server <&-' - -If your startup command is a shell script, you can achieve the same inside the -script with the line - - exec <&- - -To get a list of status bars that work with dwl consult our [wiki]. - -## Replacements for X applications - -You can find a [list of useful resources on our wiki]. - ## Acknowledgements dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots @@ -165,17 +181,15 @@ inspiration, and to the various contributors to the project, including: - Stivvo for output management and fullscreen support, and patch maintenance -[Discord server]: https://discord.gg/jJxZnrGPWN -[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl -[Wayland]: https://wayland.freedesktop.org/ -[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[0.x branch]: https://codeberg.org/dwl/dwl/branches -[patches repository]: https://codeberg.org/dwl/dwl-patches -[s6]: https://skarnet.org/software/s6/ +[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl +[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 [0.x branch]: https://codeberg.org/dwl/dwl/branches [anopa]: https://jjacky.com/anopa/ -[runit]: http://smarden.org/runit/faq.html#userservices [dinit]: https://davmac.org/projects/dinit/ -[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User -[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars -[list of useful resources on our wiki]: - https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[dwl-patches]: https://codeberg.org/dwl/dwl-patches [list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[main]: https://codeberg.org/dwl/dwl/src/branch/main +[release]: https://codeberg.org/dwl/dwl/releases +[runit]: http://smarden.org/runit/faq.html#userservices +[s6]: https://skarnet.org/software/s6/ +[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ +[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN +[Wayland]: https://wayland.freedesktop.org/ From ea6a4501213e73119c4f17c05d7122fcbb9bfd0d Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sun, 21 Jul 2024 14:28:08 -0500 Subject: [PATCH 56/58] README.md Fix links formatting issue after re-flow text to 80 columns --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cec84f5..90222e6 100644 --- a/README.md +++ b/README.md @@ -181,15 +181,19 @@ inspiration, and to the various contributors to the project, including: - Stivvo for output management and fullscreen support, and patch maintenance -[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl -[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 [0.x branch]: https://codeberg.org/dwl/dwl/branches +[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User +[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl +[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 +[0.x branch]: https://codeberg.org/dwl/dwl/branches [anopa]: https://jjacky.com/anopa/ [dinit]: https://davmac.org/projects/dinit/ -[dwl-patches]: https://codeberg.org/dwl/dwl-patches [list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[dwl-patches]: https://codeberg.org/dwl/dwl-patches +[list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x [main]: https://codeberg.org/dwl/dwl/src/branch/main [release]: https://codeberg.org/dwl/dwl/releases [runit]: http://smarden.org/runit/faq.html#userservices [s6]: https://skarnet.org/software/s6/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN +[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars +[Discord server]: https://discord.gg/jJxZnrGPWN [Wayland]: https://wayland.freedesktop.org/ From 4bbbb4907ec3e239353aa6ba8685ab1aa4a5fea5 Mon Sep 17 00:00:00 2001 From: Lennart Jablonka Date: Tue, 23 Jul 2024 20:12:00 +0200 Subject: [PATCH 57/58] add myself to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..911248c --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Lennart Jablonka From f2c5023a3a6b9abd45c81e7547b111fb5ab119bf Mon Sep 17 00:00:00 2001 From: Lennart Jablonka Date: Tue, 23 Jul 2024 20:14:51 +0200 Subject: [PATCH 58/58] dwl(1): use correct special characters for - and ' The hyphen-minus <-> and apostrophe-quote <'> are interpreted by troff as hyphen and right single quotation mark. See groff_char(7). Fixes: 0db6f3c5b5f9 ("add dwl(1)") --- dwl.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.1 b/dwl.1 index 387bcc9..780c78f 100644 --- a/dwl.1 +++ b/dwl.1 @@ -140,7 +140,7 @@ server. Start .Nm with s6 in the background: -.Dl dwl -s 's6-svscan <&-' +.Dl dwl \-s \(aqs6\-svscan <&\-\(aq .Sh SEE ALSO .Xr foot 1 , .Xr wmenu 1 ,