Changeset View
Changeset View
Standalone View
Standalone View
xkb.cpp
Show All 28 Lines | |||||
29 | #include <QKeyEvent> | 29 | #include <QKeyEvent> | ||
30 | // xkbcommon | 30 | // xkbcommon | ||
31 | #include <xkbcommon/xkbcommon.h> | 31 | #include <xkbcommon/xkbcommon.h> | ||
32 | #include <xkbcommon/xkbcommon-compose.h> | 32 | #include <xkbcommon/xkbcommon-compose.h> | ||
33 | #include <xkbcommon/xkbcommon-keysyms.h> | 33 | #include <xkbcommon/xkbcommon-keysyms.h> | ||
34 | // system | 34 | // system | ||
35 | #include <sys/mman.h> | 35 | #include <sys/mman.h> | ||
36 | #include <unistd.h> | 36 | #include <unistd.h> | ||
37 | #include <bitset> | ||||
37 | 38 | | |||
38 | Q_LOGGING_CATEGORY(KWIN_XKB, "kwin_xkbcommon", QtCriticalMsg) | 39 | Q_LOGGING_CATEGORY(KWIN_XKB, "kwin_xkbcommon", QtCriticalMsg) | ||
39 | 40 | | |||
40 | namespace KWin | 41 | namespace KWin | ||
41 | { | 42 | { | ||
42 | 43 | | |||
43 | static void xkbLogHandler(xkb_context *context, xkb_log_level priority, const char *format, va_list args) | 44 | static void xkbLogHandler(xkb_context *context, xkb_log_level priority, const char *format, va_list args) | ||
44 | { | 45 | { | ||
Show All 25 Lines | 69 | Xkb::Xkb(QObject *parent) | |||
70 | , m_context(xkb_context_new(XKB_CONTEXT_NO_FLAGS)) | 71 | , m_context(xkb_context_new(XKB_CONTEXT_NO_FLAGS)) | ||
71 | , m_keymap(NULL) | 72 | , m_keymap(NULL) | ||
72 | , m_state(NULL) | 73 | , m_state(NULL) | ||
73 | , m_shiftModifier(0) | 74 | , m_shiftModifier(0) | ||
74 | , m_capsModifier(0) | 75 | , m_capsModifier(0) | ||
75 | , m_controlModifier(0) | 76 | , m_controlModifier(0) | ||
76 | , m_altModifier(0) | 77 | , m_altModifier(0) | ||
77 | , m_metaModifier(0) | 78 | , m_metaModifier(0) | ||
79 | , m_numModifier(0) | ||||
78 | , m_numLock(0) | 80 | , m_numLock(0) | ||
79 | , m_capsLock(0) | 81 | , m_capsLock(0) | ||
80 | , m_scrollLock(0) | 82 | , m_scrollLock(0) | ||
81 | , m_modifiers(Qt::NoModifier) | 83 | , m_modifiers(Qt::NoModifier) | ||
82 | , m_consumedModifiers(Qt::NoModifier) | 84 | , m_consumedModifiers(Qt::NoModifier) | ||
83 | , m_keysym(XKB_KEY_NoSymbol) | 85 | , m_keysym(XKB_KEY_NoSymbol) | ||
84 | , m_leds() | 86 | , m_leds() | ||
85 | { | 87 | { | ||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Line(s) | 210 | if (map == MAP_FAILED) { | |||
209 | return; | 211 | return; | ||
210 | } | 212 | } | ||
211 | xkb_keymap *keymap = xkb_keymap_new_from_string(m_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_MAP_COMPILE_PLACEHOLDER); | 213 | xkb_keymap *keymap = xkb_keymap_new_from_string(m_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_MAP_COMPILE_PLACEHOLDER); | ||
212 | munmap(map, size); | 214 | munmap(map, size); | ||
213 | if (!keymap) { | 215 | if (!keymap) { | ||
214 | qCDebug(KWIN_XKB) << "Could not map keymap from file"; | 216 | qCDebug(KWIN_XKB) << "Could not map keymap from file"; | ||
215 | return; | 217 | return; | ||
216 | } | 218 | } | ||
219 | m_ownership = Ownership::Client; | ||||
217 | updateKeymap(keymap); | 220 | updateKeymap(keymap); | ||
218 | } | 221 | } | ||
219 | 222 | | |||
220 | void Xkb::updateKeymap(xkb_keymap *keymap) | 223 | void Xkb::updateKeymap(xkb_keymap *keymap) | ||
221 | { | 224 | { | ||
222 | Q_ASSERT(keymap); | 225 | Q_ASSERT(keymap); | ||
223 | xkb_state *state = xkb_state_new(keymap); | 226 | xkb_state *state = xkb_state_new(keymap); | ||
224 | if (!state) { | 227 | if (!state) { | ||
225 | qCDebug(KWIN_XKB) << "Could not create XKB state"; | 228 | qCDebug(KWIN_XKB) << "Could not create XKB state"; | ||
226 | xkb_keymap_unref(keymap); | 229 | xkb_keymap_unref(keymap); | ||
227 | return; | 230 | return; | ||
228 | } | 231 | } | ||
229 | // now release the old ones | 232 | // now release the old ones | ||
230 | xkb_state_unref(m_state); | 233 | xkb_state_unref(m_state); | ||
231 | xkb_keymap_unref(m_keymap); | 234 | xkb_keymap_unref(m_keymap); | ||
232 | 235 | | |||
233 | m_keymap = keymap; | 236 | m_keymap = keymap; | ||
234 | m_state = state; | 237 | m_state = state; | ||
235 | 238 | | |||
236 | m_shiftModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT); | 239 | m_shiftModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT); | ||
237 | m_capsModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CAPS); | 240 | m_capsModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CAPS); | ||
238 | m_controlModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL); | 241 | m_controlModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL); | ||
239 | m_altModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT); | 242 | m_altModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT); | ||
240 | m_metaModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO); | 243 | m_metaModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO); | ||
244 | m_numModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_NUM); | ||||
241 | 245 | | |||
242 | m_numLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_NUM); | 246 | m_numLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_NUM); | ||
243 | m_capsLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_CAPS); | 247 | m_capsLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_CAPS); | ||
244 | m_scrollLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_SCROLL); | 248 | m_scrollLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_SCROLL); | ||
245 | 249 | | |||
246 | m_currentLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); | 250 | m_currentLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); | ||
247 | 251 | | |||
248 | m_modifierState.depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); | 252 | m_modifierState.depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); | ||
249 | m_modifierState.latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); | 253 | m_modifierState.latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); | ||
250 | m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); | 254 | m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); | ||
251 | 255 | | |||
256 | static bool s_startup = true; | ||||
257 | if (s_startup || qEnvironmentVariableIsSet("KWIN_FORCE_NUM_LOCK_EVALUATION")) { | ||||
258 | s_startup = false; | ||||
259 | if (m_ownership == Ownership::Server && m_numModifier != XKB_MOD_INVALID && m_numLockConfig) { | ||||
davidedmundson: The documentation in the UI says this will be "on plasma startup"
This code seems to set it… | |||||
Me neither. I was aware of the difference. My first code for this was also with a tracker whether it's first run or not. I didn't really like the code and it would have required some nasty env variables to make it testable. In the end I decided against it as only a reconfigure from the kcm can trigger this code path. Given that I thought it was acceptable that it turns the num lock on. I would vote for if we get bug reports for it we do the ugly code. graesslin: > I don't mess with keyboards enough to be able to say whether this is a good feature or a… | |||||
260 | const KConfigGroup config = m_numLockConfig->group("Keyboard"); | ||||
261 | // STATE_ON = 0, STATE_OFF = 1, STATE_UNCHANGED = 2, see plasma-desktop/kcms/keyboard/kcmmisc.h | ||||
262 | const auto setting = config.readEntry("NumLock", 2); | ||||
263 | const bool numLockIsOn = xkb_state_mod_index_is_active(m_state, m_numModifier, XKB_STATE_MODS_LOCKED); | ||||
264 | if ((setting == 0 && !numLockIsOn) || (setting == 1 && numLockIsOn)) { | ||||
265 | std::bitset<sizeof(xkb_mod_mask_t)*8> mask{m_modifierState.locked}; | ||||
266 | if (mask.size() > m_numModifier) { | ||||
267 | mask[m_numModifier] = (setting == 0); | ||||
268 | m_modifierState.locked = mask.to_ulong(); | ||||
269 | xkb_state_update_mask(m_state, m_modifierState.depressed, m_modifierState.latched, m_modifierState.locked, 0, 0, m_currentLayout); | ||||
270 | m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); | ||||
271 | } | ||||
272 | } | ||||
273 | } | ||||
274 | } | ||||
275 | | ||||
252 | createKeymapFile(); | 276 | createKeymapFile(); | ||
253 | forwardModifiers(); | 277 | forwardModifiers(); | ||
278 | updateModifiers(); | ||||
254 | } | 279 | } | ||
255 | 280 | | |||
256 | void Xkb::createKeymapFile() | 281 | void Xkb::createKeymapFile() | ||
257 | { | 282 | { | ||
258 | if (!m_seat) { | 283 | if (!m_seat) { | ||
259 | return; | 284 | return; | ||
260 | } | 285 | } | ||
261 | // TODO: uninstall keymap on server? | 286 | // TODO: uninstall keymap on server? | ||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Line(s) | 363 | if (xkb_state_mod_index_is_active(m_state, m_altModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | |||
339 | mods |= Qt::AltModifier; | 364 | mods |= Qt::AltModifier; | ||
340 | } | 365 | } | ||
341 | if (xkb_state_mod_index_is_active(m_state, m_controlModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | 366 | if (xkb_state_mod_index_is_active(m_state, m_controlModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | ||
342 | mods |= Qt::ControlModifier; | 367 | mods |= Qt::ControlModifier; | ||
343 | } | 368 | } | ||
344 | if (xkb_state_mod_index_is_active(m_state, m_metaModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | 369 | if (xkb_state_mod_index_is_active(m_state, m_metaModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | ||
345 | mods |= Qt::MetaModifier; | 370 | mods |= Qt::MetaModifier; | ||
346 | } | 371 | } | ||
372 | if (xkb_state_mod_index_is_active(m_state, m_numModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { | ||||
373 | mods |= Qt::KeypadModifier; | ||||
374 | } | ||||
347 | m_modifiers = mods; | 375 | m_modifiers = mods; | ||
348 | 376 | | |||
349 | // update LEDs | 377 | // update LEDs | ||
350 | LEDs leds; | 378 | LEDs leds; | ||
351 | if (xkb_state_led_index_is_active(m_state, m_numLock) == 1) { | 379 | if (xkb_state_led_index_is_active(m_state, m_numLock) == 1) { | ||
352 | leds = leds | LED::NumLock; | 380 | leds = leds | LED::NumLock; | ||
353 | } | 381 | } | ||
354 | if (xkb_state_led_index_is_active(m_state, m_capsLock) == 1) { | 382 | if (xkb_state_led_index_is_active(m_state, m_capsLock) == 1) { | ||
▲ Show 20 Lines • Show All 199 Lines • Show Last 20 Lines |
The documentation in the UI says this will be "on plasma startup"
This code seems to set it whenever there's a reconfigure, which is subtly different.
I don't mess with keyboards enough to be able to say whether this is a good feature or a change that will be annoying.