mirror of
https://codeberg.org/frosty/dwm.git
synced 2024-09-19 03:36:55 -04:00
Compare commits
20 commits
6efec60c11
...
238c72de12
Author | SHA1 | Date | |
---|---|---|---|
frosty | 238c72de12 | ||
frosty | 9764fb0b0c | ||
frosty | be8cb44c3e | ||
frosty | d06f822a55 | ||
frosty | 806037dec1 | ||
frosty | f6fcb96c27 | ||
frosty | 7db028d38a | ||
frosty | 996dc08212 | ||
frosty | 34edb9f650 | ||
frosty | 838f9f1392 | ||
frosty | 9f04529dd5 | ||
frosty | d22fb1a46a | ||
frosty | c1cb54a0e0 | ||
frosty | 91787c75b3 | ||
frosty | 01674e4a2b | ||
frosty | d583d30d93 | ||
frosty | 3310614718 | ||
frosty | 0b32f4a773 | ||
frosty | d5661656c7 | ||
frosty | 6a67c041e5 |
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Binaries
|
||||
dwm
|
||||
*.o
|
||||
# Config copy
|
||||
config.h
|
||||
# Patches
|
||||
*.diff
|
||||
*.patch
|
||||
# Copies
|
||||
*.orig
|
||||
*.rej
|
122
config.def.h
122
config.def.h
|
@ -1,21 +1,30 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#define TERMINAL "st"
|
||||
#define BROWSER "firefox"
|
||||
|
||||
/* appearance */
|
||||
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 char *fonts[] = { "monospace:size=10" };
|
||||
static const char dmenufont[] = "monospace:size=10";
|
||||
static const char col_gray1[] = "#222222";
|
||||
static const char col_gray2[] = "#444444";
|
||||
static const char col_gray3[] = "#bbbbbb";
|
||||
static const char col_gray4[] = "#eeeeee";
|
||||
static const char col_cyan[] = "#005577";
|
||||
static const char *colors[][3] = {
|
||||
static unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static unsigned int snap = 32; /* snap pixel */
|
||||
static unsigned int gappih = 16; /* horiz inner gap between windows */
|
||||
static unsigned int gappiv = 16; /* vert inner gap between windows */
|
||||
static unsigned int gappoh = 8; /* horiz outer gap between windows and screen edge */
|
||||
static unsigned int gappov = 8; /* vert outer gap between windows and screen edge */
|
||||
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||
static int showbar = 1; /* 0 means no bar */
|
||||
static int topbar = 1; /* 0 means bottom bar */
|
||||
static char font[] = "monospace:size=10";
|
||||
static const char *fonts[] = { font };
|
||||
static char normbgcolor[] = "#222222";
|
||||
static char normbordercolor[] = "#444444";
|
||||
static char normfgcolor[] = "#bbbbbb";
|
||||
static char selfgcolor[] = "#eeeeee";
|
||||
static char selbordercolor[] = "#005577";
|
||||
static char selbgcolor[] = "#005577";
|
||||
static char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
[SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
|
||||
[SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
|
@ -27,14 +36,16 @@ static const Rule rules[] = {
|
|||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
/* class instance title tags mask isfloating monitor */
|
||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
{ "firefox", NULL, NULL, 1 << 1, 0, -1 },
|
||||
{ "firefox", NULL, "Picture-in-Picture", 0, 1, -1 },
|
||||
{ "Signal", NULL, NULL, 1 << 3, 0, -1 },
|
||||
{ "vesktop", NULL, NULL, 1 << 3, 0, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||
static const int nmaster = 1; /* number of clients in master area */
|
||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||
static float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||
static int nmaster = 1; /* number of clients in master area */
|
||||
static int resizehints = 0; /* 1 means respect size hints in tiled resizals */
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
|
||||
static const Layout layouts[] = {
|
||||
|
@ -45,7 +56,7 @@ static const Layout layouts[] = {
|
|||
};
|
||||
|
||||
/* key definitions */
|
||||
#define MODKEY Mod1Mask
|
||||
#define MODKEY Mod4Mask
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
|
@ -55,32 +66,79 @@ static const Layout layouts[] = {
|
|||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
#define TERMCMD(cmd) { .v = (const char*[]){ TERMINAL, "-e", cmd, NULL } }
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
||||
static const char *dmenucmd[] = { "ezrun", NULL };
|
||||
static const char *termcmd[] = { "st", NULL };
|
||||
|
||||
/*
|
||||
* Xresources preferences to load at startup
|
||||
*/
|
||||
ResourcePref resources[] = {
|
||||
{ "font", STRING, &font },
|
||||
{ "normbgcolor", STRING, &normbgcolor },
|
||||
{ "normbordercolor", STRING, &normbordercolor },
|
||||
{ "normfgcolor", STRING, &normfgcolor },
|
||||
{ "selbgcolor", STRING, &selbgcolor },
|
||||
{ "selbordercolor", STRING, &selbordercolor },
|
||||
{ "selfgcolor", STRING, &selfgcolor },
|
||||
{ "borderpx", INTEGER, &borderpx },
|
||||
{ "snap", INTEGER, &snap },
|
||||
{ "showbar", INTEGER, &showbar },
|
||||
{ "topbar", INTEGER, &topbar },
|
||||
{ "nmaster", INTEGER, &nmaster },
|
||||
{ "resizehints", INTEGER, &resizehints },
|
||||
{ "mfact", FLOAT, &mfact },
|
||||
{ "gappih", INTEGER, &gappih },
|
||||
{ "gappiv", INTEGER, &gappiv },
|
||||
{ "gappoh", INTEGER, &gappoh },
|
||||
{ "gappov", INTEGER, &gappov },
|
||||
{ "smartgaps", INTEGER, &smartgaps },
|
||||
};
|
||||
|
||||
#include "shiftview.c"
|
||||
|
||||
static const Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_w, spawn, SHCMD(BROWSER) },
|
||||
{ MODKEY, XK_v, spawn, TERMCMD("pulsemixer") },
|
||||
{ MODKEY, XK_e, spawn, SHCMD("thunar") },
|
||||
{ ControlMask|Mod1Mask, XK_u, spawn, TERMCMD("htop") },
|
||||
{ ControlMask|Mod1Mask, XK_p, spawn, SHCMD("screenshot select") },
|
||||
{ ControlMask|Mod1Mask, XK_o, spawn, SHCMD("screenshot full") },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY|ShiftMask, XK_j, pushdown, {0} },
|
||||
{ MODKEY|ShiftMask, XK_k, pushup, {0} },
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||
{ MODKEY, XK_Return, zoom, {0} },
|
||||
{ MODKEY, XK_h, setmfact, {.f = -0.0125} },
|
||||
{ MODKEY, XK_l, setmfact, {.f = +0.0125} },
|
||||
{ MODKEY|ShiftMask, XK_h, setmfact, {.f = -0.05} },
|
||||
{ MODKEY|ShiftMask, XK_l, setmfact, {.f = +0.05} },
|
||||
{ MODKEY, XK_bracketright, incrgaps, {.i = +4 } },
|
||||
{ MODKEY, XK_bracketleft, incrgaps, {.i = -4 } },
|
||||
{ MODKEY, XK_equal, togglegaps, {0} },
|
||||
{ MODKEY|ShiftMask, XK_equal, defaultgaps, {0} },
|
||||
{ MODKEY|ShiftMask, XK_Return, zoom, {0} },
|
||||
{ MODKEY, XK_Tab, view, {0} },
|
||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, /* tile */
|
||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, /* floating */
|
||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, /* monocle */
|
||||
{ MODKEY, XK_space, setlayout, {0} },
|
||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||
{ MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
|
||||
{ MODKEY|ShiftMask, XK_s, togglesticky, {0} },
|
||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
||||
{ MODKEY, XK_y, shiftview, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_y, shiftview, {.i = -1 } },
|
||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||
|
@ -94,7 +152,12 @@ static const Key keys[] = {
|
|||
TAGKEYS( XK_7, 6)
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
{ ControlMask|Mod1Mask, XK_r, quit, {0} },
|
||||
{ ControlMask|Mod1Mask, XK_Delete, spawn, SHCMD("pkill xinit") },
|
||||
{ MODKEY, XK_F9, spawn, SHCMD("sys-volume toggle") },
|
||||
{ MODKEY, XK_F10, spawn, SHCMD("sys-volume 5%-") },
|
||||
{ MODKEY, XK_F11, spawn, SHCMD("sys-volume 5%+") },
|
||||
{ MODKEY, XK_F12, spawn, SHCMD("sys-lock") },
|
||||
};
|
||||
|
||||
/* button definitions */
|
||||
|
@ -113,4 +176,3 @@ static const Button buttons[] = {
|
|||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||
};
|
||||
|
||||
|
|
4
drw.c
4
drw.c
|
@ -190,12 +190,14 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
|||
DefaultColormap(drw->dpy, drw->screen),
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
|
||||
dest->pixel |= 0xff << 24;
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
|
|
2
drw.h
2
drw.h
|
@ -40,7 +40,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
|||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
|
|
3
dwm.1
3
dwm.1
|
@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
|
|||
.B Mod1\-Shift\-c
|
||||
Close focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-f
|
||||
Toggle fullscreen for focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-space
|
||||
Toggle focused window between tiled and floating state.
|
||||
.TP
|
||||
|
|
440
dwm.c
440
dwm.c
|
@ -36,6 +36,7 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
#ifdef XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif /* XINERAMA */
|
||||
|
@ -49,7 +50,7 @@
|
|||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
||||
#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
|
@ -61,7 +62,7 @@
|
|||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||
NetWMFullscreen, NetWMSticky, NetActiveWindow, NetWMWindowType,
|
||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
||||
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||
|
@ -92,7 +93,7 @@ struct Client {
|
|||
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
Monitor *mon;
|
||||
|
@ -111,6 +112,7 @@ typedef struct {
|
|||
void (*arrange)(Monitor *);
|
||||
} Layout;
|
||||
|
||||
typedef struct Pertag Pertag;
|
||||
struct Monitor {
|
||||
char ltsymbol[16];
|
||||
float mfact;
|
||||
|
@ -119,6 +121,10 @@ struct Monitor {
|
|||
int by; /* bar geometry */
|
||||
int mx, my, mw, mh; /* screen size */
|
||||
int wx, wy, ww, wh; /* window area */
|
||||
int gappih; /* horizontal gap between windows */
|
||||
int gappiv; /* vertical gap between windows */
|
||||
int gappoh; /* horizontal outer gaps */
|
||||
int gappov; /* vertical outer gaps */
|
||||
unsigned int seltags;
|
||||
unsigned int sellt;
|
||||
unsigned int tagset[2];
|
||||
|
@ -130,6 +136,7 @@ struct Monitor {
|
|||
Monitor *next;
|
||||
Window barwin;
|
||||
const Layout *lt[2];
|
||||
Pertag *pertag;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -141,12 +148,26 @@ typedef struct {
|
|||
int monitor;
|
||||
} Rule;
|
||||
|
||||
/* Xresources preferences */
|
||||
enum resource_type {
|
||||
STRING = 0,
|
||||
INTEGER = 1,
|
||||
FLOAT = 2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
enum resource_type type;
|
||||
void *dst;
|
||||
} ResourcePref;
|
||||
|
||||
/* function declarations */
|
||||
static void applyrules(Client *c);
|
||||
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||
static void arrange(Monitor *m);
|
||||
static void arrangemon(Monitor *m);
|
||||
static void attach(Client *c);
|
||||
static void attachbottom(Client *c);
|
||||
static void attachstack(Client *c);
|
||||
static void buttonpress(XEvent *e);
|
||||
static void checkotherwm(void);
|
||||
|
@ -186,7 +207,10 @@ static void motionnotify(XEvent *e);
|
|||
static void movemouse(const Arg *arg);
|
||||
static Client *nexttiled(Client *c);
|
||||
static void pop(Client *c);
|
||||
static Client *prevtiled(Client *c);
|
||||
static void propertynotify(XEvent *e);
|
||||
static void pushdown(const Arg *arg);
|
||||
static void pushup(const Arg *arg);
|
||||
static void quit(const Arg *arg);
|
||||
static Monitor *recttomon(int x, int y, int w, int h);
|
||||
static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||
|
@ -200,6 +224,11 @@ static void sendmon(Client *c, Monitor *m);
|
|||
static void setclientstate(Client *c, long state);
|
||||
static void setfocus(Client *c);
|
||||
static void setfullscreen(Client *c, int fullscreen);
|
||||
static void setgaps(int oh, int ov, int ih, int iv);
|
||||
static void incrgaps(const Arg *arg);
|
||||
static void togglegaps(const Arg *arg);
|
||||
static void defaultgaps(const Arg *arg);
|
||||
static void setsticky(Client *c, int sticky);
|
||||
static void setlayout(const Arg *arg);
|
||||
static void setmfact(const Arg *arg);
|
||||
static void setup(void);
|
||||
|
@ -211,6 +240,8 @@ static void tagmon(const Arg *arg);
|
|||
static void tile(Monitor *m);
|
||||
static void togglebar(const Arg *arg);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscr(const Arg *arg);
|
||||
static void togglesticky(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
static void unfocus(Client *c, int setfocus);
|
||||
|
@ -233,6 +264,8 @@ static int xerror(Display *dpy, XErrorEvent *ee);
|
|||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
static void zoom(const Arg *arg);
|
||||
static void load_xresources(void);
|
||||
static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
|
@ -240,6 +273,7 @@ static char stext[256];
|
|||
static int screen;
|
||||
static int sw, sh; /* X display screen geometry width, height */
|
||||
static int bh; /* bar height */
|
||||
static int enablegaps = 1; /* enables gaps, used by togglegaps */
|
||||
static int lrpad; /* sum of left and right padding for text */
|
||||
static int (*xerrorxlib)(Display *, XErrorEvent *);
|
||||
static unsigned int numlockmask = 0;
|
||||
|
@ -271,6 +305,14 @@ static Window root, wmcheckwin;
|
|||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
struct Pertag {
|
||||
unsigned int curtag, prevtag; /* current and previous tag */
|
||||
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
||||
unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
|
||||
const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
|
||||
};
|
||||
|
||||
/* compile-time check if all tags fit into an unsigned int bit array. */
|
||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||
|
||||
|
@ -408,6 +450,15 @@ attach(Client *c)
|
|||
c->mon->clients = c;
|
||||
}
|
||||
|
||||
void
|
||||
attachbottom(Client *c)
|
||||
{
|
||||
Client **tc;
|
||||
c->next = NULL;
|
||||
for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
|
||||
*tc = c;
|
||||
}
|
||||
|
||||
void
|
||||
attachstack(Client *c)
|
||||
{
|
||||
|
@ -433,9 +484,15 @@ buttonpress(XEvent *e)
|
|||
}
|
||||
if (ev->window == selmon->barwin) {
|
||||
i = x = 0;
|
||||
do
|
||||
unsigned int occ = 0;
|
||||
for(c = m->clients; c; c=c->next)
|
||||
occ |= c->tags == TAGMASK ? 0 : c->tags;
|
||||
do {
|
||||
/* Do not reserve space for vacant tags */
|
||||
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||
continue;
|
||||
x += TEXTW(tags[i]);
|
||||
while (ev->x >= x && ++i < LENGTH(tags));
|
||||
} while (ev->x >= x && ++i < LENGTH(tags));
|
||||
if (i < LENGTH(tags)) {
|
||||
click = ClkTagBar;
|
||||
arg.ui = 1 << i;
|
||||
|
@ -525,6 +582,10 @@ clientmessage(XEvent *e)
|
|||
|| cme->data.l[2] == netatom[NetWMFullscreen])
|
||||
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|
||||
|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
|
||||
|
||||
if (cme->data.l[1] == netatom[NetWMSticky]
|
||||
|| cme->data.l[2] == netatom[NetWMSticky])
|
||||
setsticky(c, (cme->data.l[0] == 1 || (cme->data.l[0] == 2 && !c->issticky)));
|
||||
} else if (cme->message_type == netatom[NetActiveWindow]) {
|
||||
if (c != selmon->sel && !c->isurgent)
|
||||
seturgent(c, 1);
|
||||
|
@ -634,6 +695,7 @@ Monitor *
|
|||
createmon(void)
|
||||
{
|
||||
Monitor *m;
|
||||
int i;
|
||||
|
||||
m = ecalloc(1, sizeof(Monitor));
|
||||
m->tagset[0] = m->tagset[1] = 1;
|
||||
|
@ -641,9 +703,28 @@ createmon(void)
|
|||
m->nmaster = nmaster;
|
||||
m->showbar = showbar;
|
||||
m->topbar = topbar;
|
||||
m->gappih = gappih;
|
||||
m->gappiv = gappiv;
|
||||
m->gappoh = gappoh;
|
||||
m->gappov = gappov;
|
||||
m->lt[0] = &layouts[0];
|
||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||
if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
|
||||
die("fatal: could not malloc() %u bytes\n", sizeof(Pertag));
|
||||
m->pertag->curtag = m->pertag->prevtag = 1;
|
||||
for (i=0; i <= LENGTH(tags); i++) {
|
||||
/* init nmaster */
|
||||
m->pertag->nmasters[i] = m->nmaster;
|
||||
|
||||
/* init mfacts */
|
||||
m->pertag->mfacts[i] = m->mfact;
|
||||
|
||||
/* init layouts */
|
||||
m->pertag->ltidxs[i][0] = m->lt[0];
|
||||
m->pertag->ltidxs[i][1] = m->lt[1];
|
||||
m->pertag->sellts[i] = m->sellt;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -715,19 +796,18 @@ drawbar(Monitor *m)
|
|||
}
|
||||
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
occ |= c->tags;
|
||||
occ |= c->tags == TAGMASK ? 0 : c->tags;
|
||||
if (c->isurgent)
|
||||
urg |= c->tags;
|
||||
}
|
||||
x = 0;
|
||||
for (i = 0; i < LENGTH(tags); i++) {
|
||||
/* Do not draw vacant tags */
|
||||
if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||
continue;
|
||||
w = TEXTW(tags[i]);
|
||||
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
|
||||
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
|
||||
if (occ & 1 << i)
|
||||
drw_rect(drw, x + boxs, boxs, boxw, boxw,
|
||||
m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
|
||||
urg & 1 << i);
|
||||
x += w;
|
||||
}
|
||||
w = TEXTW(m->ltsymbol);
|
||||
|
@ -980,7 +1060,7 @@ grabkeys(void)
|
|||
void
|
||||
incnmaster(const Arg *arg)
|
||||
{
|
||||
selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
||||
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
|
@ -1068,13 +1148,15 @@ manage(Window w, XWindowAttributes *wa)
|
|||
updatewindowtype(c);
|
||||
updatesizehints(c);
|
||||
updatewmhints(c);
|
||||
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
||||
c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||
grabbuttons(c, 0);
|
||||
if (!c->isfloating)
|
||||
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
||||
if (c->isfloating)
|
||||
XRaiseWindow(dpy, c->win);
|
||||
attach(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||
(unsigned char *) &(c->win), 1);
|
||||
|
@ -1113,16 +1195,49 @@ maprequest(XEvent *e)
|
|||
void
|
||||
monocle(Monitor *m)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
unsigned int n = 0, oe = enablegaps;
|
||||
Client *c;
|
||||
|
||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if (smartgaps == n) {
|
||||
oe = 0; // outer gaps disabled
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
for (c = m->clients; c; c = c->next)
|
||||
if (ISVISIBLE(c))
|
||||
n++;
|
||||
|
||||
if (n > 0) /* override layout symbol */
|
||||
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
||||
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
||||
|
||||
int newx, newy, neww, newh;
|
||||
for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||
if (m->gappoh == 0) {
|
||||
newx = m->wx - c->bw;
|
||||
newy = m->wy - c->bw;
|
||||
neww = m->ww;
|
||||
newh = m->wh;
|
||||
} else {
|
||||
newx = m->wx + m->gappoh*oe - c->bw;
|
||||
newy = m->wy + m->gappoh*oe - c->bw;
|
||||
neww = m->ww - 2 * (m->gappoh*oe + c->bw);
|
||||
newh = m->wh - 2 * (m->gappoh*oe + c->bw);
|
||||
}
|
||||
applysizehints(c, &newx, &newy, &neww, &newh, 0);
|
||||
if (neww < m->ww) {
|
||||
newx = m->wx + (m->ww - (neww + 2 * c->bw)) / 2;
|
||||
}
|
||||
if (newh < m->wh) {
|
||||
newy = m->wy + (m->wh - (newh + 2 * c->bw)) / 2;
|
||||
resize(c, newx, newy, neww, newh, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1149,7 +1264,6 @@ movemouse(const Arg *arg)
|
|||
Client *c;
|
||||
Monitor *m;
|
||||
XEvent ev;
|
||||
Time lasttime = 0;
|
||||
|
||||
if (!(c = selmon->sel))
|
||||
return;
|
||||
|
@ -1172,10 +1286,6 @@ movemouse(const Arg *arg)
|
|||
handler[ev.type](&ev);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if ((ev.xmotion.time - lasttime) <= (1000 / 60))
|
||||
continue;
|
||||
lasttime = ev.xmotion.time;
|
||||
|
||||
nx = ocx + (ev.xmotion.x - x);
|
||||
ny = ocy + (ev.xmotion.y - y);
|
||||
if (abs(selmon->wx - nx) < snap)
|
||||
|
@ -1218,6 +1328,16 @@ pop(Client *c)
|
|||
arrange(c->mon);
|
||||
}
|
||||
|
||||
Client *
|
||||
prevtiled(Client *c) {
|
||||
Client *p, *r;
|
||||
|
||||
for(p = selmon->clients, r = NULL; p && p != c; p = p->next)
|
||||
if(!p->isfloating && ISVISIBLE(p))
|
||||
r = p;
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
propertynotify(XEvent *e)
|
||||
{
|
||||
|
@ -1255,6 +1375,49 @@ propertynotify(XEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
pushdown(const Arg *arg) {
|
||||
Client *sel = selmon->sel, *c;
|
||||
|
||||
if(!sel || sel->isfloating)
|
||||
return;
|
||||
if((c = nexttiled(sel->next))) {
|
||||
detach(sel);
|
||||
sel->next = c->next;
|
||||
c->next = sel;
|
||||
} else {
|
||||
detach(sel);
|
||||
attach(sel);
|
||||
}
|
||||
focus(sel);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
pushup(const Arg *arg) {
|
||||
Client *sel = selmon->sel, *c;
|
||||
|
||||
if(!sel || sel->isfloating)
|
||||
return;
|
||||
if((c = prevtiled(sel))) {
|
||||
detach(sel);
|
||||
sel->next = c;
|
||||
if(selmon->clients == c)
|
||||
selmon->clients = sel;
|
||||
else {
|
||||
for(c = selmon->clients; c->next != sel->next; c = c->next);
|
||||
c->next = sel;
|
||||
}
|
||||
} else {
|
||||
for(c = sel; c->next; c = c->next);
|
||||
detach(sel);
|
||||
sel->next = NULL;
|
||||
c->next = sel;
|
||||
}
|
||||
focus(sel);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
quit(const Arg *arg)
|
||||
{
|
||||
|
@ -1300,23 +1463,23 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
|||
void
|
||||
resizemouse(const Arg *arg)
|
||||
{
|
||||
int ocx, ocy, nw, nh;
|
||||
int x, y, ocw, och, nw, nh;
|
||||
Client *c;
|
||||
Monitor *m;
|
||||
XEvent ev;
|
||||
Time lasttime = 0;
|
||||
|
||||
if (!(c = selmon->sel))
|
||||
return;
|
||||
if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
|
||||
return;
|
||||
restack(selmon);
|
||||
ocx = c->x;
|
||||
ocy = c->y;
|
||||
ocw = c->w;
|
||||
och = c->h;
|
||||
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
|
||||
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
|
||||
return;
|
||||
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
|
||||
if(!getrootptr(&x, &y))
|
||||
return;
|
||||
do {
|
||||
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
|
||||
switch(ev.type) {
|
||||
|
@ -1326,12 +1489,8 @@ resizemouse(const Arg *arg)
|
|||
handler[ev.type](&ev);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if ((ev.xmotion.time - lasttime) <= (1000 / 60))
|
||||
continue;
|
||||
lasttime = ev.xmotion.time;
|
||||
|
||||
nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
|
||||
nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
|
||||
nw = MAX(ocw + (ev.xmotion.x - x), 1);
|
||||
nh = MAX(och + (ev.xmotion.y - y), 1);
|
||||
if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
|
||||
&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
|
||||
{
|
||||
|
@ -1344,7 +1503,6 @@ resizemouse(const Arg *arg)
|
|||
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);
|
||||
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
|
||||
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
|
||||
|
@ -1354,6 +1512,45 @@ resizemouse(const Arg *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
setgaps(int oh, int ov, int ih, int iv)
|
||||
{
|
||||
if (oh < 0) oh = 0;
|
||||
if (ov < 0) ov = 0;
|
||||
if (ih < 0) ih = 0;
|
||||
if (iv < 0) iv = 0;
|
||||
|
||||
selmon->gappoh = oh;
|
||||
selmon->gappov = ov;
|
||||
selmon->gappih = ih;
|
||||
selmon->gappiv = iv;
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
togglegaps(const Arg *arg)
|
||||
{
|
||||
enablegaps = !enablegaps;
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
defaultgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(gappoh, gappov, gappih, gappiv);
|
||||
}
|
||||
|
||||
void
|
||||
incrgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh + arg->i,
|
||||
selmon->gappov + arg->i,
|
||||
selmon->gappih + arg->i,
|
||||
selmon->gappiv + arg->i
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
restack(Monitor *m)
|
||||
{
|
||||
|
@ -1427,7 +1624,7 @@ sendmon(Client *c, Monitor *m)
|
|||
detachstack(c);
|
||||
c->mon = m;
|
||||
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||
attach(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
focus(NULL);
|
||||
arrange(NULL);
|
||||
|
@ -1507,13 +1704,33 @@ setfullscreen(Client *c, int fullscreen)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
setsticky(Client *c, int sticky)
|
||||
{
|
||||
|
||||
if(sticky && !c->issticky) {
|
||||
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char *) &netatom[NetWMSticky], 1);
|
||||
c->issticky = 1;
|
||||
} else if(!sticky && c->issticky){
|
||||
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char *)0, 0);
|
||||
c->issticky = 0;
|
||||
arrange(c->mon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setlayout(const Arg *arg)
|
||||
{
|
||||
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||
selmon->sellt ^= 1;
|
||||
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
|
||||
selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
|
||||
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||
}
|
||||
if (arg && arg->v)
|
||||
selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
||||
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
|
||||
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
|
||||
if (selmon->sel)
|
||||
arrange(selmon);
|
||||
|
@ -1532,7 +1749,7 @@ setmfact(const Arg *arg)
|
|||
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
||||
if (f < 0.05 || f > 0.95)
|
||||
return;
|
||||
selmon->mfact = f;
|
||||
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
|
@ -1576,6 +1793,7 @@ setup(void)
|
|||
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
|
||||
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
netatom[NetWMSticky] = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
|
||||
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
||||
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
||||
|
@ -1687,28 +1905,34 @@ tagmon(const Arg *arg)
|
|||
void
|
||||
tile(Monitor *m)
|
||||
{
|
||||
unsigned int i, n, h, mw, my, ty;
|
||||
unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty;
|
||||
Client *c;
|
||||
|
||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if (smartgaps == n) {
|
||||
oe = 0; // outer gaps disabled
|
||||
}
|
||||
|
||||
if (n > m->nmaster)
|
||||
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||
mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0;
|
||||
else
|
||||
mw = m->ww;
|
||||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||
mw = m->ww - 2*m->gappov*oe + m->gappiv*ie;
|
||||
for (i = 0, my = ty = m->gappoh*oe, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||
if (i < m->nmaster) {
|
||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
if (my + HEIGHT(c) < m->wh)
|
||||
my += HEIGHT(c);
|
||||
r = MIN(n, m->nmaster) - i;
|
||||
h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
|
||||
resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0);
|
||||
if (my + HEIGHT(c) + m->gappih*ie < m->wh)
|
||||
my += HEIGHT(c) + m->gappih*ie;
|
||||
} else {
|
||||
h = (m->wh - ty) / (n - i);
|
||||
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
if (ty + HEIGHT(c) < m->wh)
|
||||
ty += HEIGHT(c);
|
||||
r = n - i;
|
||||
h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
|
||||
resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0);
|
||||
if (ty + HEIGHT(c) + m->gappih*ie < m->wh)
|
||||
ty += HEIGHT(c) + m->gappih*ie;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1735,6 +1959,22 @@ togglefloating(const Arg *arg)
|
|||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
togglefullscr(const Arg *arg)
|
||||
{
|
||||
if(selmon->sel)
|
||||
setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
|
||||
}
|
||||
|
||||
void
|
||||
togglesticky(const Arg *arg)
|
||||
{
|
||||
if (!selmon->sel)
|
||||
return;
|
||||
setsticky(selmon->sel, !selmon->sel->issticky);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
toggletag(const Arg *arg)
|
||||
{
|
||||
|
@ -1754,9 +1994,27 @@ void
|
|||
toggleview(const Arg *arg)
|
||||
{
|
||||
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
|
||||
int i;
|
||||
|
||||
if (newtagset) {
|
||||
if (newtagset == ~0) {
|
||||
selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||
selmon->pertag->curtag = 0;
|
||||
}
|
||||
/* test if the user did not select the same tag */
|
||||
if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
|
||||
selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||
for (i=0; !(newtagset & 1 << i); i++) ;
|
||||
selmon->pertag->curtag = i + 1;
|
||||
}
|
||||
selmon->tagset[selmon->seltags] = newtagset;
|
||||
|
||||
/* apply settings for this view */
|
||||
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||
selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||
focus(NULL);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
@ -1915,7 +2173,7 @@ updategeom(void)
|
|||
m->clients = c->next;
|
||||
detachstack(c);
|
||||
c->mon = mons;
|
||||
attach(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
}
|
||||
if (m == selmon)
|
||||
|
@ -2027,6 +2285,9 @@ updatewindowtype(Client *c)
|
|||
|
||||
if (state == netatom[NetWMFullscreen])
|
||||
setfullscreen(c, 1);
|
||||
if (state == netatom[NetWMSticky]) {
|
||||
setsticky(c, 1);
|
||||
}
|
||||
if (wtype == netatom[NetWMWindowTypeDialog])
|
||||
c->isfloating = 1;
|
||||
}
|
||||
|
@ -2053,11 +2314,31 @@ updatewmhints(Client *c)
|
|||
void
|
||||
view(const Arg *arg)
|
||||
{
|
||||
int i;
|
||||
unsigned int tmptag;
|
||||
|
||||
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||
return;
|
||||
selmon->seltags ^= 1; /* toggle sel tagset */
|
||||
if (arg->ui & TAGMASK)
|
||||
if (arg->ui & TAGMASK) {
|
||||
selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||
if (arg->ui == ~0)
|
||||
selmon->pertag->curtag = 0;
|
||||
else {
|
||||
for (i=0; !(arg->ui & 1 << i); i++) ;
|
||||
selmon->pertag->curtag = i + 1;
|
||||
}
|
||||
} else {
|
||||
tmptag = selmon->pertag->prevtag;
|
||||
selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||
selmon->pertag->curtag = tmptag;
|
||||
}
|
||||
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||
selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||
focus(NULL);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
@ -2140,6 +2421,60 @@ zoom(const Arg *arg)
|
|||
pop(c);
|
||||
}
|
||||
|
||||
void
|
||||
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||
{
|
||||
char *sdst = NULL;
|
||||
int *idst = NULL;
|
||||
float *fdst = NULL;
|
||||
|
||||
sdst = dst;
|
||||
idst = dst;
|
||||
fdst = dst;
|
||||
|
||||
char fullname[256];
|
||||
char *type;
|
||||
XrmValue ret;
|
||||
|
||||
snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
|
||||
fullname[sizeof(fullname) - 1] = '\0';
|
||||
|
||||
XrmGetResource(db, fullname, "*", &type, &ret);
|
||||
if (!(ret.addr == NULL || strncmp("String", type, 64)))
|
||||
{
|
||||
switch (rtype) {
|
||||
case STRING:
|
||||
strcpy(sdst, ret.addr);
|
||||
break;
|
||||
case INTEGER:
|
||||
*idst = strtoul(ret.addr, NULL, 10);
|
||||
break;
|
||||
case FLOAT:
|
||||
*fdst = strtof(ret.addr, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_xresources(void)
|
||||
{
|
||||
Display *display;
|
||||
char *resm;
|
||||
XrmDatabase db;
|
||||
ResourcePref *p;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
resm = XResourceManagerString(display);
|
||||
if (!resm)
|
||||
return;
|
||||
|
||||
db = XrmGetStringDatabase(resm);
|
||||
for (p = resources; p < resources + LENGTH(resources); p++)
|
||||
resource_load(db, p->name, p->type, p->dst);
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -2152,6 +2487,8 @@ main(int argc, char *argv[])
|
|||
if (!(dpy = XOpenDisplay(NULL)))
|
||||
die("dwm: cannot open display");
|
||||
checkotherwm();
|
||||
XrmInitialize();
|
||||
load_xresources();
|
||||
setup();
|
||||
#ifdef __OpenBSD__
|
||||
if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||
|
@ -2163,3 +2500,4 @@ main(int argc, char *argv[])
|
|||
XCloseDisplay(dpy);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
19
shiftview.c
Normal file
19
shiftview.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/** Function to shift the current view to the left/right
|
||||
*
|
||||
* @param: "arg->i" stores the number of tags to shift right (positive value)
|
||||
* or left (negative value)
|
||||
*/
|
||||
void
|
||||
shiftview(const Arg *arg) {
|
||||
Arg shifted;
|
||||
|
||||
if(arg->i > 0) // left circular shift
|
||||
shifted.ui = (selmon->tagset[selmon->seltags] << arg->i)
|
||||
| (selmon->tagset[selmon->seltags] >> (LENGTH(tags) - arg->i));
|
||||
|
||||
else // right circular shift
|
||||
shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i)
|
||||
| selmon->tagset[selmon->seltags] << (LENGTH(tags) + arg->i);
|
||||
|
||||
view(&shifted);
|
||||
}
|
Loading…
Reference in a new issue