wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit a206679e896c5377933394b929140a4011bc6dfc
parent 15c62b0874fe7a8eba103a1d1d1d513557d81ad2
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Mon,  3 Jul 2006 12:14:26 +0200

added prelim version of keyboard handling, however don't try it now


Diffstat:
cmd/wm/client.c | 7+++++--
cmd/wm/event.c | 43++++++++++++++++++++-----------------------
cmd/wm/frame.c | 7++++---
liblitz/blitz.h | 5+++--
liblitz/input.c | 216+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
5 files changed, 228 insertions(+), 50 deletions(-)

diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -116,8 +116,7 @@ create_client(Window w, XWindowAttributes *wa) fwa.background_pixmap = ParentRelative; fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ExposureMask - | ButtonPressMask | PointerMotionMask | FocusChangeMask - | ButtonReleaseMask | KeyPressMask; + | ButtonPressMask | PointerMotionMask | ButtonReleaseMask | KeyPressMask; c->framewin = XCreateWindow(blz.display, blz.root, c->rect.x, c->rect.y, c->rect.width + 2 * def.border, @@ -770,6 +769,7 @@ apply_tags(Client *c, const char *tags) int len; char buf[256]; char *toks[32]; + Frame *f; cext_strlcpy(buf, tags, sizeof(buf)); if(!(n = cext_tokenize(toks, 31, buf, '+'))) @@ -801,6 +801,9 @@ apply_tags(Client *c, const char *tags) XChangeProperty(blz.display, c->win, tags_atom, XA_STRING, 8, PropModeReplace, (unsigned char *)c->tags, strlen(c->tags)); + + for(f = c->frame; f; f = f->cnext) + blitz_settext_input(&f->tagbar, c->tags); } static void diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -16,8 +16,6 @@ static void handle_buttonrelease(XEvent *e); static void handle_configurerequest(XEvent *e); static void handle_destroynotify(XEvent *e); static void handle_enternotify(XEvent *e); -static void handle_focusin(XEvent *e); -static void handle_focusout(XEvent *e); static void handle_leavenotify(XEvent *e); static void handle_expose(XEvent *e); static void handle_keypress(XEvent *e); @@ -33,8 +31,6 @@ void (*handler[LASTEvent]) (XEvent *) = { [ConfigureRequest]= handle_configurerequest, [DestroyNotify] = handle_destroynotify, [EnterNotify] = handle_enternotify, - [FocusIn] = handle_focusin, - [FocusOut] = handle_focusout, [LeaveNotify] = handle_leavenotify, [Expose] = handle_expose, [KeyPress] = handle_keypress, @@ -89,24 +85,6 @@ handle_buttonrelease(XEvent *e) } static void -handle_focusin(XEvent *e) -{ - Frame *f; - XFocusChangeEvent *ev = &e->xfocus; - if((f = frame_of_win(ev->window))) - blitz_focusin_input(&f->tagbar); -} - -static void -handle_focusout(XEvent *e) -{ - Frame *f; - XFocusChangeEvent *ev = &e->xfocus; - if((f = frame_of_win(ev->window))) - blitz_focusout_input(&f->tagbar); -} - -static void handle_motionnotify(XEvent *e) { Frame *f; @@ -282,8 +260,27 @@ static void handle_keypress(XEvent *e) { XKeyEvent *ev = &e->xkey; + KeySym k; + char buf[32]; + int n; + static Frame *f; + + ev->state &= valid_mask; - handle_key(blz.root, ev->state, (KeyCode) ev->keycode); + if((f = frame_of_win(ev->window))) { + buf[0] = 0; + if((n = XLookupString(ev, buf, sizeof(buf), &k, 0) != 1)) + return; + if(IsFunctionKey(k) || IsKeypadKey(k) || IsMiscFunctionKey(k) + || IsPFKey(k) || IsPrivateKeypadKey(k)) + return; + buf[n] = 0; + + if(blitz_kpress_input(&f->tagbar, ev->state, k, buf)) + draw_frame(f); + } + else + handle_key(blz.root, ev->state, (KeyCode) ev->keycode); } static void diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c @@ -40,11 +40,11 @@ create_frame(Client *c, View *v) f->tagbar.blitz = &blz; f->tagbar.drawable = pmap; + f->tagbar.window = c->framewin; f->tagbar.gc = c->gc; f->tagbar.font = &def.font; f->tagbar.color = def.normcolor; - f->tagbar.text = c->tags; - f->tagbar.size = sizeof(c->tags); + blitz_settext_input(&f->tagbar, c->tags); return f; } @@ -118,7 +118,8 @@ draw_frame(Frame *f) /* tag bar */ f->tagbar.rect = f->posbar.rect; f->tagbar.rect.x = 0; - f->tagbar.rect.width = f->tagbar.rect.height + blitz_textwidth(&def.font, f->tagbar.text); + f->tagbar.rect.width = + f->tagbar.rect.height + blitz_textwidth(&def.font, f->tagbar.text); if(f->tagbar.rect.width > f->rect.width / 3) f->tagbar.rect.width = f->rect.width / 3; diff --git a/liblitz/blitz.h b/liblitz/blitz.h @@ -69,6 +69,7 @@ struct BlitzInput { Bool drag; unsigned int size; Drawable drawable; + Window window; GC gc; BlitzColor color; BlitzFont *font; @@ -100,5 +101,5 @@ Bool blitz_bpress_input(BlitzInput *i, int x, int y); Bool blitz_brelease_input(BlitzInput *i, int x, int y); Bool blitz_bmotion_input(BlitzInput *i, int x, int y); Bool blitz_ispointinrect(int x, int y, XRectangle * r); -void blitz_focusin_input(BlitzInput *i); -void blitz_focusout_input(BlitzInput *i); +void blitz_settext_input(BlitzInput *i, const char *text); +Bool blitz_kpress_input(BlitzInput *i, unsigned long mod, KeySym k, const char *ks); diff --git a/liblitz/input.c b/liblitz/input.c @@ -7,6 +7,8 @@ #include <stdlib.h> #include <string.h> #include <cext.h> +#include <X11/keysym.h> +#include <X11/Xutil.h> #include "blitz.h" static void @@ -54,6 +56,33 @@ xdrawtextpart(BlitzInput *i, char *start, char *end, *end = c; } +static char * +curend(BlitzInput *i) +{ + if(i->curstart && i->curend) { + if(i->curstart < i->curend) + return i->curend; + else + return i->curstart; + } + else if(i->curend) + return nil; + return i->curend; +} + +static char * +curstart(BlitzInput *i) +{ + if(i->curstart && i->curend) { + if(i->curstart < i->curend) + return i->curstart; + else + return i->curend; + } + else if(i->curend) + return i->curend; + return i->curstart; +} void blitz_draw_input(BlitzInput *i) @@ -70,22 +99,8 @@ blitz_draw_input(BlitzInput *i) yoff = i->rect.y + (i->rect.height - h) / 2 + i->font->ascent; xcursor = xoff = i->rect.x + i->rect.height / 2; - start = i->curstart; - end = i->curend; - if(i->curstart && i->curend) { - if(i->curstart < i->curend) { - start = i->curstart; - end = i->curend; - } - else { - start = i->curend; - end = i->curstart; - } - } - else if(i->curend) { /* && !i->curstart */ - start = i->curend; - end = nil; - } + start = curstart(i); + end = curend(i); /* draw normal text */ xchangegc(i, &i->color, False); @@ -148,14 +163,101 @@ charof(BlitzInput *i, int x, int y) return xcharof(i, x, i->text, strlen(i->text)); } -void -blitz_focusin_input(BlitzInput *i) +static char * +cursor(BlitzInput *i) +{ + char *start = curstart(i); + char *end = curend(i); + + if(!start && i->text) + return i->text + (i->size - 1); + return end; +} + +static Bool +insert(BlitzInput *i, const char s) +{ + char *buf, *c, *p, *q; + + if(!(c = cursor(i))) + return False; + + buf = cext_emallocz(++i->size); + for(p = i->text, q = buf; p != c; p++, q++) + *q = *p; + *q = s; + for(q++; *p; p++, q++) + *q = *p; + + return True; +} + +static Bool +delete(BlitzInput *i) +{ + char *c, *p, *q; + + if(!(c = cursor(i))) + return False; + + for(q = c, p = c + 1; *p; p++, q++) + *q = *p; + return True; +} + +static void +left(BlitzInput *i) +{ + char *c; + if(!(c = cursor(i))) + return; + + if(c > i->text) + i->curstart = i->curend = c - 1; + else + i->curstart = i->curstart = i->text; +} + +static void +right(BlitzInput *i) { + char *c = cursor(i); + + if(!c) + i->curstart = i->curend = nil; + else { + if(c < i->text + (i->size - 1)) + i->curstart = i->curend = c + 1; + else + i->curstart = i->curend = nil; + } } void -blitz_focusout_input(BlitzInput *i) +blitz_settext_input(BlitzInput *i, const char *text) { + unsigned int len = 0; + + if(!text) { + i->size = 0; + if(i->text) + free(i->text); + i->text = nil; + return; + } + + if(!(len = strlen(text))) + return; + + i->size = len + 1; + i->text = realloc(i->text, i->size); + memcpy(i->text, text, i->size); +} + +static void +escape(BlitzInput *i) +{ + XUngrabKeyboard(i->blitz->display, i->window); } Bool @@ -178,6 +280,8 @@ blitz_brelease_input(BlitzInput *i, int x, int y) if(!(i->drag = blitz_ispointinrect(x, y, &i->rect))) return False; + XGrabKeyboard(i->blitz->display, i->window, True, + GrabModeAsync, GrabModeAsync, CurrentTime); oend = i->curend; i->curend = charof(i, x, y); i->drag = False; @@ -189,10 +293,82 @@ blitz_bmotion_input(BlitzInput *i, int x, int y) { char *oend; - if(!i->drag || !(i->drag = blitz_ispointinrect(x, y, &i->rect))) + if(!i->drag || !(i->drag = blitz_ispointinrect(x, y, &i->rect))) { + escape(i); return False; + } oend = i->curend; i->curend = charof(i, x, y); return i->curend == oend; } + +Bool +blitz_kpress_input(BlitzInput *i, unsigned long mod, KeySym k, const char *ks) +{ + if (mod & ControlMask) { + switch (k) { + case XK_a: + k = XK_Begin; + break; + case XK_b: + k = XK_Left; + break; + case XK_e: + k = XK_End; + break; + case XK_h: + k = XK_BackSpace; + break; + case XK_j: + k= XK_Return; + break; + case XK_k: + k = XK_Delete; + break; + case XK_u: + blitz_settext_input(i, nil); + return True; + case XK_w: + k = XK_BackSpace; + break; + default: + return False; + } + } + + if(IsCursorKey(k)) { + switch(k) { + case XK_Home: + case XK_Begin: + i->curstart = i->curend = i->text; + return True; + case XK_Left: + left(i); + return True; + case XK_Right: + right(i); + return True; + case XK_End: + i->curstart = i->curend = nil; + return True; + } + } + else { + switch(k) { + case XK_Tab: + case XK_Num_Lock: + case XK_Return: + break; + case XK_Escape: + escape(i); + return False; + case XK_Delete: + case XK_BackSpace: + return delete(i); + default: + return insert(i, *ks); + } + } + return False; +}