diff --git a/globalshortcuts.cpp b/globalshortcuts.cpp index bd80397019..b7c6585b1e 100644 --- a/globalshortcuts.cpp +++ b/globalshortcuts.cpp @@ -34,6 +34,7 @@ GlobalShortcut::GlobalShortcut(const QKeySequence &shortcut) : m_shortcut(shortcut) , m_pointerModifiers(Qt::NoModifier) , m_pointerButtons(Qt::NoButton) + , m_axis(PointerAxisUp) { } @@ -41,6 +42,15 @@ GlobalShortcut::GlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt: : m_shortcut(QKeySequence()) , m_pointerModifiers(pointerButtonModifiers) , m_pointerButtons(pointerButtons) + , m_axis(PointerAxisUp) +{ +} + +GlobalShortcut::GlobalShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis) + : m_shortcut(QKeySequence()) + , m_pointerModifiers(modifiers) + , m_pointerButtons(Qt::NoButton) + , m_axis(axis) { } @@ -60,6 +70,12 @@ InternalGlobalShortcut::InternalGlobalShortcut(Qt::KeyboardModifiers pointerButt { } +InternalGlobalShortcut::InternalGlobalShortcut(Qt::KeyboardModifiers axisModifiers, PointerAxisDirection axis, QAction *action) + : GlobalShortcut(axisModifiers, axis) + , m_action(action) +{ +} + InternalGlobalShortcut::~InternalGlobalShortcut() { } @@ -88,6 +104,7 @@ GlobalShortcutsManager::~GlobalShortcutsManager() { clearShortcuts(m_shortcuts); clearShortcuts(m_pointerShortcuts); + clearShortcuts(m_axisShortcuts); } template @@ -110,6 +127,7 @@ void GlobalShortcutsManager::objectDeleted(QObject *object) { handleDestroyedAction(object, m_shortcuts); handleDestroyedAction(object, m_pointerShortcuts); + handleDestroyedAction(object, m_axisShortcuts); } void GlobalShortcutsManager::registerShortcut(QAction *action, const QKeySequence &shortcut) @@ -165,6 +183,21 @@ void GlobalShortcutsManager::registerPointerShortcut(QAction *action, Qt::Keyboa connect(action, &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted); } +void GlobalShortcutsManager::registerAxisShortcut(QAction *action, Qt::KeyboardModifiers modifiers, PointerAxisDirection axis) +{ + GlobalShortcut *cut = new InternalGlobalShortcut(modifiers, axis, action); + auto it = m_axisShortcuts.find(modifiers); + if (it != m_axisShortcuts.end()) { + // TODO: check if shortcut already exists + (*it).insert(axis, cut); + } else { + QHash shortcuts; + shortcuts.insert(axis, cut); + m_axisShortcuts.insert(modifiers, shortcuts); + } + connect(action, &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted); +} + QKeySequence GlobalShortcutsManager::getShortcutForAction(const QString &componentName, const QString &actionName, const QKeySequence &defaultShortcut) { if (!m_config->hasGroup(componentName)) { @@ -210,4 +243,9 @@ bool GlobalShortcutsManager::processPointerPressed(Qt::KeyboardModifiers mods, Q return processShortcut(mods, pointerButtons, m_pointerShortcuts); } +bool GlobalShortcutsManager::processAxis(Qt::KeyboardModifiers mods, PointerAxisDirection axis) +{ + return processShortcut(mods, axis, m_axisShortcuts); +} + } // namespace diff --git a/globalshortcuts.h b/globalshortcuts.h index 9a6f0343ed..8ac4564a7c 100644 --- a/globalshortcuts.h +++ b/globalshortcuts.h @@ -19,6 +19,8 @@ along with this program. If not, see . *********************************************************************/ #ifndef KWIN_GLOBALSHORTCUTS_H #define KWIN_GLOBALSHORTCUTS_H +// KWin +#include // KDE #include // Qt @@ -61,6 +63,14 @@ public: * @param pointerButtons The pointer button which needs to be pressed */ void registerPointerShortcut(QAction *action, Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons); + /** + * @brief Registers an internal global axis shortcut + * + * @param action The action to trigger if the shortcut is triggered + * @param modifiers The modifiers which need to be hold to trigger the action + * @param pointerButtons The pointer axis + */ + void registerAxisShortcut(QAction *action, Qt::KeyboardModifiers modifiers, PointerAxisDirection axis); /** * @brief Processes a key event to decide whether a shortcut needs to be triggered. @@ -75,11 +85,24 @@ public: */ bool processKey(Qt::KeyboardModifiers modifiers, uint32_t key); bool processPointerPressed(Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons); + /** + * @brief Processes a pointer axis event to decide whether a shortcut needs to be triggered. + * + * If a shortcut triggered this method returns @c true to indicate to the caller that the event + * should not be further processed. If there is no shortcut which triggered for the key, then + * @c false is returned. + * + * @param modifiers The current hold modifiers + * @param axis The axis direction which has triggered this event + * @return @c true if a shortcut triggered, @c false otherwise + */ + bool processAxis(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis); private: void objectDeleted(QObject *object); QKeySequence getShortcutForAction(const QString &componentName, const QString &actionName, const QKeySequence &defaultShortcut); QHash > m_shortcuts; QHash > m_pointerShortcuts; + QHash > m_axisShortcuts; KSharedConfigPtr m_config; }; @@ -96,11 +119,13 @@ public: protected: GlobalShortcut(const QKeySequence &shortcut); GlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons); + GlobalShortcut(Qt::KeyboardModifiers axisModifiers, PointerAxisDirection axis); private: QKeySequence m_shortcut; Qt::KeyboardModifiers m_pointerModifiers; Qt::MouseButtons m_pointerButtons; + PointerAxisDirection m_axis; }; class InternalGlobalShortcut : public GlobalShortcut @@ -108,6 +133,7 @@ class InternalGlobalShortcut : public GlobalShortcut public: InternalGlobalShortcut(const QKeySequence &shortcut, QAction *action); InternalGlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons, QAction *action); + InternalGlobalShortcut(Qt::KeyboardModifiers axisModifiers, PointerAxisDirection axis, QAction *action); virtual ~InternalGlobalShortcut(); void invoke() override; diff --git a/input.cpp b/input.cpp index 31216d92f1..6a05f17602 100644 --- a/input.cpp +++ b/input.cpp @@ -252,6 +252,27 @@ void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qr return; } emit pointerAxisChanged(axis, delta); +#if HAVE_XKB + if (m_xkb->modifiers() != Qt::NoModifier) { + PointerAxisDirection direction = PointerAxisUp; + if (axis == PointerAxisHorizontal) { + if (delta > 0) { + direction = PointerAxisUp; + } else { + direction = PointerAxisDown; + } + } else { + if (delta > 0) { + direction = PointerAxisLeft; + } else { + direction = PointerAxisRight; + } + } + if (m_shortcuts->processAxis(m_xkb->modifiers(), direction)) { + return; + } + } +#endif // TODO: check which part of KWin would like to intercept the event // TODO: Axis support for effect redirection @@ -459,4 +480,9 @@ void InputRedirection::registerPointerShortcut(Qt::KeyboardModifiers modifiers, m_shortcuts->registerPointerShortcut(action, modifiers, pointerButtons); } +void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) +{ + m_shortcuts->registerAxisShortcut(action, modifiers, axis); +} + } // namespace diff --git a/input.h b/input.h index 695d9fa614..ca30a06640 100644 --- a/input.h +++ b/input.h @@ -83,6 +83,7 @@ public: void registerShortcut(const QKeySequence &shortcut, QAction *action); void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action); + void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action); /** * @internal diff --git a/libkwineffects/kwinglobals.h b/libkwineffects/kwinglobals.h index a45ff63fa9..041b488c7b 100644 --- a/libkwineffects/kwinglobals.h +++ b/libkwineffects/kwinglobals.h @@ -113,6 +113,17 @@ enum KWinOption { SwitchDesktopOnScreenEdgeMovingWindows }; +/** + * @brief The direction in which a pointer axis is moved. + * + */ +enum PointerAxisDirection { + PointerAxisUp, + PointerAxisDown, + PointerAxisLeft, + PointerAxisRight +}; + inline KWIN_EXPORT Display* display() {