From 8559141b30bfa9acdad4c2385b712b5ee51e1794 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 3 Oct 2022 23:28:58 -0500 Subject: avoid usage of goto Based on this suggestion: https://github.com/guyuming76/dwl/commit/bc72af6e2430cfb8db2f5fa1b9800c86f445b6d6#commitcomment-85592855 --- dwl.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index b4fa1ef..5f9cbcd 100644 --- a/dwl.c +++ b/dwl.c @@ -2388,14 +2388,12 @@ unmapnotify(struct wl_listener *listener, void *data) if (c->mon) c->mon->un_map = 1; - if (client_is_unmanaged(c)) - goto end; - - wl_list_remove(&c->link); - setmon(c, NULL, 0); - wl_list_remove(&c->flink); + if (!client_is_unmanaged(c)) { + wl_list_remove(&c->link); + setmon(c, NULL, 0); + wl_list_remove(&c->flink); + } -end: wl_list_remove(&c->commit.link); wlr_scene_node_destroy(c->scene); printstatus(); -- cgit v1.2.3 From f6820a6c29b6bcb9a14166793d7f1fba2f98444e Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 7 Oct 2022 00:02:29 -0500 Subject: fix drag and drop not working this fixes another issue where the cursor doesn't change when selecting text but there is still an issue about not changing border color of clients during dnd operations Bug: https://github.com/djpohly/dwl/issues/318 --- dwl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 5f9cbcd..fc8f7b2 100644 --- a/dwl.c +++ b/dwl.c @@ -1535,7 +1535,7 @@ motionnotify(uint32_t time) /* Find the client under the pointer and send the event along. */ xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); - if (cursor_mode == CurPressed) { + if (cursor_mode == CurPressed && !seat->drag) { surface = seat->pointer_state.focused_surface; c = client_from_wlr_surface(surface); sx = c ? cursor->x - c->geom.x : 0; @@ -1545,7 +1545,7 @@ motionnotify(uint32_t time) /* If there's no client surface under the cursor, set the cursor image to a * default. This is what makes the cursor image appear when you move it * off of a client or over its border. */ - if (!surface && (!cursor_image || strcmp(cursor_image, "left_ptr"))) + if (!surface && !seat->drag && (!cursor_image || strcmp(cursor_image, "left_ptr"))) wlr_xcursor_manager_set_cursor_image(cursor_mgr, (cursor_image = "left_ptr"), cursor); pointerfocus(c, surface, sx, sy, time); @@ -1906,7 +1906,7 @@ setcursor(struct wl_listener *listener, void *data) /* If we're "grabbing" the cursor, don't use the client's image, we will * restore it after "grabbing" sending a leave event, followed by a enter * event, which will result in the client requesting set the cursor surface */ - if (cursor_mode != CurNormal) + if (cursor_mode != CurNormal && cursor_mode != CurPressed) return; cursor_image = NULL; /* This can be sent by any client, so we check to make sure this one is -- cgit v1.2.3 From 0d1ca4663ca62329e1e171053ceb35bbc71ec30a Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Sat, 8 Oct 2022 13:20:34 +0000 Subject: allow moveresize() while the left mouse button is pressed Fixes: https://github.com/djpohly/dwl/issues/319 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index fc8f7b2..3fdef90 100644 --- a/dwl.c +++ b/dwl.c @@ -1569,7 +1569,7 @@ motionrelative(struct wl_listener *listener, void *data) void moveresize(const Arg *arg) { - if (cursor_mode != CurNormal) + if (cursor_mode != CurNormal && cursor_mode != CurPressed) return; xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); if (!grabc || client_is_unmanaged(grabc)) -- cgit v1.2.3 From 952fde68a3cb1871f39c464d56f999d5a966e7a4 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 8 Oct 2022 13:00:03 -0500 Subject: correctly handle cursor motion when button is held (for layer surfaces) --- client.h | 15 +++++++++++++++ dwl.c | 11 +++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index 4ecdd47..09e7609 100644 --- a/client.h +++ b/client.h @@ -307,3 +307,18 @@ toplevel_from_popup(struct wlr_xdg_popup *popup) } } } + +static inline void * +toplevel_from_wlr_layer_surface(struct wlr_surface *s) +{ + Client *c; + struct wlr_layer_surface_v1 *wlr_layer_surface; + + if ((c = client_from_wlr_surface(s))) + return c; + else if (s && wlr_surface_is_layer_surface(s) + && (wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(s))) + return wlr_layer_surface->data; + + return NULL; +} diff --git a/dwl.c b/dwl.c index 3fdef90..76430aa 100644 --- a/dwl.c +++ b/dwl.c @@ -1504,6 +1504,7 @@ motionnotify(uint32_t time) { double sx = 0, sy = 0; Client *c = NULL; + LayerSurface *l; struct wlr_surface *surface = NULL; struct wlr_drag_icon *icon; @@ -1536,10 +1537,12 @@ motionnotify(uint32_t time) xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); if (cursor_mode == CurPressed && !seat->drag) { - surface = seat->pointer_state.focused_surface; - c = client_from_wlr_surface(surface); - sx = c ? cursor->x - c->geom.x : 0; - sy = c ? cursor->y - c->geom.y : 0; + if ((l = toplevel_from_wlr_layer_surface( + seat->pointer_state.focused_surface))) { + surface = seat->pointer_state.focused_surface; + sx = cursor->x - l->geom.x; + sy = cursor->y - l->geom.y; + } } /* If there's no client surface under the cursor, set the cursor image to a -- cgit v1.2.3 From 7f3c9fa0ae83c9113b10b0e1b92ae2bc53836c80 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 8 Oct 2022 20:48:48 -0500 Subject: rename LyrNoFocus -> LyrDragIcon --- dwl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 76430aa..8c02b40 100644 --- a/dwl.c +++ b/dwl.c @@ -68,7 +68,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11Managed, X11Unmanaged }; /* client types */ -enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrNoFocus, NUM_LAYERS }; /* scene layers */ +enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrDragIcon, NUM_LAYERS }; /* scene layers */ #ifdef XWAYLAND enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ @@ -2080,7 +2080,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; + layers[LyrDragIcon] = &wlr_scene_tree_create(&scene->node)->node; /* Create a renderer with the default implementation */ if (!(drw = wlr_renderer_autocreate(backend))) @@ -2256,7 +2256,7 @@ startdrag(struct wl_listener *listener, void *data) if (!drag->icon) return; - drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrNoFocus], drag->icon->surface); + drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrDragIcon], drag->icon->surface); motionnotify(0); wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy); } -- cgit v1.2.3 From 3902fba76961beff924e900e3de3f952d7f98bbc Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 8 Oct 2022 20:50:17 -0500 Subject: rename dragicondestroy() -> destroydragicon() to match the rest of the code --- dwl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 8c02b40..78e8d54 100644 --- a/dwl.c +++ b/dwl.c @@ -229,11 +229,11 @@ static void createmon(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data); static void createpointer(struct wlr_input_device *device); 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); 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); @@ -340,6 +340,7 @@ static struct wl_listener cursor_button = {.notify = buttonpress}; static struct wl_listener cursor_frame = {.notify = cursorframe}; static struct wl_listener cursor_motion = {.notify = motionrelative}; static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute}; +static struct wl_listener drag_icon_destroy = {.notify = destroydragicon}; static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor}; static struct wl_listener idle_inhibitor_destroy = {.notify = destroyidleinhibitor}; static struct wl_listener layout_change = {.notify = updatemons}; @@ -356,7 +357,6 @@ 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); @@ -1085,6 +1085,16 @@ cursorframe(struct wl_listener *listener, void *data) wlr_seat_pointer_notify_frame(seat); } +void +destroydragicon(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 destroyidleinhibitor(struct wl_listener *listener, void *data) { @@ -1141,16 +1151,6 @@ dirtomon(enum wlr_direction dir) return selmon; } -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 focusclient(Client *c, int lift) { -- cgit v1.2.3 From 1438dfc1509b22612166407c565f65f635d3ab97 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 8 Oct 2022 20:51:05 -0500 Subject: fix bad indentation in createpointer() --- dwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 78e8d54..c77464f 100644 --- a/dwl.c +++ b/dwl.c @@ -1059,8 +1059,8 @@ createpointer(struct wlr_input_device *device) if (libinput_device_config_scroll_get_methods(libinput_device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) libinput_device_config_scroll_set_method (libinput_device, scroll_method); - if (libinput_device_config_click_get_methods(libinput_device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE) - libinput_device_config_click_set_method (libinput_device, click_method); + if (libinput_device_config_click_get_methods(libinput_device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE) + libinput_device_config_click_set_method (libinput_device, click_method); if (libinput_device_config_send_events_get_modes(libinput_device)) libinput_device_config_send_events_set_mode(libinput_device, send_events_mode); -- cgit v1.2.3 From 765656902fdaaf8c4320d4a16ea8cba4294656a7 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 8 Oct 2022 20:51:40 -0500 Subject: use `/* */` for comments in applybounds() --- dwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index c77464f..29c9eea 100644 --- a/dwl.c +++ b/dwl.c @@ -392,9 +392,9 @@ applybounds(Client *c, struct wlr_box *bbox) c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height); /* Some clients set them max size to INT_MAX, which does not violates * the protocol but its innecesary, they can set them max size to zero. */ - if (max.width > 0 && !(2 * c->bw > INT_MAX - max.width)) // Checks for overflow + if (max.width > 0 && !(2 * c->bw > INT_MAX - max.width)) /* Checks for overflow */ c->geom.width = MIN(max.width + (2 * c->bw), c->geom.width); - if (max.height > 0 && !(2 * c->bw > INT_MAX - max.height)) // Checks for overflow + if (max.height > 0 && !(2 * c->bw > INT_MAX - max.height)) /* Checks for overflow */ c->geom.height = MIN(max.height + (2 * c->bw), c->geom.height); } -- cgit v1.2.3 From 4eabf6f7eb4ec596e41db4ced0c5ac7149e0eaeb Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 11 Oct 2022 13:11:14 -0500 Subject: disable and destroy monitor's layer surfaces when it's being destroyed Fixes: https://github.com/djpohly/dwl/issues/314 --- dwl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 29c9eea..64bf2e2 100644 --- a/dwl.c +++ b/dwl.c @@ -762,7 +762,15 @@ void cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); - int nmons, i = 0; + LayerSurface *l, *tmp; + int nmons, 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, 0); + wlr_layer_surface_v1_destroy(l->layer_surface); + } + } wl_list_remove(&m->destroy.link); wl_list_remove(&m->frame.link); @@ -771,7 +779,7 @@ cleanupmon(struct wl_listener *listener, void *data) wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); - if ((nmons = wl_list_length(&mons))) + if (!(i = 0) && (nmons = wl_list_length(&mons))) do /* don't switch to disabled mons */ selmon = wl_container_of(mons.prev, selmon, link); while (!selmon->wlr_output->enabled && i++ < nmons); -- cgit v1.2.3 From 332ceb7136da268ff3e62f32d40bc8969f0aca37 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 16 Jun 2022 16:05:07 -0500 Subject: allow unmanaged clients (like dzen or dmenu) to have keyboard focus --- client.h | 11 +++++++++++ dwl.c | 29 ++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index 09e7609..49982e0 100644 --- a/client.h +++ b/client.h @@ -275,6 +275,17 @@ client_surface_at(Client *c, double cx, double cy, double *sx, double *sy) return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy); } +static inline int +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; +#endif + return 0; +} + static inline int client_wants_fullscreen(Client *c) { diff --git a/dwl.c b/dwl.c index 64bf2e2..2f0d9a6 100644 --- a/dwl.c +++ b/dwl.c @@ -659,8 +659,7 @@ buttonpress(struct wl_listener *listener, void *data) case WLR_BUTTON_PRESSED: /* Change focus if the button was _pressed_ over a client */ xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL); - /* Don't focus unmanaged clients */ - if (c && !client_is_unmanaged(c)) + if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) focusclient(c, 1); keyboard = wlr_seat_get_keyboard(seat); @@ -1173,7 +1172,7 @@ focusclient(Client *c, int lift) return; /* Put the new client atop the focus stack and select its monitor */ - if (c) { + if (c && !client_is_unmanaged(c)) { wl_list_remove(&c->flink); wl_list_insert(&fstack, &c->flink); selmon = c->mon; @@ -1192,6 +1191,7 @@ focusclient(Client *c, int lift) /* If an overlay is focused, don't focus or activate the client, * but only update its position in fstack to render its border with focuscolor * and focus it after the overlay is closed. */ + Client *w = client_from_wlr_surface(old); if (wlr_surface_is_layer_surface(old)) { struct wlr_layer_surface_v1 *wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(old); @@ -1200,11 +1200,13 @@ focusclient(Client *c, int lift) && (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP || wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY)) return; - } else { - Client *w; - if ((w = client_from_wlr_surface(old))) - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(w->border[i], bordercolor); + } else if (w && w == exclusive_focus && client_wants_focus(w)) { + return; + /* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg + * and probably other clients */ + } else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(w->border[i], bordercolor); client_activate_surface(old, 0); } @@ -1444,6 +1446,10 @@ mapnotify(struct wl_listener *listener, void *data) wlr_scene_node_reparent(c->scene, layers[LyrFloat]); wlr_scene_node_set_position(c->scene, c->geom.x + borderpx, c->geom.y + borderpx); + if (client_wants_focus(c)) { + focusclient(c, 1); + exclusive_focus = c; + } return; } #endif @@ -2399,7 +2405,12 @@ unmapnotify(struct wl_listener *listener, void *data) if (c->mon) c->mon->un_map = 1; - if (!client_is_unmanaged(c)) { + if (client_is_unmanaged(c)) { + if (c == exclusive_focus) + exclusive_focus = NULL; + if (client_surface(c) == seat->keyboard_state.focused_surface) + focusclient(selclient(), 1); + } else { wl_list_remove(&c->link); setmon(c, NULL, 0); wl_list_remove(&c->flink); -- cgit v1.2.3 From 2d9d758c8dec083178ff78b154da784b97260bd1 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 15 Oct 2022 15:12:37 -0500 Subject: stop trying resize clients during commitnotify() instead resize them in configurex11() --- dwl.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 2f0d9a6..c7fe999 100644 --- a/dwl.c +++ b/dwl.c @@ -836,12 +836,6 @@ void commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - struct wlr_box box = {0}; - client_get_geometry(c, &box); - - if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw - || box.height != c->geom.height - 2 * c->bw)) - arrange(c->mon); /* mark a pending resize as completed */ if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial @@ -1033,6 +1027,7 @@ createnotify(struct wl_listener *listener, void *data) LISTEN(&xdg_surface->events.map, &c->map, mapnotify); LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); + LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle); LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen, fullscreennotify); @@ -1139,8 +1134,9 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->configure.link); wl_list_remove(&c->set_hints.link); wl_list_remove(&c->activate.link); - } + } else #endif + { wl_list_remove(&c->commit.link); } free(c); } @@ -1428,14 +1424,8 @@ mapnotify(struct wl_listener *listener, void *data) c->scene_surface = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - if (client_surface(c)) { + if (client_surface(c)) client_surface(c)->data = c->scene; - /* Ideally we should do this in createnotify{,x11} but at that moment - * wlr_xwayland_surface doesn't have wlr_surface yet - */ - LISTEN(&client_surface(c)->events.commit, &c->commit, commitnotify); - - } c->scene->data = c->scene_surface->data = c; #ifdef XWAYLAND @@ -2416,7 +2406,6 @@ unmapnotify(struct wl_listener *listener, void *data) wl_list_remove(&c->flink); } - wl_list_remove(&c->commit.link); wlr_scene_node_destroy(c->scene); printstatus(); motionnotify(0); @@ -2592,9 +2581,12 @@ void configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); - struct wlr_xwayland_surface_configure_event *event = data; - wlr_xwayland_surface_configure(c->surface.xwayland, - event->x, event->y, event->width, event->height); + struct wlr_xwayland_surface_configure_event *e = data; + if (c->isfloating) + resize(c, (struct wlr_box){.x = e->x, .y = e->y, + .width = e->width, .height = e->height}, 0); + else + arrange(c->mon); } void -- cgit v1.2.3 From 110cde8f67e24d9d1d2483e19f7740612163ebb6 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 15 Oct 2022 18:09:42 -0500 Subject: update comment about exclusive focus in focusclient() --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index c7fe999..1a52255 100644 --- a/dwl.c +++ b/dwl.c @@ -1175,8 +1175,7 @@ focusclient(Client *c, int lift) c->isurgent = 0; client_restack_surface(c); - /* Don't change border color if there is a exclusive focus - * (at this moment it means that a layer surface is focused) */ + /* Don't change border color if there is an exclusive focus */ if (!exclusive_focus) for (i = 0; i < 4; i++) wlr_scene_rect_set_color(c->border[i], focuscolor); -- cgit v1.2.3 From e9826de2959609f597bc80137183828562315c14 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 15 Oct 2022 18:19:43 -0500 Subject: Revert "stop trying resize clients during commitnotify()" This reverts commit 2d9d758c8dec083178ff78b154da784b97260bd1. wasn't meant to be pushed to main --- dwl.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 1a52255..a80de05 100644 --- a/dwl.c +++ b/dwl.c @@ -836,6 +836,12 @@ void commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); + struct wlr_box box = {0}; + client_get_geometry(c, &box); + + if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw + || box.height != c->geom.height - 2 * c->bw)) + arrange(c->mon); /* mark a pending resize as completed */ if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial @@ -1027,7 +1033,6 @@ createnotify(struct wl_listener *listener, void *data) LISTEN(&xdg_surface->events.map, &c->map, mapnotify); LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle); LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen, fullscreennotify); @@ -1134,9 +1139,8 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->configure.link); wl_list_remove(&c->set_hints.link); wl_list_remove(&c->activate.link); - } else + } #endif - { wl_list_remove(&c->commit.link); } free(c); } @@ -1423,8 +1427,14 @@ mapnotify(struct wl_listener *listener, void *data) c->scene_surface = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - if (client_surface(c)) + if (client_surface(c)) { client_surface(c)->data = c->scene; + /* Ideally we should do this in createnotify{,x11} but at that moment + * wlr_xwayland_surface doesn't have wlr_surface yet + */ + LISTEN(&client_surface(c)->events.commit, &c->commit, commitnotify); + + } c->scene->data = c->scene_surface->data = c; #ifdef XWAYLAND @@ -2405,6 +2415,7 @@ unmapnotify(struct wl_listener *listener, void *data) wl_list_remove(&c->flink); } + wl_list_remove(&c->commit.link); wlr_scene_node_destroy(c->scene); printstatus(); motionnotify(0); @@ -2580,12 +2591,9 @@ void configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); - struct wlr_xwayland_surface_configure_event *e = data; - if (c->isfloating) - resize(c, (struct wlr_box){.x = e->x, .y = e->y, - .width = e->width, .height = e->height}, 0); - else - arrange(c->mon); + struct wlr_xwayland_surface_configure_event *event = data; + wlr_xwayland_surface_configure(c->surface.xwayland, + event->x, event->y, event->width, event->height); } void -- cgit v1.2.3 From 9588b46b5c47a9b4990340ba54a3b4dc075ba55b Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 29 Oct 2022 15:25:13 -0500 Subject: only raise the client's node in monocle() Fixes: https://github.com/djpohly/dwl/issues/326 --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index a80de05..8c7644e 100644 --- a/dwl.c +++ b/dwl.c @@ -1495,7 +1495,8 @@ monocle(Monitor *m) continue; resize(c, m->w, 0); } - focusclient(focustop(m), 1); + if ((c = focustop(m))) + wlr_scene_node_raise_to_top(c->scene); } void -- cgit v1.2.3 From cb01ce9bcfd1f968fd2537643d2c61137b76e829 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 13 Aug 2022 19:54:01 -0500 Subject: move focus and clients off disabled monitors --- dwl.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 8c7644e..0c2328b 100644 --- a/dwl.c +++ b/dwl.c @@ -1698,6 +1698,9 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) else wlr_output_configuration_v1_send_failed(config); wlr_output_configuration_v1_destroy(config); + + /* TODO: use a wrapper function? */ + updatemons(NULL, NULL); } void @@ -2435,14 +2438,38 @@ updatemons(struct wl_listener *listener, void *data) struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create(); Client *c; + struct wlr_output_configuration_head_v1 *config_head; Monitor *m; + + /* First remove from the layout the disabled monitors */ + wl_list_for_each(m, &mons, link) { + int nmons, i = 0; + if (m->wlr_output->enabled) + continue; + config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); + config_head->state.enabled = 0; + if (m == selmon && (nmons = wl_list_length(&mons))) + do /* don't switch to disabled mons */ + selmon = wl_container_of(mons.next, selmon, link); + while (!selmon->wlr_output->enabled && i++ < nmons); + /* Remove this output from the layout to avoid cursor enter inside it */ + wlr_output_layout_remove(output_layout, m->wlr_output); + focusclient(focustop(selmon), 1); + closemon(m); + memset(&m->m, 0, sizeof(m->m)); + memset(&m->w, 0, sizeof(m->w)); + } + /* Insert outputs that need to */ + wl_list_for_each(m, &mons, link) + if (m->wlr_output->enabled + && !wlr_output_layout_get(output_layout, m->wlr_output)) + wlr_output_layout_add_auto(output_layout, m->wlr_output); + /* Now that we update the output layout we can get its box */ sgeom = *wlr_output_layout_get_box(output_layout, NULL); 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); - - /* TODO: move clients off disabled monitors */ - /* TODO: move focus if selmon is disabled */ + if (!m->wlr_output->enabled) + continue; + config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); /* Get the effective monitor geometry to use for surfaces */ m->m = m->w = *wlr_output_layout_get_box(output_layout, m->wlr_output); @@ -2452,7 +2479,7 @@ updatemons(struct wl_listener *listener, void *data) /* Don't move clients to the left output when plugging monitors */ arrange(m); - config_head->state.enabled = m->wlr_output->enabled; + config_head->state.enabled = 1; config_head->state.mode = m->wlr_output->current_mode; config_head->state.x = m->m.x; config_head->state.y = m->m.y; -- cgit v1.2.3 From 9b5f0f0fc5d668538e190f525f01c5a150a5570a Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 19 Aug 2022 10:05:51 -0500 Subject: use just one loop in outputmgrapplyortest() we do the magic in updatemons() --- dwl.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 0c2328b..50a8416 100644 --- a/dwl.c +++ b/dwl.c @@ -1631,28 +1631,13 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) struct wlr_output_configuration_head_v1 *config_head; int ok = 1; - /* First disable outputs we need to disable */ - wl_list_for_each(config_head, &config->heads, link) { - struct wlr_output *wlr_output = config_head->state.output; - if (!wlr_output->enabled || config_head->state.enabled) - continue; - wlr_output_enable(wlr_output, 0); - if (test) { - ok &= wlr_output_test(wlr_output); - wlr_output_rollback(wlr_output); - } else { - ok &= wlr_output_commit(wlr_output); - } - } - - /* Then enable outputs that need to */ wl_list_for_each(config_head, &config->heads, link) { struct wlr_output *wlr_output = config_head->state.output; Monitor *m = wlr_output->data; - if (!config_head->state.enabled) - continue; - wlr_output_enable(wlr_output, 1); + wlr_output_enable(wlr_output, config_head->state.enabled); + if (!config_head->state.enabled) + goto apply_or_test; if (config_head->state.mode) wlr_output_set_mode(wlr_output, config_head->state.mode); else @@ -1669,6 +1654,7 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) wlr_output_set_transform(wlr_output, config_head->state.transform); wlr_output_set_scale(wlr_output, config_head->state.scale); +apply_or_test: if (test) { ok &= wlr_output_test(wlr_output); wlr_output_rollback(wlr_output); @@ -1678,7 +1664,7 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) * 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) + if (!config_head->state.mode && config_head->state.enabled) ok &= (output_ok = wlr_output_test(wlr_output) && wlr_output_commit(wlr_output)); else -- cgit v1.2.3 From a9e2ebaf4163278086d2cc290f164028dec0839b Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 1 Sep 2022 19:25:27 -0500 Subject: closemon() now updates selmon if needed --- dwl.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 50a8416..85edb9d 100644 --- a/dwl.c +++ b/dwl.c @@ -762,7 +762,7 @@ cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); LayerSurface *l, *tmp; - int nmons, i; + int i; for (i = 0; i <= ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; i++) { wl_list_for_each_safe(l, tmp, &m->layers[i], link) { @@ -778,12 +778,6 @@ cleanupmon(struct wl_listener *listener, void *data) wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); - if (!(i = 0) && (nmons = wl_list_length(&mons))) - do /* don't switch to disabled mons */ - selmon = wl_container_of(mons.prev, selmon, link); - while (!selmon->wlr_output->enabled && i++ < nmons); - - focusclient(focustop(selmon), 1); closemon(m); free(m); } @@ -791,8 +785,17 @@ cleanupmon(struct wl_listener *listener, void *data) void closemon(Monitor *m) { - /* move closed monitor's clients to the focused one */ + /* update selmon if needed and + * move closed monitor's clients to the focused one */ Client *c; + if (wl_list_empty(&mons)) { + selmon = NULL; + } else if (m == selmon) { + int nmons = wl_list_length(&mons), i = 0; + do /* don't switch to disabled mons */ + selmon = wl_container_of(mons.next, selmon, link); + while (!selmon->wlr_output->enabled && i++ < nmons); + } wl_list_for_each(c, &clients, link) { if (c->isfloating && c->geom.x > m->m.width) @@ -801,6 +804,7 @@ closemon(Monitor *m) if (c->mon == m) setmon(c, selmon, c->tags); } + focusclient(focustop(selmon), 1); printstatus(); } @@ -2429,18 +2433,12 @@ updatemons(struct wl_listener *listener, void *data) /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { - int nmons, i = 0; if (m->wlr_output->enabled) continue; config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); config_head->state.enabled = 0; - if (m == selmon && (nmons = wl_list_length(&mons))) - do /* don't switch to disabled mons */ - selmon = wl_container_of(mons.next, selmon, link); - while (!selmon->wlr_output->enabled && i++ < nmons); /* Remove this output from the layout to avoid cursor enter inside it */ wlr_output_layout_remove(output_layout, m->wlr_output); - focusclient(focustop(selmon), 1); closemon(m); memset(&m->m, 0, sizeof(m->m)); memset(&m->w, 0, sizeof(m->w)); -- cgit v1.2.3 From 846ce52b926797dc51f9fcdc2d121ee63fb68580 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 8 Sep 2022 15:43:20 -0500 Subject: fix crash in dirtomon() when selmon is disabled --- dwl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 85edb9d..2baa659 100644 --- a/dwl.c +++ b/dwl.c @@ -1152,10 +1152,12 @@ Monitor * dirtomon(enum wlr_direction dir) { struct wlr_output *next; - if ((next = wlr_output_layout_adjacent_output(output_layout, + if (wlr_output_layout_get(output_layout, selmon->wlr_output) + && (next = wlr_output_layout_adjacent_output(output_layout, dir, selmon->wlr_output, selmon->m.x, selmon->m.y))) return next->data; - if ((next = wlr_output_layout_farthest_output(output_layout, + if (wlr_output_layout_get(output_layout, selmon->wlr_output) + && (next = wlr_output_layout_farthest_output(output_layout, dir ^ (WLR_DIRECTION_LEFT|WLR_DIRECTION_RIGHT), selmon->wlr_output, selmon->m.x, selmon->m.y))) return next->data; -- cgit v1.2.3