如何在 XCB 中正确重新堆叠所有 windows(如 XLIB 中的 XRestackWindows)
How to restack all windows properly in XCB (like XRestackWindows in XLIB)
目前我使用的Xlib只有一个功能XRestackWindows,其余的是XCB和QT5。要求是只能使用XCB和QT5。
我想知道在 XCB 中拥有合适的 XRestackWindows 的方法,我尝试了 的解决方案,但 windows 会闪烁
它在 XLIB 中的工作方式几乎完全相同。重新堆叠时没有 windows 闪烁,如果我重新堆叠 windows 的相同顺序,则不应出现屏幕闪烁。
无法正常工作的 XCB 代码(问题:重新堆叠时闪烁 windows):
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);
}
注意:我尝试了不同的方法,但没有成功,我一直在看XRestackWindows函数,好像他们使用了LockDisplay和UnlockDisplay,我在XCB中找不到它。
这是 XRestackWindows
的源代码(从 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;
}
这为列表中的每个 window 发送一个 ConfigureWindow
请求,前一个 window 为 "below"。
等效的 XCB 代码应该如下所示(未经测试,我什至没有检查它是否编译,但它应该足以理解这个想法):
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;
}
目前我使用的Xlib只有一个功能XRestackWindows,其余的是XCB和QT5。要求是只能使用XCB和QT5。
我想知道在 XCB 中拥有合适的 XRestackWindows 的方法,我尝试了
它在 XLIB 中的工作方式几乎完全相同。重新堆叠时没有 windows 闪烁,如果我重新堆叠 windows 的相同顺序,则不应出现屏幕闪烁。
无法正常工作的 XCB 代码(问题:重新堆叠时闪烁 windows):
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);
}
注意:我尝试了不同的方法,但没有成功,我一直在看XRestackWindows函数,好像他们使用了LockDisplay和UnlockDisplay,我在XCB中找不到它。
这是 XRestackWindows
的源代码(从 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;
}
这为列表中的每个 window 发送一个 ConfigureWindow
请求,前一个 window 为 "below"。
等效的 XCB 代码应该如下所示(未经测试,我什至没有检查它是否编译,但它应该足以理解这个想法):
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;
}