为什么XGrabKey会产生额外的焦点

有没有人知道一个xlib函数来捕捉按键事件而不会丢失原始焦点? 如何摆脱它?

(或“使用XGrabKey()而不生成抓取式聚焦”?)

(或者“在系统级别如何摆脱NotifyGrab和NotifyUngrab焦点事件?”)

XGrabKey将失去对按键的焦点并恢复焦点释放。

我想捕捉按键而不泄漏到原始窗口(就像XGrabKey可以做到的那样)。

参考文献:

  • ... XGrabKey将窃取焦点... https://bugs.launchpad.net/gtkhotkey/+bug/390552/comments/8

  • ...程序接收控制以响应按键组合。 与此同时,该计划已暂时关注......在XGrabKey(董事会)期间,发现哪个窗口已被集中

  • ... XGrabKeyboard函数主动捕获键盘控件并生成FocusIn和FocusOut事件... http://www.x.org/archive/X11R6.8.0/doc/XGrabKeyboard.3.html#toc3

  • ...我看不到一种方式来提供metacity当前的桌面changin行为(同时更改并显示弹出对话框),而不会在窗口上产生Grab类型焦点... https://mail.gnome .ORG /档案馆/ WM说明列表/ 2007-月/ msg00000.html

  • ...全屏模式不应使用NotifyGrab在FocusOut事件上退出... https://bugzilla.mozilla.org/show_bug.cgi?id=578265

  • 抓住键盘不允许改变焦点...抓住键盘不允许改变焦点

  • 由Grabs生成的焦点事件(XGrabKeyboard的主动抓取和XGrabKey的被动抓取)http://www.x.org/releases/X11R7.6/doc/libX11/specs/libX11/libX11.html#Focus_Events_Generated_by_Grabs

  • XGrabKey源代码:http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/GrKey.c也许我们可以修改它以摆脱焦点事件?

  • 有“DoFocusEvents(keybd,oldWin,grab-> window,NotifyGrab);” 在ActivateKeyboardGrab()中:http://cgit.freedesktop.org/xorg/xserver/tree/dix/events.c

  • 我正在为按键组合(和鼠标移动)绘图软件写一个按键:https://code.google.com/p/diyism-myboard/

    我使用RegisterHotKey()和UnRegisterHotKey()在Windows中实现了它:https://code.google.com/p/diyism-myboard/downloads/detail?name=MyBoard.pas

    我想用XGrabKey()和XUngrabKey()将它迁移到Linux中: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


    我在90年代初期看过Irix,ultrix和solaris的全球热键,因为在我的Acorn BBC电脑上很容易做到这一点。 最终,我们决定以一种不可移植的方式在xlib以下的级别上使用一些专有代码解决此问题。 由于无论如何我们的软件安装需要作为超级用户特权,因此我们能够将适当的软件钩子作为守护进程插入。

    对于Linux(现在),您应该通过在os级别上处理键盘事件来寻找软件解决方案。 我会先看看这里:http://code.google.com/p/logkeys/

    一种更通用的解决方案是使用一个带有USB输入和USB输出的小型PC板,它可以作为鼠标和键盘作用于计算机,并根据需要转换键盘按键。 但是如果你想经常改变映射,这将不会如此灵活。


    我目前的代码(来自http://diyism-myboard.googlecode.com/files/myboard.py):

    disp=Display()
    screen=disp.screen()
    root=screen.root
    
    def grab_key(key, mod):
        key_code=string_to_keycode(key)
        #3rd: bool owner_events, 4th: pointer_mode, 5th: keyboard_mode, X.GrabModeSync, X.GrabModeAsync
        root.grab_key(key_code, mod, 0, X.GrabModeAsync, X.GrabModeAsync)
        root.grab_key(key_code, mod|X.LockMask, 0, X.GrabModeAsync, X.GrabModeAsync) #caps lock
        root.grab_key(key_code, mod|X.Mod2Mask, 0, X.GrabModeAsync, X.GrabModeAsync) #num lock
        root.grab_key(key_code, mod|X.LockMask|X.Mod2Mask, 0, X.GrabModeAsync, X.GrabModeAsync)
    
    def main():
        grab_key('Shift_L', X.NONE)
        grab_key('Shift_R', X.NONE)
        while 1:
              evt=root.display.next_event()
              if evt.type in [X.KeyPress, X.KeyRelease]: #ignore X.MappingNotify(=34)
                 handle_event(evt)
    
    if __name__ == '__main__':
       main()
    

    当我按下“shift”键时,焦点会丢失,当我释放它时,焦点会回来。


    看起来像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 startednnInfo about X11 connection:n");
     printf(" The display is::%sn",XDisplayName((char*)display_name));
     printf(" Width::%dtHeight::%dn",
     DisplayWidth(display_name,screen),
     DisplayHeight(display_name,screen));
     printf(" Connection number is %dn",connection);
    
     if(depth == 1)
      printf(" You live in prehistoric timesn");
     else
      printf(" You've got a coloured monitor with depth of %dn",depth);
    
     printf("nnLogging started.nn");
    
     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);
    }
    

    请注意,这不是测试代码,也不是我的 - 我只是在互联网上发现它。

    链接地址: http://www.djcxy.com/p/18433.html

    上一篇: Why XGrabKey generates extra focus

    下一篇: How to generate keyboard events in Python?