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;
};