XSetInputFocus не работает - PullRequest
       16

XSetInputFocus не работает

1 голос
/ 01 октября 2011

В моем приложении Xlib мне нужно настроить клавиатуру так, чтобы она фокусировалась на конкретном компоненте, и я хотя бы делал это с XSetInputFocus. По какой-то причине я всегда получаю ошибку BadMatch, даже если мое окно видно (и на страницах руководства говорится, что причиной этой ошибки является окно, которое не отображается / не отображается). Когда я говорю, что он видим, я имею в виду, что вижу его на экране и знаю, что список запросов уже очищен.

Итак, вместо того, чтобы делиться своим огромным кодом, я нашел в интернете небольшую демонстрацию и попытался ее изменить. Я взял код обработки событий в Xlib, как показано в примере учебного пособия по Xlib , которое я нашел. Я попытался добавить следующую строку:

XSetInputFocus (display, win, RevertToNone, CurrentTime);

Прямо перед строкой

/* perform an events loop */

Я получил ошибку:

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  42 (X_SetInputFocus)
  Serial number of failed request:  12
  Current serial number in output stream:  12

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

  1. Создайте окно с XCreateSimpleWindow (которое должно быть InputOutput окном)
  2. Используйте XSelectInput и выберите в маске, чтобы также получить KeyPressMask)
  3. Карта окна (XMapWindow)
  4. Запросить фокусировку, используя XSetInputFocus, используя либо RevertToNone, либо RevertToParent (оба сбоя)

Я подозреваю, что это связано с тем, что мне нужно обрабатывать события создания окна, используя XNextEvent, пока я не закончу обрабатывать переопределение окна, но в этом случае я не знаю, когда я должен ждать (какие события я должен получить, прежде чем пытаться это?). В настоящее время я делаю это перед первым вызовом XNextEvent в моей программе.

Любая помощь будет высоко оценена. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 08 октября 2011

У меня была похожая проблема только вчера ... Это потому, что X-сервер обрабатывает события асинхронно; поэтому вам нужно дождаться отображения окна, прежде чем пытаться использовать XSetInputFocus () ...

Вы должны вызвать XIfEvent (), чтобы определить это.

Пример (написанный на freepascal):

// The filter-function, here you should return true if
//  the event parameter matches the one you want
//  in this case, I match the type to be MapNotify and the window to be the correct one
Function WaitForNotify(aDPY: PDisplay; anEvent: PXEvent; arg: TXPointer): LongBool; cdecl;
Begin
    Result:= (anEvent^._type = MapNotify) and (anEvent^.xmap.window = TWindow(arg));
End;

// XIfEvent cycles through the event cue, and evaluates each event through
//  the function you provide it
XIfEvent(dpy, @event, @WaitForNotify, TXPointer(xWindow));

// Then, once this call returns, you're shure you've got focus and you can safely call
//  XSetInpuFocus()
XSetInputFocus(dpy, XWindow, RevertToNone, CurrentTime);

Надеюсь, это поможет!

0 голосов
/ 07 марта 2014

Для меня также сработало упрощенное решение: После звонка на XMapWindow() я только что позвонил XSync(), прежде чем выполнить XSetInputFocus().

...