Compare commits

..

3 Commits

Author SHA1 Message Date
7f64fe2ae1 selective fake fullscreen patch w/ per client toggling 2024-07-08 00:54:24 -04:00
aaef347d15 layout menu patch 2024-07-07 23:09:33 -04:00
5d39ba4d96 move resize patch 2024-07-07 22:07:53 -04:00
6 changed files with 714 additions and 13 deletions

View File

@ -63,11 +63,11 @@ static const Rule rules[] = {
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating isterminal noswallow monitor */
{ "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 },
{ "St", NULL, NULL, 0, 0, 1, 0, -1 },
{ NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
/* class instance title tags mask isfloating isfakefullscreen isterminal noswallow monitor */
{ "Gimp", NULL, NULL, 0, 1, 0, 0, 0, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1, -1 },
{ "St", NULL, NULL, 0, 0, 0, 1, 0, -1 },
{ NULL, NULL, "Event Tester", 0, 0, 0, 0, 1, -1 }, /* xev */
};
/* window following */
@ -104,6 +104,7 @@ static const Layout layouts[] = {
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
static const char *layoutmenu_cmd = "layoutmenu.sh";
#include "exitdwm.c"
static const Key keys[] = {
/* modifier key function argument */
@ -131,7 +132,24 @@ static const Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
{ MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
{ MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
{ MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
{ MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
{ MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
{ MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
{ MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
{ MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
{ MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
{ MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
{ MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
{ MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
{ MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
{ MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
{ MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
{ MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY|Mod1Mask, XK_f, togglefakefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
@ -159,7 +177,7 @@ static const Key keys[] = {
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkLtSymbol, 0, Button3, layoutmenu, {0} },
{ ClkFollowSymbol, 0, Button1, togglefollow, {0} },
{ ClkWinTitle, 0, Button1, togglewin, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },

244
dwm.c
View File

@ -102,7 +102,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, isterminal, noswallow;
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isfakefullscreen, isterminal, noswallow;
pid_t pid;
Client *next;
Client *snext;
@ -158,6 +158,7 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
int isfakefullscreen;
int isterminal;
int noswallow;
int monitor;
@ -212,11 +213,14 @@ static void hidewin(Client *c);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
static void layoutmenu(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void motionnotify(XEvent *e);
static void moveresize(const Arg *arg);
static void moveresizeedge(const Arg *arg);
static void movemouse(const Arg *arg);
static void movestack(const Arg *arg);
static Client *nexttiled(Client *c);
@ -237,6 +241,7 @@ static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setclienttagprop(Client *c);
static void setfocus(Client *c);
static void setfakefullscreen(Client *c, int fullscreen);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
@ -253,6 +258,7 @@ static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglebar(const Arg *arg);
static void togglefakefullscr(const Arg *arg);
static void togglefullscr(const Arg *arg);
static void toggleextrabar(const Arg *arg);
static void togglefloating(const Arg *arg);
@ -409,6 +415,7 @@ applyrules(Client *c)
c->isterminal = r->isterminal;
c->noswallow = r->noswallow;
c->isfloating = r->isfloating;
c->isfakefullscreen = r->isfakefullscreen;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
@ -728,7 +735,8 @@ 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);
@ -772,7 +780,8 @@ 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 + sp, m->by + vp, m->ww - 2 * sp, bh);
XMoveResizeWindow(dpy, m->extrabarwin, m->wx + sp, m->eby - vp, m->ww - 2 * sp, bh);
@ -1400,6 +1409,24 @@ killclient(const Arg *arg)
}
}
void
layoutmenu(const Arg *arg) {
FILE *p;
char c[3], *s;
int i;
if (!(p = popen(layoutmenu_cmd, "r")))
return;
s = fgets(c, sizeof(c), p);
pclose(p);
if (!s || *s == '\0' || c[0] == '\0')
return;
i = atoi(c);
setlayout(&((Arg) { .v = &layouts[i] }));
}
void
manage(Window w, XWindowAttributes *wa)
{
@ -1480,7 +1507,7 @@ manage(Window w, XWindowAttributes *wa)
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
if (!HIDDEN(c))
setclientstate(c, NormalState);
if (selmon->sel && selmon->sel->isfullscreen)
if (selmon->sel && selmon->sel->isfullscreen && !selmon->sel->isfakefullscreen)
setfullscreen(selmon->sel, 0);
if (c->mon == selmon)
unfocus(selmon->sel, 0);
@ -1561,7 +1588,8 @@ 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;
@ -1659,6 +1687,158 @@ movemouse(const Arg *arg)
}
}
void
moveresize(const Arg *arg) {
/* only floating windows can be moved */
Client *c;
c = selmon->sel;
int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
char xAbs, yAbs, wAbs, hAbs;
int msx, msy, dx, dy, nmx, nmy;
unsigned int dui;
Window dummy;
if (!c || !arg)
return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
return;
if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
return;
/* compute new window position; prevent window from be positioned outside the current monitor */
nw = c->w + w;
if (wAbs == 'W')
nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
nh = c->h + h;
if (hAbs == 'H')
nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
nx = c->x + x;
if (xAbs == 'X') {
if (x < selmon->mx)
nx = selmon->mx;
else if (x > selmon->mx + selmon->mw)
nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
else
nx = x;
}
ny = c->y + y;
if (yAbs == 'Y') {
if (y < selmon->my)
ny = selmon->my;
else if (y > selmon->my + selmon->mh)
ny = selmon->my + selmon->mh - nh - 2 * c->bw;
else
ny = y;
}
ox = c->x;
oy = c->y;
ow = c->w;
oh = c->h;
XRaiseWindow(dpy, c->win);
Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
resize(c, nx, ny, nw, nh, True);
/* move cursor along with the window to avoid problems caused by the sloppy focus */
if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
{
nmx = c->x - ox + c->w - ow;
nmy = c->y - oy + c->h - oh;
/* make sure the cursor stays inside the window */
if ((msx + nmx) > c->x && (msy + nmy) > c->y)
XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
}
}
void
moveresizeedge(const Arg *arg) {
/* move or resize floating window to edge of screen */
Client *c;
c = selmon->sel;
char e;
int nx, ny, nw, nh, ox, oy, ow, oh, bp;
int msx, msy, dx, dy, nmx, nmy;
int starty;
unsigned int dui;
Window dummy;
nx = c->x;
ny = c->y;
nw = c->w;
nh = c->h;
starty = selmon->showbar && topbar ? bh : 0;
bp = selmon->showbar && !topbar ? bh : 0;
if (!c || !arg)
return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
return;
if(sscanf((char *)arg->v, "%c", &e) != 1)
return;
if(e == 't')
ny = starty;
if(e == 'b')
ny = c->h > selmon->mh - 2 * c->bw ? c->h - bp : selmon->mh - c->h - 2 * c->bw - bp;
if(e == 'l')
nx = selmon->mx;
if(e == 'r')
nx = c->w > selmon->mw - 2 * c->bw ? selmon->mx + c->w : selmon->mx + selmon->mw - c->w - 2 * c->bw;
if(e == 'T') {
/* if you click to resize again, it will return to old size/position */
if(c->h + starty == c->oldh + c->oldy) {
nh = c->oldh;
ny = c->oldy;
} else {
nh = c->h + c->y - starty;
ny = starty;
}
}
if(e == 'B')
nh = c->h + c->y + 2 * c->bw + bp == selmon->mh ? c->oldh : selmon->mh - c->y - 2 * c->bw - bp;
if(e == 'L') {
if(selmon->mx + c->w == c->oldw + c->oldx) {
nw = c->oldw;
nx = c->oldx;
} else {
nw = c->w + c->x - selmon->mx;
nx = selmon->mx;
}
}
if(e == 'R')
nw = c->w + c->x + 2 * c->bw == selmon->mx + selmon->mw ? c->oldw : selmon->mx + selmon->mw - c->x - 2 * c->bw;
ox = c->x;
oy = c->y;
ow = c->w;
oh = c->h;
XRaiseWindow(dpy, c->win);
Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
resizeclient(c, nx, ny, nw, nh);
/* move cursor along with the window to avoid problems caused by the sloppy focus */
if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) {
nmx = c->x - ox + c->w - ow;
nmy = c->y - oy + c->h - oh;
/* make sure the cursor stays inside the window */
if ((msx + nmx) > c->x && (msy + nmy) > c->y)
XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
}
}
Client *
nexttiled(Client *c)
{
@ -1897,7 +2077,8 @@ 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;
@ -2113,13 +2294,48 @@ setfocus(Client *c)
sendevent(c, wmatom[WMTakeFocus]);
}
void
setfakefullscreen(Client *c, int fakefullscreen)
{
if (fakefullscreen && !c->isfakefullscreen) {
c->isfakefullscreen = 1;
if (c->isfullscreen) {
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);
}
} else if (!fakefullscreen && c->isfakefullscreen){
c->isfakefullscreen = 0;
if (c->isfullscreen) {
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
setfullscreen(Client *c, int fullscreen)
{
if (fullscreen && !c->isfullscreen) {
// make non fs win a fs win
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;
@ -2127,9 +2343,14 @@ setfullscreen(Client *c, int fullscreen)
resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
XRaiseWindow(dpy, c->win);
} else if (!fullscreen && c->isfullscreen){
// make a fs win a non fs win
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;
@ -2500,7 +2721,8 @@ 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)
@ -2521,6 +2743,13 @@ togglefloating(const Arg *arg)
arrange(selmon);
}
void
togglefakefullscr(const Arg *arg)
{
if (selmon->sel)
setfakefullscreen(selmon->sel, !selmon->sel->isfakefullscreen);
}
void
togglefullscr(const Arg *arg)
{
@ -2528,6 +2757,7 @@ togglefullscr(const Arg *arg)
setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
}
void
toggletag(const Arg *arg)
{

View File

@ -0,0 +1,212 @@
From 7ac106cad72c909fbb05d302f84191cdec8f2ac0 Mon Sep 17 00:00:00 2001
From: oxinosg <oxinosg@gmail.com>
Date: Sat, 10 Dec 2022 15:24:14 +0100
Subject: [PATCH] [dwm][moveresize]: fix for resize to edge
---
config.def.h | 16 ++++++
dwm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/config.def.h b/config.def.h
index 9efa774..99049e7 100644
--- a/config.def.h
+++ b/config.def.h
@@ -79,6 +79,22 @@ static const Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
+ { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
+ { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
+ { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
+ { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
+ { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
+ { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
+ { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
+ { MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
+ { MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
+ { MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
+ { MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.c b/dwm.c
index 03baf42..89ec70d 100644
--- a/dwm.c
+++ b/dwm.c
@@ -183,6 +183,8 @@ static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void motionnotify(XEvent *e);
+static void moveresize(const Arg *arg);
+static void moveresizeedge(const Arg *arg);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
static void pop(Client *c);
@@ -1203,6 +1205,158 @@ movemouse(const Arg *arg)
}
}
+void
+moveresize(const Arg *arg) {
+ /* only floating windows can be moved */
+ Client *c;
+ c = selmon->sel;
+ int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
+ char xAbs, yAbs, wAbs, hAbs;
+ int msx, msy, dx, dy, nmx, nmy;
+ unsigned int dui;
+ Window dummy;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
+ return;
+
+ /* compute new window position; prevent window from be positioned outside the current monitor */
+ nw = c->w + w;
+ if (wAbs == 'W')
+ nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
+
+ nh = c->h + h;
+ if (hAbs == 'H')
+ nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
+
+ nx = c->x + x;
+ if (xAbs == 'X') {
+ if (x < selmon->mx)
+ nx = selmon->mx;
+ else if (x > selmon->mx + selmon->mw)
+ nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
+ else
+ nx = x;
+ }
+
+ ny = c->y + y;
+ if (yAbs == 'Y') {
+ if (y < selmon->my)
+ ny = selmon->my;
+ else if (y > selmon->my + selmon->mh)
+ ny = selmon->my + selmon->mh - nh - 2 * c->bw;
+ else
+ ny = y;
+ }
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resize(c, nx, ny, nw, nh, True);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
+ {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ /* make sure the cursor stays inside the window */
+ if ((msx + nmx) > c->x && (msy + nmy) > c->y)
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
+void
+moveresizeedge(const Arg *arg) {
+ /* move or resize floating window to edge of screen */
+ Client *c;
+ c = selmon->sel;
+ char e;
+ int nx, ny, nw, nh, ox, oy, ow, oh, bp;
+ int msx, msy, dx, dy, nmx, nmy;
+ int starty;
+ unsigned int dui;
+ Window dummy;
+
+ nx = c->x;
+ ny = c->y;
+ nw = c->w;
+ nh = c->h;
+
+ starty = selmon->showbar && topbar ? bh : 0;
+ bp = selmon->showbar && !topbar ? bh : 0;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if(sscanf((char *)arg->v, "%c", &e) != 1)
+ return;
+
+ if(e == 't')
+ ny = starty;
+
+ if(e == 'b')
+ ny = c->h > selmon->mh - 2 * c->bw ? c->h - bp : selmon->mh - c->h - 2 * c->bw - bp;
+
+ if(e == 'l')
+ nx = selmon->mx;
+
+ if(e == 'r')
+ nx = c->w > selmon->mw - 2 * c->bw ? selmon->mx + c->w : selmon->mx + selmon->mw - c->w - 2 * c->bw;
+
+ if(e == 'T') {
+ /* if you click to resize again, it will return to old size/position */
+ if(c->h + starty == c->oldh + c->oldy) {
+ nh = c->oldh;
+ ny = c->oldy;
+ } else {
+ nh = c->h + c->y - starty;
+ ny = starty;
+ }
+ }
+
+ if(e == 'B')
+ nh = c->h + c->y + 2 * c->bw + bp == selmon->mh ? c->oldh : selmon->mh - c->y - 2 * c->bw - bp;
+
+ if(e == 'L') {
+ if(selmon->mx + c->w == c->oldw + c->oldx) {
+ nw = c->oldw;
+ nx = c->oldx;
+ } else {
+ nw = c->w + c->x - selmon->mx;
+ nx = selmon->mx;
+ }
+ }
+
+ if(e == 'R')
+ nw = c->w + c->x + 2 * c->bw == selmon->mx + selmon->mw ? c->oldw : selmon->mx + selmon->mw - c->x - 2 * c->bw;
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resizeclient(c, nx, ny, nw, nh);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ /* make sure the cursor stays inside the window */
+ if ((msx + nmx) > c->x && (msy + nmy) > c->y)
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
Client *
nexttiled(Client *c)
{
--
2.34.1

View File

@ -0,0 +1,89 @@
From e45e286b3d639b90ef202996d87054cced1fd80e Mon Sep 17 00:00:00 2001
From: tdu <tdukv@protonmail.com>
Date: Mon, 31 Aug 2020 00:07:32 +0300
Subject: [PATCH] Right clicking the layout symbol opens an xmenu prompt to
select layout.
Xmenu need to be installed for this to work.
Edit layoutmenu.sh with the correct layout table, and place in PATH.
---
config.def.h | 3 ++-
dwm.c | 19 +++++++++++++++++++
layoutmenu.sh | 7 +++++++
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100755 layoutmenu.sh
diff --git a/config.def.h b/config.def.h
index 1c0b587..c9e0833 100644
--- a/config.def.h
+++ b/config.def.h
@@ -58,6 +58,7 @@ static const Layout layouts[] = {
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
+static const char *layoutmenu_cmd = "layoutmenu.sh";
static Key keys[] = {
/* modifier key function argument */
@@ -101,7 +102,7 @@ static Key keys[] = {
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkLtSymbol, 0, Button3, layoutmenu, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
diff --git a/dwm.c b/dwm.c
index 4465af1..2508a0a 100644
--- a/dwm.c
+++ b/dwm.c
@@ -177,6 +177,7 @@ static void grabkeys(void);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
+static void layoutmenu(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
@@ -1014,6 +1015,24 @@ killclient(const Arg *arg)
}
}
+void
+layoutmenu(const Arg *arg) {
+ FILE *p;
+ char c[3], *s;
+ int i;
+
+ if (!(p = popen(layoutmenu_cmd, "r")))
+ return;
+ s = fgets(c, sizeof(c), p);
+ pclose(p);
+
+ if (!s || *s == '\0' || c[0] == '\0')
+ return;
+
+ i = atoi(c);
+ setlayout(&((Arg) { .v = &layouts[i] }));
+}
+
void
manage(Window w, XWindowAttributes *wa)
{
diff --git a/layoutmenu.sh b/layoutmenu.sh
new file mode 100755
index 0000000..1bf95f2
--- /dev/null
+++ b/layoutmenu.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+cat <<EOF | xmenu
+[]= Tiled Layout 0
+><> Floating Layout 1
+[M] Monocle Layout 2
+EOF
--
2.28.0

View File

@ -0,0 +1,145 @@
From 7b7230cba4a3b886aa4239edecb86665dffcd9d8 Mon Sep 17 00:00:00 2001
From: Francisco Tapia <link_1232@yahoo.com.mx>
Date: Mon, 30 Nov 2020 12:43:18 -0600
Subject: [PATCH] Fix for selectivefakefullscreen resize issue
Fixed a problem where entering a fake full screen caused the client
to resize incorrectly, resulting in a truncated window, and
requiring the user to force a whole screen update, e.g. toggling
on and off the bar, to correctly draw the whole window.
---
config.def.h | 6 +++---
dwm.c | 30 +++++++++++++++++++++++-------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..b7a445b 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 isfakefullscreen monitor */
+ { "Gimp", NULL, NULL, 0, 1, 0, -1 },
+ { "Firefox", NULL, NULL, 1 << 8, 0, 1, -1 },
};
/* layout(s) */
diff --git a/dwm.c b/dwm.c
index 664c527..a7418aa 100644
--- a/dwm.c
+++ b/dwm.c
@@ -92,7 +92,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
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;
@@ -138,6 +138,7 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
+ int isfakefullscreen;
int monitor;
} Rule;
@@ -299,6 +300,7 @@ applyrules(Client *c)
&& (!r->instance || strstr(instance, r->instance)))
{
c->isfloating = r->isfloating;
+ c->isfakefullscreen = r->isfakefullscreen;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
@@ -522,7 +524,8 @@ 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);
@@ -566,7 +569,8 @@ 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);
}
@@ -1144,7 +1148,8 @@ 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;
@@ -1299,7 +1304,8 @@ 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;
@@ -1477,6 +1483,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;
@@ -1487,6 +1497,10 @@ 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;
@@ -1619,7 +1633,8 @@ 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 {
@@ -1713,7 +1728,8 @@ 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)
--
2.20.1

7
scripts/layoutmenu.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
cat <<EOF | xmenu
[]= Tiled Layout 0
><> Floating Layout 1
[M] Monocle Layout 2
EOF