为什么XGrabKey会生成额外的focusout和focusin事件?

2024-10-01 17:38:03 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有人知道一个xlib函数可以在不丢失原始焦点的情况下捕获按键事件?如何摆脱它?在

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

(或“如何在系统级别除去NotifyGrab和NotifyUngrab焦点事件?)在

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

我想在不泄漏到原始窗口的情况下捕获按键(就像XGrabKey一样)。在

参考文献:

  1. …XGrabKey会抢走焦点。。。 https://bugs.launchpad.net/gtkhotkey/+bug/390552/comments/8

  2. …程序接收控制,以响应组合键执行某些操作。同时,这个项目暂时集中在。。。 During XGrabKey(board), discover which window had been focused

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

  4. 我看不见 提供metacity当前桌面更改行为的方法(更改 同时显示弹出对话框)而不会导致 把焦点放在窗外。。。 https://mail.gnome.org/archives/wm-spec-list/2007-May/msg00000.html

  5. …对于使用NotifyGrab的FocusOut事件,不应退出全屏模式。。。 https://bugzilla.mozilla.org/show_bug.cgi?id=578265

  6. 抓住键盘不允许改变焦点。。。 grabbing keyboard doesnt allow changing focus

  7. Grabs生成的焦点事件(XGrabKeyboard的主动抓取和XGrabKey的被动抓取) 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也许我们可以修改它来去掉focus out事件?

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

我正在编写一个按键到按键组合(和鼠标移动)的映射软件:https://code.google.com/p/diyism-myboard/

我用RegisterHotKey()和UnRegisterHotKey()实现了它: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


Tags: httpsorgcomhttphtmlwwwgoogle事件
3条回答

我的当前代码(来自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”键时,焦点消失了,当我松开它时,焦点又回来了。在

最后,正如您所知道的,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:

^{pr2}$

现在我的板.py效果很好。在

如果您使用的是ubuntu raring updates edition,您可以尝试:

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

我在90年代初查看了Irix、ultrix和solaris的全球热键,就像在我的Acorn BBC电脑上很容易做到的那样。最终,我们决定在xlib以下的一个级别上用一些专有代码来解决这个问题。 由于我们的软件安装无论如何都需要超级用户权限,所以我们能够将适当的软件挂钩作为守护程序插入。在

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

一个更通用的解决方案是有一个带有USB输入和USB输出的小型PC板,它对计算机起到鼠标和键盘的作用,并根据需要转换键盘键。但是,如果您想经常更改映射,这就不那么灵活了。在

相关问题 更多 >

    热门问题