微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果不创建窗口,是否可以检测到当前的XCB修改器状态?

如何解决如果不创建窗口,是否可以检测到当前的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 举报,一经查实,本站将立刻删除。