2015-05-04 5 views
5

मैं किसी भी सूचक गति के बारे में अधिसूचित होने की कोशिश कर रहा हूं। चूंकि मैं विंडो मैनेजर के रूप में नहीं चलना चाहता हूं, इसलिए मुझे स्टार्टअप पर दोनों विंडोज़ पर XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION सेट करना होगा और जब मैं एक फॉर्म को सूचित करता हूं।एक्ससीबी - गति प्राप्त नहीं करना सभी विंडोज़ पर घटनाओं को सूचित करें

यह सामान्य रूप में ठीक से काम करने लगता है और मैं प्राप्त प्रस्ताव सभी खिड़कियों पर घटनाओं को सूचित करें। हालांकि, किसी भी तरह, यह Google क्रोम विंडोज़ के लिए सच नहीं है। मैंने इवेंट मास्क को स्पष्ट रूप से बाद में पूछताछ करके चेक किया और यह सही ढंग से सेट है। मैं प्रचार मास्क में असामान्य कुछ भी नहीं देखता हूं।

क्या गूगल क्रोम की रिपोर्ट नहीं करने के लिए प्रस्ताव की घटनाओं को सूचित कारण बन सकता है? AFAIK, एक्स प्रोटोकॉल अनुमति देता है कि सक्रिय पॉइंटर grabs को छोड़कर जो क्रोम निश्चित रूप से नहीं है।

यहाँ कैसे मैं अपने आप को सभी मौजूदा खिड़कियों पर रजिस्टर है। मैं जड़ खिड़की पर 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

यदि आप इसे चोम विंडो से संलग्न करते हैं तो आप 'xev' से क्या प्राप्त करते हैं? –

+0

@AndrewHenle यह अटैच किया जा रहा है और वहाँ मेरी माउस को ले, यह चारों ओर घूमते रहते हैं, जिससे यह आराम और खिड़की फिर से छोड़ने के केवल देता है मुझे दर्ज/LeaveNotify, KeymapNotify और Focusin/आउट (http://pastebin.com/XQ3ZkVhW) –

+0

मैं भी ऐसा करना चाहिए इंगित करें कि क्रोमियम के साथ एक अलग मशीन पर एक ही अवलोकन किया जा सकता है। –

उत्तर

2

जबकि @Jay Kominek के जवाब उपयोगी और वैध था , मुझे अब एहसास हुआ है कि Xinput एक्सटेंशन का उपयोग करना एक बेहतर तरीका प्रदान करता है क्योंकि यह एप्लिकेशन के साथ हस्तक्षेप नहीं करेगा।

, बस पूरे पेड़ पर चयन करने के मुद्दों के सभी प्रकार का कारण बनता है, उदाहरण के लिए, मंडराना क्रोम में अब और काम नहीं करता।

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

हाँ, ऐसा लगता है कि यह समस्या थी। मैं प्रचार मास्क के बारे में बहुत जटिल सोच रहा था। मैंने इसे ठीक करने से पहले जांच की है कि अगर मैंने एक * नई * क्रोम विंडो खोली है तो मुझे सभी घटनाएं मिलती हैं क्योंकि मुझे सभी सबविंडो के लिए घटनाओं को सूचित करने के लिए मिलता है। बस यह प्रारंभिक हिस्सा त्रुटिपूर्ण था। धन्यवाद, यह मुझे पागल कर रहा था! –

+1

आह, मुझे लगता है कि यह हल हो गया है। XWindows की पागल दुनिया में आपका स्वागत है। –

संबंधित मुद्दे