当前位置: 首页 > 面试题库 >

监听键盘事件而不在X11中消耗它们-键盘挂接

林鸿彩
2023-03-14
问题内容

我试图编写一个程序,只要在Ubuntu(KDE)中按下该键,它就会挂接键盘消息以发音每个键的名称。不会干扰程序中键盘的正常操作(只是宣布键名)。

这是我的程序:

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

using namespace std;

void SendPressKeyEvent(Display *display, XKeyEvent xkey)
{
    Window current_focus_window;
    int current_focus_revert;
    XGetInputFocus(display, &current_focus_window, &current_focus_revert);
    xkey.type =  KeyPress;
    xkey.display = display;
    xkey.window = current_focus_window;
    xkey.root = DefaultRootWindow(display);
    xkey.subwindow = None;
    xkey.time = 1000 * time(0);
    xkey.x = 0;
    xkey.y = 0;
    xkey.x_root = 0;
    xkey.y_root = 0;
    xkey.same_screen = True;
    XSendEvent(display, InputFocus,  True, KeyPressMask, (XEvent *)(&xkey));
}

void SendReleaseKeyEvent(Display *display, XKeyEvent xkey)
{
    Window current_focus_window;
    int current_focus_revert;
    XGetInputFocus(display, &current_focus_window, &current_focus_revert);
    xkey.type =  KeyRelease;
    xkey.display = display;
    xkey.window = current_focus_window;
    xkey.root = DefaultRootWindow(display);
    xkey.subwindow = None;
    xkey.time = 1000 * time(0);
    xkey.x = 0;
    xkey.y = 0;
    xkey.x_root = 0;
    xkey.y_root = 0;
    xkey.same_screen = True;
    XSendEvent(display, InputFocus, True, KeyReleaseMask, (XEvent *)(&xkey));
}

void *TaskCode(void* arg)
{
    switch(*(int*)arg)
    {
    case 38:
        system("espeak -v en "  "\"a\"");
    }
    return 0;
}

int main()
{
    Display *display = XOpenDisplay(0);
    if(display == 0)
        exit(1);
    XGrabKeyboard(display, DefaultRootWindow(display), True, GrabModeAsync, GrabModeAsync, CurrentTime);
    XEvent event;
    while(true)
    {
        XNextEvent(display, &event);
        if(event.type == Expose)
        {

        }
        if(event.type == KeyPress)
        {
            SendPressKeyEvent(display,event.xkey);
            if(event.xkey.keycode == 38)
            {
                pthread_t thread;
                int thread_arg = event.xkey.keycode;
                pthread_create(&thread,0, TaskCode, (void*) &thread_arg);
            }
        }
        if(event.type == KeyRelease)
            SendReleaseKeyEvent(display,event.xkey);
    }
    XCloseDisplay(display);
}

该程序仅适用于a可以扩展到其他键的键。

但是,当该程序运行时,某些程序(例如Chromium)不会在其编辑框中显示闪烁信号(光标)。同样,所有的KDE热键也被禁用。

如何解决?


问题答案:

这是我的例子

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <ctype.h>


int main ()
{
    Display* d = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(d);
    Window curFocus;
    char buf[17];
    KeySym ks;
    XComposeStatus comp;
    int len;
    int revert;

    XGetInputFocus (d, &curFocus, &revert);
    XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);

    while (1)
    {
        XEvent ev;
        XNextEvent(d, &ev);
        switch (ev.type)
        {
            case FocusOut:
                printf ("Focus changed!\n");
                printf ("Old focus is %d\n", (int)curFocus);
                if (curFocus != root)
                    XSelectInput(d, curFocus, 0);
                XGetInputFocus (d, &curFocus, &revert);
                printf ("New focus is %d\n", (int)curFocus);
                if (curFocus == PointerRoot)
                    curFocus = root;
                XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);
                break;

            case KeyPress:
                printf ("Got key!\n");
                len = XLookupString(&ev.xkey, buf, 16, &ks, &comp);
                if (len > 0 && isprint(buf[0]))
                {
                    buf[len]=0;
                    printf("String is: %s\n", buf);
                }
                else
                {
                    printf ("Key is: %d\n", (int)ks);
                }
        }

    }
}

它不可靠,但在大多数情况下都有效。(它显示的是我正在此框中输入的键)。您可能会调查为什么有时会失败;)原则上它也不能显示热键。热键是获取的密钥,只有一个客户端可以获取获取的密钥。除了加载为此目的而设计的特殊X11扩展(例如XEvIE)以外,这里绝对不能做任何事情。



 类似资料:
  • 本文向大家介绍vue如何监听键盘事件?相关面试题,主要包含被问及vue如何监听键盘事件?时的应答技巧和注意事项,需要的朋友参考一下 方法 addEventListener

  • 本文向大家介绍JavaScript监听键盘事件代码实现,包括了JavaScript监听键盘事件代码实现的使用技巧和注意事项,需要的朋友参考一下 在写网页的时候,常常需要监听键盘事件,让我们来看看如何实现吧。 监听方式 键盘事件往往是全局监听,设监听的函数为keyboard()。 keyup事件类型。该类型触发条件为按键按下去并松开。 //长按并松开只触发一次 document.addEventLi

  • 本文向大家介绍vue监听键盘事件的相关总结,包括了vue监听键盘事件的相关总结的使用技巧和注意事项,需要的朋友参考一下 按键修饰符 在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符: 你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。 为了在必要的情况下支持旧浏览器,Vue 提供了

  • 所以我无法编译这段代码。我正在用一本过时的书来学习,到目前为止,大多数东西都很有效。我只遇到了几个通过谷歌搜索很容易解决的障碍,但我想这一个要复杂一些。下面是引发错误的两段代码。 在ckl.calculatorKeypadListener的两个实例中,我都收到一个错误,说找不到符号。这是我唯一收到的两个错误,我相信这是由于Java的更新。有人能帮助我做错了什么吗?如果可能的话,我不想重写整个东西,

  • 键盘事件的种类 键盘事件由用户击打键盘触发,主要有keydown、keypress、keyup三个事件,它们都继承了KeyboardEvent接口。 keydown:按下键盘时触发。 keypress:按下有值的键时触发,即按下 Ctrl、Alt、Shift、Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发keydown事件,再触发这个事件。 keyup:松开键盘时触发该事件。

  • 输入框接口 用于弹起输入框,供用户输入文字。可以通过注册监听函数进行监听用户的输入,监听完毕请及时调用注销方法,取消监听。 BK.UI.showKeyboard(Object) 显示输入框,弹出键盘 手Q版本:7.6.5 函数参数Object: 属性名 类型 是否必填 说明 deaultText string 否 默认要展示的字符串 complete Function 否 接口调用完成回调 示例: