summaryrefslogtreecommitdiff
path: root/dwm/dwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'dwm/dwm.c')
-rw-r--r--dwm/dwm.c210
1 files changed, 204 insertions, 6 deletions
diff --git a/dwm/dwm.c b/dwm/dwm.c
index f265f18..6c6b979 100644
--- a/dwm/dwm.c
+++ b/dwm/dwm.c
@@ -141,6 +141,13 @@ typedef union
typedef struct
{
+ char *gname;
+ void (*func)(const Arg *arg);
+ const Arg arg;
+} Gesture;
+
+typedef struct
+{
unsigned int click;
unsigned int mask;
unsigned int button;
@@ -169,7 +176,7 @@ struct Client
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
int bw, oldbw;
unsigned int tags;
- int wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky;
+ int allowkill, wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky;
unsigned char expandmask;
int expandx1, expandy1, expandx2, expandy2;
pid_t pid;
@@ -230,6 +237,7 @@ typedef struct
const char *instance;
const char *title;
unsigned int tags;
+ int allowkill;
int isfloating;
int isterminal;
int noswallow;
@@ -298,6 +306,7 @@ static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void motionnotify(XEvent *e);
+static void gesture(const Arg *arg);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
static void pop(Client *c);
@@ -321,6 +330,7 @@ static void setfullscreen(Client *c, int fullscreen);
static void setinsertmode(void);
static void setkeymode(const Arg *arg);
static void setlayout(const Arg *arg);
+static void setmark(Client *c);
static void setcfact(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
@@ -334,12 +344,17 @@ static void sigdwmblocks(const Arg *arg);
static void sighup(int unused);
static void sigterm(int unused);
static void spawn(const Arg *arg);
+static void swapclient(const Arg *arg);
+static void swapfocus(const Arg *arg);
static int stackpos(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
+static void spawntag(const Arg *arg);
static void togglebar(const Arg *arg);
static void toggleborder(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void toggleallowkill(const Arg *arg);
+static void togglemark(const Arg *arg);
static void togglescratch(const Arg *arg);
static void togglesticky(const Arg *arg);
static void togglefullscr(const Arg *arg);
@@ -417,6 +432,7 @@ static Drw *drw;
static KeySym cmdkeysym[4];
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
+static Client *mark;
static int useargb = 0;
static Visual *visual;
@@ -456,6 +472,7 @@ applyrules(Client *c)
/* rule matching */
c->isfloating = 0;
c->tags = 0;
+ c->allowkill = allowkill;
XGetClassHint(dpy, c->win, &ch);
class = ch.res_class ? ch.res_class : broken;
instance = ch.res_name ? ch.res_name : broken;
@@ -471,6 +488,7 @@ applyrules(Client *c)
c->isfloating = r->isfloating;
c->noswallow = r->noswallow;
c->tags |= r->tags;
+ c->allowkill = r->allowkill;
if ((r->tags & SPTAGMASK) && r->isfloating)
{
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
@@ -1182,7 +1200,10 @@ focus(Client *c)
detachstack(c);
attachstack(c);
grabbuttons(c, 1);
- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+ if (c == mark)
+ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColMark].pixel);
+ else
+ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
setfocus(c);
}
else
@@ -1472,7 +1493,7 @@ killclient(const Arg *arg)
{
Client *c;
- if (!selmon->sel)
+ if (!selmon->sel || !selmon->sel->allowkill)
return;
if (!arg->ui || arg->ui == 0)
@@ -1545,7 +1566,10 @@ manage(Window w, XWindowAttributes *wa)
wc.border_width = c->bw;
XConfigureWindow(dpy, w, CWBorderWidth, &wc);
- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
+ if (c == mark)
+ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColMark].pixel);
+ else
+ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
configure(c); /* propagates border_width, if size doesn't change */
updatewindowtype(c);
updatesizehints(c);
@@ -1667,6 +1691,68 @@ motionnotify(XEvent *e)
}
void
+gesture(const Arg *arg) {
+ int x, y, dx, dy, q;
+ int valid=0, listpos=0, gestpos=0, count=0;
+ char move, currGest[10];
+ XEvent ev;
+
+ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
+ return;
+ if(!getrootptr(&x, &y))
+ return;
+ do {
+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+ switch (ev.type) {
+ case ConfigureRequest:
+ case Expose:
+ case MapRequest:
+ handler[ev.type](&ev);
+ break;
+ case MotionNotify:
+ if(count++ < 10)
+ break;
+ count = 0;
+ dx = ev.xmotion.x - x;
+ dy = ev.xmotion.y - y;
+ x = ev.xmotion.x;
+ y = ev.xmotion.y;
+
+ if( abs(dx)/(abs(dy)+1) == 0 )
+ move = dy<0?'u':'d';
+ else
+ move = dx<0?'l':'r';
+
+ if(move!=currGest[gestpos-1])
+ {
+ if(gestpos>9)
+ { ev.type++;
+ break;
+ }
+
+ currGest[gestpos] = move;
+ currGest[++gestpos] = '\0';
+
+ valid = 0;
+ for(q = 0; q<LENGTH(gestures); q++)
+ { if(!strcmp(currGest, gestures[q].gname))
+ { valid++;
+ listpos = q;
+ }
+ }
+ }
+
+ }
+ } while(ev.type != ButtonRelease);
+
+ if(valid)
+ gestures[listpos].func(&(gestures[listpos].arg));
+
+ XUngrabPointer(dpy, CurrentTime);
+}
+
+void
movemouse(const Arg *arg)
{
int x, y, ocx, ocy, nx, ny;
@@ -2210,6 +2296,24 @@ setcfact(const Arg *arg)
arrange(selmon);
}
+void
+setmark(Client *c)
+{
+ if (c == mark)
+ return;
+ if (mark) {
+ XSetWindowBorder(dpy, mark->win, scheme[mark == selmon->sel
+ ? SchemeSel : SchemeNorm][ColBorder].pixel);
+ mark = 0;
+ }
+ if (c) {
+ XSetWindowBorder(dpy, c->win, scheme[c == selmon->sel
+ ? SchemeSel : SchemeNorm][ColMark].pixel);
+ mark = c;
+ }
+}
+
+
/* arg > 1.0 will set mfact absolutely */
void
setmfact(const Arg *arg)
@@ -2277,7 +2381,7 @@ setup(void)
/* init appearance */
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
+ scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 4);
/* init bars */
updatebars();
updatestatus();
@@ -2414,6 +2518,74 @@ setclienttagprop(Client *c)
}
void
+swapclient(const Arg *arg)
+{
+ Client *s, *m, t;
+
+ if (!mark || !selmon->sel || mark == selmon->sel
+ || !selmon->lt[selmon->sellt]->arrange)
+ return;
+ s = selmon->sel;
+ m = mark;
+ t = *s;
+ strcpy(s->name, m->name);
+ s->win = m->win;
+ s->x = m->x;
+ s->y = m->y;
+ s->w = m->w;
+ s->h = m->h;
+
+ m->win = t.win;
+ strcpy(m->name, t.name);
+ m->x = t.x;
+ m->y = t.y;
+ m->w = t.w;
+ m->h = t.h;
+
+ selmon->sel = m;
+ mark = s;
+ focus(s);
+ setmark(m);
+
+ arrange(s->mon);
+ if (s->mon != m->mon) {
+ arrange(m->mon);
+ }
+}
+
+void
+swapfocus(const Arg *arg)
+{
+ Client *t;
+
+ if (!selmon->sel || !mark || selmon->sel == mark)
+ return;
+ t = selmon->sel;
+ if (mark->mon != selmon) {
+ unfocus(selmon->sel, 0);
+ selmon = mark->mon;
+ }
+ if (ISVISIBLE(mark)) {
+ focus(mark);
+ restack(selmon);
+ } else {
+ selmon->seltags ^= 1;
+ selmon->tagset[selmon->seltags] = mark->tags;
+ focus(mark);
+ arrange(selmon);
+ }
+ setmark(t);
+}
+
+void
+togglemark(const Arg *arg)
+{
+ if (!selmon->sel)
+ return;
+ setmark(selmon->sel == mark ? 0 : selmon->sel);
+}
+
+void
tag(const Arg *arg)
{
Client *c;
@@ -2428,6 +2600,19 @@ tag(const Arg *arg)
}
void
+spawntag(const Arg *arg)
+{
+ if (arg->ui & TAGMASK) {
+ for (int i = LENGTH(tags); i >= 0; i--) {
+ if (arg->ui & 1<<i) {
+ spawn(&tagexec[i]);
+ return;
+ }
+ }
+ }
+}
+
+void
tagmon(const Arg *arg)
{
if (!selmon->sel || !mons->next)
@@ -2463,6 +2648,13 @@ toggleborder(const Arg *arg)
}
void
+toggleallowkill(const Arg *arg)
+{
+ if (!selmon->sel) return;
+ selmon->sel->allowkill = !selmon->sel->allowkill;
+}
+
+void
togglefloating(const Arg *arg)
{
if (!selmon->sel)
@@ -2594,7 +2786,10 @@ unfocus(Client *c, int setfocus)
if (!c)
return;
grabbuttons(c, 0);
- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
+ if (c == mark)
+ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColMark].pixel);
+ else
+ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
if (setfocus)
{
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -2623,6 +2818,9 @@ unmanage(Client *c, int destroyed)
focus(NULL);
return;
}
+
+ if (c == mark)
+ setmark(0);
detach(c);
detachstack(c);