Проигнорируйте автоматическое повторение в приложениях X11

Если Вы нажимаете и держите ключ в X11, в то время как AutoRepeat включают, Вы непрерывно получаете события KeyPress и KeyRelease. Я знаю, что AutoRepeat может быть отключен с помощью функционального XAutoRepeatOff (), но это изменяет настройки для целого X-сервера. Существует ли способ или отключить AutoRepeat для отдельного приложения или проигнорировать повторенные нажатия клавиш?

То, что я ищу, является единственным событием KeyPress, когда клавиша нажата и единственное событие KeyRelease, когда клавиша отпускается, не вмешиваясь в установку AutoRepeat X-сервера.

Вот минимальный пример для получения Вас движение (главным образом от Новичка Xlib Tutorial):

#include 
#include 
#include 
#include 
#include 
#include 
#include 

Display *dis;
Window win;
XEvent report;

int main ()
{
  dis = XOpenDisplay (NULL);
  // XAutoRepeatOn(dis);
  win = XCreateSimpleWindow (dis, RootWindow (dis, 0), 1, 1, 500, 500,
        0, BlackPixel (dis, 0), BlackPixel (dis, 0));
  XSelectInput (dis, win, KeyPressMask | KeyReleaseMask);
  XMapWindow (dis, win);
  XFlush (dis);

  while (1)
    {
      XNextEvent (dis, &report);
      switch (report.type)
 {
 case KeyPress:
   fprintf (stdout, "key #%ld was pressed.\n",
     (long) XLookupKeysym (&report.xkey, 0));
   break;
 case KeyRelease:
   fprintf (stdout, "key #%ld was released.\n",
     (long) XLookupKeysym (&report.xkey, 0));
   break;
 }
    }

  return (0);
}

21
задан mzuther 20 January 2010 в 10:34
поделиться

4 ответа

Когда вы получаете отпускание клавиши, и следующим событием является нажатие клавиши той же комбинации клавиш, то происходит автоповтор, и клавиша не была отпущена автоматически. Вы можете использовать подобный код для просмотра следующего события

if (event->type == KeyRelease && XEventsQueued(disp, QueuedAfterReading))
{
  XEvent nev;
  XPeekEvent(disp, &nev);

  if (nev.type == KeyPress && nev.xkey.time == event->xkey.time &&
      nev.xkey.keycode == event->xkey.keycode)
  {
    /* Key wasn’t actually released */
  }
}
19
ответ дан 29 November 2019 в 21:05
поделиться

Вы можете использовать функцию XKBSETDECTECTALEAUTOREPEAT , чтобы сообщить об этом сервере X только отправлять события Keyrelease, когда пользователь На самом деле выпускает ключ - когда вы не хотите, чтобы события Autorepeat вы отказываетесь от любого клавиши без совпадения keyrelease.

9
ответ дан 29 November 2019 в 21:05
поделиться

Вы можете установить таймер, когда клавиша нажата или выпускается, и игнорирует события ключей и клавиатуры, которые происходят в интервале повторения.

1
ответ дан 29 November 2019 в 21:05
поделиться

Для справки, вот рабочий минимальный пример, который удаляет автоматически повторяющиеся события KeyPress . Спасибо, кралик!

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

Display *dis;
Window win;
XEvent report;

int main ()
{
  dis = XOpenDisplay (NULL);
  // XAutoRepeatOn(dis);
  win = XCreateSimpleWindow (dis, RootWindow (dis, 0), 1, 1, 500, 500,
        0, BlackPixel (dis, 0), BlackPixel (dis, 0));
  XSelectInput (dis, win, KeyPressMask | KeyReleaseMask);
  XMapWindow (dis, win);
  XFlush (dis);

  while (1)
    {
      XNextEvent (dis, &report);
      switch (report.type)
 {
 case KeyPress:
   fprintf (stdout, "key #%ld was pressed.\n",
     (long) XLookupKeysym (&report.xkey, 0));
   break;
 case KeyRelease:
   {
     unsigned short is_retriggered = 0;

     if (XEventsQueued(dis, QueuedAfterReading))
       {
         XEvent nev;
         XPeekEvent(dis, &nev);

         if (nev.type == KeyPress && nev.xkey.time == report.xkey.time &&
             nev.xkey.keycode == report.xkey.keycode)
           {
             fprintf (stdout, "key #%ld was retriggered.\n",
               (long) XLookupKeysym (&nev.xkey, 0));

             // delete retriggered KeyPress event
             XNextEvent (dis, &report);
             is_retriggered = 1;
           }
       }

     if (!is_retriggered)
       fprintf (stdout, "key #%ld was released.\n",
         (long) XLookupKeysym (&report.xkey, 0));
   }
   break;
 }
    }

  return (0);
}
5
ответ дан 29 November 2019 в 21:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: