diff --git a/patches/fullscreenadaptivesync/README.md b/patches/fullscreenadaptivesync/README.md index 6f7118c..01f0502 100644 --- a/patches/fullscreenadaptivesync/README.md +++ b/patches/fullscreenadaptivesync/README.md @@ -22,8 +22,10 @@ Adds a function that automatically enables adaptive sync/VRR when a fullscreen c - Enabled by default. ### Download -- [git branch](https://codeberg.org/julmajustus/dwl/src/branch/fullscreenadaptivesync) -- [0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch) +- [git branch](https://codeberg.org/julmajustus/dwl/src/branch/fullscreenadaptivesync-wlroots-next) +- [0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch) +- [0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.8.patch) +- [wlroots-next-d41ecb7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fullscreenadaptivesync/fullscreenadaptivesync-wlroots-next-d41ecb7.patch) ### Authors - [julmajustus](https://codeberg.org/julmajustus) diff --git a/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch b/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch index ccc012b..ce04ba1 100644 --- a/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch +++ b/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.7.patch @@ -1,12 +1,15 @@ -From c003f450c197a0c960bbb355511f8dca7a35e3c3 Mon Sep 17 00:00:00 2001 +From 85dccbec7e6d2e967646a8c182a7a24224632c68 Mon Sep 17 00:00:00 2001 From: julmajustus -Date: Sat, 4 Jan 2025 14:24:59 +0200 -Subject: [PATCH] add fullscreenadaptivesync +Date: Mon, 18 May 2026 00:03:41 +0300 +Subject: [PATCH] fullscreen_adaptive_sync: Minor bug fixes +- Fixed logic error inside unmapnotify +- Added no-op guards inside set_adaptive_sync +- Added extra check for the config commit success --- config.def.h | 1 + - dwl.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 41 insertions(+) + dwl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 53 insertions(+) diff --git a/config.def.h b/config.def.h index 22d2171..886f1ab 100644 @@ -21,7 +24,7 @@ index 22d2171..886f1ab 100644 { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, diff --git a/dwl.c b/dwl.c -index a2711f6..7be05ef 100644 +index a2711f6..1b0682d 100644 --- a/dwl.c +++ b/dwl.c @@ -322,6 +322,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data); @@ -49,11 +52,10 @@ index a2711f6..7be05ef 100644 #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data); -@@ -2269,6 +2273,31 @@ run(char *startup_cmd) +@@ -2269,6 +2273,42 @@ run(char *startup_cmd) wl_display_run(dpy); } -+void +set_adaptive_sync(Monitor *m, int enable) +{ + struct wlr_output_state state; @@ -64,14 +66,26 @@ index a2711f6..7be05ef 100644 + || !fullscreen_adaptive_sync_enabled) + return; + ++ if (enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) ++ return; ++ ++ if (!enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED) ++ return; ++ + config = wlr_output_configuration_v1_create(); + config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); + + /* Set and commit the adaptive sync state change */ + wlr_output_state_init(&state); + wlr_output_state_set_adaptive_sync_enabled(&state, enable); -+ wlr_output_commit_state(m->wlr_output, &state); -+ wlr_output_state_finish(&state); ++ if (!wlr_output_commit_state(m->wlr_output, &state)) { ++ wlr_output_state_finish(&state); ++ wlr_output_configuration_v1_destroy(config); ++ return; ++ } ++ wlr_output_state_finish(&state); + + /* Broadcast the adaptive sync state change to output_mgr */ + config_head->state.adaptive_sync_enabled = enable; @@ -81,7 +95,7 @@ index a2711f6..7be05ef 100644 void setcursor(struct wl_listener *listener, void *data) { -@@ -2332,10 +2361,12 @@ setfullscreen(Client *c, int fullscreen) +@@ -2332,10 +2372,12 @@ setfullscreen(Client *c, int fullscreen) if (fullscreen) { c->prev = c->geom; resize(c, c->mon->m, 0); @@ -94,7 +108,7 @@ index a2711f6..7be05ef 100644 } arrange(c->mon); printstatus(); -@@ -2739,6 +2770,12 @@ togglefullscreen(const Arg *arg) +@@ -2739,6 +2781,12 @@ togglefullscreen(const Arg *arg) setfullscreen(sel, !sel->isfullscreen); } @@ -107,16 +121,24 @@ index a2711f6..7be05ef 100644 void toggletag(const Arg *arg) { -@@ -2809,6 +2846,9 @@ unmapnotify(struct wl_listener *listener, void *data) +@@ -2794,6 +2842,7 @@ unmapnotify(struct wl_listener *listener, void *data) + { + /* Called when the surface is unmapped, and should no longer be shown. */ + Client *c = wl_container_of(listener, c, unmap); ++ Monitor *lastmon = c->mon; // fullscreen_adaptive_sync + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; +@@ -2809,6 +2858,9 @@ unmapnotify(struct wl_listener *listener, void *data) setmon(c, NULL, 0); wl_list_remove(&c->flink); } + /* Toggle adaptive sync off when fullscreen client is unmapped */ -+ if (c->isfullscreen) -+ set_adaptive_sync(selmon, 0); ++ if (c->isfullscreen) ++ set_adaptive_sync(lastmon, 0); wlr_scene_node_destroy(&c->scene->node); printstatus(); -- -2.45.2 +2.53.0 diff --git a/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.8.patch b/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.8.patch new file mode 100644 index 0000000..82c97b6 --- /dev/null +++ b/patches/fullscreenadaptivesync/fullscreenadaptivesync-v0.8.patch @@ -0,0 +1,144 @@ +From 60af6f9dab09710234475b51393a104c21918db3 Mon Sep 17 00:00:00 2001 +From: julmajustus +Date: Mon, 18 May 2026 00:12:31 +0300 +Subject: [PATCH] fullscreen_adaptive_sync: Minor bug fixes + +- Fixed logic error inside unmapnotify +- Added no-op guards inside set_adaptive_sync +- Added extra check for the config commit success +--- + config.def.h | 1 + + dwl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 53 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 8a6eda0..06b3153 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -138,6 +138,7 @@ static const Key keys[] = { + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, ++ { MODKEY, XKB_KEY_F5, togglefullscreenadaptivesync, {0} }, + { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, + { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, +diff --git a/dwl.c b/dwl.c +index 44f3ad9..737f089 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -319,6 +319,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data); + static void requestmonstate(struct wl_listener *listener, void *data); + static void resize(Client *c, struct wlr_box geo, int interact); + static void run(char *startup_cmd); ++static void set_adaptive_sync(Monitor *m, int enabled); + static void setcursor(struct wl_listener *listener, void *data); + static void setcursorshape(struct wl_listener *listener, void *data); + static void setfloating(Client *c, int floating); +@@ -336,6 +337,7 @@ static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglefloating(const Arg *arg); + static void togglefullscreen(const Arg *arg); ++static void togglefullscreenadaptivesync(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unlocksession(struct wl_listener *listener, void *data); +@@ -436,6 +438,8 @@ static struct wl_listener request_start_drag = {.notify = requeststartdrag}; + static struct wl_listener start_drag = {.notify = startdrag}; + static struct wl_listener new_session_lock = {.notify = locksession}; + ++static int fullscreen_adaptive_sync_enabled = 1; ++ + #ifdef XWAYLAND + static void activatex11(struct wl_listener *listener, void *data); + static void associatex11(struct wl_listener *listener, void *data); +@@ -2296,6 +2300,42 @@ run(char *startup_cmd) + wl_display_run(dpy); + } + ++set_adaptive_sync(Monitor *m, int enable) ++{ ++ struct wlr_output_state state; ++ struct wlr_output_configuration_v1 *config; ++ struct wlr_output_configuration_head_v1 *config_head; ++ ++ if (!m || !m->wlr_output || !m->wlr_output->enabled ++ || !fullscreen_adaptive_sync_enabled) ++ return; ++ ++ if (enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) ++ return; ++ ++ if (!enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED) ++ return; ++ ++ config = wlr_output_configuration_v1_create(); ++ config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); ++ ++ /* Set and commit the adaptive sync state change */ ++ wlr_output_state_init(&state); ++ wlr_output_state_set_adaptive_sync_enabled(&state, enable); ++ if (!wlr_output_commit_state(m->wlr_output, &state)) { ++ wlr_output_state_finish(&state); ++ wlr_output_configuration_v1_destroy(config); ++ return; ++ } ++ wlr_output_state_finish(&state); ++ ++ /* Broadcast the adaptive sync state change to output_mgr */ ++ config_head->state.adaptive_sync_enabled = enable; ++ wlr_output_manager_v1_set_configuration(output_mgr, config); ++} ++ + void + setcursor(struct wl_listener *listener, void *data) + { +@@ -2359,10 +2399,12 @@ setfullscreen(Client *c, int fullscreen) + if (fullscreen) { + c->prev = c->geom; + resize(c, c->mon->m, 0); ++ set_adaptive_sync(c->mon, 1); + } 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); ++ set_adaptive_sync(c->mon, 0); + } + arrange(c->mon); + printstatus(); +@@ -2760,6 +2802,12 @@ togglefullscreen(const Arg *arg) + setfullscreen(sel, !sel->isfullscreen); + } + ++void ++togglefullscreenadaptivesync(const Arg *arg) ++{ ++ fullscreen_adaptive_sync_enabled = !fullscreen_adaptive_sync_enabled; ++} ++ + void + toggletag(const Arg *arg) + { +@@ -2815,6 +2863,7 @@ unmapnotify(struct wl_listener *listener, void *data) + { + /* Called when the surface is unmapped, and should no longer be shown. */ + Client *c = wl_container_of(listener, c, unmap); ++ Monitor *lastmon = c->mon; // fullscreen_adaptive_sync + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; +@@ -2830,6 +2879,9 @@ unmapnotify(struct wl_listener *listener, void *data) + setmon(c, NULL, 0); + wl_list_remove(&c->flink); + } ++ /* Toggle adaptive sync off when fullscreen client is unmapped */ ++ if (c->isfullscreen) ++ set_adaptive_sync(lastmon, 0); + + wlr_scene_node_destroy(&c->scene->node); + printstatus(); +-- +2.53.0 + diff --git a/patches/fullscreenadaptivesync/fullscreenadaptivesync-wlroots-next-d41ecb7.patch b/patches/fullscreenadaptivesync/fullscreenadaptivesync-wlroots-next-d41ecb7.patch new file mode 100644 index 0000000..d3bd12e --- /dev/null +++ b/patches/fullscreenadaptivesync/fullscreenadaptivesync-wlroots-next-d41ecb7.patch @@ -0,0 +1,144 @@ +From cf817259dbb1235d1ffc073d4e0f128676552666 Mon Sep 17 00:00:00 2001 +From: julmajustus +Date: Mon, 18 May 2026 00:15:18 +0300 +Subject: [PATCH] fullscreen_adaptive_sync: Minor bug fixes + +- Fixed logic error inside unmapnotify +- Added no-op guards inside set_adaptive_sync +- Added extra check for the config commit success +--- + config.def.h | 1 + + dwl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 53 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 8a6eda0..06b3153 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -138,6 +138,7 @@ static const Key keys[] = { + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, ++ { MODKEY, XKB_KEY_F5, togglefullscreenadaptivesync, {0} }, + { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, + { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, +diff --git a/dwl.c b/dwl.c +index 8101ffa..2f1c80b 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -323,6 +323,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data); + static void requestmonstate(struct wl_listener *listener, void *data); + static void resize(Client *c, struct wlr_box geo, int interact); + static void run(char *startup_cmd); ++static void set_adaptive_sync(Monitor *m, int enabled); + static void setcursor(struct wl_listener *listener, void *data); + static void setcursorshape(struct wl_listener *listener, void *data); + static void setfloating(Client *c, int floating); +@@ -340,6 +341,7 @@ static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglefloating(const Arg *arg); + static void togglefullscreen(const Arg *arg); ++static void togglefullscreenadaptivesync(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unlocksession(struct wl_listener *listener, void *data); +@@ -440,6 +442,8 @@ static struct wl_listener request_start_drag = {.notify = requeststartdrag}; + static struct wl_listener start_drag = {.notify = startdrag}; + static struct wl_listener new_session_lock = {.notify = locksession}; + ++static int fullscreen_adaptive_sync_enabled = 1; ++ + #ifdef XWAYLAND + static void activatex11(struct wl_listener *listener, void *data); + static void associatex11(struct wl_listener *listener, void *data); +@@ -2300,6 +2304,42 @@ run(char *startup_cmd) + wl_display_run(dpy); + } + ++set_adaptive_sync(Monitor *m, int enable) ++{ ++ struct wlr_output_state state; ++ struct wlr_output_configuration_v1 *config; ++ struct wlr_output_configuration_head_v1 *config_head; ++ ++ if (!m || !m->wlr_output || !m->wlr_output->enabled ++ || !fullscreen_adaptive_sync_enabled) ++ return; ++ ++ if (enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) ++ return; ++ ++ if (!enable && m->wlr_output->adaptive_sync_status ++ == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED) ++ return; ++ ++ config = wlr_output_configuration_v1_create(); ++ config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); ++ ++ /* Set and commit the adaptive sync state change */ ++ wlr_output_state_init(&state); ++ wlr_output_state_set_adaptive_sync_enabled(&state, enable); ++ if (!wlr_output_commit_state(m->wlr_output, &state)) { ++ wlr_output_state_finish(&state); ++ wlr_output_configuration_v1_destroy(config); ++ return; ++ } ++ wlr_output_state_finish(&state); ++ ++ /* Broadcast the adaptive sync state change to output_mgr */ ++ config_head->state.adaptive_sync_enabled = enable; ++ wlr_output_manager_v1_set_configuration(output_mgr, config); ++} ++ + void + setcursor(struct wl_listener *listener, void *data) + { +@@ -2363,10 +2403,12 @@ setfullscreen(Client *c, int fullscreen) + if (fullscreen) { + c->prev = c->geom; + resize(c, c->mon->m, 0); ++ set_adaptive_sync(c->mon, 1); + } 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); ++ set_adaptive_sync(c->mon, 0); + } + arrange(c->mon); + printstatus(); +@@ -2767,6 +2809,12 @@ togglefullscreen(const Arg *arg) + setfullscreen(sel, !sel->isfullscreen); + } + ++void ++togglefullscreenadaptivesync(const Arg *arg) ++{ ++ fullscreen_adaptive_sync_enabled = !fullscreen_adaptive_sync_enabled; ++} ++ + void + toggletag(const Arg *arg) + { +@@ -2822,6 +2870,7 @@ unmapnotify(struct wl_listener *listener, void *data) + { + /* Called when the surface is unmapped, and should no longer be shown. */ + Client *c = wl_container_of(listener, c, unmap); ++ Monitor *lastmon = c->mon; // fullscreen_adaptive_sync + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; +@@ -2837,6 +2886,9 @@ unmapnotify(struct wl_listener *listener, void *data) + setmon(c, NULL, 0); + wl_list_remove(&c->flink); + } ++ /* Toggle adaptive sync off when fullscreen client is unmapped */ ++ if (c->isfullscreen) ++ set_adaptive_sync(lastmon, 0); + + wlr_scene_node_destroy(&c->scene->node); + printstatus(); +-- +2.53.0 +