Connor Lane Smith <[email protected]> writes:
> Hey,
>
> On 16/10/2011, Troels Henriksen <[email protected]> wrote:
>> You can't. dmenu does not implement the X11 input context protocol. It
>> could in a few dozen lines of code, though.
>
> I would happily accept a patch for this.
Here's a patch that solves the common cases. There's a ton of potential
issues (complex Unicode in the input) that may require more reworking,
but this patch makes dead keys work for any of the cases on my communist
European keyboard.
diff -r 2f548e0f8965 dmenu.c
--- a/dmenu.c Thu Oct 13 20:43:59 2011 +0100
+++ b/dmenu.c Sun Oct 16 15:23:29 2011 +0200
@@ -58,6 +58,7 @@
static Item *matches, *matchend;
static Item *prev, *curr, *next, *sel;
static Window win;
+static XIC xic;
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr;
@@ -230,8 +231,10 @@
keypress(XKeyEvent *ev) {
char buf[32];
KeySym ksym;
+ int len;
+ Status status;
- XLookupString(ev, buf, sizeof buf, &ksym, NULL);
+ len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status);
if(ev->state & ControlMask) {
KeySym lower, upper;
@@ -273,7 +276,7 @@
switch(ksym) {
default:
if(!iscntrl(*buf))
- insert(buf, strlen(buf));
+ insert(buf, len);
break;
case XK_Delete:
if(text[cursor] == '\0')
@@ -461,7 +464,9 @@
run(void) {
XEvent ev;
- while(!XNextEvent(dc->dpy, &ev))
+ while(!XNextEvent(dc->dpy, &ev)) {
+ if(XFilterEvent(&ev, win))
+ continue;
switch(ev.type) {
case Expose:
if(ev.xexpose.count == 0)
@@ -479,6 +484,7 @@
XRaiseWindow(dc->dpy, win);
break;
}
+ }
}
void
@@ -486,6 +492,7 @@
int x, y, screen = DefaultScreen(dc->dpy);
Window root = RootWindow(dc->dpy, screen);
XSetWindowAttributes swa;
+ XIM xim;
#ifdef XINERAMA
int n;
XineramaScreenInfo *info;
@@ -542,6 +549,11 @@
DefaultVisual(dc->dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa);
+ /* input methods */
+ xim = XOpenIM(dc->dpy, NULL, NULL, NULL);
+ xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, win, XNFocusWindow, win, NULL);
+
XMapRaised(dc->dpy, win);
resizedc(dc, mw, mh);
drawmenu();
--
\ Troels
/\ Henriksen