use games patch

This commit is contained in:
2026-07-15 22:33:00 +02:00
parent e9a681783b
commit a3bca752da
10 changed files with 338 additions and 386 deletions

View File

@@ -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";

View File

@@ -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} },

View File

@@ -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} },

BIN
dwm

Binary file not shown.

58
dwm.c
View File

@@ -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)
{ {

View File

@@ -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)
{ {

View File

@@ -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 {

BIN
dwm.o

Binary file not shown.

173
patches/dwm-games-6.6.diff Normal file
View 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

View File

@@ -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