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:
parent
9e68357ce9
commit
11f6292cb5
3 changed files with 28 additions and 22 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue