use games patch
This commit is contained in:
@@ -15,8 +15,6 @@ static const unsigned int gappov = 30; /* vert outer gap between window
|
|||||||
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
static int iconsize = 16; /* icon size */
|
|
||||||
static int iconspacing = 5; /* space between icon and title */
|
|
||||||
static const char *fonts[] = { "monospace:size=10" };
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
static const char dmenufont[] = "monospace:size=10";
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
static const char col_gray1[] = "#222222";
|
static const char col_gray1[] = "#222222";
|
||||||
|
|||||||
@@ -1,33 +1,15 @@
|
|||||||
--- config.def.h
|
--- config.def.h
|
||||||
+++ config.def.h
|
+++ config.def.h
|
||||||
@@ -67,8 +68,10 @@ static const Key keys[] = {
|
@@ -26,9 +26,11 @@ static const Rule rules[] = {
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
* WM_CLASS(STRING) = instance, class
|
||||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
* WM_NAME(STRING) = title
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
*/
|
||||||
- { MODKEY, XK_j, focusstack, {.i = +1 } },
|
- /* class instance title tags mask isfloating monitor */
|
||||||
- { MODKEY, XK_k, focusstack, {.i = -1 } },
|
+ /* class instance title tags mask isfloating monitor isgame */
|
||||||
+ { MODKEY, XK_j, focusstackvis, {.i = +1 } },
|
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
+ { MODKEY, XK_k, focusstackvis, {.i = -1 } },
|
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
+ { MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } },
|
+ { "Steam", NULL, NULL, 0, 0, -1, 1 },
|
||||||
+ { MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } },
|
+ { "steam_app",NULL, NULL, 0, 0, -1, 1 },
|
||||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
};
|
||||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
/* layout(s) */
|
||||||
@@ -87,6 +90,9 @@ static const Key keys[] = {
|
|
||||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
|
||||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
|
||||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
|
||||||
+ { MODKEY, XK_s, show, {0} },
|
|
||||||
+ { MODKEY|ShiftMask, XK_s, showall, {0} },
|
|
||||||
+ { MODKEY, XK_h, hide, {0} },
|
|
||||||
TAGKEYS( XK_1, 0)
|
|
||||||
TAGKEYS( XK_2, 1)
|
|
||||||
TAGKEYS( XK_3, 2)
|
|
||||||
@@ -105,6 +111,7 @@ static const Button buttons[] = {
|
|
||||||
/* click event mask button function argument */
|
|
||||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
|
|
||||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { ClkWinTitle, 0, Button1, togglewin, {0} },
|
|
||||||
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
|
||||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
|
||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
|
||||||
|
|||||||
31
config.h
31
config.h
@@ -52,17 +52,20 @@ static const Rule rules[] = {
|
|||||||
* WM_CLASS(STRING) = instance, class
|
* WM_CLASS(STRING) = instance, class
|
||||||
* WM_NAME(STRING) = title
|
* WM_NAME(STRING) = title
|
||||||
*/
|
*/
|
||||||
/* class instance title tags mask isfloating isterminal monitor */
|
/* class instance title tags mask isfloating monitor isgame */
|
||||||
{ "Playground", NULL, NULL, 0, 1, -1 },
|
{ "Playground", NULL, NULL, 0, 1, -1, 0 },
|
||||||
|
|
||||||
{ "steam", NULL, NULL, 1 << 1, 0, -1 },
|
{ "Steam", NULL, NULL, 1 << 1, 0, -1, 1 },
|
||||||
{ "Firefox", NULL, NULL, 1 << 2, 0, -1 },
|
{ "steam_app", NULL, NULL, 0, 0, -1, 1 },
|
||||||
{ "brave-browser", NULL, NULL, 1 << 3, 0, -1 },
|
|
||||||
{ "discord", NULL, NULL, 1 << 4, 0, -1 },
|
{ "Firefox", NULL, NULL, 1 << 2, 0, -1, 0 },
|
||||||
{ "feishin", NULL, NULL, 1 << 5, 0, -1 },
|
{ "brave-browser", NULL, NULL, 1 << 3, 0, -1, 0 },
|
||||||
{ NULL, "spterm", NULL, SPTAG(0), 1, 0 },
|
{ "discord", NULL, NULL, 1 << 4, 0, -1, 0 },
|
||||||
{ NULL, "spfm", NULL, SPTAG(1), 1, 0 },
|
{ "feishin", NULL, NULL, 1 << 5, 0, -1, 0 },
|
||||||
{ NULL, "keepassxc", NULL, SPTAG(2), 0, 0 },
|
|
||||||
|
{ NULL, "spterm", NULL, SPTAG(0), 1, -1, 0 },
|
||||||
|
{ NULL, "spfm", NULL, SPTAG(1), 1, -1, 0 },
|
||||||
|
{ NULL, "keepassxc", NULL, SPTAG(2), 0, -1, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
@@ -164,9 +167,9 @@ static const Key keys[] = {
|
|||||||
/* cycle layouts */
|
/* cycle layouts */
|
||||||
{ MODKEY, XK_n, cyclelayout, {.i = +1 } },
|
{ MODKEY, XK_n, cyclelayout, {.i = +1 } },
|
||||||
|
|
||||||
{ MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
|
{ MODKEY|Mod1Mask, XK_h, setcfact, {.f = +0.25} },
|
||||||
{ MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
{ MODKEY|Mod1Mask, XK_l, setcfact, {.f = -0.25} },
|
||||||
{ MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
{ MODKEY|Mod1Mask, XK_o, setcfact, {.f = 0.00} },
|
||||||
{ MODKEY|Mod1Mask, XK_u, incrgaps, {.i = +1 } },
|
{ MODKEY|Mod1Mask, XK_u, incrgaps, {.i = +1 } },
|
||||||
{ MODKEY|Mod1Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
|
{ MODKEY|Mod1Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
|
||||||
{ MODKEY|Mod1Mask, XK_i, incrigaps, {.i = +1 } },
|
{ MODKEY|Mod1Mask, XK_i, incrigaps, {.i = +1 } },
|
||||||
@@ -194,7 +197,7 @@ static const Key keys[] = {
|
|||||||
|
|
||||||
{ MODKEY, XK_s, show, {0} },
|
{ MODKEY, XK_s, show, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_s, showall, {0} },
|
{ MODKEY|ShiftMask, XK_s, showall, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_h, hide, {0} },
|
{ MODKEY|ShiftMask, XK_v, hide, {0} },
|
||||||
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||||
|
|||||||
58
dwm.c
58
dwm.c
@@ -51,6 +51,7 @@
|
|||||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||||
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
||||||
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
||||||
|
#define MINIMIZED(C) ((getstate(C->win) == IconicState))
|
||||||
#define HIDDEN(C) ((getstate(C->win) == IconicState))
|
#define HIDDEN(C) ((getstate(C->win) == IconicState))
|
||||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
@@ -114,7 +115,7 @@ struct Client {
|
|||||||
int bw, oldbw;
|
int bw, oldbw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
int issteam;
|
int isgame;
|
||||||
int fakefullscreen;
|
int fakefullscreen;
|
||||||
Client *next;
|
Client *next;
|
||||||
Client *snext;
|
Client *snext;
|
||||||
@@ -169,6 +170,7 @@ typedef struct {
|
|||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfloating;
|
int isfloating;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
int isgame;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
typedef struct Systray Systray;
|
typedef struct Systray Systray;
|
||||||
@@ -226,6 +228,7 @@ static void losefullscreen(Client *next);
|
|||||||
static void manage(Window w, XWindowAttributes *wa);
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
static void mappingnotify(XEvent *e);
|
static void mappingnotify(XEvent *e);
|
||||||
static void maprequest(XEvent *e);
|
static void maprequest(XEvent *e);
|
||||||
|
static void minimize(Client *c);
|
||||||
static void monocle(Monitor *m);
|
static void monocle(Monitor *m);
|
||||||
static void motionnotify(XEvent *e);
|
static void motionnotify(XEvent *e);
|
||||||
static void movemouse(const Arg *arg);
|
static void movemouse(const Arg *arg);
|
||||||
@@ -282,6 +285,7 @@ static void togglewin(const Arg *arg);
|
|||||||
static void unfocus(Client *c, int setfocus);
|
static void unfocus(Client *c, int setfocus);
|
||||||
static void unmanage(Client *c, int destroyed);
|
static void unmanage(Client *c, int destroyed);
|
||||||
static void unmapnotify(XEvent *e);
|
static void unmapnotify(XEvent *e);
|
||||||
|
static void unminimize(Client *c);
|
||||||
static void updatecurrentdesktop(void);
|
static void updatecurrentdesktop(void);
|
||||||
static void updatebarpos(Monitor *m);
|
static void updatebarpos(Monitor *m);
|
||||||
static void updatebars(void);
|
static void updatebars(void);
|
||||||
@@ -408,9 +412,6 @@ applyrules(Client *c)
|
|||||||
class = ch.res_class ? ch.res_class : broken;
|
class = ch.res_class ? ch.res_class : broken;
|
||||||
instance = ch.res_name ? ch.res_name : broken;
|
instance = ch.res_name ? ch.res_name : broken;
|
||||||
|
|
||||||
if (strstr(class, "Steam") || strstr(class, "steam_app_"))
|
|
||||||
c->issteam = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < LENGTH(rules); i++) {
|
for (i = 0; i < LENGTH(rules); i++) {
|
||||||
r = &rules[i];
|
r = &rules[i];
|
||||||
if ((!r->title || strstr(c->name, r->title))
|
if ((!r->title || strstr(c->name, r->title))
|
||||||
@@ -419,6 +420,7 @@ applyrules(Client *c)
|
|||||||
{
|
{
|
||||||
c->isfloating = r->isfloating;
|
c->isfloating = r->isfloating;
|
||||||
c->tags |= r->tags;
|
c->tags |= r->tags;
|
||||||
|
c->isgame = r->isgame;
|
||||||
if ((r->tags & SPTAGMASK) && r->isfloating) {
|
if ((r->tags & SPTAGMASK) && r->isfloating) {
|
||||||
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
|
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
|
||||||
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
|
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
|
||||||
@@ -800,7 +802,6 @@ configurerequest(XEvent *e)
|
|||||||
c->bw = ev->border_width;
|
c->bw = ev->border_width;
|
||||||
else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
|
else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
|
||||||
m = c->mon;
|
m = c->mon;
|
||||||
if (!c->issteam) {
|
|
||||||
if (ev->value_mask & CWX) {
|
if (ev->value_mask & CWX) {
|
||||||
c->oldx = c->x;
|
c->oldx = c->x;
|
||||||
c->x = m->mx + ev->x;
|
c->x = m->mx + ev->x;
|
||||||
@@ -809,7 +810,6 @@ configurerequest(XEvent *e)
|
|||||||
c->oldy = c->y;
|
c->oldy = c->y;
|
||||||
c->y = m->my + ev->y;
|
c->y = m->my + ev->y;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (ev->value_mask & CWWidth) {
|
if (ev->value_mask & CWWidth) {
|
||||||
c->oldw = c->w;
|
c->oldw = c->w;
|
||||||
c->w = ev->width;
|
c->w = ev->width;
|
||||||
@@ -1566,6 +1566,29 @@ maprequest(XEvent *e)
|
|||||||
manage(ev->window, &wa);
|
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
|
void
|
||||||
monocle(Monitor *m)
|
monocle(Monitor *m)
|
||||||
{
|
{
|
||||||
@@ -1832,6 +1855,8 @@ propertynotify(XEvent *e)
|
|||||||
void
|
void
|
||||||
quit(const Arg *arg)
|
quit(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
if(arg->i) restart = 1;
|
||||||
|
if (!restart) {
|
||||||
// fix: reloading dwm keeps all the hidden clients hidden
|
// fix: reloading dwm keeps all the hidden clients hidden
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
Client *c;
|
Client *c;
|
||||||
@@ -1841,8 +1866,8 @@ quit(const Arg *arg)
|
|||||||
if (c && HIDDEN(c)) showwin(c);
|
if (c && HIDDEN(c)) showwin(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(arg->i) restart = 1;
|
|
||||||
running = 0;
|
running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2134,8 +2159,9 @@ setfocus(Client *c)
|
|||||||
XA_WINDOW, 32, PropModeReplace,
|
XA_WINDOW, 32, PropModeReplace,
|
||||||
(unsigned char *) &(c->win), 1);
|
(unsigned char *) &(c->win), 1);
|
||||||
}
|
}
|
||||||
if (c->issteam)
|
|
||||||
setclientstate(c, NormalState);
|
if (c->isgame && c->isfullscreen)
|
||||||
|
unminimize(c);
|
||||||
|
|
||||||
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -2662,6 +2688,10 @@ unfocus(Client *c, int setfocus)
|
|||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (c->isgame && c->isfullscreen)
|
||||||
|
minimize(c);
|
||||||
|
|
||||||
grabbuttons(c, 0);
|
grabbuttons(c, 0);
|
||||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||||
if (setfocus) {
|
if (setfocus) {
|
||||||
@@ -2716,6 +2746,16 @@ unmapnotify(XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unminimize(Client *c)
|
||||||
|
{
|
||||||
|
if (!c || !MINIMIZED(c))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XMapWindow(dpy, c->win);
|
||||||
|
setclientstate(c, NormalState);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updatebars(void)
|
updatebars(void)
|
||||||
{
|
{
|
||||||
|
|||||||
247
dwm.c.orig
247
dwm.c.orig
@@ -25,7 +25,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -52,6 +51,7 @@
|
|||||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||||
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
||||||
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
||||||
|
#define MINIMIZED(C) ((getstate(C->win) == IconicState))
|
||||||
#define HIDDEN(C) ((getstate(C->win) == IconicState))
|
#define HIDDEN(C) ((getstate(C->win) == IconicState))
|
||||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
/* enums */
|
/* enums */
|
||||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */
|
enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */
|
||||||
enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck,
|
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
|
NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
|
||||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */
|
NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */
|
||||||
@@ -115,9 +115,8 @@ struct Client {
|
|||||||
int bw, oldbw;
|
int bw, oldbw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
unsigned int icw, ich;
|
|
||||||
Picture icon;
|
|
||||||
int issteam;
|
int issteam;
|
||||||
|
int isgame;
|
||||||
int fakefullscreen;
|
int fakefullscreen;
|
||||||
Client *next;
|
Client *next;
|
||||||
Client *snext;
|
Client *snext;
|
||||||
@@ -172,6 +171,7 @@ typedef struct {
|
|||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfloating;
|
int isfloating;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
int isgame;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
typedef struct Systray Systray;
|
typedef struct Systray Systray;
|
||||||
@@ -188,7 +188,6 @@ static void arrangemon(Monitor *m);
|
|||||||
static void attach(Client *c);
|
static void attach(Client *c);
|
||||||
static void attachaside(Client *c);
|
static void attachaside(Client *c);
|
||||||
static void attachstack(Client *c);
|
static void attachstack(Client *c);
|
||||||
static uint32_t *bilinear_scale(const uint32_t *src, int sw, int sh, uint32_t dw, uint32_t dh);
|
|
||||||
static void buttonpress(XEvent *e);
|
static void buttonpress(XEvent *e);
|
||||||
static void checkotherwm(void);
|
static void checkotherwm(void);
|
||||||
static void cleanup(void);
|
static void cleanup(void);
|
||||||
@@ -214,11 +213,9 @@ static void focusmon(const Arg *arg);
|
|||||||
static void focusstackvis(const Arg *arg);
|
static void focusstackvis(const Arg *arg);
|
||||||
static void focusstackhid(const Arg *arg);
|
static void focusstackhid(const Arg *arg);
|
||||||
static void focusstack(int inc, int vis);
|
static void focusstack(int inc, int vis);
|
||||||
static void freeicon(Client *c);
|
|
||||||
static Atom getatomprop(Client *c, Atom prop);
|
static Atom getatomprop(Client *c, Atom prop);
|
||||||
static int getrootptr(int *x, int *y);
|
static int getrootptr(int *x, int *y);
|
||||||
static long getstate(Window w);
|
static long getstate(Window w);
|
||||||
static Picture geticonprop(Display *dpy, Window w, int iconsize, unsigned int *icw, unsigned int *ich);
|
|
||||||
static unsigned int getsystraywidth();
|
static unsigned int getsystraywidth();
|
||||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||||
static void grabbuttons(Client *c, int focused);
|
static void grabbuttons(Client *c, int focused);
|
||||||
@@ -232,6 +229,7 @@ static void losefullscreen(Client *next);
|
|||||||
static void manage(Window w, XWindowAttributes *wa);
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
static void mappingnotify(XEvent *e);
|
static void mappingnotify(XEvent *e);
|
||||||
static void maprequest(XEvent *e);
|
static void maprequest(XEvent *e);
|
||||||
|
static void minimize(Client *c);
|
||||||
static void monocle(Monitor *m);
|
static void monocle(Monitor *m);
|
||||||
static void motionnotify(XEvent *e);
|
static void motionnotify(XEvent *e);
|
||||||
static void movemouse(const Arg *arg);
|
static void movemouse(const Arg *arg);
|
||||||
@@ -239,7 +237,6 @@ static Client *nexttagged(Client *c);
|
|||||||
static Client *nexttiled(Client *c);
|
static Client *nexttiled(Client *c);
|
||||||
static void placedir(const Arg *arg);
|
static void placedir(const Arg *arg);
|
||||||
static void pop(Client *c);
|
static void pop(Client *c);
|
||||||
static uint32_t prealpha(uint32_t p);
|
|
||||||
static void propertynotify(XEvent *e);
|
static void propertynotify(XEvent *e);
|
||||||
static void quit(const Arg *arg);
|
static void quit(const Arg *arg);
|
||||||
static Monitor *recttomon(int x, int y, int w, int h);
|
static Monitor *recttomon(int x, int y, int w, int h);
|
||||||
@@ -289,12 +286,12 @@ static void togglewin(const Arg *arg);
|
|||||||
static void unfocus(Client *c, int setfocus);
|
static void unfocus(Client *c, int setfocus);
|
||||||
static void unmanage(Client *c, int destroyed);
|
static void unmanage(Client *c, int destroyed);
|
||||||
static void unmapnotify(XEvent *e);
|
static void unmapnotify(XEvent *e);
|
||||||
|
static void unminimize(Client *c);
|
||||||
static void updatecurrentdesktop(void);
|
static void updatecurrentdesktop(void);
|
||||||
static void updatebarpos(Monitor *m);
|
static void updatebarpos(Monitor *m);
|
||||||
static void updatebars(void);
|
static void updatebars(void);
|
||||||
static void updateclientlist(void);
|
static void updateclientlist(void);
|
||||||
static int updategeom(void);
|
static int updategeom(void);
|
||||||
static void updateicon(Client *c);
|
|
||||||
static void updatenumlockmask(void);
|
static void updatenumlockmask(void);
|
||||||
static void updatesizehints(Client *c);
|
static void updatesizehints(Client *c);
|
||||||
static void updatestatus(void);
|
static void updatestatus(void);
|
||||||
@@ -427,6 +424,7 @@ applyrules(Client *c)
|
|||||||
{
|
{
|
||||||
c->isfloating = r->isfloating;
|
c->isfloating = r->isfloating;
|
||||||
c->tags |= r->tags;
|
c->tags |= r->tags;
|
||||||
|
c->isgame = r->isgame;
|
||||||
if ((r->tags & SPTAGMASK) && r->isfloating) {
|
if ((r->tags & SPTAGMASK) && r->isfloating) {
|
||||||
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
|
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
|
||||||
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
|
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
|
||||||
@@ -559,57 +557,6 @@ attachstack(Client *c)
|
|||||||
c->mon->stack = c;
|
c->mon->stack = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *
|
|
||||||
bilinear_scale(const uint32_t *src, int sw, int sh, unsigned int dw, unsigned int dh)
|
|
||||||
{
|
|
||||||
uint32_t *dst = calloc(dw * dh, sizeof(uint32_t));
|
|
||||||
if (!dst) return NULL;
|
|
||||||
|
|
||||||
for (int y = 0; y < dh; y++) {
|
|
||||||
/* Source position (in fixed-point) */
|
|
||||||
float sy = (y + 0.5f) * sh / (float)dh - 0.5f;
|
|
||||||
int y0 = (sy < 0) ? (int)(sy - 1) : (int)(sy);;
|
|
||||||
int y1 = y0 + 1;
|
|
||||||
float fy = sy - y0;
|
|
||||||
if (y0 < 0) { y0 = 0; y1 = 0; fy = 0; }
|
|
||||||
if (y1 >= sh) { y1 = sh-1; y0 = y1; fy = 0; }
|
|
||||||
|
|
||||||
for (int x = 0; x < dw; x++) {
|
|
||||||
float sx = (x + 0.5f) * sw / (float)dw - 0.5f;
|
|
||||||
int x0 = (sx < 0) ? (int)(sx - 1) : (int)(sx);
|
|
||||||
int x1 = x0 + 1;
|
|
||||||
float fx = sx - x0;
|
|
||||||
if (x0 < 0) { x0 = 0; x1 = 0; fx = 0; }
|
|
||||||
if (x1 >= sw) { x1 = sw-1; x0 = x1; fx = 0; }
|
|
||||||
|
|
||||||
uint32_t p00 = prealpha(src[y0*sw + x0]);
|
|
||||||
uint32_t p10 = prealpha(src[y0*sw + x1]);
|
|
||||||
uint32_t p01 = prealpha(src[y1*sw + x0]);
|
|
||||||
uint32_t p11 = prealpha(src[y1*sw + x1]);
|
|
||||||
|
|
||||||
/* Extract premultiplied channels */
|
|
||||||
int a00 = p00 >> 24, r00 = (p00 >> 16) & 0xFF, g00 = (p00 >> 8) & 0xFF, b00 = p00 & 0xFF;
|
|
||||||
int a10 = p10 >> 24, r10 = (p10 >> 16) & 0xFF, g10 = (p10 >> 8) & 0xFF, b10 = p10 & 0xFF;
|
|
||||||
int a01 = p01 >> 24, r01 = (p01 >> 16) & 0xFF, g01 = (p01 >> 8) & 0xFF, b01 = p01 & 0xFF;
|
|
||||||
int a11 = p11 >> 24, r11 = (p11 >> 16) & 0xFF, g11 = (p11 >> 8) & 0xFF, b11 = p11 & 0xFF;
|
|
||||||
|
|
||||||
/* Bilinear weights */
|
|
||||||
float w00 = (1.0f - fx) * (1.0f - fy);
|
|
||||||
float w10 = fx * (1.0f - fy);
|
|
||||||
float w01 = (1.0f - fx) * fy;
|
|
||||||
float w11 = fx * fy;
|
|
||||||
|
|
||||||
int a = (int)(a00*w00 + a10*w10 + a01*w01 + a11*w11 + 0.5f);
|
|
||||||
int r = (int)(r00*w00 + r10*w10 + r01*w01 + r11*w11 + 0.5f);
|
|
||||||
int g = (int)(g00*w00 + g10*w10 + g01*w01 + g11*w11 + 0.5f);
|
|
||||||
int b = (int)(b00*w00 + b10*w10 + b01*w01 + b11*w11 + 0.5f);
|
|
||||||
|
|
||||||
dst[y*dw + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
buttonpress(XEvent *e)
|
buttonpress(XEvent *e)
|
||||||
{
|
{
|
||||||
@@ -1057,12 +1004,7 @@ drawbar(Monitor *m)
|
|||||||
}
|
}
|
||||||
remainder--;
|
remainder--;
|
||||||
}
|
}
|
||||||
if (c->icon) {
|
|
||||||
drw_text(drw, x, 0, w > m->ww - tw - stw - x ? m->ww - tw - stw - x : w, bh, lrpad / 2 + c->ich + iconspacing, c->name, 0);
|
|
||||||
drw_pic(drw, x + lrpad / 2, (bh - c->ich) / 2, c->icw, c->ich, c->icon);
|
|
||||||
} else {
|
|
||||||
drw_text(drw, x, 0, tabw > m->ww - tw - stw - x ? m->ww - tw - stw - x : tabw, bh, lrpad / 2, c->name, 0);
|
drw_text(drw, x, 0, tabw > m->ww - tw - stw - x ? m->ww - tw - stw - x : tabw, bh, lrpad / 2, c->name, 0);
|
||||||
}
|
|
||||||
x += tabw;
|
x += tabw;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1290,15 +1232,6 @@ focusstack(int inc, int hid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
freeicon(Client *c)
|
|
||||||
{
|
|
||||||
if (c->icon) {
|
|
||||||
XRenderFreePicture(dpy, c->icon);
|
|
||||||
c->icon = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Atom
|
Atom
|
||||||
getatomprop(Client *c, Atom prop)
|
getatomprop(Client *c, Atom prop)
|
||||||
{
|
{
|
||||||
@@ -1361,104 +1294,6 @@ getstate(Window w)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* geticonprop: read, scale, and return an XRender Picture */
|
|
||||||
Picture
|
|
||||||
geticonprop(Display *dpy, Window win, int iconsize, unsigned int *icw, unsigned int *ich) {
|
|
||||||
Atom net_wm_icon = XInternAtom(dpy, "_NET_WM_ICON", False);
|
|
||||||
Atom actual_type;
|
|
||||||
int actual_format;
|
|
||||||
unsigned long nitems, bytes_after;
|
|
||||||
unsigned char *data = NULL;
|
|
||||||
Picture pict = None;
|
|
||||||
|
|
||||||
if (XGetWindowProperty(dpy, win, net_wm_icon, 0, LONG_MAX, False, AnyPropertyType,
|
|
||||||
&actual_type, &actual_format, &nitems, &bytes_after, &data) != Success || !data) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long *p = (unsigned long *)data;
|
|
||||||
unsigned long *end = p + nitems;
|
|
||||||
|
|
||||||
/* Pick icon closest to desired size */
|
|
||||||
unsigned long *best = NULL;
|
|
||||||
unsigned long best_w = 0, best_h = 0;
|
|
||||||
unsigned long best_diff = ~0UL;
|
|
||||||
|
|
||||||
while (p + 2 < end) {
|
|
||||||
unsigned long w0 = *p++;
|
|
||||||
unsigned long h0 = *p++;
|
|
||||||
if (w0 == 0 || h0 == 0 || p + w0*h0 > end) break;
|
|
||||||
|
|
||||||
unsigned long diff = (w0 > (unsigned long)iconsize ? w0 - iconsize : iconsize - w0)
|
|
||||||
+ (h0 > (unsigned long)iconsize ? h0 - iconsize : iconsize - h0);
|
|
||||||
|
|
||||||
if (diff < best_diff) {
|
|
||||||
best_diff = diff;
|
|
||||||
best_w = w0;
|
|
||||||
best_h = h0;
|
|
||||||
best = p;
|
|
||||||
}
|
|
||||||
p += w0 * h0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!best) {
|
|
||||||
XFree(data);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy into fixed 32-bit array */
|
|
||||||
uint32_t *src = malloc(best_w * best_h * sizeof(uint32_t));
|
|
||||||
for (size_t i = 0; i < best_w * best_h; i++)
|
|
||||||
src[i] = (uint32_t)best[i];
|
|
||||||
|
|
||||||
/* Scale */
|
|
||||||
int dst_w, dst_h;
|
|
||||||
if (best_w > best_h) {
|
|
||||||
dst_w = iconsize;
|
|
||||||
dst_h = best_h * iconsize / best_w;
|
|
||||||
} else {
|
|
||||||
dst_h = iconsize;
|
|
||||||
dst_w = best_w * iconsize / best_h;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *scaled = bilinear_scale(src, best_w, best_h, dst_w, dst_h);
|
|
||||||
free(src);
|
|
||||||
XFree(data);
|
|
||||||
if (!scaled) return None;
|
|
||||||
|
|
||||||
/* Create pixmap and upload pixels */
|
|
||||||
Pixmap pm = XCreatePixmap(dpy, root, dst_w, dst_h, 32);
|
|
||||||
|
|
||||||
XImage img;
|
|
||||||
memset(&img, 0, sizeof img);
|
|
||||||
img.width = dst_w;
|
|
||||||
img.height = dst_h;
|
|
||||||
img.format = ZPixmap;
|
|
||||||
img.data = (char*)scaled;
|
|
||||||
img.byte_order = LSBFirst;
|
|
||||||
img.bitmap_unit = 32;
|
|
||||||
img.bitmap_bit_order = LSBFirst;
|
|
||||||
img.bitmap_pad = 32;
|
|
||||||
img.depth = 32;
|
|
||||||
img.bits_per_pixel = 32;
|
|
||||||
img.bytes_per_line = dst_w * 4;
|
|
||||||
|
|
||||||
XInitImage(&img);
|
|
||||||
GC gc = XCreateGC(dpy, pm, 0, NULL);
|
|
||||||
XPutImage(dpy, pm, gc, &img, 0, 0, 0, 0, dst_w, dst_h);
|
|
||||||
XFreeGC(dpy, gc);
|
|
||||||
|
|
||||||
XRenderPictFormat *fmt = XRenderFindStandardFormat(dpy, PictStandardARGB32);
|
|
||||||
pict = XRenderCreatePicture(dpy, pm, fmt, 0, NULL);
|
|
||||||
XFreePixmap(dpy, pm);
|
|
||||||
|
|
||||||
free(scaled);
|
|
||||||
|
|
||||||
*icw = dst_w;
|
|
||||||
*ich = dst_h;
|
|
||||||
return pict;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
gettextprop(Window w, Atom atom, char *text, unsigned int size)
|
gettextprop(Window w, Atom atom, char *text, unsigned int size)
|
||||||
{
|
{
|
||||||
@@ -1640,7 +1475,6 @@ manage(Window w, XWindowAttributes *wa)
|
|||||||
c->oldbw = wa->border_width;
|
c->oldbw = wa->border_width;
|
||||||
c->cfact = 1.0;
|
c->cfact = 1.0;
|
||||||
|
|
||||||
updateicon(c);
|
|
||||||
updatetitle(c);
|
updatetitle(c);
|
||||||
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
||||||
c->mon = t->mon;
|
c->mon = t->mon;
|
||||||
@@ -1738,6 +1572,29 @@ maprequest(XEvent *e)
|
|||||||
manage(ev->window, &wa);
|
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
|
void
|
||||||
monocle(Monitor *m)
|
monocle(Monitor *m)
|
||||||
{
|
{
|
||||||
@@ -1953,14 +1810,6 @@ pop(Client *c)
|
|||||||
arrange(c->mon);
|
arrange(c->mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
|
||||||
prealpha(uint32_t p) {
|
|
||||||
uint8_t a = p >> 24u;
|
|
||||||
uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
|
|
||||||
uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
|
|
||||||
return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
propertynotify(XEvent *e)
|
propertynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
@@ -2004,11 +1853,6 @@ propertynotify(XEvent *e)
|
|||||||
if (c == c->mon->sel)
|
if (c == c->mon->sel)
|
||||||
drawbar(c->mon);
|
drawbar(c->mon);
|
||||||
}
|
}
|
||||||
if (ev->atom == netatom[NetWMIcon]) {
|
|
||||||
updateicon(c);
|
|
||||||
if (c == c->mon->sel)
|
|
||||||
drawbar(c->mon);
|
|
||||||
}
|
|
||||||
if (ev->atom == netatom[NetWMWindowType])
|
if (ev->atom == netatom[NetWMWindowType])
|
||||||
updatewindowtype(c);
|
updatewindowtype(c);
|
||||||
}
|
}
|
||||||
@@ -2017,6 +1861,8 @@ propertynotify(XEvent *e)
|
|||||||
void
|
void
|
||||||
quit(const Arg *arg)
|
quit(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
if(arg->i) restart = 1;
|
||||||
|
if (!restart) {
|
||||||
// fix: reloading dwm keeps all the hidden clients hidden
|
// fix: reloading dwm keeps all the hidden clients hidden
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
Client *c;
|
Client *c;
|
||||||
@@ -2026,8 +1872,8 @@ quit(const Arg *arg)
|
|||||||
if (c && HIDDEN(c)) showwin(c);
|
if (c && HIDDEN(c)) showwin(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(arg->i) restart = 1;
|
|
||||||
running = 0;
|
running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2319,6 +2165,10 @@ setfocus(Client *c)
|
|||||||
XA_WINDOW, 32, PropModeReplace,
|
XA_WINDOW, 32, PropModeReplace,
|
||||||
(unsigned char *) &(c->win), 1);
|
(unsigned char *) &(c->win), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->isgame && c->isfullscreen)
|
||||||
|
unminimize(c);
|
||||||
|
|
||||||
if (c->issteam)
|
if (c->issteam)
|
||||||
setclientstate(c, NormalState);
|
setclientstate(c, NormalState);
|
||||||
|
|
||||||
@@ -2494,7 +2344,6 @@ setup(void)
|
|||||||
netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
|
netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
|
||||||
netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
|
netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
|
||||||
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
||||||
netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
|
|
||||||
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
|
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
|
||||||
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
||||||
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
@@ -2848,6 +2697,10 @@ unfocus(Client *c, int setfocus)
|
|||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (c->isgame && c->isfullscreen)
|
||||||
|
minimize(c);
|
||||||
|
|
||||||
grabbuttons(c, 0);
|
grabbuttons(c, 0);
|
||||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||||
if (setfocus) {
|
if (setfocus) {
|
||||||
@@ -2864,7 +2717,6 @@ unmanage(Client *c, int destroyed)
|
|||||||
|
|
||||||
detach(c);
|
detach(c);
|
||||||
detachstack(c);
|
detachstack(c);
|
||||||
freeicon(c);
|
|
||||||
if (!destroyed) {
|
if (!destroyed) {
|
||||||
wc.border_width = c->oldbw;
|
wc.border_width = c->oldbw;
|
||||||
XGrabServer(dpy); /* avoid race conditions */
|
XGrabServer(dpy); /* avoid race conditions */
|
||||||
@@ -2903,6 +2755,16 @@ unmapnotify(XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unminimize(Client *c)
|
||||||
|
{
|
||||||
|
if (!c || !MINIMIZED(c))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XMapWindow(dpy, c->win);
|
||||||
|
setclientstate(c, NormalState);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updatebars(void)
|
updatebars(void)
|
||||||
{
|
{
|
||||||
@@ -2967,13 +2829,6 @@ void updatecurrentdesktop(void){
|
|||||||
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
updateicon(Client *c)
|
|
||||||
{
|
|
||||||
freeicon(c);
|
|
||||||
c->icon = geticonprop(dpy, c->win, iconsize, &c->icw, &c->ich);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
updategeom(void)
|
updategeom(void)
|
||||||
{
|
{
|
||||||
|
|||||||
49
dwm.c.rej
49
dwm.c.rej
@@ -1,46 +1,19 @@
|
|||||||
--- dwm.c
|
--- dwm.c
|
||||||
+++ dwm.c
|
+++ dwm.c
|
||||||
@@ -59,7 +58,7 @@
|
@@ -92,7 +92,6 @@ struct Client {
|
||||||
/* enums */
|
|
||||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
|
||||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
|
||||||
-enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck,
|
|
||||||
+enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
|
||||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
|
||||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
|
||||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
|
||||||
@@ -92,8 +91,6 @@ struct Client {
|
|
||||||
int bw, oldbw;
|
int bw, oldbw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
- unsigned int icw, ich;
|
- int issteam;
|
||||||
- Picture icon;
|
|
||||||
Client *next;
|
Client *next;
|
||||||
Client *snext;
|
Client *snext;
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
@@ -170,11 +166,9 @@ static void focus(Client *c);
|
@@ -1476,8 +1470,6 @@ setfocus(Client *c)
|
||||||
static void focusin(XEvent *e);
|
XA_WINDOW, 32, PropModeReplace,
|
||||||
static void focusmon(const Arg *arg);
|
(unsigned char *) &(c->win), 1);
|
||||||
static void focusstack(const Arg *arg);
|
}
|
||||||
-static void freeicon(Client *c);
|
- if (c->issteam)
|
||||||
static Atom getatomprop(Client *c, Atom prop);
|
- setclientstate(c, NormalState);
|
||||||
static int getrootptr(int *x, int *y);
|
sendevent(c, wmatom[WMTakeFocus]);
|
||||||
static long getstate(Window w);
|
}
|
||||||
-static Picture geticonprop(Display *dpy, Window w, int iconsize, unsigned int *icw, unsigned int *ich);
|
|
||||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
|
||||||
static void grabbuttons(Client *c, int focused);
|
|
||||||
static void grabkeys(void);
|
|
||||||
@@ -740,12 +681,7 @@ drawbar(Monitor *m)
|
|
||||||
if ((w = m->ww - tw - x) > bh) {
|
|
||||||
if (m->sel) {
|
|
||||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
|
|
||||||
- if (m->sel->icon) {
|
|
||||||
- drw_text(drw, x, 0, w, bh, lrpad / 2 + m->sel->icw + iconspacing, m->sel->name, 0);
|
|
||||||
- drw_pic(drw, x + lrpad / 2, (bh - m->sel->ich) / 2, m->sel->icw, m->sel->ich, m->sel->icon);
|
|
||||||
- } else {
|
|
||||||
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
|
|
||||||
- }
|
|
||||||
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
|
|
||||||
if (m->sel->isfloating)
|
|
||||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
|
|
||||||
} else {
|
|
||||||
|
|||||||
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
|
||||||
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
From df7d9a685f38b64b8087faa3c72f05acf0190383 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Bakkeby <bakkeby@gmail.com>
|
|
||||||
Date: Wed, 26 Jun 2024 23:06:37 +0200
|
|
||||||
Subject: [PATCH] Steam patch
|
|
||||||
|
|
||||||
Steam, and steam windows (games), trigger a ConfigureNotify request every time the window
|
|
||||||
gets focus. More so, the configure event passed along from Steam tends to have the wrong
|
|
||||||
x and y co-ordinates which can make the window, if floating, jump around the screen.
|
|
||||||
|
|
||||||
This patch works around this age-old issue by ignoring the x and y co-ordinates for
|
|
||||||
ConfigureNotify requests relating to Steam windows.
|
|
||||||
---
|
|
||||||
dwm.c | 22 +++++++++++++++-------
|
|
||||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 1443802..d99a6fb 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -92,6 +92,7 @@ struct Client {
|
|
||||||
int bw, oldbw;
|
|
||||||
unsigned int tags;
|
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
|
||||||
+ int issteam;
|
|
||||||
Client *next;
|
|
||||||
Client *snext;
|
|
||||||
Monitor *mon;
|
|
||||||
@@ -290,6 +291,9 @@ applyrules(Client *c)
|
|
||||||
class = ch.res_class ? ch.res_class : broken;
|
|
||||||
instance = ch.res_name ? ch.res_name : broken;
|
|
||||||
|
|
||||||
+ if (strstr(class, "Steam") || strstr(class, "steam_app_"))
|
|
||||||
+ c->issteam = 1;
|
|
||||||
+
|
|
||||||
for (i = 0; i < LENGTH(rules); i++) {
|
|
||||||
r = &rules[i];
|
|
||||||
if ((!r->title || strstr(c->name, r->title))
|
|
||||||
@@ -590,13 +594,15 @@ configurerequest(XEvent *e)
|
|
||||||
c->bw = ev->border_width;
|
|
||||||
else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
|
|
||||||
m = c->mon;
|
|
||||||
- if (ev->value_mask & CWX) {
|
|
||||||
- c->oldx = c->x;
|
|
||||||
- c->x = m->mx + ev->x;
|
|
||||||
- }
|
|
||||||
- if (ev->value_mask & CWY) {
|
|
||||||
- c->oldy = c->y;
|
|
||||||
- c->y = m->my + ev->y;
|
|
||||||
+ if (!c->issteam) {
|
|
||||||
+ if (ev->value_mask & CWX) {
|
|
||||||
+ c->oldx = c->x;
|
|
||||||
+ c->x = m->mx + ev->x;
|
|
||||||
+ }
|
|
||||||
+ if (ev->value_mask & CWY) {
|
|
||||||
+ c->oldy = c->y;
|
|
||||||
+ c->y = m->my + ev->y;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if (ev->value_mask & CWWidth) {
|
|
||||||
c->oldw = c->w;
|
|
||||||
@@ -1475,6 +1481,8 @@ setfocus(Client *c)
|
|
||||||
XA_WINDOW, 32, PropModeReplace,
|
|
||||||
(unsigned char *) &(c->win), 1);
|
|
||||||
}
|
|
||||||
+ if (c->issteam)
|
|
||||||
+ setclientstate(c, NormalState);
|
|
||||||
sendevent(c, wmatom[WMTakeFocus]);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.50.1
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user