1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
#pragma once
#include "../defines.hpp"
#include <vector>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <functional>
#include <xkbcommon/xkbcommon.h>
#include "../devices/IPointer.hpp"
#include "eventLoop/EventLoopTimer.hpp"
#include "../helpers/time/Timer.hpp"
class CInputManager;
class CPluginSystem;
class IKeyboard;
enum eMouseBindMode : int8_t;
struct SSubmap {
std::string name = "";
std::string reset = "";
bool operator==(const SSubmap& other) const {
return name == other.name;
}
};
using KeybindKey = std::pair<xkb_keysym_t, xkb_keycode_t>;
struct SKeybind {
std::string key = "";
std::vector<KeybindKey> sMkKeys = {};
uint32_t keycode = 0;
bool catchAll = false;
uint32_t modmask = 0;
std::vector<KeybindKey> sMkMods = {};
std::string handler = "";
std::string arg = "";
bool locked = false;
SSubmap submap = {};
std::string description = "";
bool release = false;
bool repeat = false;
bool longPress = false;
bool mouse = false;
bool nonConsuming = false;
bool autoConsuming = false;
bool transparent = false;
bool ignoreMods = false;
bool multiKey = false;
bool hasDescription = false;
bool dontInhibit = false;
bool click = false;
bool drag = false;
bool submapUniversal = false;
bool deviceInclusive = false;
std::unordered_set<std::string> devices = {};
bool enabled = true;
std::string displayKey = "";
// DO NOT INITIALIZE
bool shadowed = false;
};
enum eFocusWindowMode : uint8_t {
MODE_CLASS_REGEX = 0,
MODE_INITIAL_CLASS_REGEX,
MODE_TITLE_REGEX,
MODE_INITIAL_TITLE_REGEX,
MODE_TAG_REGEX,
MODE_ADDRESS,
MODE_PID,
MODE_ACTIVE_WINDOW
};
struct SPressedKeyWithMods {
std::string keyName = "";
xkb_keysym_t keysym = 0;
uint32_t keycode = 0;
uint32_t modmaskAtPressTime = 0;
bool sent = false;
SSubmap submapAtPress = {};
Vector2D mousePosAtPress = {};
};
struct SParsedKey {
std::string key = "";
uint32_t keycode = 0;
bool catchAll = false;
};
enum eMultiKeyCase : uint8_t {
MK_NO_MATCH = 0,
MK_PARTIAL_MATCH,
MK_FULL_MATCH
};
namespace Config::Legacy {
class CConfigManager;
}
namespace Config::Lua {
class CConfigManager;
}
class CKeybindManager {
public:
CKeybindManager();
~CKeybindManager();
bool onKeyEvent(std::any, SP<IKeyboard>);
bool onAxisEvent(const IPointer::SAxisEvent&, SP<IPointer>);
bool onMouseEvent(const IPointer::SButtonEvent&, SP<IPointer>);
void resizeWithBorder(const IPointer::SButtonEvent&);
void onSwitchEvent(const std::string&);
void onSwitchOnEvent(const std::string&);
void onSwitchOffEvent(const std::string&);
SP<SKeybind> addKeybind(SKeybind);
void removeKeybind(uint32_t, const SParsedKey&);
void removeKeybind(const std::string& displayKeys);
uint32_t stringToModMask(std::string);
uint32_t keycodeToModifier(xkb_keycode_t);
void clearKeybinds();
void shadowKeybinds(const xkb_keysym_t& doesntHave = 0, const uint32_t doesntHaveCode = 0);
SSubmap getCurrentSubmap();
std::unordered_map<std::string, std::function<SDispatchResult(std::string)>> m_dispatchers;
bool m_groupsLocked = false;
std::vector<SP<SKeybind>> m_keybinds;
SP<SKeybind> m_currentKeybind;
//since we can't find keycode through keyname in xkb:
//on sendshortcut call, we once search for keyname (e.g. "g") the correct keycode (e.g. 42)
//and cache it in this map to make sendshortcut calls faster
//we also store the keyboard pointer (in the string) to differentiate between different keyboard (layouts)
std::unordered_map<std::string, xkb_keycode_t> m_keyToCodeCache;
static SDispatchResult changeMouseBindMode(const eMouseBindMode mode);
private:
std::vector<SPressedKeyWithMods> m_pressedKeys;
std::vector<WP<SKeybind>> m_activeKeybinds;
WP<SKeybind> m_lastLongPressKeybind;
SP<CEventLoopTimer> m_longPressTimer;
SP<CEventLoopTimer> m_repeatKeyTimer;
uint32_t m_repeatKeyRate = 50;
std::vector<WP<SKeybind>> m_pressedSpecialBinds;
CTimer m_scrollTimer;
SDispatchResult handleKeybinds(const uint32_t, const SPressedKeyWithMods&, bool, SP<IKeyboard>, SP<IHID>);
std::set<KeybindKey> m_mkKeys = {};
std::set<KeybindKey> m_mkMods = {};
eMultiKeyCase mkBindMatches(const SP<SKeybind>);
eMultiKeyCase mkKeysymSetMatches(const std::vector<KeybindKey>&, const std::set<KeybindKey>&);
bool handleInternalKeybinds(xkb_keysym_t);
bool handleVT(xkb_keysym_t);
xkb_state* m_xkbTranslationState = nullptr;
void updateXKBTranslationState();
bool ensureMouseBindState();
friend class CCompositor;
friend class CInputManager;
friend class Config::Legacy::CConfigManager;
friend class Config::Lua::CConfigManager;
friend class CWorkspace;
friend class CPointerManager;
};
inline UP<CKeybindManager> g_pKeybindManager;
|