gpt4 book ai didi

c - XCB:映射一次后窗口不会取消映射

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:22:21 26 4
gpt4 key购买 nike

我有一个用 C 编写的小示例程序,它使用 XCB API 打开一个窗口。

严格来说,之后我已经创建了并且显示了窗口,我想(稍后)隐藏窗口。

(显然,在这个特定示例中,我可以删除对 xcb_map_window 的调用,并且窗口将被隐藏,但我想稍后在我的大型应用程序中执行此操作,例如显示/隐藏窗口的切换,注意:我不想最小化它)。

这是示例代码(注意:由于答案,这段代码现在可以工作了):

#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
#include <xcb/xcb.h>

void set_window_visible(xcb_connection_t* c, xcb_window_t win, bool visible) {
xcb_generic_event_t *event;

if(visible) {
// Map the window on the screen
xcb_map_window (c, win);

// Make sure the map window command is sent
xcb_flush(c);

// Wait for EXPOSE event.
//
// TODO: add timeout in-case X server does not ever send the expose event.
while(event = xcb_wait_for_event(c)) {
bool gotExpose = false;

switch(event->response_type & ~0x80) {
case XCB_EXPOSE:
gotExpose = true;
break;

default:
break; // We don't know the event type, then.
}
free(event);

if(gotExpose) {
break;
}
}

} else {
// Hide the window
xcb_unmap_window(c, win);

// Make sure the unmap window command is sent
xcb_flush(c);
}
}

int main() {
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_window_t win;
xcb_generic_event_t *event;

// Open the connection to the X server
c = xcb_connect (NULL, NULL);

// Get the first screen
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;

// Ask for our window's Id
win = xcb_generate_id(c);

// Create the window
uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t valwin[] = {XCB_EVENT_MASK_EXPOSURE | XCB_BUTTON_PRESS};
xcb_create_window(
c, // Connection
XCB_COPY_FROM_PARENT, // depth (same as root)
win, // window Id
screen->root, // parent window
0, 0, // x, y
150, 150, // width, height
10, // border_width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
screen->root_visual, // visual
mask, valwin // masks
);

bool visible = true;
set_window_visible(c, win, true);

while(1) {
sleep(2);

// Toggle visibility
visible = !visible;
set_window_visible(c, win, visible);

printf("Window visible: ");
if(visible) {
printf("true.\n");
} else {
printf("false.\n");
}
}

// pause until Ctrl-C
pause();
return 0;
}

我用它编译和运行:

gcc xcbwindow.c -o xcbwindow -lxcb
./xcbwindow

根据我在 Google 或此处可以找到的任何内容,我所做的一切都是正确的。所以为了澄清,我使用的是 Unity 和 Ubuntu 12.04 LTS:

unity --version 报告:

unity 5.20.0

uname -a 报告:

Linux [redacted] 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

谁能解释一下我在这段代码中哪里出错了?

编辑:在 xcb_unmap_window() 之后用 flush() 更新了代码;还是不行。

EDIT2:尝试用肉桂 WM 编写代码;仍然不起作用(这不是 Unity 错误)。

EDIT3:这篇文章中更新的代码现在可以使用了。

最佳答案

您的程序运行得太快了。

它映射窗口然后立即取消映射。窗口是顶层的,这意味着请求被重定向到窗口管理器。但是当窗口还没有被映射时,窗口管理器收到了取消映射请求,所以它简单地丢弃了这个请求。在 map 和 unmap 调用之间插入 sleep(3) 并观察。

在实际代码中,您的窗口在发送取消映射请求之前需要至少获得一个公开事件。这保证了它实际上是由窗口管理器映射的。

关于c - XCB:映射一次后窗口不会取消映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19413806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com