2015-05-04 29 views
5

Tôi đang cố gắng được thông báo về bất kỳ chuyển động con trỏ nào. Vì tôi không muốn chạy như trình quản lý cửa sổ, tôi cần đặt XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION trên tất cả các cửa sổ mà tôi thực hiện cả khi khởi động và khi tôi nhận được thông báo tạo sự kiện.XCB - Không nhận được chuyển động thông báo sự kiện trên tất cả các cửa sổ

Điều này dường như hoạt động tốt nói chung và tôi nhận được chuyển động thông báo sự kiện trên tất cả các cửa sổ. Tuy nhiên, bằng cách nào đó, điều này không đúng đối với các cửa sổ Google Chrome. Tôi đã kiểm tra mặt nạ sự kiện bằng cách truy vấn nó một cách rõ ràng sau đó và nó được đặt chính xác. Tôi cũng không thấy bất cứ điều gì bất thường trong mặt nạ nhân giống.

Điều gì có thể khiến Google Chrome không báo cáo chuyển động thông báo cho các sự kiện? AFAIK, giao thức X không cho phép ngoại trừ con trỏ hoạt động mà Chrome chắc chắn không có.

Đây là cách tôi đăng ký bản thân trên tất cả các cửa sổ hiện có. Tôi gọi register_events trên cửa sổ gốc và bất cứ khi nào tôi nhận được một sự kiện tạo thông báo cũng như:

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

Bạn nhận được gì từ 'xev' nếu bạn đính kèm nó vào cửa sổ Chome? –

+0

@AndrewHenle Gắn nó và di chuyển con chuột của tôi ở đó, di chuyển nó xung quanh, để cho nó nghỉ ngơi và rời khỏi cửa sổ một lần nữa chỉ mang lại cho tôi Enter/LeaveNotify, KeymapNotify và FocusIn/Out (http://pastebin.com/XQ3ZkVhW) –

+0

Tôi cũng nên chỉ ra rằng cùng một quan sát có thể được thực hiện với Chromium trên một máy khác. –

Trả lời

2

Trong khi câu trả lời @ Jay Kominek là hữu ích và có giá trị , Tôi đã nhận ra rằng việc sử dụng phần mở rộng Xinput cung cấp một cách tiếp cận tốt hơn nhiều vì nó sẽ không can thiệp vào các ứng dụng.

Chỉ cần chọn trên toàn bộ cây gây ra tất cả các loại sự cố, ví dụ: di chuột không hoạt động trong Chrome nữa.

5

Các cửa sổ Chrome xuất hiện để được bao gồm khá cây của cửa sổ con lồng nhau. Có vẻ như bạn sẽ cần phải đi bộ cây của cửa sổ và theo dõi tất cả chúng. Mã này nhặt các sự kiện chuyển động con trỏ trên toàn bộ các cửa sổ Chrome của tôi:

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

(Đó chỉ là dự định như là bằng chứng của khái niệm, và không phải là rất tốt đẹp.)

+0

Tôi có linh cảm rằng nó có thể là một loại vấn đề làm tổ, nhưng chỉ nhìn "một mức độ sâu". Tôi không nghĩ mình phải đi * tất cả * đệ quy. Tôi sẽ cung cấp cho một shot và lấy lại cho bạn. Cảm ơn câu trả lời! –

+0

Vâng, có vẻ như đây là vấn đề. Tôi đã suy nghĩ quá phức tạp về mặt nạ tuyên truyền. Tôi đã kiểm tra trước khi sửa nó ngay bây giờ nếu tôi mở một cửa sổ * mới * Chrome, tôi nhận tất cả các sự kiện vì tôi nhận được thông báo tạo sự kiện ngay cả đối với tất cả các cửa sổ phụ. Chỉ là phần ban đầu này là thiếu sót. Cảm ơn, điều này đã khiến tôi phát điên! –

+1

Ahh, tôi thấy nó đã được giải quyết. Chào mừng bạn đến với thế giới điên rồ của XWindows. –

Các vấn đề liên quan