diff --git a/config.def.h b/config.def.h index 5366cca..3c730da 100644 --- a/config.def.h +++ b/config.def.h @@ -31,12 +31,14 @@ static const Rule rules[] = { * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title */ - /* class instance title tags mask isfloating isterminal noswallow nofakefullscreen monitor */ - //{ "Gimp", NULL, NULL, 0, 0, 0, 0, 0, -1 }, - //{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, 0, -1 }, - { "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, -1 }, - { "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, -1 }, - { NULL, NULL, "noswallow", 0, 0, 0, 1, 0, -1 } + /* class instance title tags mask isfloating isterminal noswallow nofakefullscreen iskeyboard monitor */ + //{ "Gimp", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 }, + //{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, 0, 0, -1 }, + { "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 }, + { "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 }, + { NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 }, + { "Onboard", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 }, + { "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 } }; diff --git a/dwm.c b/dwm.c index 673f284..14a1be2 100644 --- a/dwm.c +++ b/dwm.c @@ -51,7 +51,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->iskeyboard)) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx) @@ -94,7 +94,7 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, nofakefullscreen; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, nofakefullscreen, iskeyboard; pid_t pid; Client *next; Client *snext; @@ -145,6 +145,7 @@ typedef struct { int isterminal; int noswallow; int nofakefullscreen; + int iskeyboard; int monitor; } Rule; @@ -244,6 +245,7 @@ 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 adjustborders(Monitor *m); static pid_t getparentprocess(pid_t p); static int isdescprocess(pid_t p, pid_t c); @@ -321,6 +323,7 @@ applyrules(Client *c) c->noswallow = r->noswallow; c->isfloating = r->isfloating; c->nofakefullscreen = r->nofakefullscreen; + c->iskeyboard = r->iskeyboard; c->tags |= r->tags; for (m = mons; m && m->num != r->monitor; m = m->next); if (m) @@ -340,6 +343,10 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) int baseismin; Monitor *m = c->mon; + if (c->iskeyboard){ + return(False); + } + /* set minimum possible */ *w = MAX(1, *w); *h = MAX(1, *h); @@ -401,12 +408,14 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) } void -arrange(Monitor *m) -{ - if (m) +arrange(Monitor *m) { + if (m){ + adjustborders(m); showhide(m->stack); - else for (m = mons; m; m = m->next) + } else for (m = mons; m; m = m->next){ + adjustborders(m); showhide(m->stack); + } if (m) { arrangemon(m); restack(m); @@ -459,7 +468,7 @@ attachstack(Client *c) void swallow(Client *p, Client *c) { - if (c->noswallow || c->isterminal) + if (c->noswallow || c->isterminal || c->isfloating) return; detach(c); @@ -498,8 +507,7 @@ unswallow(Client *c) } void -buttonpress(XEvent *e) -{ +buttonpress(XEvent *e) { unsigned int i, x, click; Arg arg = {0}; Client *c; @@ -540,8 +548,7 @@ buttonpress(XEvent *e) } void -checkotherwm(void) -{ +checkotherwm(void) { xerrorxlib = XSetErrorHandler(xerrorstart); /* this causes an error if some other window manager is running */ XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); @@ -551,8 +558,7 @@ checkotherwm(void) } void -cleanup(void) -{ +cleanup(void) { Arg a = {.ui = ~0}; Layout foo = { "", NULL }; Monitor *m; @@ -578,8 +584,7 @@ cleanup(void) } void -cleanupmon(Monitor *mon) -{ +cleanupmon(Monitor *mon) { Monitor *m; if (mon == mons) @@ -613,8 +618,7 @@ clientmessage(XEvent *e) } void -configure(Client *c) -{ +configure(Client *c) { XConfigureEvent ce; ce.type = ConfigureNotify; @@ -632,8 +636,7 @@ configure(Client *c) } void -configurenotify(XEvent *e) -{ +configurenotify(XEvent *e) { Monitor *m; XConfigureEvent *ev = &e->xconfigure; int dirty; @@ -656,14 +659,13 @@ configurenotify(XEvent *e) } void -configurerequest(XEvent *e) -{ +configurerequest(XEvent *e) { Client *c; Monitor *m; XConfigureRequestEvent *ev = &e->xconfigurerequest; XWindowChanges wc; - if ((c = wintoclient(ev->window))) { + if ((c = wintoclient(ev->window)) && !c->iskeyboard) { if (ev->value_mask & CWBorderWidth) c->bw = ev->border_width; else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { @@ -708,8 +710,7 @@ configurerequest(XEvent *e) } Monitor * -createmon(void) -{ +createmon(void) { Monitor *m; m = ecalloc(1, sizeof(Monitor)); @@ -725,8 +726,7 @@ createmon(void) } void -destroynotify(XEvent *e) -{ +destroynotify(XEvent *e) { Client *c; XDestroyWindowEvent *ev = &e->xdestroywindow; @@ -738,8 +738,7 @@ destroynotify(XEvent *e) } void -detach(Client *c) -{ +detach(Client *c) { Client **tc; for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); @@ -747,8 +746,7 @@ detach(Client *c) } void -detachstack(Client *c) -{ +detachstack(Client *c) { Client **tc, *t; for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); @@ -761,8 +759,7 @@ detachstack(Client *c) } Monitor * -dirtomon(int dir) -{ +dirtomon(int dir) { Monitor *m = NULL; if (dir > 0) { @@ -775,8 +772,7 @@ dirtomon(int dir) return m; } -void -drawbar(Monitor *m) +void drawbar(Monitor *m) { int x, w, tw = 0; int boxs = drw->fonts->h / 9; @@ -844,6 +840,11 @@ enternotify(XEvent *e) if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; c = wintoclient(ev->window); + + if ( c && c->iskeyboard ){ + return; + } + m = c ? c->mon : wintomon(ev->window); if (m != selmon) { unfocus(selmon->sel, 1); @@ -854,8 +855,7 @@ enternotify(XEvent *e) } void -expose(XEvent *e) -{ +expose(XEvent *e) { Monitor *m; XExposeEvent *ev = &e->xexpose; @@ -864,8 +864,10 @@ expose(XEvent *e) } void -focus(Client *c) -{ +focus(Client *c) { + if ( c && c->iskeyboard ) { + return; + } if (!c || !ISVISIBLE(c)) for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); if (selmon->sel && selmon->sel != c) @@ -899,8 +901,7 @@ focusin(XEvent *e) } void -focusmon(const Arg *arg) -{ +focusmon(const Arg *arg) { Monitor *m; if (!mons->next) @@ -914,23 +915,23 @@ focusmon(const Arg *arg) } void -focusstack(const Arg *arg) -{ +focusstack(const Arg *arg) { Client *c = NULL, *i; if (!selmon->sel) return; if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->iskeyboard); c = c->next); if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { + for(c = selmon->clients; c && (!ISVISIBLE(c) || c->iskeyboard); c = c->next); + } + else { for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) + if(ISVISIBLE(i) && !i->iskeyboard) c = i; if (!c) for (; i; i = i->next) - if (ISVISIBLE(i)) + if(ISVISIBLE(i) && !i->iskeyboard) c = i; } if (c) { @@ -940,8 +941,7 @@ focusstack(const Arg *arg) } Atom -getatomprop(Client *c, Atom prop) -{ +getatomprop(Client *c, Atom prop) { int di; unsigned long dl; unsigned char *p = NULL; @@ -956,8 +956,7 @@ getatomprop(Client *c, Atom prop) } int -getrootptr(int *x, int *y) -{ +getrootptr(int *x, int *y) { int di; unsigned int dui; Window dummy; @@ -966,8 +965,7 @@ getrootptr(int *x, int *y) } long -getstate(Window w) -{ +getstate(Window w) { int format; long result = -1; unsigned char *p = NULL; @@ -1030,8 +1028,7 @@ grabbuttons(Client *c, int focused) } void -grabkeys(void) -{ +grabkeys(void) { updatenumlockmask(); { unsigned int i, j; @@ -1048,8 +1045,7 @@ grabkeys(void) } void -incnmaster(const Arg *arg) -{ +incnmaster(const Arg *arg) { selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); arrange(selmon); } @@ -1067,8 +1063,7 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) #endif /* XINERAMA */ void -keypress(XEvent *e) -{ +keypress(XEvent *e) { unsigned int i; KeySym keysym; XKeyEvent *ev; @@ -1099,8 +1094,7 @@ killclient(const Arg *arg) } void -manage(Window w, XWindowAttributes *wa) -{ +manage(Window w, XWindowAttributes *wa) { Client *c, *t = NULL, *term = NULL; Window trans = None; XWindowChanges wc; @@ -1108,13 +1102,6 @@ manage(Window w, XWindowAttributes *wa) c = ecalloc(1, sizeof(Client)); c->win = w; c->pid = winpid(w); - /* geometry */ - c->x = c->oldx = wa->x; - c->y = c->oldy = wa->y; - c->w = c->oldw = wa->width; - c->h = c->oldh = wa->height; - c->oldbw = wa->border_width; - updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { c->mon = t->mon; @@ -1125,15 +1112,43 @@ manage(Window w, XWindowAttributes *wa) term = termforwin(c); } - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + + + /* If Keyboard */ + + if (c->iskeyboard) { + c->y = c->mon->my + c->mon->mh - c->h; + c->mon->mh -= HEIGHT(c); + } else { + if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) + c->x = c->mon->mx + c->mon->mw - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) + c->y = c->mon->my + c->mon->mh - HEIGHT(c); + c->x = MAX(c->x, c->mon->mx); + /* only fix client y-offset, if the client center might cover the bar */ + c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + } + + updatewindowtype(c); + if (c->isfloating) { + c->bw = (c->isfullscreen || c->iskeyboard) ? 0 : borderpx; + } else { + c->bw = 0; + for(t = c->mon->clients; t; t = c->next) { + if (!t->isfloating && c != t && c->tags & t->tags) { + c->bw = borderpx; + break; + } + } + adjustborders(c->mon); + } wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc); @@ -1224,8 +1239,7 @@ motionnotify(XEvent *e) } void -movemouse(const Arg *arg) -{ +movemouse(const Arg *arg) { int x, y, ocx, ocy, nx, ny; Client *c; Monitor *m; @@ -1282,15 +1296,13 @@ movemouse(const Arg *arg) } Client * -nexttiled(Client *c) -{ +nexttiled(Client *c) { for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); return c; } void -pop(Client *c) -{ +pop(Client *c) { detach(c); attach(c); focus(c); @@ -1298,8 +1310,7 @@ pop(Client *c) } void -propertynotify(XEvent *e) -{ +propertynotify(XEvent *e) { Client *c; Window trans; XPropertyEvent *ev = &e->xproperty; @@ -1355,15 +1366,67 @@ recttomon(int x, int y, int w, int h) } void -resize(Client *c, int x, int y, int w, int h, int interact) -{ +adjustborders(Monitor *m) { + Client *c, *l = NULL; + int visible = 0; + + for(c = m->clients; c; c = c->next) { + if (ISVISIBLE(c) && !c->isfloating && m->lt[m->sellt]->arrange) { + if (m->lt[m->sellt]->arrange == monocle) { + visible = 1; + c->oldbw = c->bw; + c->bw = 0; + } else { + visible++; + c->oldbw = c->bw; + c->bw = borderpx; + } + + l = c; + } + } + + if (l && visible == 1 && l->bw) { + l->oldbw = l->bw; + l->bw = 0; + resizeclient(l, l->x, l->y, l->w, l->h); + } +} + +void +resize(Client *c, int x, int y, int w, int h, int interact) { + int n; + + if (c && c->iskeyboard) { + return; + } + + n = c->mon->mx + c->mon->mw; + if (x + w + 1 + (2 * c->bw) >= n) { + w = n - x - c->bw; + } + + n = c->mon->my + c->mon->mh; + if (y + h + 1 + (2 * c->bw) >= n) { + h = n - y - c->bw; + } + + if (x <= c->mon->mx) { + x -= c->bw; + w += c->bw; + } + + if (y <= c->mon->my) { + y -= c->bw; + y += c->bw; + } + if (applysizehints(c, &x, &y, &w, &h, interact)) resizeclient(c, x, y, w, h); } void -resizeclient(Client *c, int x, int y, int w, int h) -{ +resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; unsigned int n; unsigned int gapoffset; @@ -1372,6 +1435,10 @@ resizeclient(Client *c, int x, int y, int w, int h) wc.border_width = c->bw; + if (c->iskeyboard) { + return; + } + /* Get number of clients for the selected monitor */ for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++); @@ -1867,6 +1934,10 @@ unmanage(Client *c, int destroyed) Monitor *m = c->mon; XWindowChanges wc; + if (c->iskeyboard) { + updategeom(); + } + if (c->swallowing) { unswallow(c); return;