Add support for modifier only shortcuts on Wayland
On popular demand! This change tracks how modifiers are used and detects a modifier only key press/release. That is: * no other key is pressed when the modifier gets pressed * no other key gets pressed before the modifier gets released If such a press/release is detected, we call a configurable dbus call. The possible shortcuts can be configured in kwinrc, group "ModifierOnlyShortcuts". The following keys are supported: * Shift * Control * Alt * Meta As value it takes a QStringList (comma seperated string) with service,path,interface,method,additionalargs E.g. to invoke Desktop Grid effect on Meta key: [ModifierOnlyShortcuts] Meta=org.kde.kglobalaccel,/component/kwin/,org.kde.kglobalaccel.Component,invokeShortcut,ShowDesktopGrid I do not intend to add a config interface for it. Let's keep it a hidden way. REVIEW: 124954icc-effect-5.14.5
parent
f6f555d688
commit
07414e88a5
28
input.cpp
28
input.cpp
|
@ -42,6 +42,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <decorations/decoratedclient.h>
|
#include <decorations/decoratedclient.h>
|
||||||
#include <KDecoration2/Decoration>
|
#include <KDecoration2/Decoration>
|
||||||
// Qt
|
// Qt
|
||||||
|
#include <QDBusMessage>
|
||||||
|
#include <QDBusPendingCall>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
@ -183,6 +185,32 @@ void Xkb::updateKey(uint32_t key, InputRedirection::KeyboardKeyState state)
|
||||||
}
|
}
|
||||||
xkb_state_update_key(m_state, key + 8, static_cast<xkb_key_direction>(state));
|
xkb_state_update_key(m_state, key + 8, static_cast<xkb_key_direction>(state));
|
||||||
updateModifiers();
|
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()
|
void Xkb::updateModifiers()
|
||||||
|
|
4
input.h
4
input.h
|
@ -262,6 +262,10 @@ private:
|
||||||
xkb_mod_index_t m_altModifier;
|
xkb_mod_index_t m_altModifier;
|
||||||
xkb_mod_index_t m_metaModifier;
|
xkb_mod_index_t m_metaModifier;
|
||||||
Qt::KeyboardModifiers m_modifiers;
|
Qt::KeyboardModifiers m_modifiers;
|
||||||
|
struct {
|
||||||
|
uint pressCount = 0;
|
||||||
|
Qt::KeyboardModifier modifier = Qt::NoModifier;
|
||||||
|
} m_modOnlyShortcut;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|
21
options.cpp
21
options.cpp
|
@ -838,6 +838,22 @@ void Options::loadConfig()
|
||||||
setMaxFpsInterval(1 * 1000 * 1000 * 1000 / config.readEntry("MaxFPS", Options::defaultMaxFps()));
|
setMaxFpsInterval(1 * 1000 * 1000 * 1000 / config.readEntry("MaxFPS", Options::defaultMaxFps()));
|
||||||
setRefreshRate(config.readEntry("RefreshRate", Options::defaultRefreshRate()));
|
setRefreshRate(config.readEntry("RefreshRate", Options::defaultRefreshRate()));
|
||||||
setVBlankTime(config.readEntry("VBlankTime", Options::defaultVBlankTime()) * 1000); // config in micro, value in nano resolution
|
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()
|
void Options::syncFromKcfgc()
|
||||||
|
@ -1124,4 +1140,9 @@ Options::WindowOperation Options::operationMaxButtonClick(Qt::MouseButtons butto
|
||||||
opMaxButtonLeftClick;
|
opMaxButtonLeftClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList Options::modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const
|
||||||
|
{
|
||||||
|
return m_modifierOnlyShortcuts.value(mod);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -589,6 +589,8 @@ public:
|
||||||
return m_glPreferBufferSwap;
|
return m_glPreferBufferSwap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const;
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setFocusPolicy(FocusPolicy focusPolicy);
|
void setFocusPolicy(FocusPolicy focusPolicy);
|
||||||
void setNextFocusPrefersMouse(bool nextFocusPrefersMouse);
|
void setNextFocusPrefersMouse(bool nextFocusPrefersMouse);
|
||||||
|
@ -929,6 +931,8 @@ private:
|
||||||
bool condensed_title;
|
bool condensed_title;
|
||||||
int animationSpeed; // 0 - instant, 5 - very slow
|
int animationSpeed; // 0 - instant, 5 - very slow
|
||||||
|
|
||||||
|
QHash<Qt::KeyboardModifier, QStringList> m_modifierOnlyShortcuts;
|
||||||
|
|
||||||
MouseCommand wheelToMouseCommand(MouseWheelCommand com, int delta) const;
|
MouseCommand wheelToMouseCommand(MouseWheelCommand com, int delta) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue