URI:
       add fullscreenmodes patch for dwm - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit b0a8c246398ecc62b16d22ccb63d84cc61914706
   DIR parent c7e1829cd463fa21a41f92bcdb7489644d836475
  HTML 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:
         A dwm.suckless.org/patches/fullscree… |     280 +++++++++++++++++++++++++++++++
         A dwm.suckless.org/patches/fullscree… |      24 ++++++++++++++++++++++++
       
       2 files changed, 304 insertions(+), 0 deletions(-)
       ---
   DIR 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
       +
   DIR 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>