【问题标题】:Recording multiple key presses in x11在 x11 中记录多个按键
【发布时间】:2019-05-31 07:39:14
【问题描述】:

我想记录同时按下的按键并使用 C 在 x11 中测试一个功能。例如,我可以设置类似, 如果按下“Q”, 让窗口调整大小。

但我找不到使用 Ctrl+Enter 等组合键执行相同操作的方法,因此当按下“Ctrl+Enter”时,窗口会调整大小。

x11 中是否有任何事件类型或掩码或函数来记录这些同时发生的关键事件?

下面的代码是我迄今为止编写的用于记录单个键并执行指定操作的代码。

// USES KEYBOARD KEY TO RESIZE A WINDOW

// Compile : gcc -o go key_and_win.c -lX11

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    Display *d;
    Window window;
    XEvent event, ev;
    int s;

    /* open connection with the server */
    d = XOpenDisplay(NULL);
    if (d == NULL)
    {
        fprintf(stderr, "Cannot open d\n");
        exit(1);
    }

    s = DefaultScreen(d);

    /* create window */
    window = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1,
                           BlackPixel(d, s), BlackPixel(d, s));

    /* select kind of events we are interested in */
    XSelectInput(d, window, StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask );

    /* map (show) the window */
    XMapWindow(d, window);

    /* event loop */
    while (1)
    {
        XNextEvent(d, &event);

        /* keyboard events */
        if (event.type == KeyPress)
        {
            printf( "KeyPress: %x\n", event.xkey.keycode );         

            if(event.xkey.keycode == 0x18)      // Resize on pressing Q as, key Q => 0x18
            {
                printf("Here in Q\n");

                int r = XResizeWindow(d, window, 100, 200);     // Resizing the window through Q keypress
                if(r==BadValue || r==BadWindow)
                    printf("Error in resizing\n");

                XNextEvent(d, &event);                          // To get ConfigureNotify event
                if(event.type == ConfigureNotify)
                    printf("Resized!\n");
                else
                    printf("Not resized\n");
                //XMapWindow(d, window);                            // Map the resized window   (not necessary)
            }
            /* exit on ESC key press */
            if ( event.xkey.keycode == 0x09 )
                break;
        }
    }

    /* close connection to server */
    XCloseDisplay(d);

    return 0;
}

【问题讨论】:

    标签: c keyboard x11


    【解决方案1】:

    你要看看event.xkey.state

    来自10.5.2 Keyboard and Pointer Events: 状态成员设置为指示事件之前指针按钮和修饰键的逻辑状态,这是一个或多个按钮或修饰键掩码的按位或运算:Button1Mask、Button2Mask、Button3Mask、Button4Mask、Button5Mask 、ShiftMaskLockMaskControlMask、Mod1Mask、Mod2Mask、Mod3Mask、Mod4Mask 和 Mod5Mask。

    【讨论】:

    • 嗨。我用event.xkey.state成员试了一下,发现当我按下Ctrl+Shift+Enter的时候,状态变成了21。如果只按下Ctrl+Enter,状态就是20。但是我也发现按下Ctrl+Shift+ X(X 可以是任何字母键)也给出 21。那么,如何指定 Ctrl+Shift+Enter 作为激活调整大小功能的组合?
    • 我只是将 if 的条件替换为 event.xkey.state == 21 以完成工作,但这并不能使其成为唯一的组合键。所以有可能这样做
    • state 只管理 按钮和修饰符(shift、control ...),这就是为什么 Ctrl+Shift 键给出 21 的原因。密钥由 keycode 给出,您需要同时查看 keycodestate
    • 您可以将它们与event.key.state * 256 + event.xkey.keycode 结合使用(如果 keycode 可以大于 255,则大于 256,当然,抱歉我现在不记得可能的值了)跨度>
    • 非常感谢。这种组合节省了很多。我找到了 Ctrl、Shift 和 Enter 的 unsigned int 键码。按下 Ctrl+Shift+Enter 时的 state 是 21。最后按下的键(在此处输入)的键码为 36。所以使用你的技巧,我将条件设置为 if(event.key.state * 256 + event.xkey.keycode == 21*256 + 36) ,这仅在需要时才有效键被按下。
    猜你喜欢
    • 1970-01-01
    • 2020-06-26
    • 2020-05-30
    • 2019-08-29
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2020-05-15
    相关资源
    最近更新 更多