diff --git a/input.cpp b/input.cpp index 92724d7b75..2e02662615 100644 --- a/input.cpp +++ b/input.cpp @@ -42,6 +42,8 @@ along with this program. If not, see . #include #include // Qt +#include +#include #include #include #include @@ -183,6 +185,32 @@ void Xkb::updateKey(uint32_t key, InputRedirection::KeyboardKeyState state) } xkb_state_update_key(m_state, key + 8, static_cast(state)); updateModifiers(); + if (state == InputRedirection::KeyboardKeyPressed) { + m_modOnlyShortcut.pressCount++; + if (m_modOnlyShortcut.pressCount == 1) { + m_modOnlyShortcut.modifier = Qt::KeyboardModifier(int(m_modifiers)); + } else { + m_modOnlyShortcut.modifier = Qt::NoModifier; + } + } else { + m_modOnlyShortcut.pressCount--; + // TODO: ignore on lock screen + if (m_modOnlyShortcut.pressCount == 0) { + if (m_modOnlyShortcut.modifier != Qt::NoModifier) { + const auto list = options->modifierOnlyDBusShortcut(m_modOnlyShortcut.modifier); + if (list.size() >= 4) { + auto call = QDBusMessage::createMethodCall(list.at(0), list.at(1), list.at(2), list.at(3)); + QVariantList args; + for (int i = 4; i < list.size(); ++i) { + args << list.at(i); + } + call.setArguments(args); + QDBusConnection::sessionBus().asyncCall(call); + } + } + } + m_modOnlyShortcut.modifier = Qt::NoModifier; + } } void Xkb::updateModifiers() diff --git a/input.h b/input.h index cfb693dc06..72b6d1b0e2 100644 --- a/input.h +++ b/input.h @@ -262,6 +262,10 @@ private: xkb_mod_index_t m_altModifier; xkb_mod_index_t m_metaModifier; Qt::KeyboardModifiers m_modifiers; + struct { + uint pressCount = 0; + Qt::KeyboardModifier modifier = Qt::NoModifier; + } m_modOnlyShortcut; }; inline diff --git a/options.cpp b/options.cpp index 64269d64bc..00b1b85b76 100644 --- a/options.cpp +++ b/options.cpp @@ -838,6 +838,22 @@ void Options::loadConfig() setMaxFpsInterval(1 * 1000 * 1000 * 1000 / config.readEntry("MaxFPS", Options::defaultMaxFps())); setRefreshRate(config.readEntry("RefreshRate", Options::defaultRefreshRate())); setVBlankTime(config.readEntry("VBlankTime", Options::defaultVBlankTime()) * 1000); // config in micro, value in nano resolution + + // Modifier Only Shortcuts + config = KConfigGroup(m_settings->config(), "ModifierOnlyShortcuts"); + m_modifierOnlyShortcuts.clear(); + if (config.hasKey("Shift")) { + m_modifierOnlyShortcuts.insert(Qt::ShiftModifier, config.readEntry("Shift", QStringList())); + } + if (config.hasKey("Control")) { + m_modifierOnlyShortcuts.insert(Qt::ControlModifier, config.readEntry("Control", QStringList())); + } + if (config.hasKey("Alt")) { + m_modifierOnlyShortcuts.insert(Qt::AltModifier, config.readEntry("Alt", QStringList())); + } + if (config.hasKey("Meta")) { + m_modifierOnlyShortcuts.insert(Qt::MetaModifier, config.readEntry("Meta", QStringList())); + } } void Options::syncFromKcfgc() @@ -1124,4 +1140,9 @@ Options::WindowOperation Options::operationMaxButtonClick(Qt::MouseButtons butto opMaxButtonLeftClick; } +QStringList Options::modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const +{ + return m_modifierOnlyShortcuts.value(mod); +} + } // namespace diff --git a/options.h b/options.h index 07c5193e3b..96ad4d333a 100644 --- a/options.h +++ b/options.h @@ -589,6 +589,8 @@ public: return m_glPreferBufferSwap; } + QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const; + // setters void setFocusPolicy(FocusPolicy focusPolicy); void setNextFocusPrefersMouse(bool nextFocusPrefersMouse); @@ -929,6 +931,8 @@ private: bool condensed_title; int animationSpeed; // 0 - instant, 5 - very slow + QHash m_modifierOnlyShortcuts; + MouseCommand wheelToMouseCommand(MouseWheelCommand com, int delta) const; };