python - XGrabKey अतिरिक्त फ़ोकस-आउट और फ़ोकस-इन घटनाओं को क्यों उत्पन्न करता है?




linux x11 (5)

अंत में, जैसा कि आप जानते हैं कि linux का मतलब स्वतंत्रता है, मैंने हड़पने वाले स्टाइल फोकस से छुटकारा पाने के लिए xserver को संशोधित किया:

sudo apt-get build-dep xorg-server
apt-get source xorg-server
cd xorg-server-*
#modify or patch dix/events.c: comment off "DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);" in ActivateKeyboardGrab(), comment off "DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);" in DeactivateKeyboardGrab()
sudo apt-get install devscripts
debuild -us -uc    #"-us -uc" to avoid the signature step
cd ..
sudo dpkg --install xserver-xorg-core_*.deb
#clear dependencies:
sudo apt-mark auto $(apt-cache showsrc xorg-server | grep Build-Depends | perl -p -e 's/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g')
sudo apt-get autoremove

और मुझे gtk संदर्भ मेनू में XGrabKeyboard से छुटकारा पाने की आवश्यकता है:

sudo apt-get build-dep gtk+2.0
apt-get source gtk+2.0
cd gtk+2.0-*
#modify or patch it: add "return TRUE;" in first line of popup_grab_on_window() of gtk/gtkmenu.c
dpkg-source --commit
debuild -us -uc  #"-us -uc" to avoid the signature step, maybe need: sudo apt-get install devscripts
cd ..
sudo dpkg --install libgtk2.0-0_*.deb
#clear dependencies:
sudo apt-mark auto $(apt-cache showsrc gtk+2.0 | grep Build-Depends | perl -p -e 's/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g')
sudo apt-get autoremove

अब myboard.py अच्छी तरह से काम करता है।

यदि आप ubuntu रेयरिंग-अपडेट संस्करण का उपयोग कर रहे हैं, तो आप इसके लिए प्रयास कर सकते हैं:

https://code.google.com/p/diyism-myboard/downloads/detail?name=xserver-xorg-core_1.13.3-0ubuntu6.2_i386.deb

तथा:

https://code.google.com/p/diyism-myboard/downloads/detail?name=libgtk2.0-0_2.24.17-0ubuntu2_i386.deb

क्या किसी को मूल फोकस खोए बिना एक कीप ईवेंट को फंसाने के लिए एक xlib फ़ंक्शन पता है? मैं इससे छुटकारा कैसे पाऊं?

(या "ग्रैब-स्टाइल फोकसआउट उत्पन्न किए बिना XGrabKey () का उपयोग करने के लिए?")

(या "सिस्टम स्तर पर NotifyGrab और NotifyUngrab फ़ोकस घटनाओं से कैसे छुटकारा पाएं?"

XGrabKey कुंजी दबाए गए पर ध्यान केंद्रित करने और जारी किए गए कुंजी पर ध्यान केंद्रित करने को खो देगा।

और मैं मूल विंडो में लीक किए बिना कीप को फंसाना चाहता हूं (जैसा कि XGrabKey यह कर सकता है)।

संदर्भ:

  1. ... XGrabKey फोकस चुराएगा ... https://bugs.launchpad.net/gtkhotkey/+bug/390552/comments/8

  2. ... कार्यक्रम को कुंजी संयोजन के जवाब में कुछ करने के लिए नियंत्रण प्राप्त होता है। इस बीच, कार्यक्रम को अस्थायी रूप से केंद्रित किया गया है ... XGrabKey (बोर्ड) के दौरान, पता लगाएं कि किस विंडो पर ध्यान केंद्रित किया गया था

  3. ... XGrabKeyboard फ़ंक्शन सक्रिय रूप से कीबोर्ड का नियंत्रण पकड़ लेता है और FocusIn और FocusOut ईवेंट उत्पन्न करता है ... http://www.x.org/archive/X11R6.8.0/doc/XGrabKeyboard.3.html#toc3

  4. ... मैं मेट्रेस के वर्तमान डेस्कटॉप चेंजिन व्यवहार (एक ही समय में पॉपअप डायलॉग को बदलने और दिखाने) को विंडो पर ग्रैब-टाइप फोकस के बिना प्रदान करने का कोई तरीका नहीं देख सकता ... https://mail.gnome.org/archives/wm-spec-list/2007-May/msg00000.html

  5. ... फ़ुलस्क्रीन मोड फ़ोकसआउट इवेंट्स पर NotifyGrab से बाहर नहीं जाना चाहिए ... https://bugzilla.mozilla.org/show_bug.cgi?id=578265

  6. कीबोर्ड को हथियाने के ध्यान को बदलने की अनुमति नहीं है ... कीबोर्ड के हथियाने को बदलने पर ध्यान केंद्रित करने की अनुमति नहीं है

  7. फोकस इवेंट्स जो कि ग्रेब्स (XGrabKeyboard के सक्रिय हड़पने और XGrabKey के निष्क्रिय हड़पने) http://www.x.org/releases/X11R7.6/doc/libX11/specs/libX11/libX11.html#Focus_Events_Generated_by_Grabs बनाए गए हैं http://www.x.org/releases/X11R7.6/doc/libX11/specs/libX11/libX11.html#Focus_Events_Generated_by_Grabs

  8. XGrabKey स्रोत कोड: http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/GrKey.c शायद हम इसे फोकस-आउट घटनाओं से छुटकारा पाने के लिए संशोधित कर सकते हैं?

  9. "DoFocusEvents (कीबड, ओल्डविन, ग्रैब-> विंडो, नोटिफ़ग्रैब)" है; ActivateKeyboardGrab () में: http://cgit.freedesktop.org/xorg/xserver/tree/dix/events.c

मैं कुंजी-संयोजन (और माउस आंदोलन) मैपिंग सॉफ़्टवेयर के लिए एक-कीस्ट्रोक लिख रहा हूं: https://code.google.com/p/diyism-myboard/

मैंने इसे Windows में RegisterHotKey () और UnRegisterHotKey (): https://code.google.com/p/diyism-myboard/downloads/detail?name=MyBoard.pas साथ महसूस किया है

और मैं इसे XGrabKey () और XUngrabKey (): https://code.google.com/p/diyism-myboard/downloads/detail?name=myboard.py साथ लिनक्स में स्थानांतरित करना चाहता हूं।

मैंने इस समस्या को हल करने के लिए $ 10 इनाम बनाया है। हमें बाउंटी लगाने के लिए अधिक बैकर्स की जरूरत है। https://www.bountysource.com/issues/1072081-right-button-menu-flashes-while-jkli-keys-move-the-mouse-pointer


आप घटनाओं को पढ़ने के लिए XTestKey का उपयोग कर सकते हैं, फिर आप एक बैकस्पेस कुंजी ईवेंट भेजने के लिए XTestKey का उपयोग कर सकते हैं और फिर वह कुंजी जिसे आप दबाया जाना चाहते हैं। बेहतर है, आप सभी कीबोर्ड ईवेंट के लिए हॉटकी पंजीकृत कर सकते हैं और फिर XTestKey का उपयोग करके महत्वपूर्ण ईवेंट जनरेट कर सकते हैं। BTW, केडीई के "कस्टम शॉर्टकट" नियंत्रण मॉड्यूल की-बोर्ड उत्पन्न करने के लिए शॉर्टकट का उपयोग करने की अनुमति देता है। स्रोत कोड


ऐसा लगता है कि XQueryKeymap आपको सॉर्ट करेगा। C ++ स्रोत कोड के लिए नीचे देखें मैंने पाया :

/* compile with g++ keytest.cpp -LX11 -o keytest */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

double gettime() {
 timeval tim;
 gettimeofday(&tim, NULL);
 double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
 return t1;
}

int main() {
 Display *display_name;
 int depth,screen,connection;
 display_name = XOpenDisplay(NULL);
 screen = DefaultScreen(display_name);
 depth = DefaultDepth(display_name,screen);
 connection = ConnectionNumber(display_name);
 printf("Keylogger started\n\nInfo about X11 connection:\n");
 printf(" The display is::%s\n",XDisplayName((char*)display_name));
 printf(" Width::%d\tHeight::%d\n",
 DisplayWidth(display_name,screen),
 DisplayHeight(display_name,screen));
 printf(" Connection number is %d\n",connection);

 if(depth == 1)
  printf(" You live in prehistoric times\n");
 else
  printf(" You've got a coloured monitor with depth of %d\n",depth);

 printf("\n\nLogging started.\n\n");

 char keys_return[32];
 while(1) {
  XQueryKeymap(display_name,keys_return);
  for (int i=0; i<32; i++) {
   if (keys_return[i] != 0) {
    int pos = 0;
    int num = keys_return[i];
    printf("%.20f: ",gettime());
    while (pos < 8) {
     if ((num & 0x01) == 1) {
      printf("%d ",i*8+pos);
     }
     pos++; num /= 2;
    }
    printf("\n");
   }
  }
  usleep(30000);
 }
 XCloseDisplay(display_name);
}

ध्यान दें, यह परीक्षण कोड नहीं है, न ही यह मेरा है - मैंने इसे इंटरनेट पर पाया।


मुझे पता चला है कि मुझे पूरा यकीन है कि मैं काम करूँगा, लेकिन मुझे बिस्तर पर जाना होगा और मैं खुद इसका परीक्षण नहीं कर सकता, और यह सुंदर नहीं है, क्योंकि मुझे नहीं लगता कि आपके पास ऐसा करने का कोई तरीका है। एक्स में चाहते हैं। यहाँ मैं मन में है कदम है। संक्षेप में: X में कीबोर्ड को अक्षम करें, निचले स्तर के एपीआई से घटनाओं को पढ़ें, और चुनिंदा रूप से उन्हें एक्स को खुद खिलाएं। आपको X में कीबोर्ड को अक्षम करना होगा क्योंकि अन्यथा, आप घटना को देख सकते हैं, लेकिन इसे रोक नहीं सकते हैं; आप इसे एक्स के साथ पढ़ेंगे, इसे इंटरसेप्ट नहीं करेंगे।

तो यहाँ यह टूट गया है:

1) कीबोर्ड एक्स उपयोग कर रहा है पाने के लिए xinput -list चलाएँ

2) डिवाइस सक्षम संपत्ति को खोजने के लिए xinput list-props आईडी चलाएँ

3) X में डिवाइस को निष्क्रिय करने के लिए xinput set-prop id prop 0 चलाएं:

xinput -list
xinput list-props 12 # 12 is the id of the keyboard in the list... (example # btw)
xinput set-prop 12 119 0 # 119 is the "Device Enabled" prop, we turn it off

मुझे नहीं पता है कि xinput xlib स्तर पर कैसे काम करता है, मैं इसे लागू करने की सादगी के लिए शेल को कॉल करूंगा।

4) ओपन /dev/input/eventX , जहां एक्स कीबोर्ड डिवाइस है। मैं वास्तव में / xinput (सूची में दिए गए) नाम के लिए / dev / input / by-id के तहत खोज करूँगा और इसे इस तरह से खोलूँगा। इसकी संभावना कुछ बिंदु पर रूट की आवश्यकता होगी, क्योंकि इन पर अनुमतियाँ आम तौर पर बहुत प्रतिबंधक होती हैं।

5) वहां से कीबोर्ड इनपुट पढ़ें:

इनपुट घटनाओं से डेटा का प्रारूप है:

struct input_event {
    int tv_sec; // time of the event
    int tv_usec; // ditto
    ushort type; // == 1 for key event
    ushort code; // key code, not the same as X keysyms, you should check it experimentally. 42 is left shift on mine, 54 is right shift
    int value; // for keys, 1 == pressed, 0 == released, 2 == repeat
}

इनट्स 32 बिट हैं, ushorts 16 बिट हैं। चूंकि आप केवल कीबोर्ड इनपुट में रुचि रखते हैं, आप इसे बहुत सरलता से कर सकते हैं:

  • 8 बाइट्स पढ़ें और अनदेखा करें।

  • अगला बाइट 1 होना चाहिए, फिर अगला एक है। यदि नहीं, तो इस घटना को छोड़ दें

  • अगला बाइट कुंजी कोड का थोड़ा अंत है, और चूंकि <255 चाबियाँ हैं, इसलिए यह काफी अच्छा है

  • अगले बाइट को छोड़ दें।

  • अगले बाइट को पढ़ने के लिए देखें कि क्या इटिस दबाया गया है या जारी किया गया है

  • अगले तीन बाइट्स छोड़ें

6) जब आपको कोई ऐसी घटना मिलती है, जिसमें आप फंसने में रुचि रखते हैं, तो उसे स्वयं संभाल लें। अन्यथा, X को भेजने के लिए XSendEvent का उपयोग करें ताकि इसे सामान्य रूप से संसाधित किया जा सके। उपयुक्त कीडेम के लिए आपको / dev / इनपुट से मिलने वाले हार्डवेयर कोड की मैपिंग एक ट्रिक हो सकती है, लेकिन मुझे यकीन है कि इसके साथ मदद करने के लिए xlib में एक फंक्शन है।

7) गोटो 5 और लूप तब तक करें जब तक आप काम न कर लें

8) सुनिश्चित करें कि आपने बाहर निकलते समय सब कुछ सेट कर दिया था, या आप उपयोगकर्ता के कीबोर्ड इनपुट को एक्स तक तोड़ सकते थे!

मेरा सुझाव है कि एक दूसरे USB कीबोर्ड के साथ इसका परीक्षण करें, आप / dev / input और xinput के साथ एक दूसरे से स्वतंत्र रूप से कीबोर्ड को अक्षम और सुन सकते हैं, इसलिए यदि आप क्रैश करते हैं, तो आपके पास सामान्य रूप से और काम करने वाला पहला कीबोर्ड है। (वास्तव में, मुझे लगता है कि यह जानबूझकर एक दूसरे कीबोर्ड के साथ करना अच्छा होगा, हॉटकीज़ को दोगुना करना होगा!)

लेकिन हाँ, रूट की जरूरत है और संभावित रूप से X से "अलग" कीबोर्ड को छोड़ना बिल्कुल भी सुंदर नहीं है, और यह कि फॉरवर्डिंग-सेंडकी के साथ तुलना में आसान कहा जा सकता है, लेकिन मुझे पूरा यकीन है कि यह काम करेगा और आपको अधिकतम लचीलापन देगा। ।


मैंने 90 के दशक की शुरुआत में इरिक्स, अल्ट्रिक्स और सोलारिस के लिए वैश्विक हॉटकीज़ को देखा, क्योंकि यह मेरे एकॉर्न बीबीसी कंप्यूटर पर करना आसान था। आखिरकार हमने इसे कुछ मालिकाना कोड के साथ xlib से नीचे के स्तर पर गैर-पोर्टेबल तरीके से हल करने का फैसला किया। चूंकि हमारे सॉफ़्टवेयर इंस्टालेशन को सुपरसुइर प्राइवेटिलिज के रूप में वैसे भी आवश्यक था, हम डेमोंस के रूप में उपयुक्त सॉफ़्टवेयर हुक सम्मिलित करने में सक्षम थे।

लिनक्स (आजकल) के लिए आपको ओएस स्तर पर कीबोर्ड ईवेंट को संसाधित करके सॉफ़्टवेयर समाधान की तलाश करनी चाहिए। मैं यहां एक नज़र http://code.google.com/p/logkeys/ शुरू करूंगा: http://code.google.com/p/logkeys/

एक अधिक सामान्य समाधान के लिए USB और USB के साथ एक छोटा पीसी बोर्ड होना चाहिए, जो कंप्यूटर पर माउस और कीबोर्ड के रूप में कार्य करता है और आवश्यकतानुसार कीबोर्ड कीज़ का अनुवाद करता है। लेकिन यह इतना लचीला नहीं होगा यदि आप मैपिंग को अक्सर बदलना चाहते हैं।





xlib