commit bd9f907d88b706c05c9e1e0e3958f8625b5b26cb
parent 26bd6db557b3e60b3746c3924680a21f045a0f9b
Author: Kris Maglione <kris@suckless.org>
Date: Sat, 31 Jul 2010 19:11:45 -0400
[menu] Allow composed input.
Diffstat:
5 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/cmd/menu/caret.c b/cmd/menu/caret.c
@@ -89,7 +89,7 @@ caret_find(int dir, int type) {
return p;
case CHAR:
if(p > end)
- return p-1;
+ return prev_rune(end, p, &r);
return end;
}
}
diff --git a/cmd/menu/main.c b/cmd/menu/main.c
@@ -186,7 +186,7 @@ main(int argc, char *argv[]) {
int i;
long ndump;
- setlocale(LC_CTYPE, "");
+ setlocale(LC_ALL, "");
fmtinstall('r', errfmt);
quotefmtinstall();
diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c
@@ -29,7 +29,13 @@ menu_init(void) {
wa.event_mask = ExposureMask | KeyPressMask;
barwin = createwindow(&scr.root, Rect(-1, -1, 1, 1), scr.depth, InputOutput,
- &wa, CWEventMask);
+ &wa, CWEventMask);
+ if(scr.xim)
+ barwin->xic = XCreateIC(scr.xim,
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, barwin->xid,
+ XNFocusWindow, barwin->xid,
+ nil);
changeprop_long(barwin, Net("WM_WINDOW_TYPE"), "ATOM",
(long[]){ TYPE("MENU") }, 1);
@@ -262,29 +268,42 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) {
char **action, **p;
char *key;
char buf[32];
- int num;
+ int num, status;
KeySym ksym;
- buf[0] = '\0';
- num = XLookupString(e, buf, sizeof buf, &ksym, 0);
- buf[num] = '\0';
- key = XKeysymToString(ksym);
- if(IsKeypadKey(ksym))
- if(ksym == XK_KP_Enter)
- ksym = XK_Return;
- else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
- ksym = (ksym - XK_KP_0) + XK_0;
-
- if(IsFunctionKey(ksym)
- || IsMiscFunctionKey(ksym)
- || IsKeypadKey(ksym)
- || IsPrivateKeypadKey(ksym)
- || IsPFKey(ksym))
+ if(XFilterEvent((XEvent*)e, w->xid))
return false;
- action = find_key(key, e->state);
- if(action == nil || action[0] == nil) {
+ status = XLookupBoth;
+ if(w->xic)
+ num = Xutf8LookupString(w->xic, e, buf, sizeof buf - 1, &ksym,
+ &status);
+ else
+ num = XLookupString(e, buf, sizeof buf - 1, &ksym, nil);
+
+ if(status != XLookupChars && status != XLookupKeySym && status != XLookupBoth)
+ return false;
+
+ if(status == XLookupKeySym || status == XLookupBoth) {
+ key = XKeysymToString(ksym);
+ if(IsKeypadKey(ksym))
+ if(ksym == XK_KP_Enter)
+ ksym = XK_Return;
+ else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
+ ksym = (ksym - XK_KP_0) + XK_0;
+
+ if(IsFunctionKey(ksym)
+ || IsMiscFunctionKey(ksym)
+ || IsKeypadKey(ksym)
+ || IsPrivateKeypadKey(ksym)
+ || IsPFKey(ksym))
+ return false;
+ action = find_key(key, e->state);
+ }
+
+ if(status == XLookupChars || action == nil || action[0] == nil) {
if(num && !iscntrl(buf[0])) {
+ buf[num] = '\0';
caret_insert(buf, false);
update_filter(true);
menu_draw();
diff --git a/include/stuff/x11.h b/include/stuff/x11.h
@@ -146,6 +146,7 @@ struct WinHints {
struct Window {
int type;
XID xid;
+ XIC xic;
GC gc;
Visual* visual;
Colormap colormap;
@@ -202,6 +203,7 @@ struct Screen {
Rectangle rect;
int depth;
int fd;
+ XIM xim;
};
#ifdef VARARGCK
diff --git a/lib/libstuff/x11/initdisplay.c b/lib/libstuff/x11/initdisplay.c
@@ -76,6 +76,8 @@ initdisplay(void) {
scr.root.parent = &scr.root;
+ scr.xim = XOpenIM(display, nil, nil, nil);
+
windowmap.bucket = wbucket;
windowmap.nhash = nelem(wbucket);
atommap.bucket = abucket;