X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=dwm.c;h=b42fb73740754ac95d66430c02c78fb32ab9a551;hp=5e9b184d916bd9aedd9d45f145e2af7a6e66aab7;hb=5ce95a6e416345b2e6a5528d93700cb5de11a928;hpb=9e1b6ce2986e804caf74a728f70d35d6fa8f788d diff --git a/dwm.c b/dwm.c index 5e9b184..b42fb73 100644 --- a/dwm.c +++ b/dwm.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -200,6 +201,7 @@ static void restack(Monitor *m); static void run(void); static void scan(void); static Bool sendevent(Client *c, Atom proto); +static void send_keycode(KeyCode key, unsigned int state); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); @@ -209,6 +211,7 @@ static void setmfact(const Arg *arg); 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); @@ -240,6 +243,13 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee); static void zoom(const Arg *arg); /* variables */ +typedef struct { + KeyCode keycode; + unsigned int state; +} BufferedKey; +static BufferedKey key_buffer[200]; +static int key_buffer_len = 0; +static Bool key_buffering = False; static const char broken[] = "broken"; static char stext[256]; static int screen; @@ -358,6 +368,9 @@ applyrules(Client *c) { && (!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); @@ -482,7 +495,7 @@ attachstack(Client *c) { void buttonpress(XEvent *e) { - unsigned int i, x, click; + unsigned int i, click; Arg arg = {0}; Client *c; Monitor *m; @@ -496,20 +509,7 @@ buttonpress(XEvent *e) { 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; + return; } else if((c = wintoclient(ev->window))) { focus(c); @@ -752,10 +752,11 @@ detachstack(Client *c) { 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) { @@ -1045,18 +1046,8 @@ grabbuttons(Client *c, Bool focused) { void grabkeys(void) { updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) - 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); - } + //XUngrabKey(dpy, AnyKey, AnyModifier, root); + XGrabKey(dpy, AnyKey, AnyModifier, root, True, GrabModeAsync, GrabModeAsync); } void @@ -1077,18 +1068,60 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { #endif /* XINERAMA */ void +send_keycode(KeyCode key, unsigned int state) { + XKeyEvent event; + if(!selmon->sel) { + return; + } + event.display = dpy; + event.root = root; + event.window = selmon->sel->win; + event.subwindow = None; + event.same_screen = True; + event.x = 1; + event.y = 1; + event.x_root = 1; + event.y_root = 1; + event.time = CurrentTime; + event.state = state; // modifiers + event.keycode = key; + event.type = KeyPress; + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); + event.type = KeyRelease; + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); +} + +void keypress(XEvent *e) { unsigned int i; KeySym keysym; XKeyEvent *ev; + Bool called = False; ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 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)); + called = True; + } + if(!called) { + if(key_buffering) { + if(key_buffer_len == LENGTH(key_buffer)) { + // buffer full, bail + key_buffer_len = 0; + key_buffering = False; + } else { + key_buffer[key_buffer_len].keycode = (KeyCode)ev->keycode; + key_buffer[key_buffer_len].state = (KeyCode)ev->state; + key_buffer_len += 1; + } + } else { + send_keycode(ev->keycode, ev->state); + } + } } void @@ -1111,6 +1144,7 @@ manage(Window w, XWindowAttributes *wa) { Client *c, *t = NULL; Window trans = None; XWindowChanges wc; + int i; if(!(c = calloc(1, sizeof(Client)))) die("fatal: could not malloc() %u bytes\n", sizeof(Client)); @@ -1126,8 +1160,13 @@ manage(Window w, XWindowAttributes *wa) { 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; @@ -1167,6 +1206,15 @@ manage(Window w, XWindowAttributes *wa) { arrange(c->mon); XMapWindow(dpy, c->win); focus(c); + if(key_buffering) { + if(key_buffer_len > 0) { + for(i = 0; i < key_buffer_len; ++i) { + send_keycode(key_buffer[i].keycode, key_buffer[i].state); + } + } + key_buffer_len = 0; + key_buffering = False; + } } void @@ -1185,8 +1233,11 @@ maprequest(XEvent *e) { if(!XGetWindowAttributes(dpy, ev->window, &wa)) return; - if(wa.override_redirect) + if(wa.override_redirect) { + key_buffer_len = 0; + key_buffering = False; return; + } if(!wintoclient(ev->window)) manage(ev->window, &wa); } @@ -1711,6 +1762,13 @@ sigchld(int unused) { } void +kbspawn(const Arg *arg) { + key_buffering = True; + key_buffer_len = 0; + spawn(arg); +} + +void spawn(const Arg *arg) { int tag = 0, i; if(arg->v == termcmd) {