Split out touch related functionality from InputRedirection
Similar to c044ad98be
this change splits
all touch handling related functionality into a dedicated class called
TouchInputRedirection.
This commit is contained in:
parent
fed7a48112
commit
b8f8b2d8a0
5 changed files with 278 additions and 119 deletions
|
@ -333,6 +333,7 @@ set(kwin_KDEINIT_SRCS
|
|||
globalshortcuts.cpp
|
||||
input.cpp
|
||||
pointer_input.cpp
|
||||
touch_input.cpp
|
||||
netinfo.cpp
|
||||
placement.cpp
|
||||
atoms.cpp
|
||||
|
|
130
input.cpp
130
input.cpp
|
@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*********************************************************************/
|
||||
#include "input.h"
|
||||
#include "pointer_input.h"
|
||||
#include "touch_input.h"
|
||||
#include "client.h"
|
||||
#include "effects.h"
|
||||
#include "globalshortcuts.h"
|
||||
|
@ -412,10 +413,10 @@ public:
|
|||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
if (!seat->isTouchSequence()) {
|
||||
input()->updateTouchWindow(pos);
|
||||
input()->touch()->update(pos);
|
||||
}
|
||||
if (touchSurfaceAllowed()) {
|
||||
input()->insertTouchId(id, seat->touchDown(pos));
|
||||
input()->touch()->insertId(id, seat->touchDown(pos));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -426,7 +427,7 @@ public:
|
|||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
if (touchSurfaceAllowed()) {
|
||||
const qint32 kwaylandId = input()->touchId(id);
|
||||
const qint32 kwaylandId = input()->touch()->mappedId(id);
|
||||
if (kwaylandId != -1) {
|
||||
seat->touchMove(kwaylandId, pos);
|
||||
}
|
||||
|
@ -440,10 +441,10 @@ public:
|
|||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
if (touchSurfaceAllowed()) {
|
||||
const qint32 kwaylandId = input()->touchId(id);
|
||||
const qint32 kwaylandId = input()->touch()->mappedId(id);
|
||||
if (kwaylandId != -1) {
|
||||
seat->touchUp(kwaylandId);
|
||||
input()->removeTouchId(id);
|
||||
input()->touch()->removeId(id);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -774,8 +775,8 @@ public:
|
|||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
if (!seat->isTouchSequence()) {
|
||||
input()->updateTouchWindow(pos);
|
||||
if (AbstractClient *c = dynamic_cast<AbstractClient*>(input()->m_touchWindow.data())) {
|
||||
input()->touch()->update(pos);
|
||||
if (AbstractClient *c = dynamic_cast<AbstractClient*>(input()->touch()->window().data())) {
|
||||
// perform same handling as if it were a left click
|
||||
bool wasAction = false;
|
||||
const Options::MouseCommand command = c->getMouseCommand(Qt::LeftButton, &wasAction);
|
||||
|
@ -787,7 +788,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
input()->insertTouchId(id, seat->touchDown(pos));
|
||||
input()->touch()->insertId(id, seat->touchDown(pos));
|
||||
return true;
|
||||
}
|
||||
bool touchMotion(quint32 id, const QPointF &pos, quint32 time) override {
|
||||
|
@ -796,7 +797,7 @@ public:
|
|||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
const qint32 kwaylandId = input()->touchId(id);
|
||||
const qint32 kwaylandId = input()->touch()->mappedId(id);
|
||||
if (kwaylandId != -1) {
|
||||
seat->touchMove(kwaylandId, pos);
|
||||
}
|
||||
|
@ -808,10 +809,10 @@ public:
|
|||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(time);
|
||||
const qint32 kwaylandId = input()->touchId(id);
|
||||
const qint32 kwaylandId = input()->touch()->mappedId(id);
|
||||
if (kwaylandId != -1) {
|
||||
seat->touchUp(kwaylandId);
|
||||
input()->removeTouchId(id);
|
||||
input()->touch()->removeId(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -822,6 +823,7 @@ KWIN_SINGLETON_FACTORY(InputRedirection)
|
|||
InputRedirection::InputRedirection(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_pointer(new PointerInputRedirection(this))
|
||||
, m_touch(new TouchInputRedirection(this))
|
||||
, m_xkb(new Xkb(this))
|
||||
, m_shortcuts(new GlobalShortcutsManager(this))
|
||||
{
|
||||
|
@ -930,15 +932,9 @@ void InputRedirection::setupWorkspace()
|
|||
connect(workspace(), &Workspace::configChanged, this, &InputRedirection::reconfigure);
|
||||
|
||||
m_pointer->init();
|
||||
m_touch->init();
|
||||
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updateKeyboardWindow);
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this,
|
||||
[this] {
|
||||
cancelTouch();
|
||||
// position doesn't matter
|
||||
updateTouchWindow(QPointF());
|
||||
}
|
||||
);
|
||||
}
|
||||
setupInputFilters();
|
||||
}
|
||||
|
@ -1022,11 +1018,11 @@ void InputRedirection::setupLibInput()
|
|||
m_pointer->processMotion(screen, time);
|
||||
}
|
||||
);
|
||||
connect(conn, &LibInput::Connection::touchDown, this, &InputRedirection::processTouchDown);
|
||||
connect(conn, &LibInput::Connection::touchUp, this, &InputRedirection::processTouchUp);
|
||||
connect(conn, &LibInput::Connection::touchMotion, this, &InputRedirection::processTouchMotion);
|
||||
connect(conn, &LibInput::Connection::touchCanceled, this, &InputRedirection::cancelTouch);
|
||||
connect(conn, &LibInput::Connection::touchFrame, this, &InputRedirection::touchFrame);
|
||||
connect(conn, &LibInput::Connection::touchDown, m_touch, &TouchInputRedirection::processDown);
|
||||
connect(conn, &LibInput::Connection::touchUp, m_touch, &TouchInputRedirection::processUp);
|
||||
connect(conn, &LibInput::Connection::touchMotion, m_touch, &TouchInputRedirection::processMotion);
|
||||
connect(conn, &LibInput::Connection::touchCanceled, m_touch, &TouchInputRedirection::cancel);
|
||||
connect(conn, &LibInput::Connection::touchFrame, m_touch, &TouchInputRedirection::frame);
|
||||
if (screens()) {
|
||||
setupLibInputWithScreens();
|
||||
} else {
|
||||
|
@ -1087,19 +1083,6 @@ void InputRedirection::setupLibInputWithScreens()
|
|||
#endif
|
||||
}
|
||||
|
||||
void InputRedirection::updateFocusedTouchPosition()
|
||||
{
|
||||
if (m_touchWindow.isNull()) {
|
||||
return;
|
||||
}
|
||||
if (auto seat = findSeat()) {
|
||||
if (m_touchWindow.data()->surface() != seat->focusedTouchSurface()) {
|
||||
return;
|
||||
}
|
||||
seat->setFocusedTouchSurfacePosition(m_touchWindow.data()->pos());
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::processPointerMotion(const QPointF &pos, uint32_t time)
|
||||
{
|
||||
m_pointer->processMotion(pos, time);
|
||||
|
@ -1200,92 +1183,27 @@ void InputRedirection::processKeymapChange(int fd, uint32_t size)
|
|||
|
||||
void InputRedirection::processTouchDown(qint32 id, const QPointF &pos, quint32 time)
|
||||
{
|
||||
for (auto it = m_filters.constBegin(), end = m_filters.constEnd(); it != end; it++) {
|
||||
if ((*it)->touchDown(id, pos, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_touch->processDown(id, pos, time);
|
||||
}
|
||||
|
||||
void InputRedirection::updateTouchWindow(const QPointF &pos)
|
||||
{
|
||||
// TODO: handle pointer grab aka popups
|
||||
Toplevel *t = findToplevel(pos.toPoint());
|
||||
auto oldWindow = m_touchWindow;
|
||||
if (!oldWindow.isNull() && t == oldWindow.data()) {
|
||||
return;
|
||||
}
|
||||
if (auto seat = findSeat()) {
|
||||
// disconnect old surface
|
||||
if (oldWindow) {
|
||||
disconnect(oldWindow.data(), &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedTouchPosition);
|
||||
}
|
||||
if (t && t->surface()) {
|
||||
seat->setFocusedTouchSurface(t->surface(), t->pos());
|
||||
connect(t, &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedTouchPosition);
|
||||
} else {
|
||||
seat->setFocusedTouchSurface(nullptr);
|
||||
t = nullptr;
|
||||
}
|
||||
}
|
||||
if (!t) {
|
||||
m_touchWindow.clear();
|
||||
return;
|
||||
}
|
||||
m_touchWindow = QWeakPointer<Toplevel>(t);
|
||||
}
|
||||
|
||||
|
||||
void InputRedirection::processTouchUp(qint32 id, quint32 time)
|
||||
{
|
||||
for (auto it = m_filters.constBegin(), end = m_filters.constEnd(); it != end; it++) {
|
||||
if ((*it)->touchUp(id, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_touch->processUp(id, time);
|
||||
}
|
||||
|
||||
void InputRedirection::processTouchMotion(qint32 id, const QPointF &pos, quint32 time)
|
||||
{
|
||||
for (auto it = m_filters.constBegin(), end = m_filters.constEnd(); it != end; it++) {
|
||||
if ((*it)->touchMotion(id, pos, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_touch->processMotion(id, pos, time);
|
||||
}
|
||||
|
||||
void InputRedirection::cancelTouch()
|
||||
{
|
||||
if (auto seat = findSeat()) {
|
||||
seat->cancelTouchSequence();
|
||||
}
|
||||
m_touchIdMapper.clear();
|
||||
m_touch->cancel();
|
||||
}
|
||||
|
||||
void InputRedirection::touchFrame()
|
||||
{
|
||||
if (auto seat = findSeat()) {
|
||||
seat->touchFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::insertTouchId(quint32 internalId, qint32 kwaylandId)
|
||||
{
|
||||
m_touchIdMapper.insert(internalId, kwaylandId);
|
||||
}
|
||||
|
||||
qint32 InputRedirection::touchId(quint32 internalId)
|
||||
{
|
||||
auto it = input()->m_touchIdMapper.constFind(internalId);
|
||||
if (it != input()->m_touchIdMapper.constEnd()) {
|
||||
return it.value();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void InputRedirection::removeTouchId(quint32 internalId)
|
||||
{
|
||||
m_touchIdMapper.remove(internalId);
|
||||
m_touch->frame();
|
||||
}
|
||||
|
||||
Qt::MouseButtons InputRedirection::qtButtonStates() const
|
||||
|
|
18
input.h
18
input.h
|
@ -45,6 +45,7 @@ class Toplevel;
|
|||
class Xkb;
|
||||
class InputEventFilter;
|
||||
class PointerInputRedirection;
|
||||
class TouchInputRedirection;
|
||||
|
||||
namespace Decoration
|
||||
{
|
||||
|
@ -144,12 +145,8 @@ public:
|
|||
GlobalShortcutsManager *shortcuts() const {
|
||||
return m_shortcuts;
|
||||
}
|
||||
void insertTouchId(quint32 internalId, qint32 kwaylandId);
|
||||
qint32 touchId(quint32 internalId);
|
||||
void removeTouchId(quint32 internalId);
|
||||
|
||||
void updateKeyboardWindow();
|
||||
void updateTouchWindow(const QPointF &pos);
|
||||
|
||||
QVector<InputEventFilter*> filters() const {
|
||||
return m_filters;
|
||||
|
@ -157,6 +154,9 @@ public:
|
|||
PointerInputRedirection *pointer() const {
|
||||
return m_pointer;
|
||||
}
|
||||
TouchInputRedirection *touch() const {
|
||||
return m_touch;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
@ -201,21 +201,13 @@ private:
|
|||
void setupLibInput();
|
||||
void setupLibInputWithScreens();
|
||||
void registerShortcutForGlobalAccelTimestamp(QAction *action);
|
||||
void updateFocusedTouchPosition();
|
||||
void setupWorkspace();
|
||||
void reconfigure();
|
||||
void setupInputFilters();
|
||||
void installInputEventFilter(InputEventFilter *filter);
|
||||
PointerInputRedirection *m_pointer;
|
||||
TouchInputRedirection *m_touch;
|
||||
QScopedPointer<Xkb> m_xkb;
|
||||
/**
|
||||
* @brief The Toplevel which currently receives touch events
|
||||
*/
|
||||
QWeakPointer<Toplevel> m_touchWindow;
|
||||
/**
|
||||
* external/kwayland
|
||||
**/
|
||||
QHash<qint32, qint32> m_touchIdMapper;
|
||||
|
||||
GlobalShortcutsManager *m_shortcuts;
|
||||
|
||||
|
|
171
touch_input.cpp
Normal file
171
touch_input.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013, 2016 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 "touch_input.h"
|
||||
#include "input.h"
|
||||
#include "toplevel.h"
|
||||
#include "wayland_server.h"
|
||||
// KWayland
|
||||
#include <KWayland/Server/seat_interface.h>
|
||||
// screenlocker
|
||||
#include <KScreenLocker/KsldApp>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
TouchInputRedirection::TouchInputRedirection(InputRedirection *parent)
|
||||
: QObject(parent)
|
||||
, m_input(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TouchInputRedirection::~TouchInputRedirection() = default;
|
||||
|
||||
void TouchInputRedirection::init()
|
||||
{
|
||||
Q_ASSERT(!m_inited);
|
||||
m_inited = true;
|
||||
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this,
|
||||
[this] {
|
||||
cancel();
|
||||
// position doesn't matter
|
||||
update();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void TouchInputRedirection::update(const QPointF &pos)
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
// TODO: handle pointer grab aka popups
|
||||
Toplevel *t = m_input->findToplevel(pos.toPoint());
|
||||
auto oldWindow = m_window;
|
||||
if (!oldWindow.isNull() && t == oldWindow.data()) {
|
||||
return;
|
||||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
// disconnect old surface
|
||||
if (oldWindow) {
|
||||
disconnect(m_windowGeometryConnection);
|
||||
m_windowGeometryConnection = QMetaObject::Connection();
|
||||
}
|
||||
if (t && t->surface()) {
|
||||
seat->setFocusedTouchSurface(t->surface(), t->pos());
|
||||
m_windowGeometryConnection = connect(t, &Toplevel::geometryChanged, this,
|
||||
[this] {
|
||||
if (m_window.isNull()) {
|
||||
return;
|
||||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
if (m_window.data()->surface() != seat->focusedTouchSurface()) {
|
||||
return;
|
||||
}
|
||||
seat->setFocusedTouchSurfacePosition(m_window.data()->pos());
|
||||
}
|
||||
);
|
||||
} else {
|
||||
seat->setFocusedTouchSurface(nullptr);
|
||||
t = nullptr;
|
||||
}
|
||||
if (!t) {
|
||||
m_window.clear();
|
||||
return;
|
||||
}
|
||||
m_window = QPointer<Toplevel>(t);
|
||||
}
|
||||
|
||||
void TouchInputRedirection::insertId(quint32 internalId, qint32 kwaylandId)
|
||||
{
|
||||
m_idMapper.insert(internalId, kwaylandId);
|
||||
}
|
||||
|
||||
qint32 TouchInputRedirection::mappedId(quint32 internalId)
|
||||
{
|
||||
auto it = m_idMapper.constFind(internalId);
|
||||
if (it != m_idMapper.constEnd()) {
|
||||
return it.value();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TouchInputRedirection::removeId(quint32 internalId)
|
||||
{
|
||||
m_idMapper.remove(internalId);
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 time)
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->touchDown(id, pos, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processUp(qint32 id, quint32 time)
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->touchUp(id, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processMotion(qint32 id, const QPointF &pos, quint32 time)
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->touchMotion(id, pos, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputRedirection::cancel()
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
waylandServer()->seat()->cancelTouchSequence();
|
||||
m_idMapper.clear();
|
||||
}
|
||||
|
||||
void TouchInputRedirection::frame()
|
||||
{
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
waylandServer()->seat()->touchFrame();
|
||||
}
|
||||
|
||||
}
|
77
touch_input.h
Normal file
77
touch_input.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013, 2016 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_TOUCH_INPUT_H
|
||||
#define KWIN_TOUCH_INPUT_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QPointF>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class InputRedirection;
|
||||
class Toplevel;
|
||||
|
||||
class TouchInputRedirection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TouchInputRedirection(InputRedirection *parent);
|
||||
virtual ~TouchInputRedirection();
|
||||
|
||||
void update(const QPointF &pos = QPointF());
|
||||
void init();
|
||||
|
||||
void processDown(qint32 id, const QPointF &pos, quint32 time);
|
||||
void processUp(qint32 id, quint32 time);
|
||||
void processMotion(qint32 id, const QPointF &pos, quint32 time);
|
||||
void cancel();
|
||||
void frame();
|
||||
|
||||
void insertId(quint32 internalId, qint32 kwaylandId);
|
||||
void removeId(quint32 internalId);
|
||||
qint32 mappedId(quint32 internalId);
|
||||
|
||||
/**
|
||||
* @brief The Toplevel which currently receives touch events
|
||||
*/
|
||||
QPointer<Toplevel> window() const {
|
||||
return m_window;
|
||||
}
|
||||
|
||||
private:
|
||||
InputRedirection *m_input;
|
||||
bool m_inited = false;
|
||||
/**
|
||||
* @brief The Toplevel which currently receives touch events
|
||||
*/
|
||||
QPointer<Toplevel> m_window;
|
||||
/**
|
||||
* external/kwayland
|
||||
**/
|
||||
QHash<qint32, qint32> m_idMapper;
|
||||
QMetaObject::Connection m_windowGeometryConnection;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue