From 3300f6c9114885160706e1599801b5000de1dd31 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Tue, 18 Jan 2022 11:33:56 -0600 Subject: [PATCH 01/47] Upgrade for wlroots surface refactoring See [1] for details. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3412 --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 8683462..5020a78 100644 --- a/dwl.c +++ b/dwl.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -2029,6 +2030,7 @@ setup(void) wlr_gamma_control_manager_v1_create(dpy); wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); + wlr_subcompositor_create(dpy); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); From ed44bc0c9069e0b55a4765bca10a5ad87732f019 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Wed, 2 Feb 2022 23:18:58 -0600 Subject: [PATCH 02/47] update wlr-output-layout-get-box --- dwl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 8683462..ab34d56 100644 --- a/dwl.c +++ b/dwl.c @@ -863,7 +863,7 @@ createmon(struct wl_listener *listener, void *data) * output (such as DPI, scale factor, manufacturer, etc). */ wlr_output_layout_add(output_layout, wlr_output, r->x, r->y); - sgeom = *wlr_output_layout_get_box(output_layout, NULL); + wlr_output_layout_get_box(output_layout, NULL, &sgeom); /* When adding monitors, the geometries of all monitors must be updated */ wl_list_for_each(m, &mons, link) { @@ -2305,7 +2305,7 @@ updatemons(struct wl_listener *listener, void *data) struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create(); Monitor *m; - sgeom = *wlr_output_layout_get_box(output_layout, NULL); + wlr_output_layout_get_box(output_layout, NULL, &sgeom); wl_list_for_each(m, &mons, link) { struct wlr_output_configuration_head_v1 *config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); @@ -2314,7 +2314,8 @@ updatemons(struct wl_listener *listener, void *data) /* TODO: move focus if selmon is disabled */ /* Get the effective monitor geometry to use for surfaces */ - m->m = m->w = *wlr_output_layout_get_box(output_layout, m->wlr_output); + wlr_output_layout_get_box(output_layout, m->wlr_output, &(m->m)); + wlr_output_layout_get_box(output_layout, m->wlr_output, &(m->w)); /* Calculate the effective monitor geometry to use for clients */ arrangelayers(m); /* Don't move clients to the left output when plugging monitors */ From b8ce8d0fbb7cd1ad09ea15ded4a19dc1346e9bcd Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Thu, 3 Feb 2022 21:54:44 -0600 Subject: [PATCH 03/47] Account for changes expecting wlr_xdg_toplevel rather than wlr_xdg_surface --- client.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client.h b/client.h index 4fd1863..ce41c1c 100644 --- a/client.h +++ b/client.h @@ -39,7 +39,7 @@ client_activate_surface(struct wlr_surface *s, int activated) #endif if (wlr_surface_is_xdg_surface(s)) wlr_xdg_toplevel_set_activated( - wlr_xdg_surface_from_wlr_surface(s), activated); + wlr_xdg_surface_from_wlr_surface(s)->toplevel, activated); } static inline void @@ -121,7 +121,7 @@ client_send_close(Client *c) return; } #endif - wlr_xdg_toplevel_send_close(c->surface.xdg); + wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); } static inline void @@ -133,7 +133,7 @@ client_set_fullscreen(Client *c, int fullscreen) return; } #endif - wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen); + wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); } static inline uint32_t @@ -146,7 +146,7 @@ client_set_size(Client *c, uint32_t width, uint32_t height) return 0; } #endif - return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height); + return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height); } static inline void @@ -156,7 +156,7 @@ client_set_tiled(Client *c, uint32_t edges) if (client_is_x11(c)) return; #endif - wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP | + wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); } From 230d3432e9633da09a31ed933d8bcaff491db807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 5 Mar 2022 21:07:25 -0600 Subject: [PATCH 04/47] wlr_virtual_keyboard_v1 now has its own wlr_keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit which has its own wlr_input_device Signed-off-by: Leonardo Hernández Hernández --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index ec4beb2..fcb00da 100644 --- a/dwl.c +++ b/dwl.c @@ -2375,7 +2375,7 @@ void virtualkeyboard(struct wl_listener *listener, void *data) { struct wlr_virtual_keyboard_v1 *keyboard = data; - struct wlr_input_device *device = &keyboard->input_device; + struct wlr_input_device *device = &keyboard->keyboard.base; createkeyboard(device); } From a7c4f6100a81c68aad6faf9061332f1fbacddd98 Mon Sep 17 00:00:00 2001 From: Leonardo Hernandez Hernandez Date: Sun, 13 Feb 2022 14:32:47 -0600 Subject: [PATCH 05/47] use scene layer shell helper --- dwl.c | 138 +++------------------------------------------------------- 1 file changed, 5 insertions(+), 133 deletions(-) diff --git a/dwl.c b/dwl.c index 657bf8d..4a46542 100644 --- a/dwl.c +++ b/dwl.c @@ -144,6 +144,7 @@ typedef struct { /* Must be first */ unsigned int type; /* LayerShell */ struct wlr_scene_node *scene; + struct wlr_scene_layer_surface_v1 *scene_layer; struct wl_list link; struct wlr_layer_surface_v1 *layer_surface; @@ -151,18 +152,8 @@ typedef struct { struct wl_listener map; struct wl_listener unmap; struct wl_listener surface_commit; - - struct wlr_box geo; } LayerSurface; -typedef struct { - uint32_t singular_anchor; - uint32_t anchor_triplet; - int *positive_axis; - int *negative_axis; - int margin; -} Edge; - typedef struct { const char *symbol; void (*arrange)(Monitor *); @@ -206,9 +197,6 @@ typedef struct { /* function declarations */ static void applybounds(Client *c, struct wlr_box *bbox); -static void applyexclusive(struct wlr_box *usable_area, uint32_t anchor, - int32_t exclusive, int32_t margin_top, int32_t margin_right, - int32_t margin_bottom, int32_t margin_left); static void applyrules(Client *c); static void arrange(Monitor *m); static void arrangelayer(Monitor *m, struct wl_list *list, @@ -386,61 +374,6 @@ applybounds(Client *c, struct wlr_box *bbox) c->geom.y = bbox->y; } -void -applyexclusive(struct wlr_box *usable_area, - uint32_t anchor, int32_t exclusive, - int32_t margin_top, int32_t margin_right, - int32_t margin_bottom, int32_t margin_left) { - Edge edges[] = { - { // Top - .singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, - .anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, - .positive_axis = &usable_area->y, - .negative_axis = &usable_area->height, - .margin = margin_top, - }, - { // Bottom - .singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = NULL, - .negative_axis = &usable_area->height, - .margin = margin_bottom, - }, - { // Left - .singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT, - .anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = &usable_area->x, - .negative_axis = &usable_area->width, - .margin = margin_left, - }, - { // Right - .singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT, - .anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, - .positive_axis = NULL, - .negative_axis = &usable_area->width, - .margin = margin_right, - } - }; - for (size_t i = 0; i < LENGTH(edges); i++) { - if ((anchor == edges[i].singular_anchor || anchor == edges[i].anchor_triplet) - && exclusive + edges[i].margin > 0) { - if (edges[i].positive_axis) - *edges[i].positive_axis += exclusive + edges[i].margin; - if (edges[i].negative_axis) - *edges[i].negative_axis -= exclusive + edges[i].margin; - break; - } - } -} - void applyrules(Client *c) { @@ -492,72 +425,11 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wl_list_for_each(layersurface, list, link) { struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_layer_surface_v1_state *state = &wlr_layer_surface->current; - struct wlr_box bounds; - struct wlr_box box = { - .width = state->desired_width, - .height = state->desired_height - }; - const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT - | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP - | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; if (exclusive != (state->exclusive_zone > 0)) continue; - bounds = state->exclusive_zone == -1 ? full_area : *usable_area; - - // Horizontal axis - if ((state->anchor & both_horiz) && box.width == 0) { - box.x = bounds.x; - box.width = bounds.width; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { - box.x = bounds.x; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { - box.x = bounds.x + (bounds.width - box.width); - } else { - box.x = bounds.x + ((bounds.width / 2) - (box.width / 2)); - } - // Vertical axis - if ((state->anchor & both_vert) && box.height == 0) { - box.y = bounds.y; - box.height = bounds.height; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { - box.y = bounds.y; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { - box.y = bounds.y + (bounds.height - box.height); - } else { - box.y = bounds.y + ((bounds.height / 2) - (box.height / 2)); - } - // Margin - if ((state->anchor & both_horiz) == both_horiz) { - box.x += state->margin.left; - box.width -= state->margin.left + state->margin.right; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { - box.x += state->margin.left; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { - box.x -= state->margin.right; - } - if ((state->anchor & both_vert) == both_vert) { - box.y += state->margin.top; - box.height -= state->margin.top + state->margin.bottom; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { - box.y += state->margin.top; - } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { - box.y -= state->margin.bottom; - } - if (box.width < 0 || box.height < 0) { - wlr_layer_surface_v1_destroy(wlr_layer_surface); - continue; - } - layersurface->geo = box; - - if (state->exclusive_zone > 0) - applyexclusive(usable_area, state->anchor, state->exclusive_zone, - state->margin.top, state->margin.right, - state->margin.bottom, state->margin.left); - wlr_scene_node_set_position(layersurface->scene, box.x, box.y); - wlr_layer_surface_v1_configure(wlr_layer_surface, box.width, box.height); + wlr_scene_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area); } } @@ -916,9 +788,9 @@ createlayersurface(struct wl_listener *listener, void *data) wlr_layer_surface->data = layersurface; m = wlr_layer_surface->output->data; - layersurface->scene = wlr_scene_subsurface_tree_create( - layers[wlr_layer_surface->pending.layer], - wlr_layer_surface->surface); + layersurface->scene_layer = wlr_scene_layer_surface_v1_create( + layers[wlr_layer_surface->pending.layer], wlr_layer_surface); + layersurface->scene = layersurface->scene_layer->node; layersurface->scene->data = layersurface; wl_list_insert(&m->layers[wlr_layer_surface->pending.layer], From 98f33cd01dc452df411c07eab3b107f0172081f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 18 Mar 2022 17:20:31 -0600 Subject: [PATCH 06/47] follow up wlroots input device events renaming --- dwl.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/dwl.c b/dwl.c index fcb00da..8a1e3ea 100644 --- a/dwl.c +++ b/dwl.c @@ -619,7 +619,7 @@ axisnotify(struct wl_listener *listener, void *data) { /* This event is forwarded by the cursor when a pointer emits an axis event, * for example when you move the scroll wheel. */ - struct wlr_event_pointer_axis *event = data; + struct wlr_pointer_axis_event *event = data; wlr_idle_notify_activity(idle, seat); /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(seat, @@ -630,7 +630,7 @@ axisnotify(struct wl_listener *listener, void *data) void buttonpress(struct wl_listener *listener, void *data) { - struct wlr_event_pointer_button *event = data; + struct wlr_pointer_button_event *event = data; struct wlr_keyboard *keyboard; uint32_t mods; Client *c; @@ -1228,7 +1228,7 @@ keypress(struct wl_listener *listener, void *data) int i; /* This event is raised when a key is pressed or released. */ Keyboard *kb = wl_container_of(listener, kb, key); - struct wlr_event_keyboard_key *event = data; + struct wlr_keyboard_key_event *event = data; /* Translate libinput keycode -> xkbcommon */ uint32_t keycode = event->keycode + 8; @@ -1340,8 +1340,8 @@ motionabsolute(struct wl_listener *listener, void *data) * move the mouse over the window. You could enter the window from any edge, * so we have to warp the mouse there. There is also some hardware which * emits these events. */ - struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(cursor, event->device, event->x, event->y); + struct wlr_pointer_motion_absolute_event *event = data; + wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y); motionnotify(event->time_msec); } @@ -1416,14 +1416,13 @@ motionrelative(struct wl_listener *listener, void *data) { /* This event is forwarded by the cursor when a pointer emits a _relative_ * pointer motion event (i.e. a delta) */ - struct wlr_event_pointer_motion *event = data; + struct wlr_pointer_motion_event *event = data; /* The cursor doesn't move unless we tell it to. The cursor automatically * handles constraining the motion to the output layout, as well as any * special configuration applied for the specific input device which * generated the event. You can pass NULL for the device if you want to move * the cursor around without any input. */ - wlr_cursor_move(cursor, event->device, - event->delta_x, event->delta_y); + wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, event->delta_y); motionnotify(event->time_msec); } From 0662bc5a69cac39b92644c60534b5490d139e2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 09:01:01 -0600 Subject: [PATCH 07/47] wlr_seat_set_keyboard() now takes wlr_keyboard as parameter --- dwl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dwl.c b/dwl.c index d9f2ae1..bac2e8c 100644 --- a/dwl.c +++ b/dwl.c @@ -129,7 +129,7 @@ typedef struct { typedef struct { struct wl_list link; - struct wlr_input_device *device; + struct wlr_keyboard *wlr_keyboard; struct wl_listener modifiers; struct wl_listener key; @@ -643,7 +643,7 @@ createkeyboard(struct wlr_input_device *device) Keyboard *kb = device->data = calloc(1, sizeof(*kb)); if (!kb) EBARF("createkeyboard: calloc"); - kb->device = device; + kb->wlr_keyboard = device->keyboard; /* Prepare an XKB keymap and assign it to the keyboard. */ context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); @@ -660,7 +660,7 @@ createkeyboard(struct wlr_input_device *device) LISTEN(&device->keyboard->events.key, &kb->key, keypress); LISTEN(&device->events.destroy, &kb->destroy, cleanupkeyboard); - wlr_seat_set_keyboard(seat, device); + wlr_seat_set_keyboard(seat, device->keyboard); /* And add the keyboard to our list of keyboards */ wl_list_insert(&keyboards, &kb->link); @@ -1135,10 +1135,10 @@ keypress(struct wl_listener *listener, void *data) /* Get a list of keysyms based on the keymap for this keyboard */ const xkb_keysym_t *syms; int nsyms = xkb_state_key_get_syms( - kb->device->keyboard->xkb_state, keycode, &syms); + kb->wlr_keyboard->xkb_state, keycode, &syms); int handled = 0; - uint32_t mods = wlr_keyboard_get_modifiers(kb->device->keyboard); + uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard); wlr_idle_notify_activity(idle, seat); @@ -1149,7 +1149,7 @@ keypress(struct wl_listener *listener, void *data) if (!handled) { /* Pass unhandled keycodes along to the client. */ - wlr_seat_set_keyboard(seat, kb->device); + wlr_seat_set_keyboard(seat, kb->wlr_keyboard); wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, event->state); } @@ -1167,10 +1167,10 @@ keypressmod(struct wl_listener *listener, void *data) * same seat. You can swap out the underlying wlr_keyboard like this and * wlr_seat handles this transparently. */ - wlr_seat_set_keyboard(seat, kb->device); + wlr_seat_set_keyboard(seat, kb->wlr_keyboard); /* Send modifiers to the client. */ wlr_seat_keyboard_notify_modifiers(seat, - &kb->device->keyboard->modifiers); + &kb->wlr_keyboard->modifiers); } void From 4276410a3d575aad3f90ff81406382824389db28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 21 Mar 2022 13:52:33 -0600 Subject: [PATCH 08/47] improve floating detection mostly copied from sway --- client.h | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/client.h b/client.h index e4a87e1..db043d2 100644 --- a/client.h +++ b/client.h @@ -91,16 +91,37 @@ client_get_title(Client *c) static inline int client_is_float_type(Client *c) { + struct wlr_xdg_toplevel *toplevel; + struct wlr_xdg_toplevel_state state; + #ifdef XWAYLAND - if (client_is_x11(c)) - for (size_t i = 0; i < c->surface.xwayland->window_type_len; i++) - if (c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeDialog] || - c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeSplash] || - c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeToolbar] || - c->surface.xwayland->window_type[i] == netatom[NetWMWindowTypeUtility]) + if (client_is_x11(c)) { + struct wlr_xwayland_surface *surface = c->surface.xwayland; + struct wlr_xwayland_surface_size_hints *size_hints; + if (surface->modal) + return 1; + + for (size_t i = 0; i < surface->window_type_len; i++) + if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] || + surface->window_type[i] == netatom[NetWMWindowTypeSplash] || + surface->window_type[i] == netatom[NetWMWindowTypeToolbar] || + surface->window_type[i] == netatom[NetWMWindowTypeUtility]) return 1; + + size_hints = surface->size_hints; + if (size_hints && size_hints->min_width > 0 && size_hints->min_height > 0 + && (size_hints->max_width == size_hints->min_width || + size_hints->max_height == size_hints->min_height)) + return 1; + } #endif - return 0; + + toplevel = c->surface.xdg->toplevel; + state = toplevel->current; + return (state.min_width != 0 && state.min_height != 0 + && (state.min_width == state.max_width + || state.min_height == state.max_height)) + || toplevel->parent; } static inline int From 40db9c88eaa4c32832c0bf7f7da56b8b73598519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 21 Mar 2022 13:28:44 -0600 Subject: [PATCH 09/47] remove a useless resize in mapnotify() applyrules() calls setmon() which calls resize() --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index bac2e8c..c6b8ab9 100644 --- a/dwl.c +++ b/dwl.c @@ -1232,7 +1232,6 @@ mapnotify(struct wl_listener *listener, void *data) /* Set initial monitor, tags, floating status, and focus */ applyrules(c); - resize(c, c->geom.x, c->geom.y, c->geom.width, c->geom.height, 0); printstatus(); if (c->isfullscreen) From a7f77779078328e40eff41d3ee8102ebc6d41af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 21 Mar 2022 21:17:58 -0600 Subject: [PATCH 10/47] only skip frames if there are visible clients that have a resize --- dwl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index c6b8ab9..222cb62 100644 --- a/dwl.c +++ b/dwl.c @@ -1497,9 +1497,11 @@ rendermon(struct wl_listener *listener, void *data) int skip = 0; struct timespec now; - /* Render if no XDG clients have an outstanding resize. */ + /* Render if no XDG clients have an outstanding resize and are visible on + * this monitor. + */ wl_list_for_each(c, &clients, link) - skip = skip || c->resize; + skip = skip || (c->resize && VISIBLEON(c, m)); if (!skip && !wlr_scene_output_commit(m->scene_output)) return; From 23af627d80d3bf42ae5d0731a79b4634ace86f9f Mon Sep 17 00:00:00 2001 From: Sevz Date: Mon, 21 Mar 2022 22:34:30 -0600 Subject: [PATCH 11/47] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9b9eef4..64e2054 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,4 +7,16 @@ assignees: '' --- +## Info +dwl's commit: +wlroots version: +## Description + From f2be10fd43a38e0a727f679aae26737470a15a77 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Mon, 21 Mar 2022 23:03:52 +0100 Subject: [PATCH 12/47] implement drag and drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For brevity, only a single drag icon at a time is supported. Co-authored-by: Leonardo Hernández Hernández --- dwl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/dwl.c b/dwl.c index 222cb62..18c2d60 100644 --- a/dwl.c +++ b/dwl.c @@ -216,6 +216,7 @@ static void cursorframe(struct wl_listener *listener, void *data); static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); +static void dragicondestroy(struct wl_listener *listener, void *data); static void focusclient(Client *c, int lift); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -243,6 +244,7 @@ static void printstatus(void); static void quit(const Arg *arg); static void quitsignal(int signo); static void rendermon(struct wl_listener *listener, void *data); +static void requeststartdrag(struct wl_listener *listener, void *data); static void resize(Client *c, int x, int y, int w, int h, int interact); static void run(char *startup_cmd); static Client *selclient(void); @@ -257,6 +259,7 @@ static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setup(void); static void sigchld(int unused); static void spawn(const Arg *arg); +static void startdrag(struct wl_listener *listener, void *data); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); @@ -329,6 +332,9 @@ static struct wl_listener request_activate = {.notify = urgent}; static struct wl_listener request_cursor = {.notify = setcursor}; static struct wl_listener request_set_psel = {.notify = setpsel}; static struct wl_listener request_set_sel = {.notify = setsel}; +static struct wl_listener request_start_drag = {.notify = requeststartdrag}; +static struct wl_listener start_drag = {.notify = startdrag}; +static struct wl_listener drag_icon_destroy = {.notify = dragicondestroy}; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -896,6 +902,16 @@ destroynotify(struct wl_listener *listener, void *data) free(c); } +void +dragicondestroy(struct wl_listener *listener, void *data) +{ + struct wlr_drag_icon *icon = data; + wlr_scene_node_destroy(icon->data); + // Focus enter isn't sent during drag, so refocus the focused node. + focusclient(selclient(), 1); + motionnotify(0); +} + void togglefullscreen(const Arg *arg) { @@ -1273,11 +1289,16 @@ motionnotify(uint32_t time) /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { + struct wlr_drag_icon *icon; wlr_idle_notify_activity(idle, seat); /* Update selmon (even while dragging a window) */ if (sloppyfocus) selmon = xytomon(cursor->x, cursor->y); + + if (seat->drag && (icon = seat->drag->icon)) + wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, + cursor->y + icon->surface->sy); } /* If we are currently grabbing the mouse, handle and return */ @@ -1538,6 +1559,18 @@ resize(Client *c, int x, int y, int w, int h, int interact) c->geom.height - 2 * c->bw); } +void +requeststartdrag(struct wl_listener *listener, void *data) +{ + struct wlr_seat_request_start_drag_event *event = data; + + if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, + event->serial)) + wlr_seat_start_pointer_drag(seat, event->drag, event->serial); + else + wlr_data_source_destroy(event->drag->source); +} + void run(char *startup_cmd) { @@ -1850,6 +1883,8 @@ setup(void) wl_signal_add(&seat->events.request_set_cursor, &request_cursor); wl_signal_add(&seat->events.request_set_selection, &request_set_sel); wl_signal_add(&seat->events.request_set_primary_selection, &request_set_psel); + wl_signal_add(&seat->events.request_start_drag, &request_start_drag); + wl_signal_add(&seat->events.start_drag, &start_drag); output_mgr = wlr_output_manager_v1_create(dpy); wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); @@ -1900,6 +1935,19 @@ spawn(const Arg *arg) } } +void +startdrag(struct wl_listener *listener, void *data) +{ + struct wlr_drag *drag = data; + + if (!drag->icon) + return; + + drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrTop], drag->icon->surface); + wlr_scene_node_raise_to_top(drag->icon->data); + wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy); +} + void tag(const Arg *arg) { From d8ab893dab76c5f2921c30bde04fa141fb788b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 22 Mar 2022 15:02:02 -0600 Subject: [PATCH 13/47] clients now works as expected in drag motion --- dwl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dwl.c b/dwl.c index 18c2d60..0f742e4 100644 --- a/dwl.c +++ b/dwl.c @@ -1289,16 +1289,11 @@ motionnotify(uint32_t time) /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { - struct wlr_drag_icon *icon; wlr_idle_notify_activity(idle, seat); /* Update selmon (even while dragging a window) */ if (sloppyfocus) selmon = xytomon(cursor->x, cursor->y); - - if (seat->drag && (icon = seat->drag->icon)) - wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, - cursor->y + icon->surface->sy); } /* If we are currently grabbing the mouse, handle and return */ @@ -1437,6 +1432,7 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, { struct timespec now; int internal_call = !time; + struct wlr_drag_icon *icon; if (sloppyfocus && !internal_call && c && !client_is_unmanaged(c)) focusclient(c, 0); @@ -1458,6 +1454,13 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_enter(seat, surface, sx, sy); wlr_seat_pointer_notify_motion(seat, time, sx, sy); + /* If there are is a drag icon, update its position */ + /* For anyone who wants to change this function: for some reason + * (maybe a wlroots bug?, or is it intended?) if we change the node position + * before telling the seat for a motion, the clients don't recognize the drag */ + if (seat->drag && (icon = seat->drag->icon)) + wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, + cursor->y + icon->surface->sy); } void From 0db6f3c5b5f971bebfbbf8ec9bf94134f5506600 Mon Sep 17 00:00:00 2001 From: Humm Date: Wed, 5 Jan 2022 01:54:02 +0100 Subject: [PATCH 14/47] add dwl(1) Documentation is good. Man pages are documentation. A program without a man page is worthless. --- Makefile | 5 +- config.mk | 1 + dwl.1 | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 dwl.1 diff --git a/Makefile b/Makefile index 5ff69e9..536454f 100644 --- a/Makefile +++ b/Makefile @@ -15,10 +15,11 @@ clean: rm -f dwl *.o *-protocol.h *-protocol.c install: dwl - install -D dwl $(PREFIX)/bin/dwl + install -Dm755 dwl $(PREFIX)/bin/dwl + install -Dm644 dwl.1 $(MANDIR)/man1/dwl.1 uninstall: - rm -f $(PREFIX)/bin/dwl + rm -f $(PREFIX)/bin/dwl $(MANDIR)/man1/dwl.1 .PHONY: all clean install uninstall diff --git a/config.mk b/config.mk index d1b161e..960fc8a 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,6 @@ # paths PREFIX = /usr/local +MANDIR = $(PREFIX)/share/man # Default compile flags (overridable by environment) CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement diff --git a/dwl.1 b/dwl.1 new file mode 100644 index 0000000..eea0f70 --- /dev/null +++ b/dwl.1 @@ -0,0 +1,144 @@ +.Dd January 8, 2021 +.Dt DWL 1 +.Os +.Sh NAME +.Nm dwl +.Nd dwm for Wayland +.Sh SYNOPSIS +.Nm +.Op Fl s Ar command +.Sh DESCRIPTION +.Nm +is a Wayland compositor based on wlroots. +It is intended to fill the same space in the Wayland world that +.Nm dwm +does for X11. +.Pp +When given the +.Fl s +option, +.Nm +starts a shell process running +.Ar command +when starting. +When stopping, it sends +.Dv SIGTERM +to the child process and waits for it to exit. +.Pp +Users are encouraged to customize +.Nm +by editing the sources, in particular +.Pa config.h . +The default key bindings are as follows: +.Bl -tag -width 20n -offset indent -compact +.It Mod-[1-9] +Show only all windows with a tag. +.It Mod-Ctrl-[1-9] +Show all windows with a tag. +.It Mod-Shift-[1-9] +Move window to a single tag. +.It Mod-Ctrl-Shift-[1-9] +Toggle tag for window. +.It Mod-p +Spawn +.Nm bemenu-run . +.It Mod-Shift-Return +Spawn +.Nm alacritty . +.It Mod-[jk] +Move focus down/up the stack. +.It Mod-[id] +Increase/decrease number of windows in master area. +.It Mod-[hl] +Decrease/increase master area. +.It Mod-Return +Move window on top of stack or switch top of stack with second window. +.It Mod-Tab +Show only all windows with previous tag. +.It Mod-Shift-c +Close window. +.It Mod-t +Switch to tabbed layout. +.It Mod-f +Switch to floating layout. +.It Mod-m +Switch to monocle layout. +.It Mod-Space +Switch to previous layout. +.It Mod-Shift-Space +Toggle floating state of window. +.It Mod-e +Toggle fullscreen state of window. +.It Mod-0 +Show all windows. +.It Mod-Shift-0 +Set all tags for window. +.It Mod-, +Move focus to previous monitor. +.It Mod-. +Move focus to next monitor. +.It Mod-Shift-, +Move window to previous monitor. +.It Mod-Shift-. +Move window to next monitor. +.It Mod-Shift-q +Quit +.Nm . +.El +These might differ depending on your keyboard layout. +.Sh ENVIRONMENT +These environment variables are used by +.Nm : +.Bl -tag -width XDG_RUNTIME_DIR +.It Ev XDG_RUNTIME_DIR +A directory where temporary user files, such as the Wayland socket, +are stored. +.It Ev XDG_CONFIG_DIR +A directory containung configuration of various programs and +libraries, including libxkbcommon. +.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET +Tell how to connect to an underlying X11 or Wayland server. +.It Ev WLR_* +Various variables specific to wlroots. +.It Ev XKB_* , XLOCALEDIR , XCOMPOSEFILE +Various variables specific to libxkbcommon. +.It Ev XCURSOR_PATH +List of directories to search for XCursor themes in. +.It Ev HOME +A directory where there are always dear files there for you. +Waiting for you to clean them up. +.El +.Pp +These are set by +.Nm : +.Bl -tag -width WAYLAND_DISPLAY +.It Ev WAYLAND_DISPLAY +Tell how to connect to +.Nm . +.It Ev DISPLAY +If using +.Nm Xwayland , +tell how to connect to the +.Nm Xwayland +server. +.El +.Sh EXAMPLES +Start +.Nm +with s6 in the background: +.Dl dwl -s 's6-svscan <&-' +.Sh SEE ALSO +.Xr alacritty 1 , +.Xr bemenu 1 , +.Xr dwm 1 , +.Xr xkeyboard-config 7 +.Sh CAVEATS +The child process's standard input is connected with a pipe to +.Nm . +If the child process neither reads from the pipe nor closes its +standard input, +.Nm +will freeze after a while due to it blocking when writing to the full +pipe buffer. +.Sh BUGS +All of them. From 1a5b7e068b1bf0c02be2ae8b13aa1c85972226ab Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 3 Aug 2021 06:29:26 +0200 Subject: [PATCH 15/47] update IRC channel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d094599..13a0000 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ You can find a [list of Wayland applications on the sway wiki](https://github.co ## IRC channel -dwl's IRC channel is #dwl on irc.freenode.net. +dwl's IRC channel is #dwl on irc.libera.chat. ## Acknowledgements From 5a1debb5f0fec4f149f8a4490828116e3b1f3b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 22 Mar 2022 23:29:01 -0600 Subject: [PATCH 16/47] add sway LICENSE file part of the code in dwl is taken from sway, so credit it. dwm and sway are both licensed under the MIT license --- LICENSE | 2 +- LICENSE.sway | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 LICENSE.sway diff --git a/LICENSE b/LICENSE index e4bb015..658085a 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ dwl - dwm for Wayland Copyright © 2020 dwl team -See also the files LICENSE.tinywl and LICENSE.dwm. +See also the files LICENSE.tinywl, LICENSE.dwm and LICENSE.sway. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/LICENSE.sway b/LICENSE.sway new file mode 100644 index 0000000..3e0cacc --- /dev/null +++ b/LICENSE.sway @@ -0,0 +1,19 @@ +Copyright (c) 2016-2017 Drew DeVault + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From b42abeac69b08558c06611a725a997f4ad0affd8 Mon Sep 17 00:00:00 2001 From: Quentin Rameau Date: Mon, 12 Jul 2021 23:44:16 +0200 Subject: [PATCH 17/47] Add a configuration option for fullscreen locking Some people are annoyed to have this new behaviour forced for some application which use fake fullscreen. --- config.def.h | 1 + dwl.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 8408659..539dba6 100644 --- a/config.def.h +++ b/config.def.h @@ -1,6 +1,7 @@ /* appearance */ static const int sloppyfocus = 1; /* focus follows mouse */ static const unsigned int borderpx = 1; /* border pixel of windows */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0}; static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0}; static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0}; diff --git a/dwl.c b/dwl.c index 0f742e4..cf6889e 100644 --- a/dwl.c +++ b/dwl.c @@ -1050,7 +1050,7 @@ focusstack(const Arg *arg) { /* Focus the next or previous client (in tiling order) on selmon */ Client *c, *sel = selclient(); - if (!sel) + if (!sel || (sel->isfullscreen && lockfullscreen)) return; if (arg->i > 0) { wl_list_for_each(c, &sel->link, link) { From a41d6cb00fb4729b690ffd962cc814f42fe3f28f Mon Sep 17 00:00:00 2001 From: Palanix Date: Mon, 28 Feb 2022 23:46:24 +0100 Subject: [PATCH 18/47] Fix dwl freezing when resizing --- dwl.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index cf6889e..a198177 100644 --- a/dwl.c +++ b/dwl.c @@ -170,6 +170,7 @@ struct Monitor { unsigned int tagset[2]; double mfact; int nmaster; + int un_map; /* If a map/unmap happened on this monitor, then this should be true */ }; typedef struct { @@ -1252,6 +1253,8 @@ mapnotify(struct wl_listener *listener, void *data) if (c->isfullscreen) setfullscreen(c, 1); + + c->mon->un_map = 1; } void @@ -1521,17 +1524,27 @@ rendermon(struct wl_listener *listener, void *data) int skip = 0; struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + /* Render if no XDG clients have an outstanding resize and are visible on - * this monitor. - */ - wl_list_for_each(c, &clients, link) - skip = skip || (c->resize && VISIBLEON(c, m)); + * this monitor. */ + /* Checking m->un_map for every client is not optimal but works */ + wl_list_for_each(c, &clients, link) { + if ((c->resize && m->un_map) || (c->type == XDGShell + && (c->surface.xdg->pending.geometry.width != + c->surface.xdg->current.geometry.width + || c->surface.xdg->pending.geometry.height != + c->surface.xdg->current.geometry.height))) { + /* Lie */ + wlr_surface_send_frame_done(client_surface(c), &now); + skip = 1; + } + } if (!skip && !wlr_scene_output_commit(m->scene_output)) return; - /* Let clients know a frame has been rendered */ - clock_gettime(CLOCK_MONOTONIC, &now); wlr_scene_output_send_frame_done(m->scene_output, &now); + m->un_map = 0; } void @@ -2070,6 +2083,9 @@ unmapnotify(struct wl_listener *listener, void *data) grabc = NULL; } + if (c->mon) + c->mon->un_map = 1; + if (client_is_unmanaged(c)) { wlr_scene_node_destroy(c->scene); return; From 855e6c189806b195e7f2f851c37dd4a21d3e5366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 14:03:07 -0600 Subject: [PATCH 19/47] add note about how to change MODKEY for windows key --- config.def.h | 1 + 1 file changed, 1 insertion(+) diff --git a/config.def.h b/config.def.h index 539dba6..9bdf8b5 100644 --- a/config.def.h +++ b/config.def.h @@ -52,6 +52,7 @@ static const int repeat_delay = 600; static const int tap_to_click = 1; static const int natural_scrolling = 0; +/* If you want to use the windows key change this to WLR_MODIFIER_LOGO */ #define MODKEY WLR_MODIFIER_ALT #define TAGKEYS(KEY,SKEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ From 281c947e5f19b5c304baa51de9d90e69c80a5a9a Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Wed, 23 Mar 2022 22:01:04 +0100 Subject: [PATCH 20/47] inline the presentation variable This variable can be removed since with scene-graph wlr_presentation_surface_sampled_on_output no longer needs to be called. --- dwl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index a198177..2d58079 100644 --- a/dwl.c +++ b/dwl.c @@ -298,7 +298,6 @@ static struct wl_list fstack; /* focus order */ static struct wlr_idle *idle; static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_output_manager_v1 *output_mgr; -static struct wlr_presentation *presentation; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_cursor *cursor; @@ -1906,8 +1905,7 @@ setup(void) wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); wl_signal_add(&output_mgr->events.test, &output_mgr_test); - presentation = wlr_presentation_create(dpy, backend); - wlr_scene_set_presentation(scene, presentation); + wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); #ifdef XWAYLAND /* From f353a0e759037e13419ddab6747afd6b6c736cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 12:13:49 -0600 Subject: [PATCH 21/47] Revert "clients now works as expected in drag motion" This reverts commit 9aec6049ecbefe3618f34002d2239cc9462c07e9. this problem is caused because xytonode() returns the surface of the drag icon --- dwl.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/dwl.c b/dwl.c index 2d58079..71996e7 100644 --- a/dwl.c +++ b/dwl.c @@ -1291,11 +1291,16 @@ motionnotify(uint32_t time) /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { + struct wlr_drag_icon *icon; wlr_idle_notify_activity(idle, seat); /* Update selmon (even while dragging a window) */ if (sloppyfocus) selmon = xytomon(cursor->x, cursor->y); + + if (seat->drag && (icon = seat->drag->icon)) + wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, + cursor->y + icon->surface->sy); } /* If we are currently grabbing the mouse, handle and return */ @@ -1434,7 +1439,6 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, { struct timespec now; int internal_call = !time; - struct wlr_drag_icon *icon; if (sloppyfocus && !internal_call && c && !client_is_unmanaged(c)) focusclient(c, 0); @@ -1456,13 +1460,6 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_enter(seat, surface, sx, sy); wlr_seat_pointer_notify_motion(seat, time, sx, sy); - /* If there are is a drag icon, update its position */ - /* For anyone who wants to change this function: for some reason - * (maybe a wlroots bug?, or is it intended?) if we change the node position - * before telling the seat for a motion, the clients don't recognize the drag */ - if (seat->drag && (icon = seat->drag->icon)) - wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, - cursor->y + icon->surface->sy); } void From c2899bc00b03c8a4a6d11c2b9a00a4114949f427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 14:18:38 -0600 Subject: [PATCH 22/47] set position of the drag icon in startdrag() --- dwl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 71996e7..9f72768 100644 --- a/dwl.c +++ b/dwl.c @@ -1288,21 +1288,20 @@ motionnotify(uint32_t time) double sx = 0, sy = 0; Client *c = NULL; struct wlr_surface *surface = NULL; + struct wlr_drag_icon *icon; /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { - struct wlr_drag_icon *icon; wlr_idle_notify_activity(idle, seat); /* Update selmon (even while dragging a window) */ if (sloppyfocus) selmon = xytomon(cursor->x, cursor->y); - - if (seat->drag && (icon = seat->drag->icon)) - wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, - cursor->y + icon->surface->sy); } + if (seat->drag && (icon = seat->drag->icon)) + wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx, + cursor->y + icon->surface->sy); /* If we are currently grabbing the mouse, handle and return */ if (cursor_mode == CurMove) { /* Move the grabbed client to the new position. */ @@ -1955,7 +1954,7 @@ startdrag(struct wl_listener *listener, void *data) return; drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrTop], drag->icon->surface); - wlr_scene_node_raise_to_top(drag->icon->data); + motionnotify(0); wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy); } From 3e79a9a5d7a7d66effaca573798f4c5b77e99773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 13:50:08 -0600 Subject: [PATCH 23/47] fix drag icon's surface returned by xytonode --- dwl.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/dwl.c b/dwl.c index 9f72768..3f3f447 100644 --- a/dwl.c +++ b/dwl.c @@ -68,7 +68,7 @@ /* enums */ enum { CurNormal, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11Managed, X11Unmanaged }; /* client types */ -enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, NUM_LAYERS }; /* scene layers */ +enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrNoFocus, NUM_LAYERS }; /* scene layers */ #ifdef XWAYLAND enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ @@ -1784,6 +1784,7 @@ setup(void) layers[LyrFloat] = &wlr_scene_tree_create(&scene->node)->node; layers[LyrTop] = &wlr_scene_tree_create(&scene->node)->node; layers[LyrOverlay] = &wlr_scene_tree_create(&scene->node)->node; + layers[LyrNoFocus] = &wlr_scene_tree_create(&scene->node)->node; /* Create a renderer with the default implementation */ if (!(drw = wlr_renderer_autocreate(backend))) @@ -1953,7 +1954,7 @@ startdrag(struct wl_listener *listener, void *data) if (!drag->icon) return; - drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrTop], drag->icon->surface); + drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrNoFocus], drag->icon->surface); motionnotify(0); wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy); } @@ -2183,17 +2184,23 @@ xytonode(double x, double y, struct wlr_surface **psurface, struct wlr_surface *surface = NULL; Client *c = NULL; LayerSurface *l = NULL; + int i; + int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg }; - if ((node = wlr_scene_node_at(&scene->node, x, y, nx, ny))) { - if (node->type == WLR_SCENE_NODE_SURFACE) - surface = wlr_scene_surface_from_node(node)->surface; - /* Walk the tree to find a node that knows the client */ - for (pnode = node; pnode && !c; pnode = pnode->parent) - c = pnode->data; - if (c && c->type == LayerShell) { - c = NULL; - l = pnode->data; + for (i = 0; i < LENGTH(focus_order); i++) { + if ((node = wlr_scene_node_at(layers[focus_order[i]], x, y, nx, ny))) { + if (node->type == WLR_SCENE_NODE_SURFACE) + surface = wlr_scene_surface_from_node(node)->surface; + /* Walk the tree to find a node that knows the client */ + for (pnode = node; pnode && !c; pnode = pnode->parent) + c = pnode->data; + if (c && c->type == LayerShell) { + c = NULL; + l = pnode->data; + } } + if (surface) + break; } if (psurface) *psurface = surface; From faaee90cbd42d991f6e96e516035df2a1bab8361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 20 Mar 2022 19:09:28 -0600 Subject: [PATCH 24/47] destroy scene_output in cleanupmon() --- dwl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dwl.c b/dwl.c index 3f3f447..86f8c34 100644 --- a/dwl.c +++ b/dwl.c @@ -582,6 +582,7 @@ cleanupmon(struct wl_listener *listener, void *data) wl_list_remove(&m->frame.link); wl_list_remove(&m->link); wlr_output_layout_remove(output_layout, m->wlr_output); + wlr_scene_output_destroy(m->scene_output); if ((nmons = wl_list_length(&mons))) do /* don't switch to disabled mons */ From f75e4262229e26ea159742b96f6b63aef472ed8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 17:05:21 -0600 Subject: [PATCH 25/47] createkeyboard now takes wlr_keyboard --- dwl.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dwl.c b/dwl.c index 86f8c34..99205c1 100644 --- a/dwl.c +++ b/dwl.c @@ -208,7 +208,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 createkeyboard(struct wlr_input_device *device); +static void createkeyboard(struct wlr_keyboard *keyboard); static void createmon(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data); static void createlayersurface(struct wl_listener *listener, void *data); @@ -562,7 +562,7 @@ void cleanupkeyboard(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - Keyboard *kb = device->data; + Keyboard *kb = device->keyboard->data; wl_list_remove(&kb->link); wl_list_remove(&kb->modifiers.link); @@ -643,31 +643,31 @@ commitnotify(struct wl_listener *listener, void *data) } void -createkeyboard(struct wlr_input_device *device) +createkeyboard(struct wlr_keyboard *keyboard) { struct xkb_context *context; struct xkb_keymap *keymap; - Keyboard *kb = device->data = calloc(1, sizeof(*kb)); + Keyboard *kb = keyboard->data = calloc(1, sizeof(*kb)); if (!kb) EBARF("createkeyboard: calloc"); - kb->wlr_keyboard = device->keyboard; + kb->wlr_keyboard = keyboard; /* Prepare an XKB keymap and assign it to the keyboard. */ context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); keymap = xkb_keymap_new_from_names(context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS); - wlr_keyboard_set_keymap(device->keyboard, keymap); + wlr_keyboard_set_keymap(keyboard, keymap); xkb_keymap_unref(keymap); xkb_context_unref(context); - wlr_keyboard_set_repeat_info(device->keyboard, repeat_rate, repeat_delay); + wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay); /* Here we set up listeners for keyboard events. */ - LISTEN(&device->keyboard->events.modifiers, &kb->modifiers, keypressmod); - LISTEN(&device->keyboard->events.key, &kb->key, keypress); - LISTEN(&device->events.destroy, &kb->destroy, cleanupkeyboard); + LISTEN(&keyboard->events.modifiers, &kb->modifiers, keypressmod); + LISTEN(&keyboard->events.key, &kb->key, keypress); + LISTEN(&keyboard->base.events.destroy, &kb->destroy, cleanupkeyboard); - wlr_seat_set_keyboard(seat, device->keyboard); + wlr_seat_set_keyboard(seat, keyboard); /* And add the keyboard to our list of keyboards */ wl_list_insert(&keyboards, &kb->link); @@ -1099,7 +1099,7 @@ inputdevice(struct wl_listener *listener, void *data) switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - createkeyboard(device); + createkeyboard(device->keyboard); break; case WLR_INPUT_DEVICE_POINTER: createpointer(device); @@ -2174,7 +2174,7 @@ virtualkeyboard(struct wl_listener *listener, void *data) { struct wlr_virtual_keyboard_v1 *keyboard = data; struct wlr_input_device *device = &keyboard->keyboard.base; - createkeyboard(device); + createkeyboard(device->keyboard); } struct wlr_scene_node * From 7018ed9218b05e15d191adcae04167f9d6fc8bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 23 Mar 2022 17:08:44 -0600 Subject: [PATCH 26/47] createpointer now takes wlr_pointer --- dwl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 99205c1..3f66be4 100644 --- a/dwl.c +++ b/dwl.c @@ -212,7 +212,7 @@ static void createkeyboard(struct wlr_keyboard *keyboard); static void createmon(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data); static void createlayersurface(struct wl_listener *listener, void *data); -static void createpointer(struct wlr_input_device *device); +static void createpointer(struct wlr_pointer *pointer); static void cursorframe(struct wl_listener *listener, void *data); static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); @@ -831,11 +831,11 @@ createlayersurface(struct wl_listener *listener, void *data) } void -createpointer(struct wlr_input_device *device) +createpointer(struct wlr_pointer *pointer) { - if (wlr_input_device_is_libinput(device)) { + if (wlr_input_device_is_libinput(&pointer->base)) { struct libinput_device *libinput_device = (struct libinput_device*) - wlr_libinput_get_device_handle(device); + wlr_libinput_get_device_handle(&pointer->base); if (tap_to_click && libinput_device_config_tap_get_finger_count(libinput_device)) libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -848,7 +848,7 @@ createpointer(struct wlr_input_device *device) * is proxied through wlr_cursor. On another compositor, you might take this * opportunity to do libinput configuration on the device to set * acceleration, etc. */ - wlr_cursor_attach_input_device(cursor, device); + wlr_cursor_attach_input_device(cursor, &pointer->base); } void @@ -1102,7 +1102,7 @@ inputdevice(struct wl_listener *listener, void *data) createkeyboard(device->keyboard); break; case WLR_INPUT_DEVICE_POINTER: - createpointer(device); + createpointer(device->pointer); break; default: /* TODO handle other input device types */ From e08bd1292288f662eb265461a8c1a9d7501b0445 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 29 Mar 2022 15:55:06 -0500 Subject: [PATCH 27/47] make sure to leave XWayland process waitable On SIGCHLD, check to make sure the terminated process is not the XWayland process before reaping it, allowing wlroots to waitpid() for it successfully. Fixes #177. --- dwl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 3f66be4..a14dc5c 100644 --- a/dwl.c +++ b/dwl.c @@ -1925,6 +1925,7 @@ setup(void) void sigchld(int unused) { + siginfo_t in; /* We should be able to remove this function in favor of a simple * signal(SIGCHLD, SIG_IGN); * but the Xwayland implementation in wlroots currently prevents us from @@ -1932,8 +1933,12 @@ sigchld(int unused) */ if (signal(SIGCHLD, sigchld) == SIG_ERR) EBARF("can't install SIGCHLD handler"); - while (0 < waitpid(-1, NULL, WNOHANG)) - ; + /* WNOWAIT leaves the child in a waitable state, in case this is the + * XWayland process + */ + while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid + && in.si_pid != xwayland->server->pid) + waitpid(in.si_pid, NULL, 0); } void From 0ddde0c85a46370759e85f3437e3475b569d5c41 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 29 Mar 2022 16:09:29 -0500 Subject: [PATCH 28/47] move sigchld() into XWayland section --- dwl.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/dwl.c b/dwl.c index a14dc5c..ae5ed93 100644 --- a/dwl.c +++ b/dwl.c @@ -258,7 +258,6 @@ static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setup(void); -static void sigchld(int unused); static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); static void tag(const Arg *arg); @@ -341,6 +340,7 @@ static void activatex11(struct wl_listener *listener, void *data); static void configurex11(struct wl_listener *listener, void *data); static void createnotifyx11(struct wl_listener *listener, void *data); static Atom getatom(xcb_connection_t *xc, const char *name); +static void sigchld(int unused); static void xwaylandready(struct wl_listener *listener, void *data); static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11}; static struct wl_listener xwayland_ready = {.notify = xwaylandready}; @@ -1762,7 +1762,11 @@ setup(void) dpy = wl_display_create(); /* Set up signal handlers */ +#ifdef XWAYLAND sigchld(0); +#else + signal(SIGCHLD, SIG_IGN); +#endif signal(SIGINT, quitsignal); signal(SIGTERM, quitsignal); @@ -1922,25 +1926,6 @@ setup(void) #endif } -void -sigchld(int unused) -{ - siginfo_t in; - /* We should be able to remove this function in favor of a simple - * signal(SIGCHLD, SIG_IGN); - * but the Xwayland implementation in wlroots currently prevents us from - * setting our own disposition for SIGCHLD. - */ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - EBARF("can't install SIGCHLD handler"); - /* WNOWAIT leaves the child in a waitable state, in case this is the - * XWayland process - */ - while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && in.si_pid != xwayland->server->pid) - waitpid(in.si_pid, NULL, 0); -} - void spawn(const Arg *arg) { @@ -2317,6 +2302,25 @@ getatom(xcb_connection_t *xc, const char *name) return atom; } +void +sigchld(int unused) +{ + siginfo_t in; + /* We should be able to remove this function in favor of a simple + * signal(SIGCHLD, SIG_IGN); + * but the Xwayland implementation in wlroots currently prevents us from + * setting our own disposition for SIGCHLD. + */ + if (signal(SIGCHLD, sigchld) == SIG_ERR) + EBARF("can't install SIGCHLD handler"); + /* WNOWAIT leaves the child in a waitable state, in case this is the + * XWayland process + */ + while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid + && in.si_pid != xwayland->server->pid) + waitpid(in.si_pid, NULL, 0); +} + void xwaylandready(struct wl_listener *listener, void *data) { From 4a2e761914f88d4d284ec74b147104f53c394523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 12 Apr 2022 23:52:05 -0500 Subject: [PATCH 29/47] replace deleted EBARF() with die() --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index dd62956..06402c0 100644 --- a/dwl.c +++ b/dwl.c @@ -2339,7 +2339,7 @@ sigchld(int unused) * setting our own disposition for SIGCHLD. */ if (signal(SIGCHLD, sigchld) == SIG_ERR) - EBARF("can't install SIGCHLD handler"); + die("can't install SIGCHLD handler:"); /* WNOWAIT leaves the child in a waitable state, in case this is the * XWayland process */ From dc7709a00edebe323d8e192ff48f14f72f1e2142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 16 Apr 2022 15:51:13 -0500 Subject: [PATCH 30/47] schedule a configure on maximize request see maximizenotify() for more info --- dwl.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dwl.c b/dwl.c index 06402c0..f4ce462 100644 --- a/dwl.c +++ b/dwl.c @@ -104,6 +104,7 @@ typedef struct { } surface; struct wl_listener commit; struct wl_listener map; + struct wl_listener maximize; struct wl_listener unmap; struct wl_listener destroy; struct wl_listener set_title; @@ -233,6 +234,7 @@ static void keypressmod(struct wl_listener *listener, void *data); static void killclient(const Arg *arg); 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); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time); @@ -840,6 +842,8 @@ createnotify(struct wl_listener *listener, void *data) 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); c->isfullscreen = 0; } @@ -1254,6 +1258,18 @@ mapnotify(struct wl_listener *listener, void *data) c->mon->un_map = 1; } +void +maximizenotify(struct wl_listener *listener, void *data) +{ + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. dwl doesn't support maximization, but + * to conform to xdg-shell protocol we still must send a configure. + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ + Client *c = wl_container_of(listener, c, maximize); + wlr_xdg_surface_schedule_configure(c->surface.xdg); +} + void monocle(Monitor *m) { From 31fa6600a174d44be69d66c16dfefd80583409a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 8 May 2022 17:51:42 -0500 Subject: [PATCH 31/47] replace wlr_xwayland_surface_size_hints with xcb_size_hints_t --- client.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client.h b/client.h index db043d2..1796ef0 100644 --- a/client.h +++ b/client.h @@ -97,7 +97,7 @@ client_is_float_type(Client *c) #ifdef XWAYLAND if (client_is_x11(c)) { struct wlr_xwayland_surface *surface = c->surface.xwayland; - struct wlr_xwayland_surface_size_hints *size_hints; + xcb_size_hints_t *size_hints; if (surface->modal) return 1; @@ -208,8 +208,7 @@ client_min_size(Client *c, int *width, int *height) struct wlr_xdg_toplevel_state *state; #ifdef XWAYLAND if (client_is_x11(c)) { - struct wlr_xwayland_surface_size_hints *size_hints; - size_hints = c->surface.xwayland->size_hints; + xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints; *width = size_hints->min_width; *height = size_hints->min_height; return; From 79a148224ffb5a55510de691f95eda2d32c6d2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 15 May 2022 17:17:58 -0500 Subject: [PATCH 32/47] specify version in wlr_xdg_shell_create() --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 40ace0c..0acb22e 100644 --- a/dwl.c +++ b/dwl.c @@ -1896,7 +1896,7 @@ setup(void) layer_shell = wlr_layer_shell_v1_create(dpy); wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface); - xdg_shell = wlr_xdg_shell_create(dpy); + xdg_shell = wlr_xdg_shell_create(dpy, 2); wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface); input_inhibit_mgr = wlr_input_inhibit_manager_create(dpy); From 283c043b5c8cc6f2d5b8a5e72e1a5924b2c1532e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 21 May 2022 20:44:08 -0500 Subject: [PATCH 33/47] chase wlroots scene-surface refactor --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 84e5f2e..65cb97a 100644 --- a/dwl.c +++ b/dwl.c @@ -2253,8 +2253,9 @@ xytonode(double x, double y, struct wlr_surface **psurface, for (layer = focus_order; layer < END(focus_order); layer++) { if ((node = wlr_scene_node_at(layers[*layer], x, y, nx, ny))) { - if (node->type == WLR_SCENE_NODE_SURFACE) - surface = wlr_scene_surface_from_node(node)->surface; + if (node->type == WLR_SCENE_NODE_BUFFER) + surface = wlr_scene_surface_from_buffer( + wlr_scene_buffer_from_node(node))->surface; /* Walk the tree to find a node that knows the client */ for (pnode = node; pnode && !c; pnode = pnode->parent) c = pnode->data; From c7007b48115ac4913fad7e887c402f1c643f51bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 7 Jun 2022 00:31:58 -0500 Subject: [PATCH 34/47] chase wlroots scene-tree changes --- dwl.c | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/dwl.c b/dwl.c index 65cb97a..8d08810 100644 --- a/dwl.c +++ b/dwl.c @@ -94,9 +94,9 @@ typedef struct Monitor Monitor; typedef struct { /* Must be first */ unsigned int type; /* XDGShell or X11* */ - struct wlr_scene_node *scene; + struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ - struct wlr_scene_node *scene_surface; + struct wlr_scene_tree *scene_surface; struct wl_list link; struct wl_list flink; union { @@ -144,7 +144,7 @@ typedef struct { /* Must be first */ unsigned int type; /* LayerShell */ int mapped; - struct wlr_scene_node *scene; + struct wlr_scene_tree *scene; struct wlr_scene_layer_surface_v1 *scene_layer; struct wl_list link; struct wlr_layer_surface_v1 *layer_surface; @@ -291,7 +291,7 @@ static const char broken[] = "broken"; static struct wl_display *dpy; static struct wlr_backend *backend; static struct wlr_scene *scene; -static struct wlr_scene_node *layers[NUM_LAYERS]; +static struct wlr_scene_tree *layers[NUM_LAYERS]; static struct wlr_renderer *drw; static struct wlr_allocator *alloc; static struct wlr_compositor *compositor; @@ -412,7 +412,7 @@ applyrules(Client *c) mon = m; } } - wlr_scene_node_reparent(c->scene, layers[c->isfloating ? LyrFloat : LyrTile]); + wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); setmon(c, mon, newtags); } @@ -421,7 +421,7 @@ arrange(Monitor *m) { Client *c; wl_list_for_each(c, &clients, link) - wlr_scene_node_set_enabled(c->scene, VISIBLEON(c, c->mon)); + wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, c->mon)); if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); @@ -632,7 +632,7 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) struct wlr_output *wlr_output = wlr_layer_surface->output; Monitor *m; - wlr_scene_node_reparent(layersurface->scene, + wlr_scene_node_reparent(&layersurface->scene->node, layers[wlr_layer_surface->current.layer]); if (!wlr_output || !(m = wlr_output->data)) @@ -730,9 +730,9 @@ createlayersurface(struct wl_listener *listener, void *data) layersurface->scene_layer = wlr_scene_layer_surface_v1_create( layers[wlr_layer_surface->pending.layer], wlr_layer_surface); layersurface->scene = wlr_layer_surface->surface->data = - layersurface->scene_layer->node; + &layersurface->scene_layer->tree->node; - layersurface->scene->data = layersurface; + layersurface->scene->node.data = layersurface; wl_list_insert(&m->layers[wlr_layer_surface->pending.layer], &layersurface->link); @@ -969,7 +969,7 @@ focusclient(Client *c, int lift) /* Raise client in stacking order if requested */ if (c && lift) - wlr_scene_node_raise_to_top(c->scene); + wlr_scene_node_raise_to_top(&c->scene->node); if (c && client_surface(c) == old) return; @@ -1236,17 +1236,17 @@ mapnotify(struct wl_listener *listener, void *data) int i; /* Create scene tree for this client and its border */ - c->scene = &wlr_scene_tree_create(layers[LyrTile])->node; + c->scene = wlr_scene_tree_create(layers[LyrTile]); c->scene_surface = client_surface(c)->data = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - c->scene_surface->data = c; + c->scene_surface->node.data = c; if (client_is_unmanaged(c)) { client_get_geometry(c, &c->geom); /* Floating */ - wlr_scene_node_reparent(c->scene, layers[LyrFloat]); - wlr_scene_node_set_position(c->scene, c->geom.x + borderpx, + 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); return; } @@ -1590,8 +1590,8 @@ resize(Client *c, int x, int y, int w, int h, int interact) applybounds(c, bbox); /* Update scene-graph, including borders */ - wlr_scene_node_set_position(c->scene, c->geom.x, c->geom.y); - wlr_scene_node_set_position(c->scene_surface, c->bw, c->bw); + wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw); wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw); wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw); @@ -1710,7 +1710,7 @@ void setfloating(Client *c, int floating) { c->isfloating = floating; - wlr_scene_node_reparent(c->scene, layers[c->isfloating ? LyrFloat : LyrTile]); + wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); arrange(c->mon); printstatus(); } @@ -1836,13 +1836,13 @@ setup(void) /* Initialize the scene graph used to lay out windows */ scene = wlr_scene_create(); - layers[LyrBg] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrBottom] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrTile] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrFloat] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrTop] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrOverlay] = &wlr_scene_tree_create(&scene->node)->node; - layers[LyrNoFocus] = &wlr_scene_tree_create(&scene->node)->node; + layers[LyrBg] = wlr_scene_tree_create(&scene->tree); + layers[LyrBottom] = wlr_scene_tree_create(&scene->tree); + layers[LyrTile] = wlr_scene_tree_create(&scene->tree); + layers[LyrFloat] = wlr_scene_tree_create(&scene->tree); + layers[LyrTop] = wlr_scene_tree_create(&scene->tree); + layers[LyrOverlay] = wlr_scene_tree_create(&scene->tree); + layers[LyrNoFocus] = wlr_scene_tree_create(&scene->tree); /* Create a renderer with the default implementation */ if (!(drw = wlr_renderer_autocreate(backend))) @@ -2139,14 +2139,14 @@ unmapnotify(struct wl_listener *listener, void *data) c->mon->un_map = 1; if (client_is_unmanaged(c)) { - wlr_scene_node_destroy(c->scene); + wlr_scene_node_destroy(&c->scene->node); return; } wl_list_remove(&c->link); setmon(c, NULL, 0); wl_list_remove(&c->flink); - wlr_scene_node_destroy(c->scene); + wlr_scene_node_destroy(&c->scene->node); printstatus(); } @@ -2252,12 +2252,12 @@ xytonode(double x, double y, struct wlr_surface **psurface, int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg }; for (layer = focus_order; layer < END(focus_order); layer++) { - if ((node = wlr_scene_node_at(layers[*layer], x, y, nx, ny))) { + if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) { if (node->type == WLR_SCENE_NODE_BUFFER) surface = wlr_scene_surface_from_buffer( wlr_scene_buffer_from_node(node))->surface; /* Walk the tree to find a node that knows the client */ - for (pnode = node; pnode && !c; pnode = pnode->parent) + for (pnode = node; pnode && !c; pnode = &pnode->parent->node) c = pnode->data; if (c && c->type == LayerShell) { c = NULL; From 4b890336e21edc6a69bd3463b22a4c1318a669e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 7 Jun 2022 00:55:41 -0500 Subject: [PATCH 35/47] use xdg-shell v3 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 8d08810..a71f294 100644 --- a/dwl.c +++ b/dwl.c @@ -1901,7 +1901,7 @@ setup(void) layer_shell = wlr_layer_shell_v1_create(dpy); wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface); - xdg_shell = wlr_xdg_shell_create(dpy, 2); + xdg_shell = wlr_xdg_shell_create(dpy, 3); wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface); input_inhibit_mgr = wlr_input_inhibit_manager_create(dpy); From 948fdcf709e86f380eef26ee529683d2c396e58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 9 Jun 2022 12:45:02 -0500 Subject: [PATCH 36/47] use xdg-shell v4 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index a71f294..852eecf 100644 --- a/dwl.c +++ b/dwl.c @@ -1901,7 +1901,7 @@ setup(void) layer_shell = wlr_layer_shell_v1_create(dpy); wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface); - xdg_shell = wlr_xdg_shell_create(dpy, 3); + xdg_shell = wlr_xdg_shell_create(dpy, 4); wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface); input_inhibit_mgr = wlr_input_inhibit_manager_create(dpy); From a32db11f16fae3f57af3795d2463996b95e7ba1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 9 Jun 2022 12:45:42 -0500 Subject: [PATCH 37/47] set client bounds at resize --- client.h | 10 ++++++++++ dwl.c | 1 + 2 files changed, 11 insertions(+) diff --git a/client.h b/client.h index 6648c59..9431d11 100644 --- a/client.h +++ b/client.h @@ -45,6 +45,16 @@ client_activate_surface(struct wlr_surface *s, int activated) wlr_xdg_toplevel_set_activated(surface->toplevel, activated); } +static inline uint32_t +client_set_bounds(Client *c, int32_t width, int32_t height) +{ +#ifdef XWAYLAND + if (client_is_x11(c)) + return 0; +#endif + return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); +} + static inline void client_for_each_surface(Client *c, wlr_surface_iterator_func_t fn, void *data) { diff --git a/dwl.c b/dwl.c index 852eecf..b56abd7 100644 --- a/dwl.c +++ b/dwl.c @@ -1582,6 +1582,7 @@ resize(Client *c, int x, int y, int w, int h, int interact) { int min_width = 0, min_height = 0; struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; + client_set_bounds(c, w, h); client_min_size(c, &min_width, &min_height); c->geom.x = x; c->geom.y = y; From 461d02d3e03a5f0dc42fbb71dd8ab728b9c7e424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 21 Jun 2022 16:25:18 -0500 Subject: [PATCH 38/47] chase wlroots input_device changes --- dwl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index b56abd7..beab572 100644 --- a/dwl.c +++ b/dwl.c @@ -575,8 +575,7 @@ cleanup(void) void cleanupkeyboard(struct wl_listener *listener, void *data) { - struct wlr_input_device *device = data; - Keyboard *kb = device->keyboard->data; + Keyboard *kb = wlr_keyboard_from_input_device(data)->data; wl_list_remove(&kb->link); wl_list_remove(&kb->modifiers.link); @@ -1118,10 +1117,10 @@ inputdevice(struct wl_listener *listener, void *data) switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - createkeyboard(device->keyboard); + createkeyboard(wlr_keyboard_from_input_device(device)); break; case WLR_INPUT_DEVICE_POINTER: - createpointer(device->pointer); + createpointer(wlr_pointer_from_input_device(device)); break; default: /* TODO handle other input device types */ @@ -2230,8 +2229,7 @@ void virtualkeyboard(struct wl_listener *listener, void *data) { struct wlr_virtual_keyboard_v1 *keyboard = data; - struct wlr_input_device *device = &keyboard->keyboard.base; - createkeyboard(device->keyboard); + createkeyboard(&keyboard->keyboard); } Monitor * From 058c699ac2552db13ea8bbef64182c59cceaf55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 15 Jul 2022 00:27:31 -0500 Subject: [PATCH 39/47] only set bounds for clients that support it --- client.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client.h b/client.h index 9431d11..978c8e1 100644 --- a/client.h +++ b/client.h @@ -52,7 +52,10 @@ client_set_bounds(Client *c, int32_t width, int32_t height) if (client_is_x11(c)) return 0; #endif - return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); + if (c->surface.xdg->client->shell->version >= + XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION) + return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); + return 0; } static inline void From 83e37820d778f935af0123d3b4bc0512265fbfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 28 Aug 2022 21:40:03 -0500 Subject: [PATCH 40/47] add support for the single pixel buffer protocol --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index f900f88..52109ee 100644 --- a/dwl.c +++ b/dwl.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1949,6 +1950,7 @@ setup(void) wlr_gamma_control_manager_v1_create(dpy); wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); + wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_subcompositor_create(dpy); /* Initializes the interface used to implement urgency hints */ From dc59f7733d0315b3240b46321f3b5ae2ecc16b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 6 Sep 2022 00:29:44 -0500 Subject: [PATCH 41/47] enable adaptive sync if supported but don't cause monitors to be ignored if it fails --- dwl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 52109ee..b80f3aa 100644 --- a/dwl.c +++ b/dwl.c @@ -803,7 +803,6 @@ createmon(struct wl_listener *listener, void *data) * monitor's preferred mode; a more sophisticated compositor would let * the user configure it. */ wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output)); - wlr_output_enable_adaptive_sync(wlr_output, 1); /* Set up event listeners */ LISTEN(&wlr_output->events.frame, &m->frame, rendermon); @@ -813,6 +812,11 @@ createmon(struct wl_listener *listener, void *data) if (!wlr_output_commit(wlr_output)) return; + /* Try to enable adaptive sync, note that not all monitors support it. + * wlr_output_commit() will deactivate it in case it cannot be enabled */ + wlr_output_enable_adaptive_sync(wlr_output, 1); + wlr_output_commit(wlr_output); + wl_list_insert(&mons, &m->link); printstatus(); From d11358762d3693e8e268ecf01861f522a0dc96f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 18 Sep 2022 15:49:30 -0500 Subject: [PATCH 42/47] add missing library (xcb-icccm) this library is also used by wlroots, so nothing new --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index 4638d5f..c7b5d16 100644 --- a/config.mk +++ b/config.mk @@ -12,4 +12,4 @@ XWAYLAND = XLIBS = # Uncomment to build XWayland support #XWAYLAND = -DXWAYLAND -#XLIBS = xcb +#XLIBS = xcb xcb-icccm From 434ed119f3427c1539aff95c57977c35921afb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 1 Oct 2022 23:33:17 -0500 Subject: [PATCH 43/47] wlroots check map state of layersurfaces this for us --- dwl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index eb072bb..32a1650 100644 --- a/dwl.c +++ b/dwl.c @@ -456,9 +456,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_layer_surface_v1_state *state = &wlr_layer_surface->current; - /* Unmapped surfaces shouldn't have exclusive zone */ - if (!((LayerSurface *)wlr_layer_surface->data)->mapped - || exclusive != (state->exclusive_zone > 0)) + if (exclusive != (state->exclusive_zone > 0)) continue; wlr_scene_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area); From 1eeb3689d3ec5b917b5ccf730a6497e4b9fcd0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 23 Oct 2022 12:32:57 -0500 Subject: [PATCH 44/47] add support for the ext-idle-notify-v1 protocol for now we use macros to support both KDE idle and ext-idle, wlroots will likely drop support for KDE idle in 0.17 --- dwl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index 32a1650..c29d554 100644 --- a/dwl.c +++ b/dwl.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ #define END(A) ((A) + LENGTH(A)) #define TAGMASK ((1 << LENGTH(tags)) - 1) #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) +#define IDLE_NOTIFY_ACTIVITY wlr_idle_notify_activity(idle, seat), wlr_idle_notifier_v1_notify_activity(idle_notifier, seat) /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ @@ -308,6 +310,7 @@ static struct wlr_xdg_activation_v1 *activation; static struct wl_list clients; /* tiling order */ static struct wl_list fstack; /* focus order */ static struct wlr_idle *idle; +static struct wlr_idle_notifier_v1 *idle_notifier; static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; static struct wlr_input_inhibit_manager *input_inhibit_mgr; static struct wlr_layer_shell_v1 *layer_shell; @@ -511,7 +514,7 @@ axisnotify(struct wl_listener *listener, void *data) /* This event is forwarded by the cursor when a pointer emits an axis event, * for example when you move the scroll wheel. */ struct wlr_pointer_axis_event *event = data; - wlr_idle_notify_activity(idle, seat); + IDLE_NOTIFY_ACTIVITY; /* TODO: allow usage of scroll whell for mousebindings, it can be implemented * checking the event's orientation and the delta of the event */ /* Notify the client with pointer focus of the axis event. */ @@ -529,7 +532,7 @@ buttonpress(struct wl_listener *listener, void *data) Client *c; const Button *b; - wlr_idle_notify_activity(idle, seat); + IDLE_NOTIFY_ACTIVITY; switch (event->state) { case WLR_BUTTON_PRESSED: @@ -599,6 +602,7 @@ checkidleinhibitor(struct wlr_surface *exclude) } wlr_idle_set_enabled(idle, NULL, !inhibited); + wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); } void @@ -1239,7 +1243,7 @@ keypress(struct wl_listener *listener, void *data) int handled = 0; uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard); - wlr_idle_notify_activity(idle, seat); + IDLE_NOTIFY_ACTIVITY; /* On _press_ if there is no active screen locker, * attempt to process a compositor keybinding. */ @@ -1403,7 +1407,7 @@ motionnotify(uint32_t time) /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { - wlr_idle_notify_activity(idle, seat); + IDLE_NOTIFY_ACTIVITY; /* Update selmon (even while dragging a window) */ if (sloppyfocus) @@ -2029,6 +2033,7 @@ setup(void) wl_list_init(&fstack); idle = wlr_idle_create(dpy); + idle_notifier = wlr_idle_notifier_v1_create(dpy); idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &idle_inhibitor_create); From 8298f20a7174eb9c70b375b92810ab3320fedf97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 29 Oct 2022 18:30:09 -0500 Subject: [PATCH 45/47] allow change adaptive sync in outputmgrapplyortest() --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 3ba4eaf..7d41883 100644 --- a/dwl.c +++ b/dwl.c @@ -1557,6 +1557,8 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) config_head->state.x, config_head->state.y); wlr_output_set_transform(wlr_output, config_head->state.transform); wlr_output_set_scale(wlr_output, config_head->state.scale); + wlr_output_enable_adaptive_sync(wlr_output, + config_head->state.adaptive_sync_enabled); apply_or_test: if (test) { From 99f062273e6a04abe4258c23284087698a8ecad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 29 Oct 2022 19:02:44 -0500 Subject: [PATCH 46/47] only destroy monitor's layer surfaces at destroy --- dwl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dwl.c b/dwl.c index 7d41883..8b019da 100644 --- a/dwl.c +++ b/dwl.c @@ -644,12 +644,9 @@ cleanupmon(struct wl_listener *listener, void *data) LayerSurface *l, *tmp; int i; - for (i = 0; i <= ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; i++) { - wl_list_for_each_safe(l, tmp, &m->layers[i], link) { - wlr_scene_node_set_enabled(&l->scene->node, 0); + for (i = 0; i <= ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; i++) + wl_list_for_each_safe(l, tmp, &m->layers[i], link) wlr_layer_surface_v1_destroy(l->layer_surface); - } - } wl_list_remove(&m->destroy.link); wl_list_remove(&m->frame.link); From 448a96de13042c76634c2a898c370889b33693d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 30 Oct 2022 01:03:44 -0500 Subject: [PATCH 47/47] remove now unneeded workaround in outputmgrapplyortest() --- dwl.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/dwl.c b/dwl.c index 8b019da..fa59386 100644 --- a/dwl.c +++ b/dwl.c @@ -1562,23 +1562,7 @@ apply_or_test: ok &= wlr_output_test(wlr_output); wlr_output_rollback(wlr_output); } else { - int output_ok = 1; - /* If it's a custom mode to avoid an assertion failed in wlr_output_commit() - * we test if that mode does not fail rather than just call wlr_output_commit(). - * We do not test normal modes because (at least in my hardware (@sevz17)) - * wlr_output_test() fails even if that mode can actually be set */ - if (!config_head->state.mode && config_head->state.enabled) - ok &= (output_ok = wlr_output_test(wlr_output) - && wlr_output_commit(wlr_output)); - else - ok &= wlr_output_commit(wlr_output); - - /* In custom modes we call wlr_output_test(), it it fails - * we need to rollback, and normal modes seems to does not cause - * assertions failed in wlr_output_commit() which rollback - * the output on failure */ - if (!output_ok) - wlr_output_rollback(wlr_output); + ok &= wlr_output_commit(wlr_output); } }