Lay some groundwork for realtime gestures in Wayland

This lays down some groundwork for realtime gestures in Wayland,
so that gestures that are 1:1 with user motion on a touchpad are
now possible to implement.

Due to earlier commits, this is mostly just glue code to make a
convenient API.

Gestures implemented with this API are four-finger gestures, to
avoid conflicting with apps that may use two or three-finger
gestures.
This commit is contained in:
Janet Blackquill 2021-04-19 00:42:46 -04:00 committed by Jan Blackquill
parent 81389a6e17
commit 6231699ac1
8 changed files with 47 additions and 2 deletions

View file

@ -174,6 +174,7 @@ public:
void registerGlobalShortcut(const QKeySequence &, QAction *) override {}
void registerPointerShortcut(Qt::KeyboardModifiers, Qt::MouseButton, QAction *) override {}
void registerTouchpadSwipeShortcut(KWin::SwipeDirection, QAction *) override {}
void registerRealtimeTouchpadSwipeShortcut(KWin::SwipeDirection, QAction*, std::function<void(qreal)>) override {}
void reloadEffect(KWin::Effect *) override {}
void removeSupportProperty(const QByteArray &, KWin::Effect *) override {}
void reserveElectricBorder(KWin::ElectricBorder, KWin::Effect *) override {}

View file

@ -750,6 +750,11 @@ void EffectsHandlerImpl::registerAxisShortcut(Qt::KeyboardModifiers modifiers, P
input()->registerAxisShortcut(modifiers, axis, action);
}
void EffectsHandlerImpl::registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, QAction* onUp, std::function<void(qreal)> progressCallback)
{
input()->registerRealtimeTouchpadSwipeShortcut(dir, onUp, progressCallback);
}
void EffectsHandlerImpl::registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action)
{
input()->registerTouchpadSwipeShortcut(direction, action);

View file

@ -110,6 +110,7 @@ public:
void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) override;
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) override;
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) override;
void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, QAction* onUp, std::function<void(qreal)> progressCallback) override;
void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) override;
void* getProxy(QString name) override;
void startMousePolling() override;

View file

@ -20,6 +20,7 @@
// Qt
#include <QAction>
#include <variant>
#include <signal.h>
namespace KWin
{
@ -39,6 +40,17 @@ GlobalShortcut::GlobalShortcut(Shortcut &&sc, QAction *action)
m_gesture->setMaximumFingerCount(4);
m_gesture->setMinimumFingerCount(4);
QObject::connect(m_gesture.get(), &SwipeGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
} else if (auto rtSwipeGesture = std::get_if<FourFingerRealtimeFeedbackSwipeShortcut>(&sc)) {
m_gesture.reset(new SwipeGesture);
m_gesture->setDirection(dirs[rtSwipeGesture->swipeDirection]);
m_gesture->setMinimumDelta(QSizeF(200, 200));
m_gesture->setMaximumFingerCount(4);
m_gesture->setMinimumFingerCount(4);
QObject::connect(m_gesture.get(), &SwipeGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_gesture.get(), &SwipeGesture::cancelled, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_gesture.get(), &SwipeGesture::progress, [cb = rtSwipeGesture->progressCallback](qreal v) {
cb(v);
});
}
}
@ -111,7 +123,7 @@ bool GlobalShortcutsManager::addIfNotExists(GlobalShortcut sc)
}
}
if (std::holds_alternative<FourFingerSwipeShortcut>(sc.shortcut())) {
if (std::holds_alternative<FourFingerSwipeShortcut>(sc.shortcut()) || std::holds_alternative<FourFingerRealtimeFeedbackSwipeShortcut>(sc.shortcut())) {
m_gestureRecognizer->registerGesture(sc.swipeGesture());
}
connect(sc.action(), &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted);
@ -134,6 +146,11 @@ void GlobalShortcutsManager::registerTouchpadSwipe(QAction *action, SwipeDirecti
addIfNotExists(GlobalShortcut(FourFingerSwipeShortcut{direction}, action));
}
void GlobalShortcutsManager::registerRealtimeTouchpadSwipe(QAction *action, std::function<void (qreal)> progressCallback, SwipeDirection direction)
{
addIfNotExists(GlobalShortcut(FourFingerRealtimeFeedbackSwipeShortcut{direction, progressCallback}, action));
}
bool GlobalShortcutsManager::processKey(Qt::KeyboardModifiers mods, int keyQt)
{
if (m_kglobalAccelInterface) {

View file

@ -60,6 +60,8 @@ public:
void registerTouchpadSwipe(QAction *action, SwipeDirection direction);
void registerRealtimeTouchpadSwipe(QAction *onUp, std::function<void(qreal)> progressCallback, SwipeDirection direction);
/**
* @brief Processes a key event to decide whether a shortcut needs to be triggered.
*
@ -141,8 +143,19 @@ struct FourFingerSwipeShortcut
return swipeDirection == rhs.swipeDirection;
}
};
struct FourFingerRealtimeFeedbackSwipeShortcut
{
SwipeDirection swipeDirection;
std::function<void(qreal)> progressCallback;
using Shortcut = std::variant<KeyboardShortcut, PointerButtonShortcut, PointerAxisShortcut, FourFingerSwipeShortcut>;
template<typename T>
bool operator==(const T& rhs) const
{
return swipeDirection == rhs.swipeDirection;
}
};
using Shortcut = std::variant<KeyboardShortcut, PointerButtonShortcut, PointerAxisShortcut, FourFingerSwipeShortcut, FourFingerRealtimeFeedbackSwipeShortcut>;
class GlobalShortcut
{

View file

@ -2701,6 +2701,11 @@ void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, Poi
m_shortcuts->registerAxisShortcut(action, modifiers, axis);
}
void InputRedirection::registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, QAction *action, std::function<void(qreal)> cb)
{
m_shortcuts->registerRealtimeTouchpadSwipe(action, cb, direction);
}
void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action)
{
m_shortcuts->registerTouchpadSwipe(action, direction);

View file

@ -139,6 +139,7 @@ public:
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action);
void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action);
void registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, QAction *onUp, std::function<void(qreal)> progressCallback);
void registerGlobalAccel(KGlobalAccelInterface *interface);
/**

View file

@ -886,6 +886,8 @@ public:
*/
virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) = 0;
virtual void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, QAction* onUp, std::function<void(qreal)> progressCallback) = 0;
/**
* Retrieve the proxy class for an effect if it has one. Will return NULL if
* the effect isn't loaded or doesn't have a proxy class.