sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit b0a8c246398ecc62b16d22ccb63d84cc61914706
parent c7e1829cd463fa21a41f92bcdb7489644d836475
Author: Niky Kovalski <nikykovalski@gmail.com>
Date:   Wed, 23 Sep 2026 00:52:57 -0400

add fullscreenmodes patch for dwm

fullscreenmodes patch adds toggleable fullscreen and fakefullscreen

Diffstat:
Adwm.suckless.org/patches/fullscreenmodes/dwm-fullscreenmodes-20260922-44dbc68.diff | 280+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/fullscreenmodes/index.d | 24++++++++++++++++++++++++
2 files changed, 304 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/fullscreenmodes/dwm-fullscreenmodes-20260922-44dbc68.diff b/dwm.suckless.org/patches/fullscreenmodes/dwm-fullscreenmodes-20260922-44dbc68.diff @@ -0,0 +1,280 @@ +From 19ffcdf58d0055c1d9bdefe72f9a23a10a13161f Mon Sep 17 00:00:00 2001 +From: Niky Kovalski <nikykovalski@gmail.com> +Date: Tue, 22 Sep 2026 15:17:25 -0400 +Subject: [PATCH] fullscreenmodes + +- toggle actual fullscreen or fake fullscreen +- switching between the two is possible +- the client never exits fullscreen when switching between +fullscreen modes +--- + config.def.h | 8 +++-- + dwm.1 | 6 ++++ + dwm.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++----- + 3 files changed, 92 insertions(+), 11 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 81c3fc0..a8ee865 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -26,9 +26,9 @@ static const Rule rules[] = { + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask isfloating isfullscreen isfakefullscreen monitor */ ++ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, ++ { "Firefox", NULL, NULL, 1 << 8, 0, 0, 1, -1 }, + }; + + /* layout(s) */ +@@ -80,6 +80,8 @@ static const Key keys[] = { + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, ++ { MODKEY|ShiftMask, XK_f, togglefullscreen, {0} }, ++ { MODKEY|ControlMask, XK_f, togglefakefullscreen, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, +diff --git a/dwm.1 b/dwm.1 +index ddc8321..9d4436d 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -116,6 +116,12 @@ Zooms/cycles focused window to/from master area (tiled layouts only). + .B Mod1\-Shift\-c + Close focused window. + .TP ++.B Mod1\-Shift\-f ++Toggle fullscreen for focused window. ++.TP ++.B Mod1\-Control\-f ++Toggle fake fullscreen for focused window. ++.TP + .B Mod1\-Shift\-space + Toggle focused window between tiled and floating state. + .TP +diff --git a/dwm.c b/dwm.c +index ab3a84c..859d3d0 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -91,7 +91,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isfakefullscreen; + Client *next; + Client *snext; + Monitor *mon; +@@ -137,6 +137,8 @@ typedef struct { + const char *title; + unsigned int tags; + int isfloating; ++ int isfullscreen; ++ int isfakefullscreen; + int monitor; + } Rule; + +@@ -199,6 +201,7 @@ static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); + static void setfullscreen(Client *c, int fullscreen); ++static void setfullscreenmode(Client *c, int fakefullscreen); + static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); +@@ -210,6 +213,8 @@ static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); ++static void togglefakefullscreen(const Arg *arg); ++static void togglefullscreen(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unfocus(Client *c, int setfocus); +@@ -284,6 +289,8 @@ applyrules(Client *c) + XClassHint ch = { NULL, NULL }; + + /* rule matching */ ++ int isfullscreen = 0; ++ c->isfakefullscreen = 0; + c->isfloating = 0; + c->tags = 0; + XGetClassHint(dpy, c->win, &ch); +@@ -296,6 +303,8 @@ applyrules(Client *c) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { ++ isfullscreen = r->isfullscreen; ++ c->isfakefullscreen = r->isfakefullscreen; + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); +@@ -307,6 +316,8 @@ applyrules(Client *c) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); ++ if (isfullscreen) ++ setfullscreen(c, 1); + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; + } + +@@ -523,7 +534,7 @@ clientmessage(XEvent *e) + if (cme->data.l[1] == netatom[NetWMFullscreen] + || cme->data.l[2] == netatom[NetWMFullscreen]) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ +- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); ++ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && (!c->isfullscreen || c->isfakefullscreen)))); + } else if (cme->message_type == netatom[NetActiveWindow]) { + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); +@@ -567,7 +578,7 @@ configurenotify(XEvent *e) + updatebars(); + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) +- if (c->isfullscreen) ++ if (c->isfullscreen && !c->isfakefullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + } +@@ -839,7 +850,7 @@ focusstack(const Arg *arg) + { + Client *c = NULL, *i; + +- if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) ++ if (!selmon->sel || (selmon->sel->isfullscreen && !selmon->sel->isfakefullscreen && lockfullscreen)) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); +@@ -1153,7 +1164,7 @@ movemouse(const Arg *arg) + + if (!(c = selmon->sel)) + return; +- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ ++ if (c->isfullscreen && !c->isfakefullscreen) /* no support moving fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; +@@ -1308,7 +1319,7 @@ resizemouse(const Arg *arg) + + if (!(c = selmon->sel)) + return; +- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ ++ if (c->isfullscreen && !c->isfakefullscreen) /* no support resizing fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; +@@ -1486,6 +1497,10 @@ setfullscreen(Client *c, int fullscreen) + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); + c->isfullscreen = 1; ++ if (c->isfakefullscreen) { ++ resizeclient(c, c->x, c->y, c->w, c->h); ++ return; ++ } + c->oldstate = c->isfloating; + c->oldbw = c->bw; + c->bw = 0; +@@ -1496,6 +1511,29 @@ setfullscreen(Client *c, int fullscreen) + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)0, 0); + c->isfullscreen = 0; ++ if (c->isfakefullscreen) { ++ resizeclient(c, c->x, c->y, c->w, c->h); ++ return; ++ } ++ c->isfloating = c->oldstate; ++ c->bw = c->oldbw; ++ c->x = c->oldx; ++ c->y = c->oldy; ++ c->w = c->oldw; ++ c->h = c->oldh; ++ resizeclient(c, c->x, c->y, c->w, c->h); ++ arrange(c->mon); ++ } ++} ++ ++void ++setfullscreenmode(Client *c, int fakefullscreen) { ++ if (!c->isfullscreen) { ++ c->isfakefullscreen = fakefullscreen; ++ return; ++ } ++ if (fakefullscreen && !c->isfakefullscreen) { ++ c->isfakefullscreen = 1; + c->isfloating = c->oldstate; + c->bw = c->oldbw; + c->x = c->oldx; +@@ -1505,6 +1543,15 @@ setfullscreen(Client *c, int fullscreen) + resizeclient(c, c->x, c->y, c->w, c->h); + arrange(c->mon); + } ++ else if (!fakefullscreen && c->isfakefullscreen) { ++ c->isfakefullscreen = 0; ++ c->oldstate = c->isfloating; ++ c->oldbw = c->bw; ++ c->bw = 0; ++ c->isfloating = 1; ++ resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); ++ XRaiseWindow(dpy, c->win); ++ } + } + + void +@@ -1634,7 +1681,7 @@ showhide(Client *c) + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); +- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) ++ if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && (!c->isfullscreen || c->isfakefullscreen)) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); + } else { +@@ -1726,7 +1773,7 @@ togglefloating(const Arg *arg) + { + if (!selmon->sel) + return; +- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ ++ if (selmon->sel->isfullscreen && !selmon->sel->isfakefullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) +@@ -1735,6 +1782,32 @@ togglefloating(const Arg *arg) + arrange(selmon); + } + ++void ++togglefakefullscreen(const Arg *arg) ++{ ++ if (!selmon->sel) ++ return; ++ if (selmon->sel->isfullscreen && !selmon->sel->isfakefullscreen) ++ setfullscreenmode(selmon->sel, 1); ++ else { ++ selmon->sel->isfakefullscreen = 1; ++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen); ++ } ++} ++ ++void ++togglefullscreen(const Arg *arg) ++{ ++ if (!selmon->sel) ++ return; ++ if (selmon->sel->isfullscreen && selmon->sel->isfakefullscreen) ++ setfullscreenmode(selmon->sel, 0); ++ else { ++ selmon->sel->isfakefullscreen = 0; ++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen); ++ } ++} ++ + void + toggletag(const Arg *arg) + { +-- +2.55.0 + diff --git a/dwm.suckless.org/patches/fullscreenmodes/index.d b/dwm.suckless.org/patches/fullscreenmodes/index.d @@ -0,0 +1,24 @@ +fullscreenmodes +=============== + +Description +----------- +This patch adds keybindings to toggle fullscreen and fake fullscreen +on the focused client. Alternating between the two doesn't cause the +client to leave fullscreen. It also adds fullscreen and fakefullscreen +rules for starting applications in fullscreen. + +Download +-------- +* [dwm-fullscreenmodes-20260922-44dbc68.diff](dwm-fullscreenmodes-20260922-44dbc68.diff) + +Notes +----- +Most of the code comes from [actualfullscreen](../actualfullscreen) and [selectivefakefullscreen](../selectivefakefullscreen) +but these patches are not compatible. However the authors of those +projects should get credit for the original fullscreen functionality +that inspired this patch. + +Author +------ +* Niky Kovalski - <nikykovalski@gmail.com>