如何解决如果不创建窗口,是否可以检测到当前的XCB修改器状态?
我使用Xkb sticky
选项,并且我想编写一个程序,当修改键状态更改时,该程序向stdout发出一些文本,例如Ctrl是否处于活动状态时,无论是否按下物理Ctrl键。我希望该程序能够在不创建可见的X窗口并使它保持打开状态的情况下工作,否则会妨碍我对其他应用程序的使用。
使用Xkb,XkbCommon,Xlib和/或XCB库是否可能?我尝试按照建议的in the Xkb spec使用XNextEvent
,但是此功能会永远阻止。
我对实现的完整尝试是here,但这是相关的部分:
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
/* VarIoUs X and Xkb data that are often needed together */
typedef struct ExtensionInfo {
display* display; /* An X display */
int base_event_code; /* Integer code offset for Xkb events */
int base_err_code; /* Integer code offset for Xkb errors */
int xkb_version_major; /* Dual-purpose version indicator; see XkbOpendisplay(3) */
int xkb_version_minor; /* Dual-purpose version indicator; see XkbOpendisplay(3) */
int xkb_reason; /* Error reason if XkbOpendisplay fails,or success reason */
} ExtensionInfo;
int main(int argc,char *argv[]) {
ExtensionInfo *extension_info;
XkbEvent xkb_event;
extension_info->display = XkbOpendisplay(
/* NULL here is allowed by XkbOpendisplay but not mentioned explicitly
* in the XkbOpendisplay man page - it defaults to $disPLAY */
NULL,&(extension_info->base_event_code),&(extension_info->base_err_code),&(extension_info->xkb_version_major),&(extension_info->xkb_version_minor),&(extension_info->xkb_reason)
);
const unsigned long int xkb_details_mask = (
XkbModifierBaseMask |
XkbModifierStateMask |
XkbModifierLatchMask |
XkbModifierLockMask
);
bool xkb_initialized = XkbSelectEventDetails(
extension_info->display,XkbUseCoreKbd,XkbStateNotifyMask,xkb_details_mask,xkb_details_mask
);
printf("Waiting...\n");
XNextEvent(extension_info->display,&xkb_event.core);
printf("Done.\n");
}
解决方法
通常是的,完全可以调用任何需要Window句柄的X11请求(例如,用于获取或设置选择内容)而无需在屏幕上弹出窗口-通过创建 InputOnly
窗口。
但是对于Xkb*
,您甚至不需要它。在发布的代码段中,您的问题是根本没有调用XkbSelectEvents
,因此没有Xkb事件将传递给您的X11客户端。
状态改变时,下面的小示例确实会发生事件:
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <err.h>
int main(void){
Display *dpy; int xkb_event;
if(!(dpy = XkbOpenDisplay(0,&xkb_event,0)))
errx(1,"cannot open display '%s'",XDisplayName(0));
XkbSelectEvents(dpy,XkbUseCoreKbd,XkbStateNotifyMask,XkbStateNotifyMask);
for(;;){
XkbEvent e; XNextEvent(dpy,&e.core);
if(e.type == xkb_event && e.any.xkb_type == XkbStateNotify)
warnx("xkb state changed!");
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。