Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Keyboard 忽略X11应用程序中的自动重复_Keyboard_X11_Autorepeat - Fatal编程技术网

Keyboard 忽略X11应用程序中的自动重复

Keyboard 忽略X11应用程序中的自动重复,keyboard,x11,autorepeat,Keyboard,X11,Autorepeat,如果在启用自动重放的同时按住X11中的某个键,则会连续收到按键和按键释放事件。我知道可以使用函数XAutoRepeatOff()禁用AutoRepeat,但这会更改整个X服务器的设置。有没有一种方法可以禁用单个应用程序的自动恢复功能,或者忽略重复的击键 我要寻找的是按键时的单个KeyPress事件和按键释放时的单个keyprelease事件,而不会干扰X服务器的自动回复设置 下面是一个简单的示例(主要来自以下方面): #包括 #包括 #包括 #包括 #包括 #包括 #包括 显示*dis; 窗口赢

如果在启用自动重放的同时按住X11中的某个键,则会连续收到按键按键释放事件。我知道可以使用函数XAutoRepeatOff()禁用AutoRepeat,但这会更改整个X服务器的设置。有没有一种方法可以禁用单个应用程序的自动恢复功能,或者忽略重复的击键

我要寻找的是按键时的单个KeyPress事件和按键释放时的单个keyprelease事件,而不会干扰X服务器的自动回复设置

下面是一个简单的示例(主要来自以下方面):

#包括
#包括
#包括
#包括
#包括
#包括
#包括
显示*dis;
窗口赢;
XEvent报告;
int main()
{
dis=XOpenDisplay(空);
//XAutoRepeatOn(dis);
win=XCreateSimpleWindow(dis,RootWindow(dis,0),1,1500,500,
0,黑像素(dis,0),黑像素(dis,0);
X选择输入(dis、win、按键掩码|按键释放掩码);
XMapWindow(dis,win);
XFlush(dis);
而(1)
{
XNextEvent(dis和报告);
开关(report.type)
{
外壳按键:
fprintf(标准输出,“按了#%ld键。\n”,
(长)XLookupKeysym(&report.xkey,0));
打破
案例密钥释放:
fprintf(标准输出,“密钥#%ld已释放。\n”,
(长)XLookupKeysym(&report.xkey,0));
打破
}
}
返回(0);
}

您可以在按键或释放按键时设置计时器,并忽略重复间隔内发生的按键按下和按键释放事件。

您可以使用该功能告知X服务器仅在用户实际释放按键时发送按键释放事件-当您不希望自动回复事件时,然后,您放弃任何没有匹配释放键的按键。

当您收到一个释放键,并且下一个事件是相同组合键的按键时,它将自动重复,并且该键未被实际释放。您可以使用这样的代码查看下一个事件

if(事件->类型==keyrease&&XEventsQueued(disp,QueuedAfterReading))
{
XEvent-nev;
XPeekEvent(disp和nev);
如果(nev.type==KeyPress&&nev.xkey.time==event->xkey.time&&
nev.xkey.keycode==事件->xkey.keycode)
{
/*钥匙实际上并没有被释放*/
}
}

为了供您参考,这里有一个删除自动重复的按键事件的最小示例。谢谢你,克莱克

#包括
#包括
#包括
#包括
#包括
#包括
#包括
显示*dis;
窗口赢;
XEvent报告;
int main()
{
dis=XOpenDisplay(空);
//XAutoRepeatOn(dis);
win=XCreateSimpleWindow(dis,RootWindow(dis,0),1,1500,500,
0,黑像素(dis,0),黑像素(dis,0);
X选择输入(dis、win、按键掩码|按键释放掩码);
XMapWindow(dis,win);
XFlush(dis);
而(1)
{
XNextEvent(dis和报告);
开关(report.type)
{
外壳按键:
fprintf(标准输出,“按了#%ld键。\n”,
(长)XLookupKeysym(&report.xkey,0));
打破
案例密钥释放:
{
无符号短路为_refigerred=0;
if(XEventsQueued(dis,QueuedAfterReading))
{
XEvent-nev;
XPeekEvent(dis和nev);
如果(nev.type==KeyPress&&nev.xkey.time==report.xkey.time&&
nev.xkey.keycode==report.xkey.keycode)
{
fprintf(标准输出,“已重新触发密钥#%ld。\n”,
(长)XLookupKeysym(&nev.xkey,0));
//删除重新触发的按键事件
XNextEvent(dis和报告);
被重新触发=1;
}
}
如果(!被重新触发)
fprintf(标准输出,“密钥#%ld已释放。\n”,
(长)XLookupKeysym(&report.xkey,0));
}
打破
}
}
返回(0);
}

另一种方法。它对我有用

char keyz[1024] = {0};
bool physical;
XEvent event, nev;

while (!quit) {
    XNextEvent(display, &event);
    ...
    switch(event.type) {
        case KeyPress:
            physical = (keyz[event.xkey.keycode] == 0);
            keyz[event.xkey.keycode] = 1;
            keyboard(event.xkey.window, true, event.xkey.keycode, physical);
            break;
        case KeyRelease:
            physical = true;
            if (XPending(display)) {
                XPeekEvent(display, &nev);
                if (nev.type == KeyPress && nev.xkey.time == event.xkey.time 
                && nev.xkey.keycode == event.xkey.keycode) physical = false;
            }
            if (physical) keyz[event.xkey.keycode] = 0;
            keyboard(event.xkey.window, false, event.xkey.keycode, physical);
            break;
    ...
    }

这是我想出的解决办法

XEvent event;

while(1)
{
    XNextEvent(display, &event);

    switch(event.type)
    {
        // Other cases
        case ...:
            ...
            break;
        ...

        // On KeyRelease
        case KeyRelease:
        {
            char keys[32];
            XQueryKeymap(display, keys);

            if(!(keys[event.xkey.keycode>>3] & (0x1 << (event.xkey.keycode % 8))))
            {
                // Stuff to do on KeyRelease
                ...
            }
        }
        break;

        // On KeyPress
        case KeyPress:
            // Stuff to do on KeyPress
            ...
            break;
        default:
            ...
    }
}
XEvent事件;
而(1)
{
XNextEvent(显示和事件);
开关(事件类型)
{
//其他情况
案例…:
...
打破
...
//关于按键释放
案例密钥释放:
{
字符键[32];
XQueryKeymap(显示、按键);

如果(!(keys[event.xkey.keycode>>3]&(0x1,谢谢,这正是我一直在寻找的!这是否有任何理由使用XEventsQueued with QueuedaftReading而不是更便宜的QueuedAlready?另外,XkbSetDetectableAutorepeat不是更好的方法,因为猜测更少?
char keyz[1024] = {0};
bool physical;
XEvent event, nev;

while (!quit) {
    XNextEvent(display, &event);
    ...
    switch(event.type) {
        case KeyPress:
            physical = (keyz[event.xkey.keycode] == 0);
            keyz[event.xkey.keycode] = 1;
            keyboard(event.xkey.window, true, event.xkey.keycode, physical);
            break;
        case KeyRelease:
            physical = true;
            if (XPending(display)) {
                XPeekEvent(display, &nev);
                if (nev.type == KeyPress && nev.xkey.time == event.xkey.time 
                && nev.xkey.keycode == event.xkey.keycode) physical = false;
            }
            if (physical) keyz[event.xkey.keycode] = 0;
            keyboard(event.xkey.window, false, event.xkey.keycode, physical);
            break;
    ...
    }
XEvent event;

while(1)
{
    XNextEvent(display, &event);

    switch(event.type)
    {
        // Other cases
        case ...:
            ...
            break;
        ...

        // On KeyRelease
        case KeyRelease:
        {
            char keys[32];
            XQueryKeymap(display, keys);

            if(!(keys[event.xkey.keycode>>3] & (0x1 << (event.xkey.keycode % 8))))
            {
                // Stuff to do on KeyRelease
                ...
            }
        }
        break;

        // On KeyPress
        case KeyPress:
            // Stuff to do on KeyPress
            ...
            break;
        default:
            ...
    }
}