Move input keyboard filter to be just before the key is sent to application.

Features like global shortcuts should be handled before the input
method.
This commit is contained in:
Weng Xuetian 2021-12-13 09:23:23 -08:00 committed by Aleix Pol Gonzalez
parent 9e68357ce9
commit 11f6292cb5
3 changed files with 28 additions and 22 deletions

View file

@ -18,6 +18,7 @@
#include "input_event.h" #include "input_event.h"
#include "input_event_spy.h" #include "input_event_spy.h"
#include "inputbackend.h" #include "inputbackend.h"
#include "inputmethod.h"
#include "keyboard_input.h" #include "keyboard_input.h"
#include "main.h" #include "main.h"
#include "pointer_input.h" #include "pointer_input.h"
@ -44,6 +45,7 @@
#include <KGlobalAccel> #include <KGlobalAccel>
#include <KLocalizedString> #include <KLocalizedString>
#include <KWaylandServer/display.h> #include <KWaylandServer/display.h>
#include <KWaylandServer/inputmethod_v1_interface.h>
#include <KWaylandServer/seat_interface.h> #include <KWaylandServer/seat_interface.h>
#include <KWaylandServer/shmclientbuffer.h> #include <KWaylandServer/shmclientbuffer.h>
#include <KWaylandServer/surface_interface.h> #include <KWaylandServer/surface_interface.h>
@ -1487,6 +1489,23 @@ public:
} }
}; };
class InputKeyboardFilter : public InputEventFilter
{
public:
bool keyEvent(QKeyEvent *event) override
{
if (auto keyboardGrab = InputMethod::self()->keyboardGrab()) {
if (event->isAutoRepeat()) {
return true;
}
auto newState = event->type() == QEvent::KeyPress ? KWaylandServer::KeyboardKeyState::Pressed : KWaylandServer::KeyboardKeyState::Released;
keyboardGrab->sendKey(waylandServer()->display()->nextSerial(), event->timestamp(), event->nativeScanCode(), newState);
return true;
}
return false;
}
};
/** /**
* The remaining default input filter which forwards events to other windows * The remaining default input filter which forwards events to other windows
*/ */
@ -2450,6 +2469,7 @@ void InputRedirection::setupInputFilters()
installInputEventFilter(new DecorationEventFilter); installInputEventFilter(new DecorationEventFilter);
installInputEventFilter(new WindowActionInputFilter); installInputEventFilter(new WindowActionInputFilter);
installInputEventFilter(new InternalWindowEventFilter); installInputEventFilter(new InternalWindowEventFilter);
installInputEventFilter(new InputKeyboardFilter);
installInputEventFilter(new ForwardInputFilter); installInputEventFilter(new ForwardInputFilter);
installInputEventFilter(new TabletInputFilter); installInputEventFilter(new TabletInputFilter);
} }

View file

@ -630,33 +630,16 @@ bool InputMethod::isActive() const
return waylandServer()->inputMethod()->context(); return waylandServer()->inputMethod()->context();
} }
class InputKeyboardFilter : public InputEventFilter { KWaylandServer::InputMethodGrabV1 *InputMethod::keyboardGrab()
public: {
InputKeyboardFilter(KWaylandServer::InputMethodGrabV1 *grab) return isActive() ? m_keyboardGrab : nullptr;
: 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) void InputMethod::installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab)
{ {
auto xkb = input()->keyboard()->xkb(); auto xkb = input()->keyboard()->xkb();
auto filter = new InputKeyboardFilter(keyboardGrab); m_keyboardGrab = keyboardGrab;
keyboardGrab->sendKeymap(xkb->keymapContents()); keyboardGrab->sendKeymap(xkb->keymapContents());
input()->prependInputEventFilter(filter);
connect(keyboardGrab, &QObject::destroyed, input(), [filter] {
input()->uninstallInputEventFilter(filter);
});
} }
void InputMethod::updateModifiersMap(const QByteArray &modifiers) void InputMethod::updateModifiersMap(const QByteArray &modifiers)

View file

@ -57,6 +57,8 @@ public:
void setPanel(InputPanelV1Client* client); void setPanel(InputPanelV1Client* client);
void setInputMethodCommand(const QString &path); void setInputMethodCommand(const QString &path);
KWaylandServer::InputMethodGrabV1 *keyboardGrab();
Q_SIGNALS: Q_SIGNALS:
void activeChanged(bool active); void activeChanged(bool active);
void enabledChanged(bool enabled); void enabledChanged(bool enabled);
@ -106,6 +108,7 @@ private:
quint32 m_serial = 0; quint32 m_serial = 0;
QPointer<InputPanelV1Client> m_inputClient; QPointer<InputPanelV1Client> m_inputClient;
QPointer<AbstractClient> m_trackedClient; QPointer<AbstractClient> m_trackedClient;
QPointer<KWaylandServer::InputMethodGrabV1> m_keyboardGrab;
QProcess *m_inputMethodProcess = nullptr; QProcess *m_inputMethodProcess = nullptr;
QTimer m_inputMethodCrashTimer; QTimer m_inputMethodCrashTimer;