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