inputmethod: Allow input methods to grab the keyboard
This allows different input methods to get information about what's beign typed from the actual hardware. This is especially useful for non-latin script languages.
This commit is contained in:
parent
c5ea99cbe5
commit
454425b43f
4 changed files with 51 additions and 4 deletions
|
@ -33,6 +33,7 @@
|
|||
#include <QDBusPendingCall>
|
||||
#include <QDBusMessage>
|
||||
#include <QMenu>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
|
@ -472,6 +473,7 @@ void InputMethod::adoptInputMethodContext()
|
|||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::cursorPosition, this, &InputMethod::setCursorPosition, Qt::UniqueConnection);
|
||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditString, this, &InputMethod::setPreeditString, Qt::UniqueConnection);
|
||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditCursor, this, &InputMethod::setPreeditCursor, Qt::UniqueConnection);
|
||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::keyboardGrabRequested, this, &InputMethod::installKeyboardGrab, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void InputMethod::updateSni()
|
||||
|
@ -628,5 +630,34 @@ bool InputMethod::isActive() const
|
|||
return waylandServer()->inputMethod()->context();
|
||||
}
|
||||
|
||||
class InputKeyboardFilter : public InputEventFilter {
|
||||
public:
|
||||
InputKeyboardFilter(KWaylandServer::InputMethodGrabV1 *grab)
|
||||
: m_keyboardGrab(grab)
|
||||
{
|
||||
}
|
||||
|
||||
bool keyEvent(QKeyEvent *event) override {
|
||||
if (event->isAutoRepeat()) {
|
||||
return true;
|
||||
}
|
||||
auto newState = event->type() == QEvent::KeyPress ? KWaylandServer::KeyboardKeyState::Pressed : KWaylandServer::KeyboardKeyState::Released;
|
||||
m_keyboardGrab->sendKey(waylandServer()->display()->nextSerial(), event->timestamp(), event->nativeScanCode(), newState);
|
||||
return true;
|
||||
}
|
||||
InputMethodGrabV1 *const m_keyboardGrab;
|
||||
};
|
||||
|
||||
void InputMethod::installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab)
|
||||
{
|
||||
auto xkb = input()->keyboard()->xkb();
|
||||
auto filter = new InputKeyboardFilter(keyboardGrab);
|
||||
keyboardGrab->sendKeymap(xkb->keymapContents());
|
||||
input()->prependInputEventFilter(filter);
|
||||
connect(keyboardGrab, &QObject::destroyed, input(), [filter] {
|
||||
input()->uninstallInputEventFilter(filter);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
class KStatusNotifierItem;
|
||||
class QProcess;
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class InputMethodGrabV1;
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -81,6 +86,7 @@ private:
|
|||
void startInputMethod();
|
||||
void stopInputMethod();
|
||||
void setTrackedClient(AbstractClient *trackedClient);
|
||||
void installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab);
|
||||
|
||||
struct {
|
||||
QString text = QString();
|
||||
|
|
17
src/xkb.cpp
17
src/xkb.cpp
|
@ -284,19 +284,28 @@ void Xkb::updateKeymap(xkb_keymap *keymap)
|
|||
|
||||
void Xkb::createKeymapFile()
|
||||
{
|
||||
if (!m_seat || !m_seat->keyboard()) {
|
||||
const auto currentKeymap = keymapContents();
|
||||
if (currentKeymap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_seat->keyboard()->setKeymap(currentKeymap);
|
||||
}
|
||||
|
||||
QByteArray Xkb::keymapContents() const
|
||||
{
|
||||
if (!m_seat || !m_seat->keyboard()) {
|
||||
return {};
|
||||
}
|
||||
// TODO: uninstall keymap on server?
|
||||
if (!m_keymap) {
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
ScopedCPointer<char> keymapString(xkb_keymap_get_as_string(m_keymap, XKB_KEYMAP_FORMAT_TEXT_V1));
|
||||
if (keymapString.isNull()) {
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
m_seat->keyboard()->setKeymap(keymapString.data());
|
||||
return keymapString.data();
|
||||
}
|
||||
|
||||
void Xkb::updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
void forwardModifiers();
|
||||
|
||||
void setSeat(KWaylandServer::SeatInterface *seat);
|
||||
QByteArray keymapContents() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void ledsChanged(const LEDs &leds);
|
||||
|
|
Loading…
Reference in a new issue