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:
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;
+}