gpt4 book ai didi

x11 - X11/Xlib 的全局热键

转载 作者:太空宇宙 更新时间:2023-11-04 06:38:46 24 4
gpt4 key购买 nike

我的目标是让一个程序在后台休眠,但可以由用户通过一些“热键”激活。通过深入研究 Xlib 手册和 Xlib O'reilly 手册,我发现正确的方法是使用 XGrabKey。然而,我对这个过程的理解是不正确的,因为简单的概念证明是行不通的。

我的理解是,如果我使用根窗口作为 grab_window 调用 XGrabKey,并且 owner_events 为 false,那么每当我的热键被按下时,事件将发送到根窗口。如果我然后从根窗口中选择 KeyPress 事件,然后监听 X 事件,我应该在按下热键时得到一个按键事件。我在下面粘贴了一个最小的示例。

我期望的是,当程序运行时,无论哪个窗口获得焦点,如果按下 Ctrl+Shift+K,我的程序都应该输出“按下热键!”在控制台中,然后终止。

此外,据我了解,如果 XGrabKey 失败,默认的错误处理程序将显示一条消息,并且由于它没有显示,我假设调用成功。

显然,我的理解存在某种缺陷。谁能指出我正确的方向?

#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>


using namespace std;


int main()
{
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;

unsigned int modifiers = ControlMask | ShiftMask;
int keycode = XKeysymToKeycode(dpy,XK_Y);
Window grab_window = root;
Bool owner_events = False;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;

XGrabKey(dpy, keycode, modifiers, grab_window, owner_events, pointer_mode,
keyboard_mode);

XSelectInput(dpy, root, KeyPressMask );
while(true)
{
bool shouldQuit = false;
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
cout << "Hot key pressed!" << endl;
XUngrabKey(dpy,keycode,modifiers,grab_window);
shouldQuit = true;

default:
break;
}

if(shouldQuit)
break;
}

XCloseDisplay(dpy);
return 0;
}

最佳答案

您的程序在这里运行。我的猜测是您激活了另一个修饰符,例如 NumLock。 GrabKey 仅适用于精确修饰符掩码。

例如,这里有一些来自 metacity 窗口管理器的 (GPL) 代码

/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
static void
meta_change_keygrab (MetaDisplay *display,
Window xwindow,
gboolean grab,
int keysym,
unsigned int keycode,
int modmask)
{
unsigned int ignored_mask;

/* Grab keycode/modmask, together with
* all combinations of ignored modifiers.
* X provides no better way to do this.
*/

meta_topic (META_DEBUG_KEYBINDINGS,
"%s keybinding %s keycode %d mask 0x%x on 0x%lx\n",
grab ? "Grabbing" : "Ungrabbing",
keysym_name (keysym), keycode,
modmask, xwindow);

/* efficiency, avoid so many XSync() */
meta_error_trap_push (display);

ignored_mask = 0;
while (ignored_mask <= display->ignored_modifier_mask)
{
if (ignored_mask & ~(display->ignored_modifier_mask))
{
/* Not a combination of ignored modifiers
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}

if (meta_is_debugging ())
meta_error_trap_push_with_return (display);
if (grab)
XGrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow,
True,
GrabModeAsync, GrabModeSync);
else
XUngrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow);

if (meta_is_debugging ())
{
int result;

result = meta_error_trap_pop_with_return (display, FALSE);

if (grab && result != Success)
{
if (result == BadAccess)
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
else
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to grab key %s with modifiers %x\n",
keysym_name (keysym), modmask | ignored_mask);
}
}

++ignored_mask;
}

meta_error_trap_pop (display, FALSE);
}

关于x11 - X11/Xlib 的全局热键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4537092/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com