2009-06-19 17 views
13

मैं एक्स 11 के तहत सभी खुली खिड़कियों की निगरानी करना चाहता हूं। वर्तमान में, मैं इस रूप में निम्न प्रकार कर रहा हूँ: XSelectInput(display, root_window, SubstructureNotifyMask | PropertyChangeMask) मैं सभी एक्स 11 विंडोज़ की पूरी सूची कैसे प्राप्त और सिंक्रनाइज़ कर सकता हूं?

  • हैंडलिंग सभी MapNotify, UnmapNotify:

    1. प्रारंभ में रिकर्सिवली जड़ खिड़की
    2. से XQueryTree बुला पूरे डेस्कटॉप पर उपसंरचना परिवर्तन के लिए सुनकर द्वारा पूरे वृक्ष घूमना और घटनाओं को नष्ट करें, प्रक्रियाओं में

    मैं मुख्य रूप से बिंदु 1 के बारे में चिंतित हूं। रिकर्सन के दौरान, XQueryTree को कई बार बुलाया जाएगा। क्या यह सुनिश्चित करने का कोई तरीका है कि पेड़ इस दौरान नहीं बदलता है? दूसरे शब्दों में, एक समय में पूरे पेड़ का 'स्नैपशॉट' प्राप्त करने के लिए?

    इसके अलावा, मैंने देखा है कि कुछ एक्स 11 सिस्टम के तहत, सभी घटनाएं सही ढंग से नहीं आती हैं। उदाहरण के लिए, डेस्कटॉप पर एक नई विंडो खोलते समय, उस विंडो के लिए MapNotify कभी भी मेरे मॉनिटरिंग एप्लिकेशन पर नहीं पहुंच सकता है। यह कैसे हो सकता है? क्या यह संभव है कि इसे आने से पहले फेंक दिया जाए?

    अद्यतन:

    मैं एक छोटा सा प्रोग्राम है जो जड़ खिड़की पर एक्स घटनाओं (देखें नीचे) निगरानी करेंगे लिखा है। अब, जब मैं इस प्रोग्राम को चलाता हूं और xcalc को छोड़ता हूं और छोड़ देता हूं, तो मुझे निम्न आउटपुट मिलता है:

    Reparented: 0x4a0005b to 0x1001e40 
    Mapped : 0x1001e40 
    Destroyed : 0x1001e40 
    

    यही है। मुझे कभी भी वास्तविक विंडो (0x4a0005b) को नष्ट नहीं किया जा रहा है। मैप किए जा रहे भी नहीं! क्या कोई मुझे बता सकता है क्यों नहीं? क्या SubStructureNotifyMask केवल की घटनाओं का कारण है सबविंडो को पूरे उपट्री के बजाय भेजा जाना चाहिए?

    वैसे, यह स्पष्ट रूप से तब नहीं होता जब कंपिज़ चल रहा हो। तो फिर कोई reparenting किया जाता है:

    Mapped : 0x4a0005b 
    Mapped : 0x4e00233 
    Destroyed : 0x4a0005b 
    Destroyed : 0x4e00233 
    

    निगरानी कार्यक्रम स्रोत:

    #include <X11/Xlib.h> 
    #include <cstdio> 
    
    int main() 
    { 
        Display *display; 
        Window rootwin; 
    
        display = XOpenDisplay(NULL); 
        rootwin = DefaultRootWindow(display); 
        XSelectInput(display, rootwin, SubstructureNotifyMask); 
    
        XEvent event; 
    
        while (1) { 
         XNextEvent(display, &event); 
         if (event.type == MapNotify) { 
          XMapEvent *mapevent = (XMapEvent *)&event; 
          printf("Mapped : 0x%x\n", (unsigned int)(mapevent->window)); 
         } 
         if (event.type == DestroyNotify) { 
          XDestroyWindowEvent *destroywindowevent = (XDestroyWindowEvent *)&event; 
          printf("Destroyed : 0x%x\n", (unsigned int)(destroywindowevent->window)); 
         } 
         if (event.type == ReparentNotify) { 
          XReparentEvent *reparentevent = (XReparentEvent *)&event; 
          printf("Reparented: 0x%x to 0x%x\n", (unsigned int)(reparentevent->window), (unsigned int)(reparentevent->parent)); 
         } 
        } 
    
        return 0; 
    } 
    
  • उत्तर

    16

    xwininfo पर एक नज़र डालें।

    आपको अधिक जानकारी प्राप्त करने के लिए xprop और xspy भी पसंद हो सकता है।

    अद्यतन: हाँ। xwininfo और -root का उपयोग करके -tree या -children के साथ सभी विंडो शामिल करने का प्रयास करें।

    और परिवर्तन xprop -spy के साथ ट्रैक किए जा सकते हैं।

    +1

    धन्यवाद! मैंने xwininfo के लिए सोर्स कोड पर एक नज़र डाली और ऐसा लगता है कि पेड़ ट्रैवर्सल जैसा ही करता है: इसके चारों ओर संरचनाओं की रक्षा किए बिना। तो यदि XQueryTree कॉल के बीच पेड़ बदलने की संभावना है, तो xwininfo भी प्रभावित होगा और सही परिणाम नहीं देगा ... – Marten

    +1

    @Marten, हाँ। xwininfo एक स्नैपशॉट है, लेकिन यह आपको विरासत देगा। फिर आप कई विंडोज़ खोल सकते हैं और अपडेट्स की जांच के लिए xprop -spy चलाने के लिए उनका उपयोग कर सकते हैं। इन उपकरणों में से कुछ हैं। Http://www.x.org/archive/X11R6.9.0/doc/html/manindex1.html –

    3

    मेरा मानना ​​है कि एक्स सर्वर (XGrabServer (3)) को पकड़ना विंडो पदानुक्रम में परिवर्तनों को रोक देगा। यद्यपि यह थोड़ा भारी हाथ है, इसलिए आपको शायद इसे केवल तभी करना चाहिए यदि आपको वास्तव में इसकी आवश्यकता हो।

    कोड का एक उदाहरण है कि खिड़की पदानुक्रम चलता है, एक पेड़ बनाता है, इसे अद्यतित रखने के लिए खिड़की की घटनाओं का उपयोग करता है, और एक्स प्रोटोकॉल त्रुटियों जो दौड़ की वजह से अपरिहार्य हैं पर ध्यान नहीं देता के लिए, स्रोत कोड में फ़ाइल src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp देखना वर्चुअलबॉक्स के लिए।

    +1

    पर मैन पेज सूची पर एक नज़र डालें XGrabServer आपको पूरा ध्यान देगा लेकिन यह उन सभी अन्य ग्राहकों को भी डिस्कनेक्ट करता है जो इसे बनाता है इस –

    +0

    के लिए बेकार, XGrabServer अन्य क्लाइंट कनेक्शन बंद नहीं करता है, यह सिर्फ एक्स सर्वर को उन पर किसी भी अनुरोध को संसाधित करने से रोकता है, जब तक आप इसे पकड़ नहीं लेते तब तक उन्हें बाहर निकालना। यदि आपका कोड कभी भी पकड़ने के दौरान लटकता है, तो आप मूल रूप से उपयोगकर्ताओं के सत्र को जमे हुए हैं, जिससे उन्हें आपके साथ काफी परेशान कर दिया जाता है। – alanc

    0

    एक्स 11 एक दूरस्थ प्रोटोकॉल है। इसका अर्थ यह है कि जब आप किसी भी जानकारी के लिए एक्स सर्वर से पूछताछ करते हैं, तो आपको हमेशा अपनी प्रति प्राप्त होती है। जब एक्स सर्वर अपने आंतरिक डेटा संरचनाओं को अद्यतन करता है तो आपकी प्रति कभी नहीं बदली जाती है।

    इसका मतलब है कि जब आप इसे पार करते हैं तो पेड़ अचानक नहीं बदलेगा, लेकिन जब आप इसमें जानकारी का उपयोग करते हैं (जैसे खिड़की की जांच करना), तो वह जानकारी पुरानी हो सकती है (किसी ने खिड़की बंद कर दी हो)। यही कारण है कि आपको उचित त्रुटि प्रबंधन करने की आवश्यकता है।