#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xproto.h>
NetWMWindowTypeDialog, NetClientList, NetSupportingWMCheck, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+ ClkClientWin, ClkRootWin, ClkAnywhere, ClkLast }; /* clicks */
typedef union {
int i;
static void setup(void);
static void showhide(Client *c);
static void sigchld(int unused);
+static void kbspawn(const Arg *arg);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void zoom(const Arg *arg);
/* variables */
+static Bool key_buffering = False;
static const char broken[] = "broken";
static char stext[256];
static int screen;
&& (!r->instance || strstr(instance, r->instance)))
{
c->isfloating = r->isfloating;
+ if(r->isfloating) {
+ c->x = -1; c->y = -2; // secret code for centered
+ }
c->tags |= r->tags;
c->screen_hog = r->screen_hog;
for(m = mons; m && m->num != r->monitor; m = m->next);
void
buttonpress(XEvent *e) {
- unsigned int i, x, click;
+ unsigned int i, click;
Arg arg = {0};
Client *c;
Monitor *m;
XButtonPressedEvent *ev = &e->xbutton;
+ Bool called = False;
+
+ for(i = 0; i < LENGTH(buttons); i++) {
+ if(buttons[i].click == ClkAnywhere && buttons[i].button == ev->button
+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
+ buttons[i].func(&buttons[i].arg);
+ called = True;
+ }
+ }
+ if (called) {
+ return;
+ }
click = ClkRootWin;
/* focus monitor if necessary */
focus(NULL);
}
if(ev->window == selmon->barwin) {
- i = x = 0;
- do
- x += TEXTW(tags[i]);
- while(ev->x >= x && ++i < LENGTH(tags));
- if(i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- }
- else if(ev->x < x + blw)
- click = ClkLtSymbol;
- else if(ev->x > selmon->ww - TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
- }
- else if((c = wintoclient(ev->window))) {
+ return;
+ } else if((c = wintoclient(ev->window))) {
focus(c);
click = ClkClientWin;
}
- for(i = 0; i < LENGTH(buttons); i++)
+ for(i = 0; i < LENGTH(buttons); i++) {
if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
+ if (click == ClkTagBar && buttons[i].arg.i == 0) {
+ buttons[i].func(&arg);
+ } else {
+ buttons[i].func(&buttons[i].arg);
+ }
+ }
+ }
}
void
for(i = nextvisible(c->mon->clients); i && i != c; i = nextvisible(i->next))
next_sel = i;
// failing that, find first visible window (besides c)
- if (!next_sel)
+ if (!next_sel) {
for(i = nextvisible(c->mon->clients); i && i == c; i = nextvisible(i->next));
if (i != c)
next_sel = i;
+ }
c->mon->sel = next_sel;
}
if (prev) {
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused) {
for(i = 0; i < LENGTH(buttons); i++)
- if(buttons[i].click == ClkClientWin)
+ if(buttons[i].click == ClkClientWin || buttons[i].click == ClkAnywhere)
for(j = 0; j < LENGTH(modifiers); j++)
XGrabButton(dpy, buttons[i].button,
buttons[i].mask | modifiers[j],
c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
- }
- else
+ } else {
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+ }
}
}
void
grabkeys(void) {
updatenumlockmask();
+ //XUngrabKey(dpy, AnyKey, AnyModifier, root);
{
unsigned int i, j;
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
if((code = XKeysymToKeycode(dpy, keys[i].keysym)))
for(j = 0; j < LENGTH(modifiers); j++)
XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
- True, GrabModeAsync, GrabModeAsync);
+ True, GrabModeAsync,
+ keys[i].func == kbspawn ? GrabModeSync : GrabModeAsync);
}
}
ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for(i = 0; i < LENGTH(keys); i++)
+ for(i = 0; i < LENGTH(keys); i++) {
if(keysym == keys[i].keysym
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keys[i].func)
+ && keys[i].func) {
keys[i].func(&(keys[i].arg));
+ }
+ }
}
void
applyrules(c);
}
/* geometry */
- c->x = c->oldx = wa->x;
- c->y = c->oldy = wa->y;
+ if(c->x == -1 && c->y == -2) { // secret code for centered
+ c->x = c->oldx = (c->mon->ww - wa->width) / 2;
+ c->y = c->oldy = (c->mon->wh - wa->height) / 2;
+ } else {
+ 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;
arrange(c->mon);
XMapWindow(dpy, c->win);
focus(c);
+ if(key_buffering) {
+ key_buffering = False;
+ XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
+ }
}
void
mappingnotify(XEvent *e) {
XMappingEvent *ev = &e->xmapping;
+ // fprintf(stderr, "MapNotify\n");
XRefreshKeyboardMapping(ev);
if(ev->request == MappingKeyboard)
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
+ // fprintf(stderr, "MapRequest\n");
if(!XGetWindowAttributes(dpy, ev->window, &wa))
return;
- if(wa.override_redirect)
+ if(wa.override_redirect) {
return;
+ }
if(!wintoclient(ev->window))
manage(ev->window, &wa);
}
XEvent ev;
/* main event loop */
XSync(dpy, False);
- while(running && !XNextEvent(dpy, &ev))
- if(handler[ev.type])
+ while(running && !XNextEvent(dpy, &ev)) {
+ if(handler[ev.type]) {
+ // fprintf(stderr, "handling event type %i\n", ev.type);
handler[ev.type](&ev); /* call handler */
+ } else {
+ // fprintf(stderr, "evt type %i\n", ev.type);
+ }
+ }
}
void
}
void
+kbspawn(const Arg *arg) {
+ key_buffering = True;
+ spawn(arg);
+}
+
+void
spawn(const Arg *arg) {
int tag = 0, i;
if(arg->v == termcmd) {