Ing*_*ürk 5 c x11 google-chrome xcb
我正在尝试通知任何指针运动.因为我不想作为窗口管理器运行,所以我需要XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION在启动时和创建通知事件时设置所有窗口.
这似乎一般工作正常,我在所有窗口上收到动作通知事件.但是,不知何故,谷歌Chrome窗口不是这样.我之后通过显式查询它来检查事件掩码,并且它已正确设置.我也没有在传播掩模中看到任何异常.
什么可能导致谷歌浏览器不报告动作通知事件?AFAIK,X协议不允许除了Chrome肯定没有的活动指针抓取.
这是我在所有现有窗口上注册的方式.我打电话register_events给根窗口,每当我收到一个创建通知事件时:
static void register_events(xcb_window_t window) {
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(connection,
window, XCB_CW_EVENT_MASK, (uint32_t[]) { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_LEAVE_WINDOW });
xcb_generic_error_t *error = xcb_request_check(connection, cookie);
if (error != NULL) {
xcb_disconnect(connection);
errx(EXIT_FAILURE, "could not subscribe to events on a window, bailing out");
}
}
static void register_existing_windows(void) {
xcb_query_tree_reply_t *reply;
if ((reply = xcb_query_tree_reply(connection, xcb_query_tree(connection, root), 0)) == NULL) {
return;
}
int len = xcb_query_tree_children_length(reply);
xcb_window_t *children = xcb_query_tree_children(reply);
for (int i = 0; i < len; i++) {
register_events(children[i]);
}
xcb_flush(connection);
free(reply);
}
Run Code Online (Sandbox Code Playgroud)
Chrome窗口似乎由嵌套的子窗口树组成.你似乎需要走在窗户的树上并监控它们.此代码会在整个Chrome窗口中捕获指针运动事件:
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
static void register_events(xcb_connection_t *conn,
xcb_window_t window) {
xcb_void_cookie_t cookie =
xcb_change_window_attributes_checked(conn,
window, XCB_CW_EVENT_MASK,
(uint32_t[]) {
XCB_EVENT_MASK_POINTER_MOTION });
xcb_generic_error_t *error = xcb_request_check(conn, cookie);
if (error != NULL) {
xcb_disconnect(conn);
exit(-1);
}
}
static void register_existing_windows(xcb_connection_t *conn,
xcb_window_t root) {
int i, len;
xcb_window_t *children;
xcb_query_tree_reply_t *reply;
if ((reply = xcb_query_tree_reply(conn,
xcb_query_tree(conn, root), 0))
== NULL)
{
return;
}
len = xcb_query_tree_children_length(reply);
children = xcb_query_tree_children(reply);
for (i = 0; i < len; i++) {
register_events(conn, children[i]);
register_existing_windows(conn, children[i]);
}
xcb_flush(conn);
}
void main(void) {
int i=0;
/* Open the connection to the X server */
xcb_connection_t *conn = xcb_connect (NULL, NULL);
/* Get the first screen */
xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (conn)).data;
register_existing_windows(conn, screen->root);
while(1) {
xcb_generic_event_t *evt;
evt = xcb_wait_for_event(conn);
printf("%i\n", i++);
}
}
Run Code Online (Sandbox Code Playgroud)
(这只是作为概念的证明,并不是很好.)
虽然 @Jay Kominek 的答案很有帮助且有效,但我现在开始意识到使用 Xinput 扩展提供了更好的方法,因为它不会干扰任何应用程序。
简单地选择整个树会导致各种问题,例如,悬停在 Chrome 中不再起作用。
| 归档时间: |
|
| 查看次数: |
993 次 |
| 最近记录: |