From ecbc2c61db180dc8ab1053b7cdc1e4817be33d36 Mon Sep 17 00:00:00 2001 From: Ben Jargowsky Date: Sun, 27 Mar 2022 17:04:41 -0700 Subject: Add configuration options for touchpads --- dwl.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 90a2789..b4b4b0d 100644 --- a/dwl.c +++ b/dwl.c @@ -981,17 +981,36 @@ createpointer(struct wlr_input_device *device) struct libinput_device *libinput_device = (struct libinput_device*) wlr_libinput_get_device_handle(device); - 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); + if (libinput_device_config_tap_get_finger_count(libinput_device)) { + libinput_device_config_tap_set_enabled(libinput_device, tap_to_click); + libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag); + libinput_device_config_tap_set_enabled(libinput_device, drag_lock); + } if (libinput_device_config_scroll_has_natural_scroll(libinput_device)) libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling); + + if (libinput_device_config_dwt_is_available(libinput_device)) + libinput_device_config_dwt_set_enabled(libinput_device, disable_while_typing); + + if (libinput_device_config_left_handed_is_available(libinput_device)) + libinput_device_config_left_handed_set(libinput_device, left_handed); + + if (libinput_device_config_middle_emulation_is_available(libinput_device)) + libinput_device_config_middle_emulation_set_enabled(libinput_device, middle_button_emulation); + + 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_send_events_get_modes(libinput_device)) + libinput_device_config_send_events_set_mode(libinput_device, send_events_mode); + + if (libinput_device_config_accel_is_available(libinput_device)) { + libinput_device_config_accel_set_profile(libinput_device, accel_profile); + libinput_device_config_accel_set_speed(libinput_device, accel_speed); + } } - /* We don't do anything special with pointers. All of our pointer handling - * 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); } -- cgit v1.2.3 From 40449fa64fcacb98372e576cc21e192ab783162f Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 23 May 2022 09:14:21 -0500 Subject: add a new function to get a client from a wlr_surface --- client.h | 7 +++++++ dwl.c | 9 ++------- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index e0964da..ec760ec 100644 --- a/client.h +++ b/client.h @@ -231,6 +231,13 @@ client_min_size(Client *c, int *width, int *height) *height = state->min_height; } +static inline Client * +client_from_wlr_surface(struct wlr_surface *surface) +{ + struct wlr_scene_node *n = surface->data; + return n ? n->data : NULL; +} + static inline Client * client_from_popup(struct wlr_xdg_popup *popup) { diff --git a/dwl.c b/dwl.c index b4b4b0d..81ad91e 100644 --- a/dwl.c +++ b/dwl.c @@ -1142,8 +1142,7 @@ focusclient(Client *c, int lift) return; } else { Client *w; - struct wlr_scene_node *node = old->data; - if (old->role_data && (w = node->data)) + if (old->role_data && (w = client_from_wlr_surface(old))) for (i = 0; i < 4; i++) wlr_scene_rect_set_color(w->border[i], bordercolor); @@ -2336,11 +2335,7 @@ void urgent(struct wl_listener *listener, void *data) { struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c; - - if (!wlr_surface_is_xdg_surface(event->surface)) - return; - c = wlr_xdg_surface_from_wlr_surface(event->surface)->data; + Client *c = client_from_wlr_surface(event->surface); if (c != selclient()) { c->isurgent = 1; printstatus(); -- cgit v1.2.3 From 48ec914f439c962ac14f75bfcb0c40282c6a0de3 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Wed, 25 May 2022 14:49:32 -0500 Subject: destroy layersurface's scene node in destroylayersurfacenotify() --- dwl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 81ad91e..a317ee9 100644 --- a/dwl.c +++ b/dwl.c @@ -1045,6 +1045,7 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) wl_list_remove(&layersurface->map.link); wl_list_remove(&layersurface->unmap.link); wl_list_remove(&layersurface->surface_commit.link); + wlr_scene_node_destroy(layersurface->scene); if (layersurface->layer_surface->output) { Monitor *m = layersurface->layer_surface->output->data; if (m) -- cgit v1.2.3 From 7018b9b65c35ece131823069d887c0a6386c8e08 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Wed, 25 May 2022 15:01:38 -0500 Subject: correct libinput function name for drag_lock --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index a317ee9..7de82f9 100644 --- a/dwl.c +++ b/dwl.c @@ -984,7 +984,7 @@ createpointer(struct wlr_input_device *device) if (libinput_device_config_tap_get_finger_count(libinput_device)) { libinput_device_config_tap_set_enabled(libinput_device, tap_to_click); libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag); - libinput_device_config_tap_set_enabled(libinput_device, drag_lock); + libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock); } if (libinput_device_config_scroll_has_natural_scroll(libinput_device)) -- cgit v1.2.3 From 52e0d00942584b4a8a9ca1f59ffdea26277604ed Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 24 May 2022 14:37:55 -0500 Subject: check client_surface() returning NULL now client_surface()->data is a pointer to the wlr_scene_tree of clients which allows us to not call wlr_scene_node_lower_to_bottom() for every clients --- dwl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7de82f9..d0f5afc 100644 --- a/dwl.c +++ b/dwl.c @@ -1376,10 +1376,12 @@ mapnotify(struct wl_listener *listener, void *data) /* Create scene tree for this client and its border */ c->scene = &wlr_scene_tree_create(layers[LyrTile])->node; - c->scene_surface = client_surface(c)->data = c->type == XDGShell + 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)); - c->scene_surface->data = c; + if (client_surface(c)) + client_surface(c)->data = c->scene; + c->scene->data = c->scene_surface->data = c; if (client_is_unmanaged(c)) { client_get_geometry(c, &c->geom); @@ -1394,7 +1396,6 @@ mapnotify(struct wl_listener *listener, void *data) c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor); c->border[i]->node.data = c; wlr_scene_rect_set_color(c->border[i], bordercolor); - wlr_scene_node_lower_to_bottom(&c->border[i]->node); } /* Initialize client geometry with room for border */ -- cgit v1.2.3 From 2623a96ebf4c0b43e65d3ff3d7c1b0e56634acf3 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 24 May 2022 14:46:03 -0500 Subject: call client_set-size() if client has a resize --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index d0f5afc..f061ebe 100644 --- a/dwl.c +++ b/dwl.c @@ -784,6 +784,8 @@ commitnotify(struct wl_listener *listener, void *data) /* mark a pending resize as completed */ if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) c->resize = 0; + else if (c->resize) + c->resize = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); } void -- cgit v1.2.3 From b91017e713d4e6719d19368b883e54af4731f0c0 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sun, 5 Jun 2022 15:27:40 -0500 Subject: disable scene node at unmaplayersurface() --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index f061ebe..ca0368a 100644 --- a/dwl.c +++ b/dwl.c @@ -2250,7 +2250,8 @@ toggleview(const Arg *arg) void unmaplayersurface(LayerSurface *layersurface) { - layersurface->layer_surface->mapped = 0; + layersurface->layer_surface->mapped = layersurface->mapped = 0; + wlr_scene_node_set_enabled(layersurface->scene, 0); if (layersurface->layer_surface->surface == seat->keyboard_state.focused_surface) focusclient(selclient(), 1); -- cgit v1.2.3 From 4dfa45659a6084cd3c800235040d83822f421afc Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sun, 5 Jun 2022 16:55:57 -0500 Subject: fix compiler error with gcc complaining about parentheses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dwl.c: In function ‘unmaplayersurface’: dwl.c:2253:9: error: suggest parentheses around assignment used as truth value [-Werror=parentheses] 2253 | layersurface->layer_surface->mapped = layersurface->mapped = 0; | ^~~~~~~~~~~~ cc1: all warnings being treated as errors make: *** [: dwl.o] Error 1 clang not affected --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index ca0368a..e4bed14 100644 --- a/dwl.c +++ b/dwl.c @@ -2250,7 +2250,7 @@ toggleview(const Arg *arg) void unmaplayersurface(LayerSurface *layersurface) { - layersurface->layer_surface->mapped = layersurface->mapped = 0; + layersurface->layer_surface->mapped = (layersurface->mapped = 0); wlr_scene_node_set_enabled(layersurface->scene, 0); if (layersurface->layer_surface->surface == seat->keyboard_state.focused_surface) -- cgit v1.2.3 From 8bce3b1583977dee0c8a1815c558cae3b9346f67 Mon Sep 17 00:00:00 2001 From: Marco Siedentopf Date: Fri, 10 Jun 2022 01:30:22 +0000 Subject: add click method configuration option Add the libinput configuration option to choose between Software Button Areas and Clickfinger --- config.def.h | 7 +++++++ dwl.c | 3 +++ 2 files changed, 10 insertions(+) (limited to 'dwl.c') diff --git a/config.def.h b/config.def.h index 4f131dd..fabadb3 100644 --- a/config.def.h +++ b/config.def.h @@ -63,10 +63,17 @@ LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN */ static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; /* You can choose between: +LIBINPUT_CONFIG_CLICK_METHOD_NONE +LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS +LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER +*/ +static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; +/* You can choose between: LIBINPUT_CONFIG_SEND_EVENTS_ENABLED LIBINPUT_CONFIG_SEND_EVENTS_DISABLED LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE */ + static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; /* You can choose between: LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT diff --git a/dwl.c b/dwl.c index e4bed14..e0f7e99 100644 --- a/dwl.c +++ b/dwl.c @@ -1003,6 +1003,9 @@ 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_send_events_get_modes(libinput_device)) libinput_device_config_send_events_set_mode(libinput_device, send_events_mode); -- cgit v1.2.3 From d26ddfc7fd36d420990eee94d3c4badb90217bd1 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 13 Jun 2022 12:01:18 -0500 Subject: kill child process in cleanup() --- dwl.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index e0f7e99..8a85c79 100644 --- a/dwl.c +++ b/dwl.c @@ -297,6 +297,7 @@ static void zoom(const Arg *arg); /* variables */ static const char broken[] = "broken"; +static pid_t child_pid = -1; static struct wl_display *dpy; static struct wlr_backend *backend; static struct wlr_scene *scene; @@ -687,7 +688,10 @@ cleanup(void) wlr_xwayland_destroy(xwayland); #endif wl_display_destroy_clients(dpy); - + if (child_pid > 0) { + kill(child_pid, SIGTERM); + waitpid(child_pid, NULL, 0); + } wlr_backend_destroy(backend); wlr_xcursor_manager_destroy(cursor_mgr); wlr_cursor_destroy(cursor); @@ -1753,8 +1757,6 @@ resize(Client *c, int x, int y, int w, int h, int interact) void run(char *startup_cmd) { - pid_t startup_pid = -1; - /* Add a Unix socket to the Wayland display. */ const char *socket = wl_display_add_socket_auto(dpy); if (!socket) @@ -1766,9 +1768,9 @@ run(char *startup_cmd) int piperw[2]; if (pipe(piperw) < 0) die("startup: pipe:"); - if ((startup_pid = fork()) < 0) + if ((child_pid = fork()) < 0) die("startup: fork:"); - if (startup_pid == 0) { + if (child_pid == 0) { dup2(piperw[0], STDIN_FILENO); close(piperw[0]); close(piperw[1]); @@ -1804,11 +1806,6 @@ run(char *startup_cmd) * loop configuration to listen to libinput events, DRM events, generate * frame events at the refresh rate, and so on. */ wl_display_run(dpy); - - if (startup_cmd) { - kill(startup_pid, SIGTERM); - waitpid(startup_pid, NULL, 0); - } } Client * @@ -2120,10 +2117,12 @@ sigchld(int unused) * but the Xwayland implementation in wlroots currently prevents us from * setting our own disposition for SIGCHLD. */ + pid_t pid; if (signal(SIGCHLD, sigchld) == SIG_ERR) die("can't install SIGCHLD handler:"); - while (0 < waitpid(-1, NULL, WNOHANG)) - ; + while (0 < (pid = waitpid(-1, NULL, WNOHANG))) + if (pid == child_pid) + child_pid = -1; } void -- cgit v1.2.3 From 2ef5abfb728bbf157641becfe0db4d6e3d57bca8 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 16 Jun 2022 15:36:27 -0500 Subject: remove unneeded check in focusclient() --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 8a85c79..d5bd989 100644 --- a/dwl.c +++ b/dwl.c @@ -1152,7 +1152,7 @@ focusclient(Client *c, int lift) return; } else { Client *w; - if (old->role_data && (w = client_from_wlr_surface(old))) + if ((w = client_from_wlr_surface(old))) for (i = 0; i < 4; i++) wlr_scene_rect_set_color(w->border[i], bordercolor); -- cgit v1.2.3 From 4ae6d0f3873451306e1ef04d88e0fab4e2b04548 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 16 Jun 2022 15:54:13 -0500 Subject: move ugglyness to client.h --- client.h | 11 +++++++++++ dwl.c | 10 +--------- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index 6791a4d..d9bb7f3 100644 --- a/client.h +++ b/client.h @@ -231,6 +231,17 @@ client_min_size(Client *c, int *width, int *height) *height = state->min_height; } +static inline void +client_restack_surface(Client *c) +{ +#ifdef XWAYLAND + if (client_is_x11(c)) + wlr_xwayland_surface_restack(c->surface.xwayland, NULL, + XCB_STACK_MODE_ABOVE); +#endif + return; +} + static inline Client * client_from_wlr_surface(struct wlr_surface *s) { diff --git a/dwl.c b/dwl.c index d5bd989..04ba50f 100644 --- a/dwl.c +++ b/dwl.c @@ -1129,6 +1129,7 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; c->isurgent = 0; + client_restack_surface(c); for (i = 0; i < 4; i++) wlr_scene_rect_set_color(c->border[i], focuscolor); @@ -1169,15 +1170,6 @@ focusclient(Client *c, int lift) return; } -#ifdef XWAYLAND - /* This resolves an issue where the last spawned xwayland client - * receives all pointer activity. - */ - if (c->type == X11Managed) - wlr_xwayland_surface_restack(c->surface.xwayland, NULL, - XCB_STACK_MODE_ABOVE); -#endif - /* Have a client, so focus its top-level wlr_surface */ kb = wlr_seat_get_keyboard(seat); if (kb) -- cgit v1.2.3 From 79ad72413d8df7e184ff8f458d53a1f53a2cb878 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 20 Jun 2022 18:05:16 -0500 Subject: don't set `c->isfullscreen` to zero calloc initializes all fields to zero --- dwl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 04ba50f..8a9f97d 100644 --- a/dwl.c +++ b/dwl.c @@ -977,7 +977,6 @@ 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); - c->isfullscreen = 0; } void @@ -2468,7 +2467,6 @@ createnotifyx11(struct wl_listener *listener, void *data) c->surface.xwayland = xwayland_surface; c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed; c->bw = borderpx; - c->isfullscreen = 0; /* Listen to the various events it can emit */ LISTEN(&xwayland_surface->events.map, &c->map, mapnotify); -- cgit v1.2.3 From 9b84940e37ec84933d1247bbf3eb76d9efe7c589 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 20 Jun 2022 23:46:11 -0500 Subject: unconstrain layer shell popups also unconstrain popups from monitor's usable area --- client.h | 8 +++++--- dwl.c | 33 ++++++++++++++++----------------- 2 files changed, 21 insertions(+), 20 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index d9bb7f3..4112fd6 100644 --- a/client.h +++ b/client.h @@ -261,15 +261,17 @@ client_from_wlr_surface(struct wlr_surface *s) return NULL; } -static inline Client * -client_from_popup(struct wlr_xdg_popup *popup) +static inline void * +toplevel_from_popup(struct wlr_xdg_popup *popup) { struct wlr_xdg_surface *surface = popup->base; while (1) { switch (surface->role) { case WLR_XDG_SURFACE_ROLE_POPUP: - if (!wlr_surface_is_xdg_surface(surface->popup->parent)) + if (wlr_surface_is_layer_surface(surface->popup->parent)) + return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data; + else if (!wlr_surface_is_xdg_surface(surface->popup->parent)) return NULL; surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent); diff --git a/dwl.c b/dwl.c index 8a9f97d..0eb8fdb 100644 --- a/dwl.c +++ b/dwl.c @@ -90,8 +90,10 @@ typedef struct { typedef struct Monitor Monitor; typedef struct { - /* Must be first */ + /* Must keep these three elements in this order */ unsigned int type; /* XDGShell or X11* */ + struct wlr_box geom; /* layout-relative, includes border */ + Monitor *mon; struct wlr_scene_node *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_node *scene_surface; @@ -107,8 +109,7 @@ typedef struct { struct wl_listener destroy; struct wl_listener set_title; struct wl_listener fullscreen; - struct wlr_box geom, prev; /* layout-relative, includes border */ - Monitor *mon; + struct wlr_box prev; /* layout-relative, includes border */ #ifdef XWAYLAND struct wl_listener activate; struct wl_listener configure; @@ -146,19 +147,19 @@ typedef struct { } Keyboard; typedef struct { - /* Must be first */ + /* Must keep these three elements in this order */ unsigned int type; /* LayerShell */ - int mapped; + struct wlr_box geom; + Monitor *mon; struct wlr_scene_node *scene; struct wl_list link; + int mapped; struct wlr_layer_surface_v1 *layer_surface; struct wl_listener destroy; struct wl_listener map; struct wl_listener unmap; struct wl_listener surface_commit; - - struct wlr_box geo; } LayerSurface; typedef struct { @@ -559,7 +560,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wlr_layer_surface_v1_destroy(wlr_layer_surface); continue; } - layersurface->geo = box; + layersurface->geom = box; if (state->exclusive_zone > 0) applyexclusive(usable_area, state->anchor, state->exclusive_zone, @@ -835,7 +836,6 @@ createlayersurface(struct wl_listener *listener, void *data) { struct wlr_layer_surface_v1 *wlr_layer_surface = data; LayerSurface *layersurface; - Monitor *m; struct wlr_layer_surface_v1_state old_state; if (!wlr_layer_surface->output) { @@ -855,14 +855,14 @@ createlayersurface(struct wl_listener *listener, void *data) layersurface->layer_surface = wlr_layer_surface; wlr_layer_surface->data = layersurface; - m = wlr_layer_surface->output->data; + layersurface->mon = wlr_layer_surface->output->data; layersurface->scene = wlr_layer_surface->surface->data = wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer], wlr_layer_surface->surface); layersurface->scene->data = layersurface; - wl_list_insert(&m->layers[wlr_layer_surface->pending.layer], + wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->pending.layer], &layersurface->link); /* Temporarily set the layer's current state to pending @@ -870,7 +870,7 @@ createlayersurface(struct wl_listener *listener, void *data) */ old_state = wlr_layer_surface->current; wlr_layer_surface->current = wlr_layer_surface->pending; - arrangelayers(m); + arrangelayers(layersurface->mon); wlr_layer_surface->current = old_state; } @@ -955,9 +955,9 @@ createnotify(struct wl_listener *listener, void *data) struct wlr_box box; xdg_surface->surface->data = wlr_scene_xdg_surface_create( xdg_surface->popup->parent->data, xdg_surface); - if (!(c = client_from_popup(xdg_surface->popup)) || !c->mon) + if (!(c = toplevel_from_popup(xdg_surface->popup)) || !c->mon) return; - box = c->mon->m; + box = c->mon->w; box.x -= c->geom.x; box.y -= c->geom.y; wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); @@ -1055,9 +1055,8 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) wl_list_remove(&layersurface->surface_commit.link); wlr_scene_node_destroy(layersurface->scene); if (layersurface->layer_surface->output) { - Monitor *m = layersurface->layer_surface->output->data; - if (m) - arrangelayers(m); + if (layersurface->mon) + arrangelayers(layersurface->mon); layersurface->layer_surface->output = NULL; } free(layersurface); -- cgit v1.2.3 From c1578bc14db7822743ffdbde93b2c22b1a0b5f6a Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 21 Jun 2022 16:03:20 -0500 Subject: use LayerSurface.mon when possible --- dwl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 0eb8fdb..3ccf9bc 100644 --- a/dwl.c +++ b/dwl.c @@ -759,14 +759,13 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit); struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_output *wlr_output = wlr_layer_surface->output; - Monitor *m; + + if (!wlr_output || !(layersurface->mon = wlr_output->data)) + return; wlr_scene_node_reparent(layersurface->scene, layers[wlr_layer_surface->current.layer]); - if (!wlr_output || !(m = wlr_output->data)) - return; - if (wlr_layer_surface->current.committed == 0 && layersurface->mapped == wlr_layer_surface->mapped) return; @@ -775,10 +774,10 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) if (layers[wlr_layer_surface->current.layer] != layersurface->scene) { wl_list_remove(&layersurface->link); - wl_list_insert(&m->layers[wlr_layer_surface->current.layer], + wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->current.layer], &layersurface->link); } - arrangelayers(m); + arrangelayers(layersurface->mon); } void @@ -1055,7 +1054,7 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) wl_list_remove(&layersurface->surface_commit.link); wlr_scene_node_destroy(layersurface->scene); if (layersurface->layer_surface->output) { - if (layersurface->mon) + if ((layersurface->mon = layersurface->layer_surface->output->data)) arrangelayers(layersurface->mon); layersurface->layer_surface->output = NULL; } @@ -1361,8 +1360,9 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { LayerSurface *layersurface = wl_container_of(listener, layersurface, map); + layersurface->mon = layersurface->layer_surface->output->data; wlr_surface_send_enter(layersurface->layer_surface->surface, - layersurface->layer_surface->output); + layersurface->mon->wlr_output); motionnotify(0); } -- cgit v1.2.3 From 097b4a30f5906fb45ce805115dd9dde48aefe60e Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 24 Jun 2022 14:30:52 -0500 Subject: unconstrain layer shell popups from monitor size unconstrain other popups from monitor usable area --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 3ccf9bc..5f4d5fd 100644 --- a/dwl.c +++ b/dwl.c @@ -956,7 +956,7 @@ createnotify(struct wl_listener *listener, void *data) xdg_surface->popup->parent->data, xdg_surface); if (!(c = toplevel_from_popup(xdg_surface->popup)) || !c->mon) return; - box = c->mon->w; + box = c->type == LayerShell ? c->mon->m : c->mon->w; box.x -= c->geom.x; box.y -= c->geom.y; wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); -- cgit v1.2.3 From 549335ae5458834f91a59ee14f385d17b2d4f888 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 24 Jun 2022 14:46:08 -0500 Subject: avoid layer surface popups appearing below x{dg,wayland} clients --- dwl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 5f4d5fd..0d4163e 100644 --- a/dwl.c +++ b/dwl.c @@ -952,9 +952,14 @@ createnotify(struct wl_listener *listener, void *data) if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { struct wlr_box box; + LayerSurface *l; + void *toplevel = toplevel_from_popup(xdg_surface->popup); xdg_surface->surface->data = wlr_scene_xdg_surface_create( xdg_surface->popup->parent->data, xdg_surface); - if (!(c = toplevel_from_popup(xdg_surface->popup)) || !c->mon) + if (wlr_surface_is_layer_surface(xdg_surface->popup->parent) && (l = toplevel) + && l->layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + wlr_scene_node_reparent(xdg_surface->surface->data, layers[LyrTop]); + if (!(c = toplevel) || !c->mon) return; box = c->type == LayerShell ? c->mon->m : c->mon->w; box.x -= c->geom.x; -- cgit v1.2.3 From 2aa391361c877f3319050e57c828e065a61d9d85 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 24 Jun 2022 15:36:13 -0500 Subject: inline unmaplayersurface() into unmaplayersurfacenotify() unmap signal is guaranted to be emitted before destroy signal so is useless checking if it is mapped at destroy --- dwl.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 0d4163e..e349d8b 100644 --- a/dwl.c +++ b/dwl.c @@ -283,7 +283,6 @@ static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); -static void unmaplayersurface(LayerSurface *layersurface); static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); static void unmapnotify(struct wl_listener *listener, void *data); static void updatemons(struct wl_listener *listener, void *data); @@ -1050,8 +1049,6 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) { LayerSurface *layersurface = wl_container_of(listener, layersurface, destroy); - if (layersurface->layer_surface->mapped) - unmaplayersurface(layersurface); wl_list_remove(&layersurface->link); wl_list_remove(&layersurface->destroy.link); wl_list_remove(&layersurface->map.link); @@ -2245,8 +2242,10 @@ toggleview(const Arg *arg) } void -unmaplayersurface(LayerSurface *layersurface) +unmaplayersurfacenotify(struct wl_listener *listener, void *data) { + LayerSurface *layersurface = wl_container_of(listener, layersurface, unmap); + layersurface->layer_surface->mapped = (layersurface->mapped = 0); wlr_scene_node_set_enabled(layersurface->scene, 0); if (layersurface->layer_surface->surface == @@ -2255,13 +2254,6 @@ unmaplayersurface(LayerSurface *layersurface) motionnotify(0); } -void -unmaplayersurfacenotify(struct wl_listener *listener, void *data) -{ - LayerSurface *layersurface = wl_container_of(listener, layersurface, unmap); - unmaplayersurface(layersurface); -} - void unmapnotify(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From 72e0a560d9836c5e8658003f548203bcd722e565 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 24 Jun 2022 19:15:24 -0500 Subject: respect size hints --- client.h | 83 +++++++++++++++++++++++++++++----------------------------------- dwl.c | 18 ++++++++------ 2 files changed, 49 insertions(+), 52 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index 4112fd6..7301d25 100644 --- a/client.h +++ b/client.h @@ -81,6 +81,32 @@ client_get_geometry(Client *c, struct wlr_box *geom) wlr_xdg_surface_get_geometry(c->surface.xdg, geom); } +static inline void +client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min) +{ + struct wlr_xdg_toplevel *toplevel; + 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; + if (size_hints) { + max->width = size_hints->max_width; + max->height = size_hints->max_height; + min->width = size_hints->min_width; + min->height = size_hints->min_height; + } + return; + } +#endif + toplevel = c->surface.xdg->toplevel; + state = &toplevel->current; + max->width = state->max_width; + max->height = state->max_height; + min->width = state->min_width; + min->height = state->min_height; +} + static inline const char * client_get_title(Client *c) { @@ -94,39 +120,31 @@ 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; + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); #ifdef XWAYLAND 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]) + 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; - - return 0; + return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0) + && (min.width == max.width || min.height == max.height)) + || c->surface.xwayland->parent; } #endif - 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; + return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0) + && (min.width == max.width || min.height == max.height)) + || c->surface.xdg->toplevel->parent; } static inline int @@ -206,31 +224,6 @@ 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 void -client_min_size(Client *c, int *width, int *height) -{ - struct wlr_xdg_toplevel *toplevel; - 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; - if (size_hints) { - *width = size_hints->min_width; - *height = size_hints->min_height; - } else { - *width = 0; - *height = 0; - } - return; - } -#endif - toplevel = c->surface.xdg->toplevel; - state = &toplevel->current; - *width = state->min_width; - *height = state->min_height; -} - static inline void client_restack_surface(Client *c) { diff --git a/dwl.c b/dwl.c index e349d8b..36a7543 100644 --- a/dwl.c +++ b/dwl.c @@ -381,9 +381,15 @@ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; void applybounds(Client *c, struct wlr_box *bbox) { - /* set minimum possible */ - c->geom.width = MAX(1, c->geom.width); - c->geom.height = MAX(1, c->geom.height); + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); + /* try to set size hints */ + c->geom.width = MAX(min.width + (2 * c->bw), c->geom.width); + c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height); + if (max.width > 0) + c->geom.width = MIN(max.width + (2 * c->bw), c->geom.width); + if (max.height > 0) + c->geom.height = MIN(max.height + (2 * c->bw), c->geom.height); if (c->geom.x >= bbox->x + bbox->width) c->geom.x = bbox->x + bbox->width - c->geom.width; @@ -1721,13 +1727,11 @@ requeststartdrag(struct wl_listener *listener, void *data) void 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_min_size(c, &min_width, &min_height); c->geom.x = x; c->geom.y = y; - c->geom.width = MAX(min_width + 2 * c->bw, w); - c->geom.height = MAX(min_height + 2 * c->bw, h); + c->geom.width = w; + c->geom.height = h; applybounds(c, bbox); /* Update scene-graph, including borders */ -- cgit v1.2.3 From 7cc6c640e2412935bf195ec55dafeb5852c71dd1 Mon Sep 17 00:00:00 2001 From: Ben Jargowsky Date: Tue, 28 Jun 2022 20:14:23 +0200 Subject: Checks for overflows for client max width and height --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 36a7543..393e80f 100644 --- a/dwl.c +++ b/dwl.c @@ -4,6 +4,7 @@ #define _POSIX_C_SOURCE 200809L #include #include +#include #include #include #include @@ -386,9 +387,9 @@ applybounds(Client *c, struct wlr_box *bbox) /* try to set size hints */ c->geom.width = MAX(min.width + (2 * c->bw), c->geom.width); c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height); - if (max.width > 0) + 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) + 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); if (c->geom.x >= bbox->x + bbox->width) -- cgit v1.2.3 From ff70337c163dfadea2c997a9b030e978fb463c2d Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Wed, 6 Jul 2022 19:14:12 -0500 Subject: check current and pending geometry to set c->resize to zero Fixes #260 --- dwl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 393e80f..675f4fc 100644 --- a/dwl.c +++ b/dwl.c @@ -792,10 +792,10 @@ commitnotify(struct wl_listener *listener, void *data) Client *c = wl_container_of(listener, c, commit); /* mark a pending resize as completed */ - if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) + if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial + || (c->surface.xdg->current.geometry.width == c->surface.xdg->pending.geometry.width + && c->surface.xdg->current.geometry.height == c->surface.xdg->pending.geometry.height))) c->resize = 0; - else if (c->resize) - c->resize = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); } void -- cgit v1.2.3 From 829dec659875d19db08bb4e4334cecb087895fda Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 24 Jun 2022 19:41:26 -0500 Subject: resize now takes `struct wlr_box` as parameter --- dwl.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 675f4fc..cb71aae 100644 --- a/dwl.c +++ b/dwl.c @@ -262,7 +262,7 @@ 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 resize(Client *c, struct wlr_box geo, int interact); static void run(char *startup_cmd); static Client *selclient(void); static void setcursor(struct wl_listener *listener, void *data); @@ -751,8 +751,8 @@ closemon(Monitor *m) wl_list_for_each(c, &clients, link) { if (c->isfloating && c->geom.x > m->m.width) - resize(c, c->geom.x - m->w.width, c->geom.y, - c->geom.width, c->geom.height, 0); + resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, + .width = c->geom.width, .height = c->geom.height}, 0); if (c->mon == m) setmon(c, selmon, c->tags); } @@ -1434,7 +1434,7 @@ monocle(Monitor *m) wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; - resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0); + resize(c, m->w, 0); } focusclient(focustop(m), 1); } @@ -1476,13 +1476,12 @@ motionnotify(uint32_t time) /* If we are currently grabbing the mouse, handle and return */ if (cursor_mode == CurMove) { /* Move the grabbed client to the new position. */ - resize(grabc, cursor->x - grabcx, cursor->y - grabcy, - grabc->geom.width, grabc->geom.height, 1); + resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, + .width = grabc->geom.width, .height = grabc->geom.height}, 1); return; } else if (cursor_mode == CurResize) { - resize(grabc, grabc->geom.x, grabc->geom.y, - cursor->x - grabc->geom.x, - cursor->y - grabc->geom.y, 1); + resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, + .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1); return; } @@ -1726,13 +1725,10 @@ requeststartdrag(struct wl_listener *listener, void *data) } void -resize(Client *c, int x, int y, int w, int h, int interact) +resize(Client *c, struct wlr_box geo, int interact) { struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; - c->geom.x = x; - c->geom.y = y; - c->geom.width = w; - c->geom.height = h; + c->geom = geo; applybounds(c, bbox); /* Update scene-graph, including borders */ @@ -1851,11 +1847,11 @@ setfullscreen(Client *c, int fullscreen) if (fullscreen) { c->prev = c->geom; - resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0); + resize(c, c->mon->m, 0); } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ - resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0); + resize(c, c->prev, 0); } arrange(c->mon); printstatus(); @@ -1904,7 +1900,7 @@ setmon(Client *c, Monitor *m, unsigned int newtags) } if (m) { /* Make sure window actually overlaps with the monitor */ - resize(c, c->geom.x, c->geom.y, c->geom.width, c->geom.height, 0); + resize(c, c->geom, 0); wlr_surface_send_enter(client_surface(c), m->wlr_output); c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ arrange(m); @@ -2170,7 +2166,7 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int i, n = 0, h, mw, my, ty; + unsigned int i, n = 0, mw, my, ty; Client *c; wl_list_for_each(c, &clients, link) @@ -2188,12 +2184,12 @@ tile(Monitor *m) if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; if (i < m->nmaster) { - h = (m->w.height - my) / (MIN(n, m->nmaster) - i); - resize(c, m->w.x, m->w.y + my, mw, h, 0); + resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, + .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); my += c->geom.height; } else { - h = (m->w.height - ty) / (n - i); - resize(c, m->w.x + mw, m->w.y + ty, m->w.width - mw, h, 0); + resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, + .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); ty += c->geom.height; } i++; -- cgit v1.2.3 From c6d97f1db741185841c20f3c1771e359acc9b66c Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Fri, 1 Apr 2022 14:03:52 -0600 Subject: arrange client's monitor if size has change since last commit --- dwl.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index cb71aae..c66d3d9 100644 --- a/dwl.c +++ b/dwl.c @@ -790,6 +790,12 @@ void commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); + struct wlr_box box; + 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 @@ -980,7 +986,6 @@ createnotify(struct wl_listener *listener, void *data) c->surface.xdg = xdg_surface; c->bw = borderpx; - LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); LISTEN(&xdg_surface->events.map, &c->map, mapnotify); LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); @@ -1085,9 +1090,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); } @@ -1387,8 +1391,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; if (client_is_unmanaged(c)) { @@ -2276,6 +2286,7 @@ unmapnotify(struct wl_listener *listener, void *data) wl_list_remove(&c->link); setmon(c, NULL, 0); wl_list_remove(&c->flink); + wl_list_remove(&c->commit.link); wlr_scene_node_destroy(c->scene); printstatus(); } -- cgit v1.2.3 From 87fc3a58ab72ff6ff6eb6e1156ff208fcb9e3739 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Wed, 6 Jul 2022 23:48:53 -0500 Subject: check pointer focus in arrange() --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index c66d3d9..7a585d5 100644 --- a/dwl.c +++ b/dwl.c @@ -496,7 +496,7 @@ arrange(Monitor *m) if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); - /* TODO recheck pointer focus here... or in resize()? */ + motionnotify(0); } void -- cgit v1.2.3 From 8e03bce6217117f0687cd727ae2c47bdd3c0fe5a Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 7 Jul 2022 00:21:51 -0500 Subject: only call wlr_seat_keyboard_notify_enter() if a keyboard is found --- dwl.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7a585d5..0c80691 100644 --- a/dwl.c +++ b/dwl.c @@ -613,8 +613,6 @@ arrangelayers(Monitor *m) if (kb) wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, kb->keycodes, kb->num_keycodes, &kb->modifiers); - else - wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, NULL, 0, NULL); return; } } @@ -1185,8 +1183,6 @@ focusclient(Client *c, int lift) if (kb) wlr_seat_keyboard_notify_enter(seat, client_surface(c), kb->keycodes, kb->num_keycodes, &kb->modifiers); - else - wlr_seat_keyboard_notify_enter(seat, client_surface(c), NULL, 0, NULL); /* Activate the new client */ client_activate_surface(client_surface(c), 1); -- cgit v1.2.3 From c70db2d06a7c868ba2d36de0984f5b39afd1a1c6 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 19 Jul 2022 11:52:15 -0500 Subject: Revert "only call wlr_seat_keyboard_notify_enter() if a keyboard is found" This reverts commit 8e03bce6217117f0687cd727ae2c47bdd3c0fe5a. fixes #270 --- dwl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 0c80691..7a585d5 100644 --- a/dwl.c +++ b/dwl.c @@ -613,6 +613,8 @@ arrangelayers(Monitor *m) if (kb) wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, kb->keycodes, kb->num_keycodes, &kb->modifiers); + else + wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, NULL, 0, NULL); return; } } @@ -1183,6 +1185,8 @@ focusclient(Client *c, int lift) if (kb) wlr_seat_keyboard_notify_enter(seat, client_surface(c), kb->keycodes, kb->num_keycodes, &kb->modifiers); + else + wlr_seat_keyboard_notify_enter(seat, client_surface(c), NULL, 0, NULL); /* Activate the new client */ client_activate_surface(client_surface(c), 1); -- cgit v1.2.3 From deb48ff48b186ff77a7e9d3b3ab724ff4c3c340f Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Tue, 19 Jul 2022 20:12:03 +0300 Subject: force line-buffered stdout if stdout is not a tty --- dwl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7a585d5..6464289 100644 --- a/dwl.c +++ b/dwl.c @@ -1674,7 +1674,6 @@ printstatus(void) sel, urg); printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); } - fflush(stdout); } void @@ -1943,6 +1942,9 @@ setsel(struct wl_listener *listener, void *data) void setup(void) { + /* Force line-buffered stdout */ + setvbuf(stdout, NULL, _IOLBF, 0); + /* The Wayland display is managed by libwayland. It handles accepting * clients from the Unix socket, manging Wayland globals, and so on. */ dpy = wl_display_create(); -- cgit v1.2.3 From e0822926068e84b0fc391e0306f66ea0ec16cf47 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Mon, 20 Jun 2022 18:33:14 -0500 Subject: do not focus clients if a layer surface is focused --- dwl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 6464289..65d7e24 100644 --- a/dwl.c +++ b/dwl.c @@ -299,6 +299,7 @@ static void zoom(const Arg *arg); /* variables */ static const char broken[] = "broken"; static pid_t child_pid = -1; +static struct wlr_surface *exclusive_focus; static struct wl_display *dpy; static struct wlr_backend *backend; static struct wlr_scene *scene; @@ -610,11 +611,12 @@ arrangelayers(Monitor *m) layersurface->layer_surface->mapped) { /* Deactivate the focused client. */ focusclient(NULL, 0); + exclusive_focus = layersurface->layer_surface->surface; if (kb) - wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, + wlr_seat_keyboard_notify_enter(seat, exclusive_focus, kb->keycodes, kb->num_keycodes, &kb->modifiers); else - wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface, NULL, 0, NULL); + wlr_seat_keyboard_notify_enter(seat, exclusive_focus, NULL, 0, NULL); return; } } @@ -1125,6 +1127,9 @@ focusclient(Client *c, int lift) struct wlr_surface *old = seat->keyboard_state.focused_surface; struct wlr_keyboard *kb; int i; + /* Do not focus clients if a layer surface is focused */ + if (exclusive_focus) + return; /* Raise client in stacking order if requested */ if (c && lift) @@ -2261,6 +2266,8 @@ unmaplayersurfacenotify(struct wl_listener *listener, void *data) layersurface->layer_surface->mapped = (layersurface->mapped = 0); wlr_scene_node_set_enabled(layersurface->scene, 0); + if (layersurface->layer_surface->surface == exclusive_focus) + exclusive_focus = NULL; if (layersurface->layer_surface->surface == seat->keyboard_state.focused_surface) focusclient(selclient(), 1); -- cgit v1.2.3 From 90a12c90a0aa0ac16327b0816de4d9dff69b357e Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 19 Jul 2022 20:13:56 -0500 Subject: always set the same monitor and tags for child clients of a client fixes #272 --- client.h | 52 +++++++++++++++++++++++++++++++++------------------- dwl.c | 11 +++++++++-- 2 files changed, 42 insertions(+), 21 deletions(-) (limited to 'dwl.c') diff --git a/client.h b/client.h index 681f842..dc4a6c4 100644 --- a/client.h +++ b/client.h @@ -26,6 +26,25 @@ client_surface(Client *c) return c->surface.xdg->surface; } +static inline Client * +client_from_wlr_surface(struct wlr_surface *s) +{ + struct wlr_xdg_surface *surface; + +#ifdef XWAYLAND + struct wlr_xwayland_surface *xsurface; + if (s && wlr_surface_is_xwayland_surface(s) + && (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) + return xsurface->data; +#endif + if (s && wlr_surface_is_xdg_surface(s) + && (surface = wlr_xdg_surface_from_wlr_surface(s)) + && surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) + return surface->data; + + return NULL; +} + /* The others */ static inline void client_activate_surface(struct wlr_surface *s, int activated) @@ -117,6 +136,20 @@ client_get_title(Client *c) return c->surface.xdg->toplevel->title; } +static inline Client * +client_get_parent(Client *c) +{ + Client *p; +#ifdef XWAYLAND + if (client_is_x11(c) && c->surface.xwayland->parent) + return client_from_wlr_surface(c->surface.xwayland->parent->surface); +#endif + if (c->surface.xdg->toplevel->parent) + return client_from_wlr_surface(c->surface.xdg->toplevel->parent->surface); + + return NULL; +} + static inline int client_is_float_type(Client *c) { @@ -235,25 +268,6 @@ client_restack_surface(Client *c) return; } -static inline Client * -client_from_wlr_surface(struct wlr_surface *s) -{ - struct wlr_xdg_surface *surface; - -#ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; - if (wlr_surface_is_xwayland_surface(s) - && (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) - return xsurface->data; -#endif - if (wlr_surface_is_xdg_surface(s) - && (surface = wlr_xdg_surface_from_wlr_surface(s)) - && surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) - return surface->data; - - return NULL; -} - static inline void * toplevel_from_popup(struct wlr_xdg_popup *popup) { diff --git a/dwl.c b/dwl.c index 65d7e24..727e6e1 100644 --- a/dwl.c +++ b/dwl.c @@ -1388,7 +1388,7 @@ void mapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - Client *c = wl_container_of(listener, c, map); + Client *p, *c = wl_container_of(listener, c, map); int i; /* Create scene tree for this client and its border */ @@ -1432,7 +1432,14 @@ mapnotify(struct wl_listener *listener, void *data) wl_list_insert(&fstack, &c->flink); /* Set initial monitor, tags, floating status, and focus */ - applyrules(c); + if ((p = client_get_parent(c))) { + /* Set the same monitor and tags than its parent */ + c->isfloating = 1; + wlr_scene_node_reparent(c->scene, layers[LyrFloat]); + setmon(c, p->mon, p->tags); + } else { + applyrules(c); + } printstatus(); if (c->isfullscreen) -- cgit v1.2.3 From 8cdb9971264adfdc35777b5a9935c2e4c47eea9f Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 23 Jul 2022 02:08:10 -0500 Subject: conform the xdg-protocol with fullscreen translucent clients see `setfullscreen()` for more info --- config.def.h | 2 ++ dwl.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'dwl.c') diff --git a/config.def.h b/config.def.h index 43f35cd..29c6dbf 100644 --- a/config.def.h +++ b/config.def.h @@ -5,6 +5,8 @@ static const int lockfullscreen = 1; /* 1 will force focus on the fullscree 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}; +/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ +static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; diff --git a/dwl.c b/dwl.c index 727e6e1..35c72f0 100644 --- a/dwl.c +++ b/dwl.c @@ -98,6 +98,7 @@ typedef struct { struct wlr_scene_node *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_node *scene_surface; + struct wlr_scene_rect *fullscreen_bg; /* See setfullscreen() for info */ struct wl_list link; struct wl_list flink; union { @@ -1869,10 +1870,23 @@ setfullscreen(Client *c, int fullscreen) if (fullscreen) { c->prev = c->geom; resize(c, c->mon->m, 0); + /* The xdg-protocol specifies: + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + * + * For brevity we set a black background for all clients + */ + c->fullscreen_bg = wlr_scene_rect_create(c->scene, + c->geom.width, c->geom.height, fullscreen_bg); + wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node); } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ resize(c, c->prev, 0); + wlr_scene_node_destroy(&c->fullscreen_bg->node); } arrange(c->mon); printstatus(); -- cgit v1.2.3 From b04c73be3de62d2739b5bb85e40f0c9af1122903 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 23 Jul 2022 13:25:47 -0500 Subject: make sure we do not create a double fullscreen_bg and also make sure we do not destroy it if it does not exist Fixes: #274 --- dwl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 35c72f0..7886b64 100644 --- a/dwl.c +++ b/dwl.c @@ -1879,14 +1879,19 @@ setfullscreen(Client *c, int fullscreen) * * For brevity we set a black background for all clients */ - c->fullscreen_bg = wlr_scene_rect_create(c->scene, - c->geom.width, c->geom.height, fullscreen_bg); - wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node); + if (!c->fullscreen_bg) { + c->fullscreen_bg = wlr_scene_rect_create(c->scene, + c->geom.width, c->geom.height, fullscreen_bg); + wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node); + } } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ resize(c, c->prev, 0); - wlr_scene_node_destroy(&c->fullscreen_bg->node); + if (c->fullscreen_bg) { + wlr_scene_node_destroy(&c->fullscreen_bg->node); + c->fullscreen_bg = NULL; + } } arrange(c->mon); printstatus(); -- cgit v1.2.3 From 7eee0a8229f2debed4ca552d0de5d7fe8a5721a5 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sun, 24 Jul 2022 16:43:13 -0500 Subject: use the layer surface to create popups --- dwl.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7886b64..42cd806 100644 --- a/dwl.c +++ b/dwl.c @@ -967,18 +967,17 @@ createnotify(struct wl_listener *listener, void *data) if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { struct wlr_box box; - LayerSurface *l; - void *toplevel = toplevel_from_popup(xdg_surface->popup); + LayerSurface *l = toplevel_from_popup(xdg_surface->popup); xdg_surface->surface->data = wlr_scene_xdg_surface_create( xdg_surface->popup->parent->data, xdg_surface); - if (wlr_surface_is_layer_surface(xdg_surface->popup->parent) && (l = toplevel) + if (wlr_surface_is_layer_surface(xdg_surface->popup->parent) && l && l->layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) wlr_scene_node_reparent(xdg_surface->surface->data, layers[LyrTop]); - if (!(c = toplevel) || !c->mon) + if (!l || !l->mon) return; - box = c->type == LayerShell ? c->mon->m : c->mon->w; - box.x -= c->geom.x; - box.y -= c->geom.y; + box = l->type == LayerShell ? l->mon->m : l->mon->w; + box.x -= l->geom.x; + box.y -= l->geom.y; wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); return; } else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) -- cgit v1.2.3 From 9d2eb8483b52a7a4858454d557196d83e1a24011 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Mon, 25 Jul 2022 08:14:33 +0300 Subject: fix segfault if parent->mon is unset --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 42cd806..d580b2d 100644 --- a/dwl.c +++ b/dwl.c @@ -1436,7 +1436,8 @@ mapnotify(struct wl_listener *listener, void *data) /* Set the same monitor and tags than its parent */ c->isfloating = 1; wlr_scene_node_reparent(c->scene, layers[LyrFloat]); - setmon(c, p->mon, p->tags); + /* TODO recheck if !p->mon is possible with wlroots 0.16.0 */ + setmon(c, p->mon ? p->mon : selmon, p->tags); } else { applyrules(c); } -- cgit v1.2.3 From 662e06e68e9bc2c41c3cb90d36c4d9998ff1f958 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 30 Jul 2022 14:44:17 -0500 Subject: check client_from_wlr_surface() returning NULL in urgent() fix #281 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index d580b2d..039b8ff 100644 --- a/dwl.c +++ b/dwl.c @@ -2377,7 +2377,7 @@ urgent(struct wl_listener *listener, void *data) { struct wlr_xdg_activation_v1_request_activate_event *event = data; Client *c = client_from_wlr_surface(event->surface); - if (c != selclient()) { + if (c && c != selclient()) { c->isurgent = 1; printstatus(); } -- cgit v1.2.3 From b6e3fc1645c5ac53277ab0dc20d7c266e1581b86 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Wed, 10 Aug 2022 23:57:03 -0500 Subject: rework outputmgrapplyortest() first disable requested monitors, then enable and/or change mode, x and y, etc. This is mostly what sway does --- dwl.c | 56 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 039b8ff..7d53ab9 100644 --- a/dwl.c +++ b/dwl.c @@ -1583,34 +1583,48 @@ 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; - - wlr_output_enable(wlr_output, config_head->state.enabled); - if (config_head->state.enabled) { - if (config_head->state.mode) - wlr_output_set_mode(wlr_output, config_head->state.mode); - else - wlr_output_set_custom_mode(wlr_output, - config_head->state.custom_mode.width, - config_head->state.custom_mode.height, - config_head->state.custom_mode.refresh); - - wlr_output_layout_move(output_layout, wlr_output, - 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); + 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); } - - if (!(ok = wlr_output_test(wlr_output))) - break; } + + /* Then enable outputs that need to */ wl_list_for_each(config_head, &config->heads, link) { - if (ok && !test) - wlr_output_commit(config_head->state.output); + struct wlr_output *wlr_output = config_head->state.output; + if (!config_head->state.enabled) + continue; + + wlr_output_enable(wlr_output, 1); + if (config_head->state.mode) + wlr_output_set_mode(wlr_output, config_head->state.mode); else - wlr_output_rollback(config_head->state.output); + wlr_output_set_custom_mode(wlr_output, + config_head->state.custom_mode.width, + config_head->state.custom_mode.height, + config_head->state.custom_mode.refresh); + + wlr_output_layout_move(output_layout, wlr_output, + 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); + + if (test) { + ok &= wlr_output_test(wlr_output); + wlr_output_rollback(wlr_output); + } else { + ok &= wlr_output_commit(wlr_output); + } } + if (ok) wlr_output_configuration_v1_send_succeeded(config); else -- cgit v1.2.3 From 48396a1bf8ce4282c4fc76d853195e1026caf7d7 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 11 Aug 2022 15:25:13 -0500 Subject: fix crash when setting a custom mode --- dwl.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7d53ab9..5031e0a 100644 --- a/dwl.c +++ b/dwl.c @@ -1621,7 +1621,23 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) ok &= wlr_output_test(wlr_output); wlr_output_rollback(wlr_output); } else { - ok &= wlr_output_commit(wlr_output); + 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) + 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); } } -- cgit v1.2.3 From f173c56c320a57e76a6bee578c3b9365f3a83950 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 13 Aug 2022 00:07:11 -0500 Subject: initialize to zero the box used in commitnotify() --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 5031e0a..0431119 100644 --- a/dwl.c +++ b/dwl.c @@ -793,7 +793,7 @@ void commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - struct wlr_box box; + 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 -- cgit v1.2.3 From 8d2516e83cb1e1d1cfc4fe31e69ed87d71405592 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 13 Aug 2022 00:38:08 -0500 Subject: reorder isfullscreen in Client definition --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 0431119..227f345 100644 --- a/dwl.c +++ b/dwl.c @@ -119,9 +119,8 @@ typedef struct { #endif int bw; unsigned int tags; - int isfloating, isurgent; + int isfloating, isurgent, isfullscreen; uint32_t resize; /* configure serial of a pending resize */ - int isfullscreen; } Client; typedef struct { -- cgit v1.2.3 From 7a343b98cf37fb293313dada734c0d433b27fba4 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 13 Aug 2022 00:41:08 -0500 Subject: change type of c->bw: int -> unsigned int --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 227f345..40ea05a 100644 --- a/dwl.c +++ b/dwl.c @@ -117,7 +117,7 @@ typedef struct { struct wl_listener configure; struct wl_listener set_hints; #endif - int bw; + unsigned int bw; unsigned int tags; int isfloating, isurgent, isfullscreen; uint32_t resize; /* configure serial of a pending resize */ -- cgit v1.2.3 From a7f77160d1b36029b496384087c0d71d27d73079 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Tue, 16 Aug 2022 20:57:09 -0500 Subject: don't respect size hints for fullscreen clients Fixes: #292 --- dwl.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 40ea05a..212afd1 100644 --- a/dwl.c +++ b/dwl.c @@ -383,15 +383,17 @@ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; void applybounds(Client *c, struct wlr_box *bbox) { - struct wlr_box min = {0}, max = {0}; - client_get_size_hints(c, &max, &min); - /* try to set size hints */ - c->geom.width = MAX(min.width + (2 * c->bw), c->geom.width); - c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height); - 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 - c->geom.height = MIN(max.height + (2 * c->bw), c->geom.height); + if (!c->isfullscreen) { + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); + /* try to set size hints */ + c->geom.width = MAX(min.width + (2 * c->bw), c->geom.width); + c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height); + 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 + c->geom.height = MIN(max.height + (2 * c->bw), c->geom.height); + } if (c->geom.x >= bbox->x + bbox->width) c->geom.x = bbox->x + bbox->width - c->geom.width; -- cgit v1.2.3 From 174919ec5342af19504661b30359068af5fcf1c1 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 18 Aug 2022 16:51:15 -0500 Subject: set monitor for clients that don't have one on monitor creation --- dwl.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 212afd1..cf7d307 100644 --- a/dwl.c +++ b/dwl.c @@ -896,6 +896,7 @@ createmon(struct wl_listener *listener, void *data) * monitor) becomes available. */ struct wlr_output *wlr_output = data; const MonitorRule *r; + Client *c; Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); m->wlr_output = wlr_output; @@ -944,15 +945,10 @@ createmon(struct wl_listener *listener, void *data) m->scene_output = wlr_scene_output_create(scene, wlr_output); wlr_output_layout_add_auto(output_layout, wlr_output); - /* If length == 1 we need update selmon. - * Maybe it will change in run(). */ - if (wl_list_length(&mons) == 1) { - Client *c; - selmon = m; - /* If there is any client, set c->mon to this monitor */ - wl_list_for_each(c, &clients, link) + /* If there are clients without monitor set this as their monitor */ + wl_list_for_each(c, &clients, link) + if (!c->mon) setmon(c, m, c->tags); - } } void -- cgit v1.2.3 From 07bf1832bf2c435107f4664c82efc756f3fdd784 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 18 Aug 2022 16:59:38 -0500 Subject: set monitor for clients that don't have one in updatemons() only if selmon is enabled and the clients are mapped --- client.h | 10 ++++++++++ dwl.c | 6 ++++++ 2 files changed, 16 insertions(+) (limited to 'dwl.c') diff --git a/client.h b/client.h index c091b81..c54a2f3 100644 --- a/client.h +++ b/client.h @@ -183,6 +183,16 @@ client_is_float_type(Client *c) || c->surface.xdg->toplevel->parent; } +static inline int +client_is_mapped(Client *c) +{ +#ifdef XWAYLAND + if (client_is_x11(c)) + return c->surface.xwayland->mapped; +#endif + return c->surface.xdg->mapped; +} + static inline int client_wants_fullscreen(Client *c) { diff --git a/dwl.c b/dwl.c index cf7d307..3a044d3 100644 --- a/dwl.c +++ b/dwl.c @@ -2365,6 +2365,7 @@ updatemons(struct wl_listener *listener, void *data) */ struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create(); + Client *c; Monitor *m; sgeom = *wlr_output_layout_get_box(output_layout, NULL); wl_list_for_each(m, &mons, link) { @@ -2388,6 +2389,11 @@ updatemons(struct wl_listener *listener, void *data) config_head->state.y = m->m.y; } + if (selmon && selmon->wlr_output->enabled) + wl_list_for_each(c, &clients, link) + if (!c->mon && client_is_mapped(c)) + setmon(c, selmon, c->tags); + wlr_output_manager_v1_set_configuration(output_mgr, config); } -- cgit v1.2.3 From dfcd142ce4079d36f5a0a73f9104ba87c365ef12 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Thu, 18 Aug 2022 17:24:11 -0500 Subject: don't try to set monitor for clients in createmon() this is done in updatemons() --- dwl.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 3a044d3..ebb74b8 100644 --- a/dwl.c +++ b/dwl.c @@ -944,11 +944,6 @@ createmon(struct wl_listener *listener, void *data) */ m->scene_output = wlr_scene_output_create(scene, wlr_output); wlr_output_layout_add_auto(output_layout, wlr_output); - - /* If there are clients without monitor set this as their monitor */ - wl_list_for_each(c, &clients, link) - if (!c->mon) - setmon(c, m, c->tags); } void -- cgit v1.2.3 From 406aebcbd2d9526834ad4131ac8b454a9f27c0d9 Mon Sep 17 00:00:00 2001 From: Leonardo Hernández Hernández Date: Sat, 13 Aug 2022 19:57:20 -0500 Subject: prevent an infinite loop if try to use focusmon() with all monitors disabled --- dwl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index ebb74b8..f76e30f 100644 --- a/dwl.c +++ b/dwl.c @@ -1192,9 +1192,11 @@ focusclient(Client *c, int lift) void focusmon(const Arg *arg) { - do - selmon = dirtomon(arg->i); - while (!selmon->wlr_output->enabled); + int i = 0, nmons = wl_list_length(&mons); + if (nmons) + do /* don't switch to disabled mons */ + selmon = dirtomon(arg->i); + while (!selmon->wlr_output->enabled && i++ < nmons); focusclient(focustop(selmon), 1); } -- cgit v1.2.3