cycle layouts
This commit is contained in:
@@ -1,15 +1,19 @@
|
|||||||
--- config.def.h
|
--- config.def.h
|
||||||
+++ config.def.h
|
+++ config.def.h
|
||||||
@@ -26,9 +26,11 @@ static const Rule rules[] = {
|
@@ -42,6 +42,7 @@ static const Layout layouts[] = {
|
||||||
* WM_CLASS(STRING) = instance, class
|
{ "[]=", tile }, /* first entry is default */
|
||||||
* WM_NAME(STRING) = title
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
*/
|
{ "[M]", monocle },
|
||||||
- /* class instance title tags mask isfloating monitor */
|
+ { NULL, NULL },
|
||||||
+ /* 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) */
|
/* key definitions */
|
||||||
|
@@ -85,6 +86,8 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
||||||
|
+ { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
|
||||||
|
+ { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
|
||||||
|
TAGKEYS( XK_1, 0)
|
||||||
|
TAGKEYS( XK_2, 1)
|
||||||
|
TAGKEYS( XK_3, 2)
|
||||||
|
|||||||
16
config.h
16
config.h
@@ -126,6 +126,7 @@ static const Key keys[] = {
|
|||||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||||
{ MODKEY, XK_p, incnmaster, {.i = -1 } },
|
{ MODKEY, XK_p, incnmaster, {.i = -1 } },
|
||||||
|
|
||||||
|
/* vim like window management / nav */
|
||||||
{ MODKEY, XK_h, focusdir, {.i = 0 } },
|
{ MODKEY, XK_h, focusdir, {.i = 0 } },
|
||||||
{ MODKEY, XK_l, focusdir, {.i = 1 } },
|
{ MODKEY, XK_l, focusdir, {.i = 1 } },
|
||||||
{ MODKEY, XK_k, focusdir, {.i = 2 } },
|
{ MODKEY, XK_k, focusdir, {.i = 2 } },
|
||||||
@@ -135,6 +136,9 @@ static const Key keys[] = {
|
|||||||
{ MODKEY|ShiftMask, XK_k, placedir, {.i = 2 } },
|
{ MODKEY|ShiftMask, XK_k, placedir, {.i = 2 } },
|
||||||
{ MODKEY|ShiftMask, XK_j, placedir, {.i = 3 } },
|
{ MODKEY|ShiftMask, XK_j, placedir, {.i = 3 } },
|
||||||
|
|
||||||
|
/* cycle layouts */
|
||||||
|
{ MODKEY, XK_n, cyclelayout, {.i = +1 } },
|
||||||
|
|
||||||
{ MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
|
{ MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
|
||||||
{ MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
{ MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
||||||
{ MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
{ MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
||||||
@@ -152,13 +156,17 @@ static const Key keys[] = {
|
|||||||
{ MODKEY|Mod1Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
|
{ MODKEY|Mod1Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
|
||||||
{ MODKEY|Mod1Mask, XK_9, incrovgaps, {.i = +1 } },
|
{ MODKEY|Mod1Mask, XK_9, incrovgaps, {.i = +1 } },
|
||||||
{ MODKEY|Mod1Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
|
{ MODKEY|Mod1Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
|
||||||
{ MODKEY|Mod1Mask, XK_0, togglegaps, {0} },
|
|
||||||
{ MODKEY|Mod1Mask|ShiftMask, XK_0, defaultgaps, {0} },
|
{ MODKEY, XK_a, togglegaps, {0} },
|
||||||
|
{ MODKEY|Mod1Mask|ShiftMask, XK_a, defaultgaps, {0} },
|
||||||
|
|
||||||
{ MODKEY, XK_Tab, view, {0} },
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
{ MODKEY, XK_q, killclient, {0} },
|
{ MODKEY, XK_q, killclient, {0} },
|
||||||
|
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
{ MODKEY, XK_v, setlayout, {.v = &layouts[1]} },
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
{ MODKEY, XK_c, setlayout, {.v = &layouts[2]} },
|
||||||
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||||
|
|||||||
6
dwm.1
6
dwm.1
@@ -92,6 +92,12 @@ Sets monocle layout.
|
|||||||
.B Mod1\-space
|
.B Mod1\-space
|
||||||
Toggles between current and previous layout.
|
Toggles between current and previous layout.
|
||||||
.TP
|
.TP
|
||||||
|
.B Mod1\-Control\-,
|
||||||
|
Cycles backwards in layout list.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Control\-.
|
||||||
|
Cycles forwards in layout list.
|
||||||
|
.TP
|
||||||
.B Mod1\-j
|
.B Mod1\-j
|
||||||
Focus next window.
|
Focus next window.
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
18
dwm.c
18
dwm.c
@@ -200,6 +200,7 @@ static void configure(Client *c);
|
|||||||
static void configurenotify(XEvent *e);
|
static void configurenotify(XEvent *e);
|
||||||
static void configurerequest(XEvent *e);
|
static void configurerequest(XEvent *e);
|
||||||
static Monitor *createmon(void);
|
static Monitor *createmon(void);
|
||||||
|
static void cyclelayout(const Arg *arg);
|
||||||
static void destroynotify(XEvent *e);
|
static void destroynotify(XEvent *e);
|
||||||
static void detach(Client *c);
|
static void detach(Client *c);
|
||||||
static void detachstack(Client *c);
|
static void detachstack(Client *c);
|
||||||
@@ -888,6 +889,23 @@ createmon(void)
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cyclelayout(const Arg *arg) {
|
||||||
|
Layout *l;
|
||||||
|
for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
|
||||||
|
if(arg->i > 0) {
|
||||||
|
if(l->symbol && (l + 1)->symbol)
|
||||||
|
setlayout(&((Arg) { .v = (l + 1) }));
|
||||||
|
else
|
||||||
|
setlayout(&((Arg) { .v = layouts }));
|
||||||
|
} else {
|
||||||
|
if(l != layouts && (l - 1)->symbol)
|
||||||
|
setlayout(&((Arg) { .v = (l - 1) }));
|
||||||
|
else
|
||||||
|
setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
destroynotify(XEvent *e)
|
destroynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
|||||||
47
dwm.c.orig
47
dwm.c.orig
@@ -57,6 +57,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 MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||||
@@ -118,6 +119,7 @@ struct Client {
|
|||||||
int bw, oldbw;
|
int bw, oldbw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
|
||||||
|
int isgame;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
Client *next;
|
Client *next;
|
||||||
Client *snext;
|
Client *snext;
|
||||||
@@ -172,6 +174,7 @@ typedef struct {
|
|||||||
int isterminal;
|
int isterminal;
|
||||||
int noswallow;
|
int noswallow;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
int isgame;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
typedef struct Systray Systray;
|
typedef struct Systray Systray;
|
||||||
@@ -223,6 +226,7 @@ static void killclient(const Arg *arg);
|
|||||||
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);
|
||||||
@@ -268,6 +272,7 @@ static void toggleview(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 updatebarpos(Monitor *m);
|
static void updatebarpos(Monitor *m);
|
||||||
static void updatebars(void);
|
static void updatebars(void);
|
||||||
static void updateclientlist(void);
|
static void updateclientlist(void);
|
||||||
@@ -411,6 +416,7 @@ applyrules(Client *c)
|
|||||||
c->noswallow = r->noswallow;
|
c->noswallow = r->noswallow;
|
||||||
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);
|
||||||
@@ -1469,6 +1475,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)
|
||||||
{
|
{
|
||||||
@@ -1997,6 +2026,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);
|
||||||
|
|
||||||
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2359,6 +2392,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) {
|
||||||
@@ -2430,6 +2467,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)
|
||||||
{
|
{
|
||||||
|
|||||||
95
patches/dwm-cyclelayouts-6.3.diff
Normal file
95
patches/dwm-cyclelayouts-6.3.diff
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
From d54f931d007a32ddc1fd9d8084258d92378597a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Wed, 26 Jun 2024 09:45:28 +0200
|
||||||
|
Subject: [PATCH] cyclelayout, function to cycle through available layouts.
|
||||||
|
|
||||||
|
MOD-CTRL-, and MOD-CTRL-.
|
||||||
|
cycle backwards and forwards through available layouts.
|
||||||
|
Probably only useful if you have a lot of additional layouts.
|
||||||
|
The NULL, NULL layout should always be the last layout in your list,
|
||||||
|
in order to guarantee consistent behavior.
|
||||||
|
|
||||||
|
Refer to https://dwm.suckless.org/patches/cyclelayouts/
|
||||||
|
---
|
||||||
|
config.def.h | 3 +++
|
||||||
|
dwm.1 | 6 ++++++
|
||||||
|
dwm.c | 18 ++++++++++++++++++
|
||||||
|
3 files changed, 27 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index a2ac963..938fd60 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -42,6 +42,7 @@ static const Layout layouts[] = {
|
||||||
|
{ "[]=", tile }, /* first entry is default */
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
+ { NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
@@ -85,6 +86,8 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
||||||
|
+ { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
|
||||||
|
+ { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
|
||||||
|
TAGKEYS( XK_1, 0)
|
||||||
|
TAGKEYS( XK_2, 1)
|
||||||
|
TAGKEYS( XK_3, 2)
|
||||||
|
diff --git a/dwm.1 b/dwm.1
|
||||||
|
index ddc8321..829047b 100644
|
||||||
|
--- a/dwm.1
|
||||||
|
+++ b/dwm.1
|
||||||
|
@@ -92,6 +92,12 @@ Sets monocle layout.
|
||||||
|
.B Mod1\-space
|
||||||
|
Toggles between current and previous layout.
|
||||||
|
.TP
|
||||||
|
+.B Mod1\-Control\-,
|
||||||
|
+Cycles backwards in layout list.
|
||||||
|
+.TP
|
||||||
|
+.B Mod1\-Control\-.
|
||||||
|
+Cycles forwards in layout list.
|
||||||
|
+.TP
|
||||||
|
.B Mod1\-j
|
||||||
|
Focus next window.
|
||||||
|
.TP
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index a96f33c..2d98c2b 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -157,6 +157,7 @@ static void configure(Client *c);
|
||||||
|
static void configurenotify(XEvent *e);
|
||||||
|
static void configurerequest(XEvent *e);
|
||||||
|
static Monitor *createmon(void);
|
||||||
|
+static void cyclelayout(const Arg *arg);
|
||||||
|
static void destroynotify(XEvent *e);
|
||||||
|
static void detach(Client *c);
|
||||||
|
static void detachstack(Client *c);
|
||||||
|
@@ -645,6 +646,23 @@ createmon(void)
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+cyclelayout(const Arg *arg) {
|
||||||
|
+ Layout *l;
|
||||||
|
+ for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
|
||||||
|
+ if(arg->i > 0) {
|
||||||
|
+ if(l->symbol && (l + 1)->symbol)
|
||||||
|
+ setlayout(&((Arg) { .v = (l + 1) }));
|
||||||
|
+ else
|
||||||
|
+ setlayout(&((Arg) { .v = layouts }));
|
||||||
|
+ } else {
|
||||||
|
+ if(l != layouts && (l - 1)->symbol)
|
||||||
|
+ setlayout(&((Arg) { .v = (l - 1) }));
|
||||||
|
+ else
|
||||||
|
+ setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
destroynotify(XEvent *e)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
||||||
200
patches/dwm-focusborder-6.3.diff
Normal file
200
patches/dwm-focusborder-6.3.diff
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
From 6d049ac4a34cb2f3a9e774cf7e13886a9da349a8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Wed, 26 Jun 2024 10:01:41 +0200
|
||||||
|
Subject: [PATCH] Adding focusborder patch
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 1 +
|
||||||
|
dwm.c | 57 +++++++++++++++++++++++++++++++++++++++++++---------
|
||||||
|
2 files changed, 48 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index a2ac963..17d326b 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
|
+static const unsigned int fh = 5; /* focus window height */
|
||||||
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
|
static const char col_gray1[] = "#222222";
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index a96f33c..5f93b7e 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -267,7 +267,7 @@ static Clr **scheme;
|
||||||
|
static Display *dpy;
|
||||||
|
static Drw *drw;
|
||||||
|
static Monitor *mons, *selmon;
|
||||||
|
-static Window root, wmcheckwin;
|
||||||
|
+static Window root, wmcheckwin, focuswin;
|
||||||
|
|
||||||
|
/* configuration, allows nested code to access above variables */
|
||||||
|
#include "config.h"
|
||||||
|
@@ -487,6 +487,7 @@ cleanup(void)
|
||||||
|
drw_cur_free(drw, cursor[i]);
|
||||||
|
for (i = 0; i < LENGTH(colors); i++)
|
||||||
|
free(scheme[i]);
|
||||||
|
+ XDestroyWindow(dpy, focuswin);
|
||||||
|
XDestroyWindow(dpy, wmcheckwin);
|
||||||
|
drw_free(drw);
|
||||||
|
XSync(dpy, False);
|
||||||
|
@@ -787,6 +788,8 @@ expose(XEvent *e)
|
||||||
|
void
|
||||||
|
focus(Client *c)
|
||||||
|
{
|
||||||
|
+ XWindowChanges wc;
|
||||||
|
+
|
||||||
|
if (!c || !ISVISIBLE(c))
|
||||||
|
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
|
||||||
|
if (selmon->sel && selmon->sel != c)
|
||||||
|
@@ -800,10 +803,16 @@ focus(Client *c)
|
||||||
|
attachstack(c);
|
||||||
|
grabbuttons(c, 1);
|
||||||
|
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
|
||||||
|
+ XMoveResizeWindow(dpy, focuswin, c->x, c->y, c->w + 2 * c->bw, fh);
|
||||||
|
+ XMoveResizeWindow(dpy, c->win, c->x, c->y + fh, c->w, c->h - fh);
|
||||||
|
+ wc.stack_mode = Above;
|
||||||
|
+ wc.sibling = c->win;
|
||||||
|
+ XConfigureWindow(dpy, focuswin, CWSibling|CWStackMode, &wc);
|
||||||
|
setfocus(c);
|
||||||
|
} else {
|
||||||
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||||
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
|
||||||
|
+ XMoveWindow(dpy, focuswin, 0, -fh);
|
||||||
|
}
|
||||||
|
selmon->sel = c;
|
||||||
|
drawbars();
|
||||||
|
@@ -1150,8 +1159,8 @@ movemouse(const Arg *arg)
|
||||||
|
if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
|
||||||
|
return;
|
||||||
|
restack(selmon);
|
||||||
|
- ocx = c->x;
|
||||||
|
- ocy = c->y;
|
||||||
|
+ nx = ocx = c->x;
|
||||||
|
+ ny = ocy = c->y;
|
||||||
|
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
|
||||||
|
None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
|
||||||
|
return;
|
||||||
|
@@ -1183,16 +1192,23 @@ movemouse(const Arg *arg)
|
||||||
|
if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
|
||||||
|
&& (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
|
||||||
|
togglefloating(NULL);
|
||||||
|
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
|
||||||
|
- resize(c, nx, ny, c->w, c->h, 1);
|
||||||
|
+ if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
|
||||||
|
+ XMoveWindow(dpy, focuswin, nx, ny);
|
||||||
|
+ XMoveWindow(dpy, c->win, nx, ny + fh);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (ev.type != ButtonRelease);
|
||||||
|
+
|
||||||
|
XUngrabPointer(dpy, CurrentTime);
|
||||||
|
+ resize(c, nx, ny, c->w, c->h, 1);
|
||||||
|
+
|
||||||
|
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
|
||||||
|
sendmon(c, m);
|
||||||
|
selmon = m;
|
||||||
|
focus(NULL);
|
||||||
|
+ } else {
|
||||||
|
+ focus(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1306,7 +1322,9 @@ resizemouse(const Arg *arg)
|
||||||
|
return;
|
||||||
|
restack(selmon);
|
||||||
|
ocx = c->x;
|
||||||
|
- ocy = c->y;
|
||||||
|
+ ocy = c->y + fh;
|
||||||
|
+ nh = c->h;
|
||||||
|
+ nw = c->w;
|
||||||
|
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
|
||||||
|
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
|
||||||
|
return;
|
||||||
|
@@ -1333,18 +1351,25 @@ resizemouse(const Arg *arg)
|
||||||
|
&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
|
||||||
|
togglefloating(NULL);
|
||||||
|
}
|
||||||
|
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
|
||||||
|
- resize(c, c->x, c->y, nw, nh, 1);
|
||||||
|
+ if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
|
||||||
|
+ XMoveResizeWindow(dpy, focuswin, c->x, c->y, nw + 2 * c->bw, fh);
|
||||||
|
+ XMoveResizeWindow(dpy, c->win, c->x, c->y + fh, nw, nh - fh);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (ev.type != ButtonRelease);
|
||||||
|
+
|
||||||
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
|
||||||
|
XUngrabPointer(dpy, CurrentTime);
|
||||||
|
+ resize(c, c->x, c->y, nw, nh, 1);
|
||||||
|
+
|
||||||
|
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
|
||||||
|
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
|
||||||
|
sendmon(c, m);
|
||||||
|
selmon = m;
|
||||||
|
focus(NULL);
|
||||||
|
+ } else {
|
||||||
|
+ focus(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1358,8 +1383,10 @@ restack(Monitor *m)
|
||||||
|
drawbar(m);
|
||||||
|
if (!m->sel)
|
||||||
|
return;
|
||||||
|
- if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
|
||||||
|
+ if (m->sel->isfloating || !m->lt[m->sellt]->arrange) {
|
||||||
|
XRaiseWindow(dpy, m->sel->win);
|
||||||
|
+ XRaiseWindow(dpy, focuswin);
|
||||||
|
+ }
|
||||||
|
if (m->lt[m->sellt]->arrange) {
|
||||||
|
wc.stack_mode = Below;
|
||||||
|
wc.sibling = m->barwin;
|
||||||
|
@@ -1534,7 +1561,7 @@ void
|
||||||
|
setup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
- XSetWindowAttributes wa;
|
||||||
|
+ XSetWindowAttributes wa, fwa;
|
||||||
|
Atom utf8string;
|
||||||
|
|
||||||
|
/* clean up any zombies immediately */
|
||||||
|
@@ -1585,6 +1612,14 @@ setup(void)
|
||||||
|
PropModeReplace, (unsigned char *) "dwm", 3);
|
||||||
|
XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
|
||||||
|
PropModeReplace, (unsigned char *) &wmcheckwin, 1);
|
||||||
|
+ /* focus window */
|
||||||
|
+ fwa.override_redirect = 1;
|
||||||
|
+ fwa.background_pixel = scheme[SchemeSel][ColBorder].pixel;
|
||||||
|
+ focuswin = XCreateWindow(dpy, root, -1, -1, 1, 1, 0, DefaultDepth(dpy, screen),
|
||||||
|
+ InputOutput, DefaultVisual(dpy, screen),
|
||||||
|
+ CWOverrideRedirect|CWBackPixel, &fwa
|
||||||
|
+ );
|
||||||
|
+ XMapWindow(dpy, focuswin);
|
||||||
|
/* EWMH support per view */
|
||||||
|
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
||||||
|
PropModeReplace, (unsigned char *) netatom, NetLast);
|
||||||
|
@@ -1723,6 +1758,7 @@ togglefloating(const Arg *arg)
|
||||||
|
resize(selmon->sel, selmon->sel->x, selmon->sel->y,
|
||||||
|
selmon->sel->w, selmon->sel->h, 0);
|
||||||
|
arrange(selmon);
|
||||||
|
+ focus(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1759,6 +1795,7 @@ unfocus(Client *c, int setfocus)
|
||||||
|
return;
|
||||||
|
grabbuttons(c, 0);
|
||||||
|
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||||
|
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||||
|
if (setfocus) {
|
||||||
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||||
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
||||||
Reference in New Issue
Block a user