window 经理:wm 为 运行 时,新启动的应用程序不可见
window manager: Newly launched applications are not visible while the wm is running
TL;DR
我正在编写一个简单的重设 window 管理器。我正在 Xephyr 的帮助下对其进行测试。虽然 window 管理器是 运行,但在此期间启动的任何应用程序都不会在屏幕上显示(不可见),而在 window 管理器启动之前启动的任何应用程序都会显示(可见)。
完整问题
我正在编写一个简单的重设 window 管理器。目前我只处理两个事件 XCB_CREATE_NOTIFY
和 XCB_BUTTON_PRESS
。我已经在根 window.
上注册了 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
和 XCB_EVENT_MASK_EXPOSURE
我正在用 Xephyr 测试 wm。并且在测试 wm 启动后启动的任何应用程序时,不会在屏幕上显示(不可见),而在启动 wm 之前启动的应用程序会完美显示(可见)。
我在某处读到,在根 window 上注册 EXPOSURE 事件可以解决问题,但对我来说似乎并非如此。下面是我的 CREATE_NOTIFY 事件代码,它试图重新设置客户端 window 的父级并将其映射到屏幕上(我认为这是我做错的地方):
case XCB_CREATE_NOTIFY:
{
xcb_create_notify_event_t *cre;
cre = (xcb_create_notify_event_t *)evt;
xcb_window_t frame = xcb_generate_id(conn);
uint32_t frameMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t fM_values[2];
fM_values[0] = custTeal->pixel; //custTeal is a custom Teal color that I've defined
fM_values[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;
xcb_window_t toBeMapped = cre->window;
xcb_get_geometry_reply_t *tbm_window_geo = xcb_get_geometry_reply(conn,xcb_get_geometry(conn,toBeMapped),NULL);
xcb_create_window(conn,0,frame,screen->root,tbm_window_geo->x,tbm_window_geo->y,(tbm_window_geo->width+4),(tbm_window_geo->height+4),1,XCB_WINDOW_CLASS_INPUT_OUTPUT,screen->root_visual,frameMask,fM_values);
xcb_reparent_window(conn,toBeMapped,frame,2,2);
xcb_map_window(conn,frame);
xcb_map_window(conn,toBeMapped);
xcb_flush(conn);
}
break;
我不知道我做错了什么(我对此很陌生)。 我是否也必须处理 EXPOSE 事件?我该如何处理?
测试
我正在使用
启动 Xephyr
Xephyr -br -ac -noreset -screen 1240x720 :2 &
并启动新的应用程序(以 xterm 为例):
DISPLAY=:2 xterm &
现在,在启动 wm 之前启动的任何应用程序(或 wm 不是 运行 时)都可以在 Xephyr 中完美显示。但是我启动wm后,启动任何应用程序都不显示。
SubstructureRedirect 意味着当其他东西试图映射 window 时,X11 服务器反而生成一个 MapRequest 事件并将其发送到 WM。因此,您应该处理 XCB_MAP_REQUEST
事件。最简单的方法是 xcb_map_window
来自事件的 window。
TL;DR
我正在编写一个简单的重设 window 管理器。我正在 Xephyr 的帮助下对其进行测试。虽然 window 管理器是 运行,但在此期间启动的任何应用程序都不会在屏幕上显示(不可见),而在 window 管理器启动之前启动的任何应用程序都会显示(可见)。
完整问题
我正在编写一个简单的重设 window 管理器。目前我只处理两个事件 XCB_CREATE_NOTIFY
和 XCB_BUTTON_PRESS
。我已经在根 window.
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
和 XCB_EVENT_MASK_EXPOSURE
我正在用 Xephyr 测试 wm。并且在测试 wm 启动后启动的任何应用程序时,不会在屏幕上显示(不可见),而在启动 wm 之前启动的应用程序会完美显示(可见)。
我在某处读到,在根 window 上注册 EXPOSURE 事件可以解决问题,但对我来说似乎并非如此。下面是我的 CREATE_NOTIFY 事件代码,它试图重新设置客户端 window 的父级并将其映射到屏幕上(我认为这是我做错的地方):
case XCB_CREATE_NOTIFY:
{
xcb_create_notify_event_t *cre;
cre = (xcb_create_notify_event_t *)evt;
xcb_window_t frame = xcb_generate_id(conn);
uint32_t frameMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t fM_values[2];
fM_values[0] = custTeal->pixel; //custTeal is a custom Teal color that I've defined
fM_values[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;
xcb_window_t toBeMapped = cre->window;
xcb_get_geometry_reply_t *tbm_window_geo = xcb_get_geometry_reply(conn,xcb_get_geometry(conn,toBeMapped),NULL);
xcb_create_window(conn,0,frame,screen->root,tbm_window_geo->x,tbm_window_geo->y,(tbm_window_geo->width+4),(tbm_window_geo->height+4),1,XCB_WINDOW_CLASS_INPUT_OUTPUT,screen->root_visual,frameMask,fM_values);
xcb_reparent_window(conn,toBeMapped,frame,2,2);
xcb_map_window(conn,frame);
xcb_map_window(conn,toBeMapped);
xcb_flush(conn);
}
break;
我不知道我做错了什么(我对此很陌生)。 我是否也必须处理 EXPOSE 事件?我该如何处理?
测试
我正在使用
启动 XephyrXephyr -br -ac -noreset -screen 1240x720 :2 &
并启动新的应用程序(以 xterm 为例):
DISPLAY=:2 xterm &
现在,在启动 wm 之前启动的任何应用程序(或 wm 不是 运行 时)都可以在 Xephyr 中完美显示。但是我启动wm后,启动任何应用程序都不显示。
SubstructureRedirect 意味着当其他东西试图映射 window 时,X11 服务器反而生成一个 MapRequest 事件并将其发送到 WM。因此,您应该处理 XCB_MAP_REQUEST
事件。最简单的方法是 xcb_map_window
来自事件的 window。