File indexing completed on 2024-12-08 07:59:26
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #pragma once 0010 // KWin 0011 #include "effect/globals.h" 0012 // Qt 0013 #include <QKeySequence> 0014 0015 #include <memory> 0016 0017 class QAction; 0018 class KGlobalAccelD; 0019 class KGlobalAccelInterface; 0020 0021 namespace KWin 0022 { 0023 class GlobalShortcut; 0024 class SwipeGesture; 0025 class PinchGesture; 0026 class GestureRecognizer; 0027 0028 enum class DeviceType { 0029 Touchpad, 0030 Touchscreen 0031 }; 0032 0033 /** 0034 * @brief Manager for the global shortcut system inside KWin. 0035 * 0036 * This class is responsible for holding all the global shortcuts and to process a key press event. 0037 * That is trigger a shortcut if there is a match. 0038 * 0039 * For internal shortcut handling (those which are delivered inside KWin) QActions are used and 0040 * triggered if the shortcut matches. For external shortcut handling a DBus interface is used. 0041 */ 0042 class GlobalShortcutsManager : public QObject 0043 { 0044 Q_OBJECT 0045 public: 0046 explicit GlobalShortcutsManager(QObject *parent = nullptr); 0047 ~GlobalShortcutsManager() override; 0048 void init(); 0049 0050 /** 0051 * @brief Registers an internal global pointer shortcut 0052 * 0053 * @param action The action to trigger if the shortcut is pressed 0054 * @param modifiers The modifiers which need to be hold to trigger the action 0055 * @param pointerButtons The pointer button which needs to be pressed 0056 */ 0057 void registerPointerShortcut(QAction *action, Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons); 0058 /** 0059 * @brief Registers an internal global axis shortcut 0060 * 0061 * @param action The action to trigger if the shortcut is triggered 0062 * @param modifiers The modifiers which need to be hold to trigger the action 0063 * @param axis The pointer axis 0064 */ 0065 void registerAxisShortcut(QAction *action, Qt::KeyboardModifiers modifiers, PointerAxisDirection axis); 0066 0067 void registerTouchpadSwipe(SwipeDirection direction, uint32_t fingerCount, QAction *action, std::function<void(qreal)> progressCallback = {}); 0068 void registerTouchpadPinch(PinchDirection direction, uint32_t fingerCount, QAction *action, std::function<void(qreal)> progressCallback = {}); 0069 void registerTouchscreenSwipe(SwipeDirection direction, uint32_t fingerCount, QAction *action, std::function<void(qreal)> progressCallback = {}); 0070 void forceRegisterTouchscreenSwipe(SwipeDirection direction, uint32_t fingerCount, QAction *action, std::function<void(qreal)> progressCallback = {}); 0071 0072 /** 0073 * @brief Processes a key event to decide whether a shortcut needs to be triggered. 0074 * 0075 * If a shortcut triggered this method returns @c true to indicate to the caller that the event 0076 * should not be further processed. If there is no shortcut which triggered for the key, then 0077 * @c false is returned. 0078 * 0079 * @param modifiers The current hold modifiers 0080 * @param keyQt The Qt::Key which got pressed 0081 * @return @c true if a shortcut triggered, @c false otherwise 0082 */ 0083 bool processKey(Qt::KeyboardModifiers modifiers, int keyQt); 0084 bool processKeyRelease(Qt::KeyboardModifiers modifiers, int keyQt); 0085 bool processPointerPressed(Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons); 0086 /** 0087 * @brief Processes a pointer axis event to decide whether a shortcut needs to be triggered. 0088 * 0089 * If a shortcut triggered this method returns @c true to indicate to the caller that the event 0090 * should not be further processed. If there is no shortcut which triggered for the key, then 0091 * @c false is returned. 0092 * 0093 * @param modifiers The current hold modifiers 0094 * @param axis The axis direction which has triggered this event 0095 * @return @c true if a shortcut triggered, @c false otherwise 0096 */ 0097 bool processAxis(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis); 0098 0099 void processSwipeStart(DeviceType device, uint fingerCount); 0100 void processSwipeUpdate(DeviceType device, const QPointF &delta); 0101 void processSwipeCancel(DeviceType device); 0102 void processSwipeEnd(DeviceType device); 0103 0104 void processPinchStart(uint fingerCount); 0105 void processPinchUpdate(qreal scale, qreal angleDelta, const QPointF &delta); 0106 void processPinchCancel(); 0107 void processPinchEnd(); 0108 0109 void setKGlobalAccelInterface(KGlobalAccelInterface *interface) 0110 { 0111 m_kglobalAccelInterface = interface; 0112 } 0113 0114 private: 0115 void objectDeleted(QObject *object); 0116 bool add(GlobalShortcut sc, DeviceType device = DeviceType::Touchpad); 0117 0118 QList<GlobalShortcut> m_shortcuts; 0119 0120 std::unique_ptr<KGlobalAccelD> m_kglobalAccel; 0121 KGlobalAccelInterface *m_kglobalAccelInterface = nullptr; 0122 std::unique_ptr<GestureRecognizer> m_touchpadGestureRecognizer; 0123 std::unique_ptr<GestureRecognizer> m_touchscreenGestureRecognizer; 0124 }; 0125 0126 struct KeyboardShortcut 0127 { 0128 QKeySequence sequence; 0129 bool operator==(const KeyboardShortcut &rhs) const 0130 { 0131 return sequence == rhs.sequence; 0132 } 0133 }; 0134 struct PointerButtonShortcut 0135 { 0136 Qt::KeyboardModifiers pointerModifiers; 0137 Qt::MouseButtons pointerButtons; 0138 bool operator==(const PointerButtonShortcut &rhs) const 0139 { 0140 return pointerModifiers == rhs.pointerModifiers && pointerButtons == rhs.pointerButtons; 0141 } 0142 }; 0143 struct PointerAxisShortcut 0144 { 0145 Qt::KeyboardModifiers axisModifiers; 0146 PointerAxisDirection axisDirection; 0147 bool operator==(const PointerAxisShortcut &rhs) const 0148 { 0149 return axisModifiers == rhs.axisModifiers && axisDirection == rhs.axisDirection; 0150 } 0151 }; 0152 struct RealtimeFeedbackSwipeShortcut 0153 { 0154 DeviceType device; 0155 SwipeDirection direction; 0156 std::function<void(qreal)> progressCallback; 0157 uint fingerCount; 0158 0159 template<typename T> 0160 bool operator==(const T &rhs) const 0161 { 0162 return direction == rhs.direction && fingerCount == rhs.fingerCount && device == rhs.device; 0163 } 0164 }; 0165 struct RealtimeFeedbackPinchShortcut 0166 { 0167 PinchDirection direction; 0168 std::function<void(qreal)> scaleCallback; 0169 uint fingerCount; 0170 0171 template<typename T> 0172 bool operator==(const T &rhs) const 0173 { 0174 return direction == rhs.direction && fingerCount == rhs.fingerCount; 0175 } 0176 }; 0177 0178 using Shortcut = std::variant<KeyboardShortcut, PointerButtonShortcut, PointerAxisShortcut, RealtimeFeedbackSwipeShortcut, RealtimeFeedbackPinchShortcut>; 0179 0180 class GlobalShortcut 0181 { 0182 public: 0183 GlobalShortcut(Shortcut &&shortcut, QAction *action); 0184 ~GlobalShortcut(); 0185 0186 void invoke() const; 0187 QAction *action() const; 0188 const Shortcut &shortcut() const; 0189 SwipeGesture *swipeGesture() const; 0190 PinchGesture *pinchGesture() const; 0191 0192 private: 0193 std::shared_ptr<SwipeGesture> m_swipeGesture; 0194 std::shared_ptr<PinchGesture> m_pinchGesture; 0195 Shortcut m_shortcut = {}; 0196 QAction *m_action = nullptr; 0197 }; 0198 0199 } // namespace