add games patch
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
--- config.def.h
|
||||
+++ config.def.h
|
||||
@@ -67,6 +67,10 @@ static const Key keys[] = {
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
+ { MODKEY|ControlMask, XK_Left, placedir, {.i = 0 } }, // left
|
||||
+ { MODKEY|ControlMask, XK_Right, placedir, {.i = 1 } }, // right
|
||||
+ { MODKEY|ControlMask, XK_Up, placedir, {.i = 2 } }, // up
|
||||
+ { MODKEY|ControlMask, XK_Down, placedir, {.i = 3 } }, // down
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||
@@ -26,9 +26,11 @@ static const Rule rules[] = {
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
- /* class instance title tags mask isfloating monitor */
|
||||
+ /* class instance title tags mask isfloating monitor isgame */
|
||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
+ { "Steam", NULL, NULL, 0, 0, -1, 1 },
|
||||
+ { "steam_app",NULL, NULL, 0, 0, -1, 1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
|
||||
5
config.h
5
config.h
@@ -52,7 +52,7 @@ static const Rule rules[] = {
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
/* class instance title tags mask isfloating isterminal isswallow monitor */
|
||||
/* class instance title tags mask isfloating isterminal isswallow monitor isgame */
|
||||
{ "Playground", NULL, NULL, 0, 1, 0, -1 -1 },
|
||||
|
||||
{ "steam", NULL, NULL, 1 << 1, 0, 0, -1 -1 },
|
||||
@@ -63,6 +63,9 @@ static const Rule rules[] = {
|
||||
{ NULL, "spterm", NULL, SPTAG(0), 1, 0, 0, -1 },
|
||||
{ NULL, "spfm", NULL, SPTAG(1), 1, 0, 0, -1 },
|
||||
{ NULL, "keepassxc", NULL, SPTAG(2), 0, 0, 0, -1 },
|
||||
|
||||
{ "Steam", NULL, NULL, 1 << 4, 0, 0, -1 -1, 0 },
|
||||
{ "steam_app", NULL, NULL, 1 << 5, 0, 0, -1 -1, 0 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
|
||||
47
dwm.c
47
dwm.c
@@ -57,6 +57,7 @@
|
||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
||||
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
||||
#define MINIMIZED(C) ((getstate(C->win) == IconicState))
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
@@ -118,6 +119,7 @@ struct Client {
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
|
||||
int isgame;
|
||||
pid_t pid;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
@@ -172,6 +174,7 @@ typedef struct {
|
||||
int isterminal;
|
||||
int noswallow;
|
||||
int monitor;
|
||||
int isgame;
|
||||
} Rule;
|
||||
|
||||
typedef struct Systray Systray;
|
||||
@@ -223,6 +226,7 @@ static void killclient(const Arg *arg);
|
||||
static void manage(Window w, XWindowAttributes *wa);
|
||||
static void mappingnotify(XEvent *e);
|
||||
static void maprequest(XEvent *e);
|
||||
static void minimize(Client *c);
|
||||
static void monocle(Monitor *m);
|
||||
static void motionnotify(XEvent *e);
|
||||
static void movemouse(const Arg *arg);
|
||||
@@ -268,6 +272,7 @@ static void toggleview(const Arg *arg);
|
||||
static void unfocus(Client *c, int setfocus);
|
||||
static void unmanage(Client *c, int destroyed);
|
||||
static void unmapnotify(XEvent *e);
|
||||
static void unminimize(Client *c);
|
||||
static void updatebarpos(Monitor *m);
|
||||
static void updatebars(void);
|
||||
static void updateclientlist(void);
|
||||
@@ -411,6 +416,7 @@ applyrules(Client *c)
|
||||
c->noswallow = r->noswallow;
|
||||
c->isfloating = r->isfloating;
|
||||
c->tags |= r->tags;
|
||||
c->isgame = r->isgame;
|
||||
if ((r->tags & SPTAGMASK) && r->isfloating) {
|
||||
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
|
||||
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
|
||||
@@ -1469,6 +1475,29 @@ maprequest(XEvent *e)
|
||||
manage(ev->window, &wa);
|
||||
}
|
||||
|
||||
void
|
||||
minimize(Client *c)
|
||||
{
|
||||
if (!c || MINIMIZED(c))
|
||||
return;
|
||||
|
||||
Window w = c->win;
|
||||
static XWindowAttributes ra, ca;
|
||||
|
||||
// more or less taken directly from blackbox's hide() function
|
||||
XGrabServer(dpy);
|
||||
XGetWindowAttributes(dpy, root, &ra);
|
||||
XGetWindowAttributes(dpy, w, &ca);
|
||||
// prevent UnmapNotify events
|
||||
XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
|
||||
XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
|
||||
XUnmapWindow(dpy, w);
|
||||
setclientstate(c, IconicState);
|
||||
XSelectInput(dpy, root, ra.your_event_mask);
|
||||
XSelectInput(dpy, w, ca.your_event_mask);
|
||||
XUngrabServer(dpy);
|
||||
}
|
||||
|
||||
void
|
||||
monocle(Monitor *m)
|
||||
{
|
||||
@@ -1997,6 +2026,10 @@ setfocus(Client *c)
|
||||
XA_WINDOW, 32, PropModeReplace,
|
||||
(unsigned char *) &(c->win), 1);
|
||||
}
|
||||
|
||||
if (c->isgame && c->isfullscreen)
|
||||
unminimize(c);
|
||||
|
||||
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -2359,6 +2392,10 @@ unfocus(Client *c, int setfocus)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
if (c->isgame && c->isfullscreen)
|
||||
minimize(c);
|
||||
|
||||
grabbuttons(c, 0);
|
||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
if (setfocus) {
|
||||
@@ -2430,6 +2467,16 @@ unmapnotify(XEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unminimize(Client *c)
|
||||
{
|
||||
if (!c || !MINIMIZED(c))
|
||||
return;
|
||||
|
||||
XMapWindow(dpy, c->win);
|
||||
setclientstate(c, NormalState);
|
||||
}
|
||||
|
||||
void
|
||||
updatebars(void)
|
||||
{
|
||||
|
||||
98
dwm.c.orig
98
dwm.c.orig
@@ -228,6 +228,7 @@ static void motionnotify(XEvent *e);
|
||||
static void movemouse(const Arg *arg);
|
||||
static Client *nexttagged(Client *c);
|
||||
static Client *nexttiled(Client *c);
|
||||
static void placedir(const Arg *arg);
|
||||
static void pop(Client *c);
|
||||
static void propertynotify(XEvent *e);
|
||||
static void quit(const Arg *arg);
|
||||
@@ -1577,6 +1578,103 @@ nexttiled(Client *c)
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
placedir(const Arg *arg)
|
||||
{
|
||||
Client *s = selmon->sel, *f = NULL, *c, *next, *fprior, *sprior;
|
||||
|
||||
if (!s || s->isfloating)
|
||||
return;
|
||||
|
||||
unsigned int score = -1;
|
||||
unsigned int client_score;
|
||||
int dist;
|
||||
int dirweight = 20;
|
||||
|
||||
next = s->next;
|
||||
if (!next)
|
||||
next = s->mon->clients;
|
||||
for (c = next; c != s; c = next) {
|
||||
|
||||
next = c->next;
|
||||
if (!next)
|
||||
next = s->mon->clients;
|
||||
|
||||
if (!ISVISIBLE(c)) // || HIDDEN(c)
|
||||
continue;
|
||||
|
||||
switch (arg->i) {
|
||||
case 0: // left
|
||||
dist = s->x - c->x - c->w;
|
||||
client_score =
|
||||
dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
|
||||
abs(s->y - c->y);
|
||||
break;
|
||||
case 1: // right
|
||||
dist = c->x - s->x - s->w;
|
||||
client_score =
|
||||
dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
|
||||
abs(c->y - s->y);
|
||||
break;
|
||||
case 2: // up
|
||||
dist = s->y - c->y - c->h;
|
||||
client_score =
|
||||
dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
|
||||
abs(s->x - c->x);
|
||||
break;
|
||||
default:
|
||||
case 3: // down
|
||||
dist = c->y - s->y - s->h;
|
||||
client_score =
|
||||
dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
|
||||
abs(c->x - s->x);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) {
|
||||
score = client_score;
|
||||
f = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (f && f != s) {
|
||||
for (fprior = f->mon->clients; fprior && fprior->next != f; fprior = fprior->next);
|
||||
for (sprior = s->mon->clients; sprior && sprior->next != s; sprior = sprior->next);
|
||||
|
||||
if (s == fprior) {
|
||||
next = f->next;
|
||||
if (sprior)
|
||||
sprior->next = f;
|
||||
else
|
||||
f->mon->clients = f;
|
||||
f->next = s;
|
||||
s->next = next;
|
||||
} else if (f == sprior) {
|
||||
next = s->next;
|
||||
if (fprior)
|
||||
fprior->next = s;
|
||||
else
|
||||
s->mon->clients = s;
|
||||
s->next = f;
|
||||
f->next = next;
|
||||
} else { // clients are not adjacent to each other
|
||||
next = f->next;
|
||||
f->next = s->next;
|
||||
s->next = next;
|
||||
if (fprior)
|
||||
fprior->next = s;
|
||||
else
|
||||
s->mon->clients = s;
|
||||
if (sprior)
|
||||
sprior->next = f;
|
||||
else
|
||||
f->mon->clients = f;
|
||||
}
|
||||
|
||||
arrange(f->mon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pop(Client *c)
|
||||
{
|
||||
|
||||
39
dwm.c.rej
39
dwm.c.rej
@@ -1,12 +1,37 @@
|
||||
--- dwm.c
|
||||
+++ dwm.c
|
||||
@@ -723,6 +790,9 @@ destroynotify(XEvent *e)
|
||||
|
||||
if ((c = wintoclient(ev->window)))
|
||||
unmanage(c, 1);
|
||||
@@ -50,6 +50,7 @@
|
||||
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
+#define MINIMIZED(C) ((getstate(C->win) == IconicState))
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
@@ -92,6 +93,7 @@ struct Client {
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
+ int isgame;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
Monitor *mon;
|
||||
@@ -301,6 +306,7 @@ applyrules(Client *c)
|
||||
{
|
||||
c->isfloating = r->isfloating;
|
||||
c->tags |= r->tags;
|
||||
+ c->isgame = r->isgame;
|
||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||
if (m)
|
||||
c->mon = m;
|
||||
@@ -1501,6 +1530,10 @@ setfocus(Client *c)
|
||||
XA_WINDOW, 32, PropModeReplace,
|
||||
(unsigned char *) &(c->win), 1);
|
||||
}
|
||||
+
|
||||
+ else if ((c = swallowingclient(ev->window)))
|
||||
+ unmanage(c->swallowing, 1);
|
||||
+ if (c->isgame && c->isfullscreen)
|
||||
+ unminimize(c);
|
||||
+
|
||||
sendevent(c, wmatom[WMTakeFocus]);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
173
patches/dwm-games-6.6.diff
Normal file
173
patches/dwm-games-6.6.diff
Normal file
@@ -0,0 +1,173 @@
|
||||
From d06cefd6e1f8b5cd9bdfe694b7dc16da1f00d83e Mon Sep 17 00:00:00 2001
|
||||
From: Bakkeby <bakkeby@gmail.com>
|
||||
Date: Mon, 1 Jul 2024 22:19:15 +0200
|
||||
Subject: [PATCH] Game rule patch
|
||||
|
||||
This patch adds a rule identifying clients as a "game" such that
|
||||
if the client is in fullscreen and it loses focus (e.g. by moving
|
||||
to another tag) then it will automatically be minimized (set to
|
||||
IconicState and unmapped).
|
||||
|
||||
When the client receives focus again (e.g. by going back to its
|
||||
tag) then it will automaticaly be unminimized (set to NormalState
|
||||
and mapped). This should address many of the black screen or window
|
||||
is tiny after having moved to another tag and back again.
|
||||
|
||||
This may conflict with the awesomebar patch which skips hidden
|
||||
(iconic) windows when selecting which client to focus on, i.e. it
|
||||
would be there but minimized and will not automatically unminimize.
|
||||
|
||||
The function names are minimize and unminimize compared to the same
|
||||
functions hide and show in the awesomebar patch. The name change is
|
||||
due to two reasons; 1) because hide and show do something very
|
||||
different compared to the showhide function and 2) because when
|
||||
minimizing and unminimizing we do not want to trigger arrange or
|
||||
a change in focus (which would affect the stacking order and thus
|
||||
prevent the window receiving focus when we move back to the previous
|
||||
tag).
|
||||
---
|
||||
config.def.h | 4 +++-
|
||||
dwm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 50 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 9efa774..9df3c97 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -26,9 +26,11 @@ static const Rule rules[] = {
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
- /* class instance title tags mask isfloating monitor */
|
||||
+ /* class instance title tags mask isfloating monitor isgame */
|
||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
+ { "Steam", NULL, NULL, 0, 0, -1, 1 },
|
||||
+ { "steam_app",NULL, NULL, 0, 0, -1, 1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 1443802..29de39a 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
+#define MINIMIZED(C) ((getstate(C->win) == IconicState))
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
@@ -92,6 +93,7 @@ struct Client {
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
+ int isgame;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
Monitor *mon;
|
||||
@@ -138,6 +140,7 @@ typedef struct {
|
||||
unsigned int tags;
|
||||
int isfloating;
|
||||
int monitor;
|
||||
+ int isgame;
|
||||
} Rule;
|
||||
|
||||
/* function declarations */
|
||||
@@ -180,6 +183,7 @@ static void killclient(const Arg *arg);
|
||||
static void manage(Window w, XWindowAttributes *wa);
|
||||
static void mappingnotify(XEvent *e);
|
||||
static void maprequest(XEvent *e);
|
||||
+static void minimize(Client *c);
|
||||
static void monocle(Monitor *m);
|
||||
static void motionnotify(XEvent *e);
|
||||
static void movemouse(const Arg *arg);
|
||||
@@ -215,6 +219,7 @@ static void toggleview(const Arg *arg);
|
||||
static void unfocus(Client *c, int setfocus);
|
||||
static void unmanage(Client *c, int destroyed);
|
||||
static void unmapnotify(XEvent *e);
|
||||
+static void unminimize(Client *c);
|
||||
static void updatebarpos(Monitor *m);
|
||||
static void updatebars(void);
|
||||
static void updateclientlist(void);
|
||||
@@ -298,6 +303,7 @@ applyrules(Client *c)
|
||||
{
|
||||
c->isfloating = r->isfloating;
|
||||
c->tags |= r->tags;
|
||||
+ c->isgame = r->isgame;
|
||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||
if (m)
|
||||
c->mon = m;
|
||||
@@ -1109,6 +1115,29 @@ maprequest(XEvent *e)
|
||||
manage(ev->window, &wa);
|
||||
}
|
||||
|
||||
+void
|
||||
+minimize(Client *c)
|
||||
+{
|
||||
+ if (!c || MINIMIZED(c))
|
||||
+ return;
|
||||
+
|
||||
+ Window w = c->win;
|
||||
+ static XWindowAttributes ra, ca;
|
||||
+
|
||||
+ // more or less taken directly from blackbox's hide() function
|
||||
+ XGrabServer(dpy);
|
||||
+ XGetWindowAttributes(dpy, root, &ra);
|
||||
+ XGetWindowAttributes(dpy, w, &ca);
|
||||
+ // prevent UnmapNotify events
|
||||
+ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
|
||||
+ XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
|
||||
+ XUnmapWindow(dpy, w);
|
||||
+ setclientstate(c, IconicState);
|
||||
+ XSelectInput(dpy, root, ra.your_event_mask);
|
||||
+ XSelectInput(dpy, w, ca.your_event_mask);
|
||||
+ XUngrabServer(dpy);
|
||||
+}
|
||||
+
|
||||
void
|
||||
monocle(Monitor *m)
|
||||
{
|
||||
@@ -1475,6 +1504,10 @@ setfocus(Client *c)
|
||||
XA_WINDOW, 32, PropModeReplace,
|
||||
(unsigned char *) &(c->win), 1);
|
||||
}
|
||||
+
|
||||
+ if (c->isgame && c->isfullscreen)
|
||||
+ unminimize(c);
|
||||
+
|
||||
sendevent(c, wmatom[WMTakeFocus]);
|
||||
}
|
||||
|
||||
@@ -1766,6 +1799,10 @@ unfocus(Client *c, int setfocus)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
+
|
||||
+ if (c->isgame && c->isfullscreen)
|
||||
+ minimize(c);
|
||||
+
|
||||
grabbuttons(c, 0);
|
||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
if (setfocus) {
|
||||
@@ -1814,6 +1851,16 @@ unmapnotify(XEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+unminimize(Client *c)
|
||||
+{
|
||||
+ if (!c || !MINIMIZED(c))
|
||||
+ return;
|
||||
+
|
||||
+ XMapWindow(dpy, c->win);
|
||||
+ setclientstate(c, NormalState);
|
||||
+}
|
||||
+
|
||||
void
|
||||
updatebars(void)
|
||||
{
|
||||
--
|
||||
2.50.1
|
||||
|
||||
Reference in New Issue
Block a user