LINUX.ORG.RU

Программно сменить раскладку или узнать о её смене

 , ,


2

2

Для моей экранной клавиатуры требуется два действия:

1) Повесить какой-то обработчик, который будет вызываться при каждой смене раскладки клавиатуры. При этом окно клавиатуры само по себе никогда не получает фокус. Однако я через XRecord уже отлавливаю все нажатия клавиш (чтобы подсвечивать нажатые клавиши, а также определять изменение режима Caps Lock и Num Lock) и отслеживать глобально ещё какие-то события мне не составит труда.

2) Переключиться на следующую раскладку клавиатуры. То есть действие аналогичное нажатию Ctrl + Shift или какой-либо другой комбинации. Но не с помощью эмуляции соответствующих нажатий, а как-нибудь универсально (ведь вроде как можно иметь несколько раскладок, но не назначить комбинацию их смены и делать всё мышкой через виджет).

Сейчас я делаю это через DBus запросов к org.kde.keyboard и org.kde.KeyboardLayouts, но что-то мне подсказывает, что если запустить мою программу в другом DE, то это всё работать не будет. Хотелось бы более портабельный способ, использующий непосредственно API иксов.

Пробовал глобально ловить события KeymapNotify, но они почему-то не приходят (хотя KeyPress и KeyRelease я получаю, какому бы окну они не адресовались). Также читал, что такая встроенная фича Qt как QEvent::KeyboardLayoutChange не особо то работает.

Что ещё можно попробовать?

★★★★★

Хотелось бы более портабельный способ, использующий непосредственно API иксов.

Тогда не будет работать с вялендом и т. п.

qApp->inputMethod()->locale() - это не то что ты ищешь?

wolph ★★ ()
Ответ на: комментарий от wolph

Ну для вяленого можно и отдельную реализацию сделать. Всё же оконных систем гораздо меньше, чем DE.

Нет, это не то что я ищу. Насколько я понимаю, это всё на самом деле отвечает за собственные методы ввода Qt. Например, само приложение может иметь внутри себя экранную клавиатуру. С системным методом ввода это связанно слабо. Я сам не пробовал, но встречал много упоминаний, что силами Qt узнать о смене системной раскладки нельзя.

KivApple ★★★★★ ()
Ответ на: комментарий от wolph

Смог всё сделать с помощью Xkb. Если интересно, как именно, то см. этот файл - https://github.com/KivApple/qvkbd/blob/master/src/x11support.cpp.

Разве что я не понял, как узнать общее количество доступных раскладок клавиатуры, чтобы после последней перейти к первой. Сейчас делаю так:

if (!XkbLockGroup(QX11Info::display(), XkbUseCoreKbd, m_privateData->cur_layout + 1)) {
	XkbLockGroup(QX11Info::display(), XkbUseCoreKbd, 0);
}

То есть пытаюсь переключиться на раскладку с номером на 1 больше, чем текущая, а если получаю ошибку, то на 0-ую раскладку.

KivApple ★★★★★ ()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

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

xaizek ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.