From c2e7350f2ef4f07810c8fa49bed3e8db37faa058 Mon Sep 17 00:00:00 2001 From: Forrest Bushstone Date: Wed, 12 Jun 2024 14:04:43 -0400 Subject: Make sure toplevel_from_wlr_surface is called with a valid surface pointer --- dwl.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 6f041a0..5a31aee 100644 --- a/dwl.c +++ b/dwl.c @@ -397,7 +397,6 @@ static struct wl_listener lock_listener = {.notify = locksession}; static struct wlr_seat *seat; static KeyboardGroup *kb_group; -static struct wlr_surface *held_grab; static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ @@ -603,7 +602,6 @@ buttonpress(struct wl_listener *listener, void *data) switch (event->state) { case WLR_BUTTON_PRESSED: cursor_mode = CurPressed; - held_grab = seat->pointer_state.focused_surface; if (locked) break; @@ -623,7 +621,6 @@ buttonpress(struct wl_listener *listener, void *data) } break; case WLR_BUTTON_RELEASED: - held_grab = NULL; /* If you released any buttons, we exit interactive move/resize mode. */ /* TODO should reset to the pointer focus's current setcursor */ if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { @@ -1757,6 +1754,18 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d struct wlr_surface *surface = NULL; struct wlr_pointer_constraint_v1 *constraint; + /* 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 && !seat->drag + && surface != seat->pointer_state.focused_surface + && toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { + c = w; + surface = seat->pointer_state.focused_surface; + sx = cursor->x - (l ? l->geom.x : w->geom.x); + sy = cursor->y - (l ? l->geom.y : w->geom.y); + } + /* time is 0 in internal calls meant to restore pointer focus. */ if (time) { wlr_relative_pointer_manager_v1_send_relative_motion( @@ -1805,17 +1814,6 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d return; } - /* 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 && !seat->drag && surface != held_grab - && toplevel_from_wlr_surface(held_grab, &w, &l) >= 0) { - c = w; - surface = held_grab; - sx = cursor->x - (l ? l->geom.x : w->geom.x); - sy = cursor->y - (l ? l->geom.y : w->geom.y); - } - /* 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. */ -- cgit v1.2.1 From 7a46fccdba35b46d91226d10c1c9b90e43418c09 Mon Sep 17 00:00:00 2001 From: Peter Hofmann Date: Tue, 18 Jun 2024 19:09:32 +0200 Subject: Run startup_cmd in new session and kill the entire group When a user's startup_cmd is a little more complex, e.g. a shell script, and forks off several processes, then killing only the main child pid might leave unwanted processes behind on exit. Not all children will notice when their parent or the compositor has quit. To fix this, put startup_cmd into its own session and process group, and kill the entire group on exit. --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 5a31aee..79ccb34 100644 --- a/dwl.c +++ b/dwl.c @@ -674,7 +674,7 @@ cleanup(void) #endif wl_display_destroy_clients(dpy); if (child_pid > 0) { - kill(child_pid, SIGTERM); + kill(-child_pid, SIGTERM); waitpid(child_pid, NULL, 0); } wlr_xcursor_manager_destroy(cursor_mgr); @@ -2141,6 +2141,7 @@ run(char *startup_cmd) if ((child_pid = fork()) < 0) die("startup: fork:"); if (child_pid == 0) { + setsid(); dup2(piperw[0], STDIN_FILENO); close(piperw[0]); close(piperw[1]); -- cgit v1.2.1 From 16076ec5a40ed708b99f27100036a4a92b4fdd59 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 4 May 2024 20:59:51 +0200 Subject: fix: make sure selmon doesn't get set to disabled mon --- dwl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 79ccb34..83bdbe4 100644 --- a/dwl.c +++ b/dwl.c @@ -727,6 +727,9 @@ closemon(Monitor *m) do /* don't switch to disabled mons */ selmon = wl_container_of(mons.next, selmon, link); while (!selmon->wlr_output->enabled && i++ < nmons); + + if (!selmon->wlr_output->enabled) + selmon = NULL; } wl_list_for_each(c, &clients, link) { @@ -2789,6 +2792,10 @@ updatemons(struct wl_listener *listener, void *data) config_head->state.x = m->m.x; config_head->state.y = m->m.y; + + if (!selmon) { + selmon = m; + } } if (selmon && selmon->wlr_output->enabled) { -- cgit v1.2.1 From 11baacbec0b75dff34abf52d5172687e4ae2cc4f Mon Sep 17 00:00:00 2001 From: Rutherther Date: Tue, 14 May 2024 17:57:59 +0200 Subject: Add output to layout after enabled state is committed --- dwl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 83bdbe4..60b74ae 100644 --- a/dwl.c +++ b/dwl.c @@ -1906,11 +1906,6 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) config_head->state.custom_mode.height, config_head->state.custom_mode.refresh); - /* Don't move monitors if position wouldn't change, this to avoid - * wlroots marking the output as manually configured */ - if (m->m.x != config_head->state.x || m->m.y != config_head->state.y) - wlr_output_layout_add(output_layout, wlr_output, - config_head->state.x, config_head->state.y); wlr_output_state_set_transform(&state, config_head->state.transform); wlr_output_state_set_scale(&state, config_head->state.scale); wlr_output_state_set_adaptive_sync_enabled(&state, @@ -1920,6 +1915,13 @@ apply_or_test: ok &= test ? wlr_output_test_state(wlr_output, &state) : wlr_output_commit_state(wlr_output, &state); + /* Don't move monitors if position wouldn't change, this to avoid + * wlroots marking the output as manually configured. + * wlr_output_layout_add does not like disabled outputs */ + if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) + wlr_output_layout_add(output_layout, wlr_output, + config_head->state.x, config_head->state.y); + wlr_output_state_finish(&state); } -- cgit v1.2.1 From 784b047b3825b0c784de85034e9b215134250e3c Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 31 May 2024 16:00:50 +0200 Subject: Check for null monitor in resize function --- dwl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 60b74ae..3dba2bf 100644 --- a/dwl.c +++ b/dwl.c @@ -2100,8 +2100,14 @@ requestmonstate(struct wl_listener *listener, void *data) void resize(Client *c, struct wlr_box geo, int interact) { - struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; + struct wlr_box *bbox; struct wlr_box clip; + + if (!c->mon) + return; + + bbox = interact ? &sgeom : &c->mon->w; + client_set_bounds(c, geo.width, geo.height); c->geom = geo; applybounds(c, bbox); -- cgit v1.2.1 From 9b1f35e42bf435b212dfcdcc510439ef8b4f2e31 Mon Sep 17 00:00:00 2001 From: Emil Miler Date: Wed, 17 Jan 2024 09:45:03 +0100 Subject: Implement support for output power management This patch is based on the original stale patch by Guido Cella @guidocella. It has been modified to apply cleanly to the latest v5.0 tag. Since the SLOC limit is now lifted, this core feature should be merged into dwl upstream. Thanks to Dima Krasner @dimkr for the cherry-pick. Closes: #559, #525 --- dwl.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 3dba2bf..7a2920e 100644 --- a/dwl.c +++ b/dwl.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -310,6 +311,7 @@ static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); static void printstatus(void); +static void powermgrsetmodenotify(struct wl_listener *listener, void *data); static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); @@ -381,6 +383,7 @@ static struct wlr_gamma_control_manager_v1 *gamma_control_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; +static struct wlr_output_power_manager_v1 *power_mgr; static struct wlr_pointer_constraints_v1 *pointer_constraints; static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; @@ -2011,6 +2014,14 @@ printstatus(void) fflush(stdout); } +void +powermgrsetmodenotify(struct wl_listener *listener, void *data) +{ + struct wlr_output_power_v1_set_mode_event *event = data; + wlr_output_enable(event->output, event->mode); + wlr_output_commit(event->output); +} + void quit(const Arg *arg) { @@ -2422,6 +2433,9 @@ setup(void) gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); + power_mgr = wlr_output_power_manager_v1_create(dpy); + LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmodenotify); + /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(); -- cgit v1.2.1 From 2902df94d6e3da04b7abc92f846b0da7d40ff4ea Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sat, 6 Apr 2024 11:29:14 -0600 Subject: Prevent updatemons() from removing monitors that have been put to sleep from the layout --- dwl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 7a2920e..4867760 100644 --- a/dwl.c +++ b/dwl.c @@ -207,6 +207,7 @@ struct Monitor { int gamma_lut_changed; int nmaster; char ltsymbol[16]; + int asleep; }; typedef struct { @@ -962,6 +963,8 @@ createmon(struct wl_listener *listener, void *data) LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); + m->asleep = 0; + wlr_output_state_set_enabled(&state, 1); wlr_output_commit_state(wlr_output, &state); wlr_output_state_finish(&state); @@ -2018,8 +2021,11 @@ void powermgrsetmodenotify(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; + wlr_output_enable(event->output, event->mode); wlr_output_commit(event->output); + + ((Monitor *)(event->output->data))->asleep = !event->mode; } void @@ -2755,7 +2761,7 @@ updatemons(struct wl_listener *listener, void *data) /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled) + if (m->wlr_output->enabled || m->asleep) continue; config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); config_head->state.enabled = 0; -- cgit v1.2.1 From 650a918010ac5769787d461812392cff786e4d3b Mon Sep 17 00:00:00 2001 From: thanatos Date: Thu, 20 Jun 2024 18:48:47 -0600 Subject: Updated power management handling to address issues raised in the PR --- dwl.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'dwl.c') diff --git a/dwl.c b/dwl.c index 4867760..2cdc819 100644 --- a/dwl.c +++ b/dwl.c @@ -312,7 +312,7 @@ static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); static void printstatus(void); -static void powermgrsetmodenotify(struct wl_listener *listener, void *data); +static void powermgrsetmode(struct wl_listener *listener, void *data); static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); @@ -963,8 +963,6 @@ createmon(struct wl_listener *listener, void *data) LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); - m->asleep = 0; - wlr_output_state_set_enabled(&state, 1); wlr_output_commit_state(wlr_output, &state); wlr_output_state_finish(&state); @@ -1899,6 +1897,10 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) Monitor *m = wlr_output->data; struct wlr_output_state state; + /* Ensure displays previously disabled by wlr-output-power-management-v1 + * are properly handled*/ + m->asleep = 0; + wlr_output_state_init(&state); wlr_output_state_set_enabled(&state, config_head->state.enabled); if (!config_head->state.enabled) @@ -2018,12 +2020,16 @@ printstatus(void) } void -powermgrsetmodenotify(struct wl_listener *listener, void *data) +powermgrsetmode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; + struct wlr_output_state state = {0}; + + if (!event->output->data) + return; - wlr_output_enable(event->output, event->mode); - wlr_output_commit(event->output); + wlr_output_state_set_enabled(&state, event->mode); + wlr_output_commit_state(event->output, &state); ((Monitor *)(event->output->data))->asleep = !event->mode; } @@ -2440,7 +2446,7 @@ setup(void) LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); power_mgr = wlr_output_power_manager_v1_create(dpy); - LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmodenotify); + LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ -- cgit v1.2.1