How to restack all windows properly in XCB (like XRestackWindows in XLIB)

Viewed 356

Currently I use Xlib for just one function XRestackWindows, rest is XCB and QT5. The requirement is to use only XCB and QT5.

I would like to know a way to have a proper XRestackWindows in XCB, I have tried a solution from here but the windows would flash

It must work almost exactly how it does in XLIB. No windows flashes upon restack, if I restack same order of windows then no screen flash should occur.

XCB code that didn’t work well (issue: flashed windows upon restack):

void restackWindows(std::vector<xcb_window_t> list)
{
xcb_connection_t *conn = QX11Info::connection(); 
unsigned int arg[1] = { XCB_STACK_MODE_ABOVE };
for ( auto win : list )
{
    xcb_configure_window(conn, win, XCB_CONFIG_WINDOW_STACK_MODE, arg);
}
xcb_flush(conn);
}

Note: I have tried diferent methods without luck, I have been looking at XRestackWindows function, it appears they use LockDisplay and UnlockDisplay, I couldn't find it in XCB.

1 Answers

Here is the source code for XRestackWindows (copied from https://sources.debian.org/src/libx11/2:1.6.9-2/src/RestackWs.c/?hl=33#L33):

int
XRestackWindows (
    register Display *dpy,
    register Window *windows,
    int n)
{
    int i = 0;

    LockDisplay(dpy);
    while (windows++, ++i < n) {
        register xConfigureWindowReq *req;

        GetReqExtra (ConfigureWindow, 8, req);
        req->window = *windows;
        req->mask = CWSibling | CWStackMode;
        {
            register CARD32 *values = (CARD32 *)
              NEXTPTR(req,xConfigureWindowReq);
            *values++ = *(windows-1);
            *values   = Below;
        }
        }
    UnlockDisplay(dpy);
    SyncHandle();
    return 1;
    }

This sends one ConfigureWindow request for each window in the list, with the previous window as "below".

Equivalent XCB code should be something like the following (untested, I didn't even check if this compiles, but it should be enough to get the idea):

int restack_windows(xcb_connection_t *conn, xcb_window_t *windows, int n)
{
    int i = 0;

    while (windows++, ++i < n) {
        xcb_configure_window(conn, *windows,
            XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
            (uint32_t[]) { *(windows - 1), XCB_STACK_MODE_BELOW });
    }
    return 1;
}
Related