Support for global pointer shortcut activation
Sharing most of the code with keyboard shortcuts allowing to trigger a QAction with holding modifiers and clicking a mouse button.
This commit is contained in:
parent
38201a8295
commit
28406d153d
4 changed files with 103 additions and 7 deletions
|
@ -32,6 +32,15 @@ namespace KWin
|
|||
|
||||
GlobalShortcut::GlobalShortcut(const QKeySequence &shortcut)
|
||||
: m_shortcut(shortcut)
|
||||
, m_pointerModifiers(Qt::NoModifier)
|
||||
, m_pointerButtons(Qt::NoButton)
|
||||
{
|
||||
}
|
||||
|
||||
GlobalShortcut::GlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons)
|
||||
: m_shortcut(QKeySequence())
|
||||
, m_pointerModifiers(pointerButtonModifiers)
|
||||
, m_pointerButtons(pointerButtons)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -45,6 +54,12 @@ InternalGlobalShortcut::InternalGlobalShortcut(const QKeySequence &shortcut, QAc
|
|||
{
|
||||
}
|
||||
|
||||
InternalGlobalShortcut::InternalGlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons, QAction *action)
|
||||
: GlobalShortcut(pointerButtonModifiers, pointerButtons)
|
||||
, m_action(action)
|
||||
{
|
||||
}
|
||||
|
||||
InternalGlobalShortcut::~InternalGlobalShortcut()
|
||||
{
|
||||
}
|
||||
|
@ -61,16 +76,24 @@ GlobalShortcutsManager::GlobalShortcutsManager(QObject *parent)
|
|||
{
|
||||
}
|
||||
|
||||
GlobalShortcutsManager::~GlobalShortcutsManager()
|
||||
template <typename T>
|
||||
void clearShortcuts(T &shortcuts)
|
||||
{
|
||||
for (auto it = m_shortcuts.begin(); it != m_shortcuts.end(); ++it) {
|
||||
for (auto it = shortcuts.begin(); it != shortcuts.end(); ++it) {
|
||||
qDeleteAll((*it));
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalShortcutsManager::objectDeleted(QObject *object)
|
||||
GlobalShortcutsManager::~GlobalShortcutsManager()
|
||||
{
|
||||
for (auto it = m_shortcuts.begin(); it != m_shortcuts.end(); ++it) {
|
||||
clearShortcuts(m_shortcuts);
|
||||
clearShortcuts(m_pointerShortcuts);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void handleDestroyedAction(QObject *object, T &shortcuts)
|
||||
{
|
||||
for (auto it = shortcuts.begin(); it != shortcuts.end(); ++it) {
|
||||
auto list = (*it);
|
||||
for (auto it2 = list.begin(); it2 != list.end(); ++it2) {
|
||||
if (InternalGlobalShortcut *shortcut = dynamic_cast<InternalGlobalShortcut*>((*it2))) {
|
||||
|
@ -83,6 +106,12 @@ void GlobalShortcutsManager::objectDeleted(QObject *object)
|
|||
}
|
||||
}
|
||||
|
||||
void GlobalShortcutsManager::objectDeleted(QObject *object)
|
||||
{
|
||||
handleDestroyedAction(object, m_shortcuts);
|
||||
handleDestroyedAction(object, m_pointerShortcuts);
|
||||
}
|
||||
|
||||
void GlobalShortcutsManager::registerShortcut(QAction *action, const QKeySequence &shortcut)
|
||||
{
|
||||
QKeySequence s = getShortcutForAction(KWIN_NAME, action->objectName(), shortcut);
|
||||
|
@ -121,6 +150,21 @@ void GlobalShortcutsManager::registerShortcut(QAction *action, const QKeySequenc
|
|||
connect(action, &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted);
|
||||
}
|
||||
|
||||
void GlobalShortcutsManager::registerPointerShortcut(QAction *action, Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons)
|
||||
{
|
||||
GlobalShortcut *cut = new InternalGlobalShortcut(modifiers, pointerButtons, action);
|
||||
auto it = m_pointerShortcuts.find(modifiers);
|
||||
if (it != m_pointerShortcuts.end()) {
|
||||
// TODO: check if shortcut already exists
|
||||
(*it).insert(pointerButtons, cut);
|
||||
} else {
|
||||
QHash<Qt::MouseButtons, GlobalShortcut*> shortcuts;
|
||||
shortcuts.insert(pointerButtons, cut);
|
||||
m_pointerShortcuts.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)) {
|
||||
|
@ -141,10 +185,11 @@ QKeySequence GlobalShortcutsManager::getShortcutForAction(const QString &compone
|
|||
return QKeySequence(parts.first());
|
||||
}
|
||||
|
||||
bool GlobalShortcutsManager::processKey(Qt::KeyboardModifiers mods, uint32_t key)
|
||||
template <typename T, typename U>
|
||||
bool processShortcut(Qt::KeyboardModifiers mods, T key, U &shortcuts)
|
||||
{
|
||||
auto it = m_shortcuts.find(mods);
|
||||
if (it == m_shortcuts.end()) {
|
||||
auto it = shortcuts.find(mods);
|
||||
if (it == shortcuts.end()) {
|
||||
return false;
|
||||
}
|
||||
auto it2 = (*it).find(key);
|
||||
|
@ -155,4 +200,14 @@ bool GlobalShortcutsManager::processKey(Qt::KeyboardModifiers mods, uint32_t key
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GlobalShortcutsManager::processKey(Qt::KeyboardModifiers mods, uint32_t key)
|
||||
{
|
||||
return processShortcut(mods, key, m_shortcuts);
|
||||
}
|
||||
|
||||
bool GlobalShortcutsManager::processPointerPressed(Qt::KeyboardModifiers mods, Qt::MouseButtons pointerButtons)
|
||||
{
|
||||
return processShortcut(mods, pointerButtons, m_pointerShortcuts);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -53,6 +53,14 @@ public:
|
|||
* @param shortcut The key sequence which triggers this shortcut
|
||||
*/
|
||||
void registerShortcut(QAction *action, const QKeySequence &shortcut);
|
||||
/**
|
||||
* @brief Registers an internal global pointer shortcut
|
||||
*
|
||||
* @param action The action to trigger if the shortcut is pressed
|
||||
* @param modifiers The modifiers which need to be hold to trigger the action
|
||||
* @param pointerButtons The pointer button which needs to be pressed
|
||||
*/
|
||||
void registerPointerShortcut(QAction *action, Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons);
|
||||
|
||||
/**
|
||||
* @brief Processes a key event to decide whether a shortcut needs to be triggered.
|
||||
|
@ -66,10 +74,12 @@ public:
|
|||
* @return @c true if a shortcut triggered, @c false otherwise
|
||||
*/
|
||||
bool processKey(Qt::KeyboardModifiers modifiers, uint32_t key);
|
||||
bool processPointerPressed(Qt::KeyboardModifiers modifiers, Qt::MouseButtons pointerButtons);
|
||||
private:
|
||||
void objectDeleted(QObject *object);
|
||||
QKeySequence getShortcutForAction(const QString &componentName, const QString &actionName, const QKeySequence &defaultShortcut);
|
||||
QHash<Qt::KeyboardModifiers, QHash<uint32_t, GlobalShortcut*> > m_shortcuts;
|
||||
QHash<Qt::KeyboardModifiers, QHash<Qt::MouseButtons, GlobalShortcut*> > m_pointerShortcuts;
|
||||
KSharedConfigPtr m_config;
|
||||
};
|
||||
|
||||
|
@ -79,19 +89,25 @@ public:
|
|||
virtual ~GlobalShortcut();
|
||||
|
||||
const QKeySequence &shortcut() const;
|
||||
Qt::KeyboardModifiers pointerButtonModifiers() const;
|
||||
Qt::MouseButtons pointerButtons() const;
|
||||
virtual void invoke() = 0;
|
||||
|
||||
protected:
|
||||
GlobalShortcut(const QKeySequence &shortcut);
|
||||
GlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons);
|
||||
|
||||
private:
|
||||
QKeySequence m_shortcut;
|
||||
Qt::KeyboardModifiers m_pointerModifiers;
|
||||
Qt::MouseButtons m_pointerButtons;
|
||||
};
|
||||
|
||||
class InternalGlobalShortcut : public GlobalShortcut
|
||||
{
|
||||
public:
|
||||
InternalGlobalShortcut(const QKeySequence &shortcut, QAction *action);
|
||||
InternalGlobalShortcut(Qt::KeyboardModifiers pointerButtonModifiers, Qt::MouseButtons pointerButtons, QAction *action);
|
||||
virtual ~InternalGlobalShortcut();
|
||||
|
||||
void invoke() override;
|
||||
|
@ -113,6 +129,18 @@ const QKeySequence &GlobalShortcut::shortcut() const
|
|||
return m_shortcut;
|
||||
}
|
||||
|
||||
inline
|
||||
Qt::KeyboardModifiers GlobalShortcut::pointerButtonModifiers() const
|
||||
{
|
||||
return m_pointerModifiers;
|
||||
}
|
||||
|
||||
inline
|
||||
Qt::MouseButtons GlobalShortcut::pointerButtons() const
|
||||
{
|
||||
return m_pointerButtons;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
12
input.cpp
12
input.cpp
|
@ -230,6 +230,13 @@ void InputRedirection::processPointerButton(uint32_t button, InputRedirection::P
|
|||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
return;
|
||||
}
|
||||
#if HAVE_XKB
|
||||
if (state == KWin::InputRedirection::PointerButtonPressed) {
|
||||
if (m_shortcuts->processPointerPressed(m_xkb->modifiers(), qtButtonStates())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// TODO: check which part of KWin would like to intercept the event
|
||||
if (m_pointerWindow.isNull()) {
|
||||
// there is no window which can receive the
|
||||
|
@ -447,4 +454,9 @@ void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *a
|
|||
m_shortcuts->registerShortcut(action, shortcut);
|
||||
}
|
||||
|
||||
void InputRedirection::registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action)
|
||||
{
|
||||
m_shortcuts->registerPointerShortcut(action, modifiers, pointerButtons);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
1
input.h
1
input.h
|
@ -82,6 +82,7 @@ public:
|
|||
Qt::KeyboardModifiers keyboardModifiers() const;
|
||||
|
||||
void registerShortcut(const QKeySequence &shortcut, QAction *action);
|
||||
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
|
Loading…
Reference in a new issue