Исключая некоторые ключи из XGrabKeyboard - PullRequest
5 голосов
/ 26 сентября 2010

Рассмотрим приложение, в котором желательно захватить клавиатуру, когда она сфокусирована, чтобы захватить все команды менеджера окон (Alt + F4 и еще много чего) для обработки. Теперь у этого есть недостаток, заключающийся в том, что у пользователя нет возможности переключаться на другое приложение или виртуальный рабочий стол с помощью клавиатуры, когда клавиатура захватывается. Я хотел бы иметь пользовательский белый список сочетаний клавиш (скажем, сочетаний клавиш для переключения виртуальных рабочих столов), которые исключены из захвата.

Я могу придумать два возможных подхода. При получении ключевого события из белого списка либо

  1. Каким-то образом скажите X, чтобы она продолжала обрабатываться как обычно. Это звучит как более естественный способ сделать это, но я не могу найти способ сделать это, или
  2. Отключите клавиатуру и повторно отправьте событие вручную диспетчеру окон для обработки, однако я не знаю, куда его отправить (корневое окно?) Или это будет работать.

Кто-нибудь может заполнить пробелы в них? Любые другие предложения?

Если нет способа исключить клавиши из захвата, я думаю, мне придется довольствоваться наличием "escape-клавиши", которая убирает клавиатуру при нажатии. Однако пользователю придется нажать и то, и другое, а затем команду менеджера окон, что не так приятно.

1 Ответ

4 голосов
/ 26 сентября 2010

Я не думаю, что есть способ сделать это. Ни один из механизмов не работает так, как вам нужно.

Подход 1 - это то, что делает оконный менеджер, если он решает, например, не перехватывать щелчок или клавишу. Однако WM использует «пассивные» захваты для определенных ключей (XGrabKey = пассивный XGrabKeyboard = active), а затем XAllowEvents (). XAllowEvents () не работает с XGrabKeyboard (). также, когда вы выполняете XAllowEvents с одним из режимов воспроизведения, событие воспроизведения игнорирует все пассивные захваты в окне, в котором был исходный захват, и во всех его родительских окнах. Захваты WM будут в корневом окне, которое всегда будет родительским, так что нет возможности воспроизвести в корневом окне, насколько я могу судить. В любом случае выполнение XGrabKey для каждого возможного ключа будет своего рода психом.

Подход 2 будет иметь проблемы с плохим состоянием гонки, потому что другие события с ключами и мышью могут быть обработаны до того, как вы сможете отправить их повторно, поэтому вы переупорядочиваете ключи и отправляете события в разрушенные окна и другую путаницу. Кроме того, нет хорошего способа отправить ключевое событие. XSendEvent () игнорируется многими клиентами (он устанавливает флаг send_event в событии, позволяющем это). Расширение XTest может быть использовано, но может быть отключено на производственных X-серверах, но все еще имеет проблемы с состоянием гонки.

Что вам, вероятно, понадобится, это расширение протокола, позволяющее вам делать AllowEvents (mode = ReplayKeyboard) после GrabKeyboard и не обходя пассивные захваты в родительских окнах.

Одно предостережение в том, что я не знаю всех диких вещей, которые можно сделать с XKB и XInput2, поэтому, возможно, что-то есть в этих расширениях.

В любом случае, насколько я знаю, вы должны согласиться на "escape-ключ", хотя в конечном итоге было бы неплохо, чтобы спецификации X-сервера и / или оконного менеджера имели "VMWare / VNC-тип-осведомленность о вещах", «Это не поможет вам в краткосрочной перспективе. Расширение спецификации EWMH может быть таким же простым, как новый _NET_WM_WINDOW_TYPE для vnc / vmware / stuff-like-that, и диспетчер окон может уменьшить свои привязки клавиш или добавить дополнительный модификатор к ним или что-то еще, когда это окно было сфокусировано, например.

...