#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>
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, Bool focused);
static void grabkeys(void);
-static void grab_typing_keys(void);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
static void run(void);
static void scan(void);
static Bool sendevent(Client *c, Atom proto);
-static void send_keycode(KeyCode key);
+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);
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 KeyCode key_buffer[100];
+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";
&& (!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;
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);
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) {
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);
- if(key_buffering)
- grab_typing_keys();
- }
-}
-
-void
-grab_typing_keys(void) {
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- KeySym typing_keys[] = {
- XK_space, XK_Return, XK_period, XK_slash, XK_minus, XK_apostrophe,
- XK_A, XK_B, XK_C, XK_D, XK_E, XK_F, XK_G, XK_H, XK_I, XK_J, XK_K,
- XK_L, XK_M, XK_N, XK_O, XK_P, XK_Q, XK_R, XK_S, XK_T, XK_U, XK_V,
- XK_W, XK_X, XK_Y, XK_Z, XK_0, XK_1, XK_2, XK_3, XK_4, XK_5, XK_6,
- XK_7, XK_8, XK_9,
- };
-
- KeyCode code;
-
- for(i = 0; i < LENGTH(typing_keys); i++)
- if((code = XKeysymToKeycode(dpy, typing_keys[i])))
- for(j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, modifiers[j], root,
- True, GrabModeAsync, GrabModeAsync);
- }
+ //XUngrabKey(dpy, AnyKey, AnyModifier, root);
+ XGrabKey(dpy, AnyKey, AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
}
void
#endif /* XINERAMA */
void
-send_keycode(KeyCode key) {
+send_keycode(KeyCode key, unsigned int state) {
XKeyEvent event;
if(!selmon->sel) {
return;
event.x_root = 1;
event.y_root = 1;
event.time = CurrentTime;
- event.state = 0; // modifiers
+ event.state = state; // modifiers
event.keycode = key;
event.type = KeyPress;
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// buffer full, bail
key_buffer_len = 0;
key_buffering = False;
- grabkeys(); // stop grabbing typing keys
} else {
- key_buffer[key_buffer_len] = (KeyCode)ev->keycode;
+ 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);
+ send_keycode(ev->keycode, ev->state);
}
}
}
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;
XMapWindow(dpy, c->win);
focus(c);
if(key_buffering) {
- key_buffering = False;
- grabkeys(); // stop grabbing typing keys
if(key_buffer_len > 0) {
for(i = 0; i < key_buffer_len; ++i) {
- send_keycode(key_buffer[i]);
+ send_keycode(key_buffer[i].keycode, key_buffer[i].state);
}
}
key_buffer_len = 0;
+ key_buffering = False;
}
}
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);
}
}
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) {
}
if(arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
- key_buffering = True;
- key_buffer_len = 0;
- grab_typing_keys();
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));