#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 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 sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
static void zoom(const Arg *arg);
/* variables */
-static KeyCode key_buffer[100];
-static int key_buffer_len = 0;
static Bool key_buffering = False;
static const char broken[] = "broken";
static char stext[256];
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 */
}
if(ev->window == selmon->barwin) {
return;
- }
- else if((c = wintoclient(ev->window))) {
+ } 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
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);
- 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);
+ True, GrabModeAsync,
+ keys[i].func == kbspawn ? GrabModeSync : GrabModeAsync);
}
}
#endif /* XINERAMA */
void
-send_keycode(KeyCode key) {
- 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 = 0; // 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++)
+ 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].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;
- grabkeys(); // stop grabbing typing keys
- } else {
- key_buffer[key_buffer_len] = (KeyCode)ev->keycode;
- key_buffer_len += 1;
- }
- } else {
- send_keycode(ev->keycode);
}
}
}
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));
XMapWindow(dpy, c->win);
focus(c);
if(key_buffering) {
- // FIXME: try turning off buffering below where we send the virt keypresses
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]);
- }
- }
- key_buffer_len = 0;
- // FIXME ie here
+ 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) {
- key_buffer_len = 0;
- key_buffering = False;
return;
}
if(!wintoclient(ev->window))
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;
- key_buffer_len = 0;
- grab_typing_keys();
spawn(arg);
}