fix(popup): raise the popup whenever it is shown
The popup window is created once at startup and only mapped afterwards, and MapWindow does not restack, so every application window (or WM frame) opened after the daemon sat above it: candidates and preedit were invisible in those windows until the daemon restarted. Configure the window above its siblings on every show. The XIM live test now checks the popup stacks above a client window created after the daemon.
This commit is contained in:
@@ -608,6 +608,41 @@ testcallbacks(Display *dpy, XIM im, Window win)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The popup is the one viewable override-redirect window on the private
|
||||
* display; created before the client window, it must still stack above it.
|
||||
*/
|
||||
static int
|
||||
popupabove(Display *dpy, Window client)
|
||||
{
|
||||
XWindowAttributes wa;
|
||||
Window root, parent, *kids;
|
||||
unsigned i, n;
|
||||
int64_t deadline;
|
||||
int above;
|
||||
|
||||
deadline = nowms() + Eventtimeout;
|
||||
for(;;){
|
||||
above = 0;
|
||||
root = DefaultRootWindow(dpy);
|
||||
if(!XQueryTree(dpy, root, &root, &parent, &kids, &n))
|
||||
return fail("query the window tree");
|
||||
for(i = 0; i < n; i++){
|
||||
if(kids[i] == client)
|
||||
above = 1;
|
||||
else if(XGetWindowAttributes(dpy, kids[i], &wa) &&
|
||||
wa.override_redirect && wa.map_state == IsViewable)
|
||||
break;
|
||||
}
|
||||
XFree(kids);
|
||||
if(i < n)
|
||||
return above || fail("popup is stacked below the client");
|
||||
if(leftms(deadline) == 0)
|
||||
return fail("popup did not appear");
|
||||
pump(dpy, 20);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
testnothing(Display *dpy, XIM im, Window win)
|
||||
{
|
||||
@@ -628,6 +663,7 @@ testnothing(Display *dpy, XIM im, Window win)
|
||||
}
|
||||
pump(dpy, 100);
|
||||
if(!sendkey(dpy, ic, win, XK_r, 0, commit, sizeof commit) ||
|
||||
!popupabove(dpy, win) ||
|
||||
!sendkey(dpy, ic, win, XK_k, 0, commit, sizeof commit) ||
|
||||
!sendkey(dpy, ic, win, XK_Return, 0, commit, sizeof commit)){
|
||||
XDestroyIC(ic);
|
||||
|
||||
8
win.c
8
win.c
@@ -316,7 +316,7 @@ winshow(Drawcmd *dc)
|
||||
Area area;
|
||||
Popup p;
|
||||
int ax, ay, px, py, x, y;
|
||||
u32int vals[4];
|
||||
u32int vals[5];
|
||||
xcb_query_pointer_reply_t *ptr;
|
||||
xcb_query_pointer_cookie_t cookie;
|
||||
|
||||
@@ -339,14 +339,16 @@ winshow(Drawcmd *dc)
|
||||
if(p.w <= 0 || p.h <= 0 || !resizebacking(p.w, p.h))
|
||||
return 0;
|
||||
popupposition(&dc->caret, px, py, &area, p.w, p.h, &x, &y);
|
||||
/* Mapping does not restack: raise above windows opened since. */
|
||||
vals[0] = x;
|
||||
vals[1] = y;
|
||||
vals[2] = p.w;
|
||||
vals[3] = p.h;
|
||||
vals[4] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(conn, win,
|
||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
vals);
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
|
||||
XCB_CONFIG_WINDOW_STACK_MODE, vals);
|
||||
popupdraw(img, dc, &p);
|
||||
putimage(p.w, p.h);
|
||||
xcb_map_window(conn, win);
|
||||
|
||||
Reference in New Issue
Block a user