KWin
Loading...
Searching...
No Matches
stickykeys.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6
7#include "stickykeys.h"
8#include "keyboard_input.h"
9#include "xkb.h"
10
12 : m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("kaccessrc")))
13{
14 const QLatin1String groupName("Keyboard");
15 connect(m_configWatcher.get(), &KConfigWatcher::configChanged, this, [this, groupName](const KConfigGroup &group) {
16 if (group.name() == groupName) {
17 loadConfig(group);
18 }
19 });
20 loadConfig(m_configWatcher->config()->group(groupName));
21
22 for (int mod : std::as_const(m_modifiers)) {
23 m_keyStates[mod] = None;
24 }
25}
26
27Qt::KeyboardModifier keyToModifier(Qt::Key key)
28{
29 if (key == Qt::Key_Shift) {
30 return Qt::ShiftModifier;
31 } else if (key == Qt::Key_Alt) {
32 return Qt::AltModifier;
33 } else if (key == Qt::Key_Control) {
34 return Qt::ControlModifier;
35 } else if (key == Qt::Key_AltGr) {
36 return Qt::GroupSwitchModifier;
37 } else if (key == Qt::Key_Meta) {
38 return Qt::MetaModifier;
39 }
40
41 return Qt::NoModifier;
42}
43
44void StickyKeysFilter::loadConfig(const KConfigGroup &group)
45{
47
48 m_lockKeys = group.readEntry<bool>("StickyKeysLatch", true);
49
50 if (!m_lockKeys) {
51 // locking keys is deactivated, unlock all locked keys
52 for (auto it = m_keyStates.keyValueBegin(); it != m_keyStates.keyValueEnd(); ++it) {
53 if (it->second == KeyState::Locked) {
54 it->second = KeyState::None;
55 KWin::input()->keyboard()->xkb()->setModifierLocked(keyToModifier(static_cast<Qt::Key>(it->first)), false);
56 }
57 }
58 }
59
60 if (group.readEntry<bool>("StickyKeys", false)) {
62 } else {
63 // sticky keys are deactivated, unlatch all latched keys
64 for (auto it = m_keyStates.keyValueBegin(); it != m_keyStates.keyValueEnd(); ++it) {
65 if (it->second != KeyState::None) {
66 it->second = KeyState::None;
67 KWin::input()->keyboard()->xkb()->setModifierLatched(keyToModifier(static_cast<Qt::Key>(it->first)), false);
68 }
69 }
70 }
71}
72
74{
75 if (m_modifiers.contains(event->key())) {
76
77 auto keyState = m_keyStates.find(event->key());
78
79 if (keyState != m_keyStates.end()) {
80 if (event->type() == QKeyEvent::KeyPress) {
81 // An unlatched modifier was pressed, latch it
82 if (keyState.value() == None) {
83 keyState.value() = Latched;
84 KWin::input()->keyboard()->xkb()->setModifierLatched(keyToModifier(static_cast<Qt::Key>(event->key())), true);
85 }
86 // A latched modifier was pressed, lock it
87 else if (keyState.value() == Latched && m_lockKeys) {
88 keyState.value() = Locked;
89 KWin::input()->keyboard()->xkb()->setModifierLocked(keyToModifier(static_cast<Qt::Key>(event->key())), true);
90 }
91 // A locked modifier was pressed, unlock it
92 else if (keyState.value() == Locked && m_lockKeys) {
93 keyState.value() = None;
94 KWin::input()->keyboard()->xkb()->setModifierLocked(keyToModifier(static_cast<Qt::Key>(event->key())), false);
95 }
96 }
97 }
98 } else if (event->type() == QKeyEvent::KeyPress) {
99 // a non-modifier key was pressed, unlatch all unlocked modifiers
100 for (auto it = m_keyStates.keyValueBegin(); it != m_keyStates.keyValueEnd(); ++it) {
101
102 if (it->second == Locked) {
103 continue;
104 }
105
106 it->second = KeyState::None;
107
108 KWin::input()->keyboard()->xkb()->setModifierLatched(keyToModifier(static_cast<Qt::Key>(it->first)), false);
109 }
110 }
111
112 return false;
113}
114
115#include "moc_stickykeys.cpp"
KeyboardInputRedirection * keyboard() const
Definition input.h:216
void uninstallInputEventFilter(InputEventFilter *filter)
Definition input.cpp:2684
void prependInputEventFilter(InputEventFilter *filter)
Definition input.cpp:2678
void setModifierLocked(Qt::KeyboardModifier mod, bool locked)
Definition xkb.cpp:690
void setModifierLatched(Qt::KeyboardModifier mod, bool latched)
Definition xkb.cpp:643
bool keyEvent(KWin::KeyEvent *event) override
InputRedirection * input()
Definition input.h:549
Qt::KeyboardModifier keyToModifier(Qt::Key key)