2015-05-04 59 views
5

我正在嘗試收到任何指針動作的通知。由於我不想作爲窗口管理器運行,因此我需要在啓動時以及獲取創建通知事件時在所有窗口上設置XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTIONXCB - 未收到所有窗口上的動作通知事件

這似乎是工作總體不錯,我收到議案上的所有窗口通知事件。但是,不管怎樣,Google 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); 
} 
+1

如果將其附加到Chome窗口,從xev獲得什麼? –

+0

@AndrewHenle附加它有移動我的鼠標,移動它,讓它休息,再次離開窗口只給我輸入/ LeaveNotify,KeymapNotify和的focusIn /輸出(http://pastebin.com/XQ3ZkVhW) –

+0

我也要指出在不同的機器上可以使用Chromium進行相同的觀察。 –

回答

2

雖然@Jay Kominek的回答是有益的和有效的,我現在認識到,使用Xinput擴展提供了更好的方法,因爲它不會干擾任何應用程序。

對整個樹簡單的選擇會導致各種問題,例如,懸停不會在Chrome中工作了。

5

的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++); 
    } 
} 

(這只是意在作爲概念驗證,而不是非常好。)

+0

我有一個預感,它可能是一個嵌套的問題,但只看起來「一個層次」。沒想到我不得不去所有*遞歸。我會給你一個機會,回覆你。感謝你的回答! –

+0

是的,這似乎是問題所在。我對傳播口罩的想法太複雜了。我現在修復它之前檢查,如果我打開*新* Chrome窗口,我得到所有事件,因爲我收到創建通知事件,即使是所有子窗口。只是這個最初的部分是有缺陷的。謝謝,這讓我瘋狂! –

+1

啊,我看到它已經解決了。歡迎來到XWindows的瘋狂世界。 –