Split Keyboard Repeat handling into a dedicated InputEventSpy
Summary: So far the keyboard repeat handling was triggered directly from KeyboardInputRedirection::processKey. With the introduction of InputEventSpies it is no longer required to be done like that, we can split it out into a dedicated spy. This means that processKey only has to care about processing the key and allows us to better extend in future. So far keyboard repeat is only functional for libinput based platforms. But it should also be possible to use it in nested setups. By splitting it out we can prepare for that. Test Plan: Auto-test using repeat still passes Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D4304
This commit is contained in:
parent
b636feb8eb
commit
eb92477210
5 changed files with 135 additions and 28 deletions
|
@ -371,6 +371,7 @@ set(kwin_KDEINIT_SRCS
|
|||
input_event_spy.cpp
|
||||
keyboard_input.cpp
|
||||
keyboard_layout.cpp
|
||||
keyboard_repeat.cpp
|
||||
pointer_input.cpp
|
||||
touch_input.cpp
|
||||
netinfo.cpp
|
||||
|
|
|
@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "input_event.h"
|
||||
#include "input_event_spy.h"
|
||||
#include "keyboard_layout.h"
|
||||
#include "keyboard_repeat.h"
|
||||
#include "abstract_client.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
|
@ -605,17 +606,10 @@ void KeyboardInputRedirection::init()
|
|||
m_keyboardLayout->init();
|
||||
m_input->installInputEventSpy(m_keyboardLayout);
|
||||
|
||||
// setup key repeat
|
||||
m_keyRepeat.timer = new QTimer(this);
|
||||
connect(m_keyRepeat.timer, &QTimer::timeout, this,
|
||||
[this] {
|
||||
if (waylandServer()->seat()->keyRepeatRate() != 0) {
|
||||
m_keyRepeat.timer->setInterval(1000 / waylandServer()->seat()->keyRepeatRate());
|
||||
}
|
||||
// TODO: better time
|
||||
processKey(m_keyRepeat.key, InputRedirection::KeyboardKeyAutoRepeat, m_keyRepeat.time);
|
||||
}
|
||||
);
|
||||
KeyboardRepeat *keyRepeatSpy = new KeyboardRepeat(m_xkb.data());
|
||||
connect(keyRepeatSpy, &KeyboardRepeat::keyRepeat, this,
|
||||
std::bind(&KeyboardInputRedirection::processKey, this, std::placeholders::_1, InputRedirection::KeyboardKeyAutoRepeat, std::placeholders::_2, nullptr));
|
||||
m_input->installInputEventSpy(keyRepeatSpy);
|
||||
|
||||
connect(workspace(), &QObject::destroyed, this, [this] { m_inited = false; });
|
||||
connect(waylandServer(), &QObject::destroyed, this, [this] { m_inited = false; });
|
||||
|
@ -725,18 +719,6 @@ void KeyboardInputRedirection::processKey(uint32_t key, InputRedirection::Keyboa
|
|||
time,
|
||||
device);
|
||||
event.setModifiersRelevantForGlobalShortcuts(m_xkb->modifiersRelevantForGlobalShortcuts());
|
||||
if (state == InputRedirection::KeyboardKeyPressed) {
|
||||
if (m_xkb->shouldKeyRepeat(key) && waylandServer()->seat()->keyRepeatDelay() != 0) {
|
||||
m_keyRepeat.timer->setInterval(waylandServer()->seat()->keyRepeatDelay());
|
||||
m_keyRepeat.key = key;
|
||||
m_keyRepeat.time = time;
|
||||
m_keyRepeat.timer->start();
|
||||
}
|
||||
} else if (state == InputRedirection::KeyboardKeyReleased) {
|
||||
if (key == m_keyRepeat.key) {
|
||||
m_keyRepeat.timer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
m_input->processSpies(std::bind(&InputEventSpy::keyEvent, std::placeholders::_1, &event));
|
||||
m_input->processFilters(std::bind(&InputEventFilter::keyEvent, std::placeholders::_1, &event));
|
||||
|
|
|
@ -180,11 +180,6 @@ private:
|
|||
bool m_inited = false;
|
||||
QScopedPointer<Xkb> m_xkb;
|
||||
QMetaObject::Connection m_activeClientSurfaceChangedConnection;
|
||||
struct {
|
||||
quint32 key = 0;
|
||||
quint32 time = 0;
|
||||
QTimer *timer = nullptr;
|
||||
} m_keyRepeat;
|
||||
ModifiersChangedSpy *m_modifiersChangedSpy = nullptr;
|
||||
KeyboardLayout *m_keyboardLayout = nullptr;
|
||||
};
|
||||
|
|
73
keyboard_repeat.cpp
Normal file
73
keyboard_repeat.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2016, 2017 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "keyboard_repeat.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "input_event.h"
|
||||
#include "wayland_server.h"
|
||||
|
||||
#include <KWayland/Server/seat_interface.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
KeyboardRepeat::KeyboardRepeat(Xkb *xkb)
|
||||
: QObject()
|
||||
, m_timer(new QTimer)
|
||||
, m_xkb(xkb)
|
||||
{
|
||||
connect(m_timer, &QTimer::timeout, this, &KeyboardRepeat::handleKeyRepeat);
|
||||
}
|
||||
|
||||
KeyboardRepeat::~KeyboardRepeat() = default;
|
||||
|
||||
void KeyboardRepeat::handleKeyRepeat()
|
||||
{
|
||||
// TODO: don't depend on WaylandServer
|
||||
if (waylandServer()->seat()->keyRepeatRate() != 0) {
|
||||
m_timer->setInterval(1000 / waylandServer()->seat()->keyRepeatRate());
|
||||
}
|
||||
// TODO: better time
|
||||
emit keyRepeat(m_key, m_time);
|
||||
}
|
||||
|
||||
void KeyboardRepeat::keyEvent(KeyEvent *event)
|
||||
{
|
||||
if (event->isAutoRepeat()) {
|
||||
return;
|
||||
}
|
||||
const quint32 key = event->nativeScanCode();
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
// TODO: don't get these values from WaylandServer
|
||||
if (m_xkb->shouldKeyRepeat(key) && waylandServer()->seat()->keyRepeatDelay() != 0) {
|
||||
m_timer->setInterval(waylandServer()->seat()->keyRepeatDelay());
|
||||
m_key = key;
|
||||
m_time = event->timestamp();
|
||||
m_timer->start();
|
||||
}
|
||||
} else if (event->type() == QEvent::KeyRelease) {
|
||||
if (key == m_key) {
|
||||
m_timer->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
56
keyboard_repeat.h
Normal file
56
keyboard_repeat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2016, 2017 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#ifndef KWIN_KEYBOARD_REPEAT
|
||||
#define KWIN_KEYBOARD_REPEAT
|
||||
|
||||
#include "input_event_spy.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Xkb;
|
||||
|
||||
class KeyboardRepeat : public QObject, public InputEventSpy
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KeyboardRepeat(Xkb *xkb);
|
||||
~KeyboardRepeat() override;
|
||||
|
||||
void keyEvent(KeyEvent *event) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void keyRepeat(quint32 key, quint32 time);
|
||||
|
||||
private:
|
||||
void handleKeyRepeat();
|
||||
QTimer *m_timer;
|
||||
Xkb *m_xkb;
|
||||
quint32 m_time;
|
||||
quint32 m_key;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue