Changeset View
Changeset View
Standalone View
Standalone View
src/runtime/plugins/xcb/kglobalaccel_x11.cpp
Show First 20 Lines • Show All 116 Lines • ▼ Show 20 Line(s) | 110 | } | |||
---|---|---|---|---|---|
117 | bool success = !grab; | 117 | bool success = !grab; | ||
118 | while (keyCodes[i] != XCB_NO_SYMBOL) { | 118 | while (keyCodes[i] != XCB_NO_SYMBOL) { | ||
119 | xcb_keycode_t keyCodeX = keyCodes[i++]; | 119 | xcb_keycode_t keyCodeX = keyCodes[i++]; | ||
120 | 120 | | |||
121 | // Check if shift needs to be added to the grab since KKeySequenceWidget | 121 | // Check if shift needs to be added to the grab since KKeySequenceWidget | ||
122 | // can remove shift for some keys. (all the %&* and such) | 122 | // can remove shift for some keys. (all the %&* and such) | ||
123 | if( !(keyQt & Qt::SHIFT) && | 123 | if( !(keyQt & Qt::SHIFT) && | ||
124 | !KKeyServer::isShiftAsModifierAllowed( keyQt ) && | 124 | !KKeyServer::isShiftAsModifierAllowed( keyQt ) && | ||
125 | !(keyQt & Qt::KeypadModifier) && | ||||
125 | keySymX != xcb_key_symbols_get_keysym(m_keySymbols, keyCodeX, 0) && | 126 | keySymX != xcb_key_symbols_get_keysym(m_keySymbols, keyCodeX, 0) && | ||
126 | keySymX == xcb_key_symbols_get_keysym(m_keySymbols, keyCodeX, 1) ) | 127 | keySymX == xcb_key_symbols_get_keysym(m_keySymbols, keyCodeX, 1) ) | ||
127 | { | 128 | { | ||
128 | qCDebug(KGLOBALACCELD) << "adding shift to the grab"; | 129 | qCDebug(KGLOBALACCELD) << "adding shift to the grab"; | ||
129 | keyModX |= KKeyServer::modXShift(); | 130 | keyModX |= KKeyServer::modXShift(); | ||
130 | } | 131 | } | ||
131 | 132 | | |||
132 | keyModX &= g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod | 133 | keyModX &= g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod | ||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Line(s) | 236 | { | |||
238 | } | 239 | } | ||
239 | 240 | | |||
240 | // Keyboard needs to be ungrabed after XGrabKey() activates the grab, | 241 | // Keyboard needs to be ungrabed after XGrabKey() activates the grab, | ||
241 | // otherwise it becomes frozen. | 242 | // otherwise it becomes frozen. | ||
242 | xcb_connection_t *c = QX11Info::connection(); | 243 | xcb_connection_t *c = QX11Info::connection(); | ||
243 | xcb_ungrab_keyboard(c, XCB_TIME_CURRENT_TIME); | 244 | xcb_ungrab_keyboard(c, XCB_TIME_CURRENT_TIME); | ||
244 | xcb_flush(c); | 245 | xcb_flush(c); | ||
245 | 246 | | |||
246 | xcb_keycode_t keyCodeX = pEvent->detail; | 247 | int keyQt; | ||
247 | uint16_t keyModX = pEvent->state & (g_keyModMaskXAccel | KKeyServer::MODE_SWITCH); | 248 | if (!KKeyServer::xcbKeyPressEventToQt(pEvent, &keyQt)) { | ||
248 | 249 | qCWarning(KGLOBALACCELD) << "KKeyServer::xcbKeyPressEventToQt failed"; | |||
249 | xcb_keysym_t keySymX = xcb_key_press_lookup_keysym(m_keySymbols, pEvent, 0); | 250 | return false; | ||
250 | | ||||
251 | // If numlock is active and a keypad key is pressed, XOR the SHIFT state. | | |||
252 | // e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left. | | |||
253 | if (pEvent->state & KKeyServer::modXNumLock()) { | | |||
254 | // If this is a keypad key, | | |||
255 | if( keySymX >= XK_KP_Space && keySymX <= XK_KP_9 ) { | | |||
256 | switch( keySymX ) { | | |||
257 | | ||||
258 | // Leave the following keys unaltered | | |||
259 | // FIXME: The proper solution is to see which keysyms don't change when shifted. | | |||
260 | case XK_KP_Multiply: | | |||
261 | case XK_KP_Add: | | |||
262 | case XK_KP_Subtract: | | |||
263 | case XK_KP_Divide: | | |||
264 | case XK_KP_Enter: | | |||
265 | break; | | |||
266 | | ||||
267 | default: | | |||
268 | keyModX ^= KKeyServer::modXShift(); | | |||
269 | } | | |||
270 | } | | |||
271 | } | | |||
272 | | ||||
273 | int keyCodeQt; | | |||
274 | int keyModQt; | | |||
275 | KKeyServer::symXToKeyQt(keySymX, &keyCodeQt); | | |||
276 | KKeyServer::modXToQt(keyModX, &keyModQt); | | |||
277 | | ||||
278 | if ((keyModQt & Qt::SHIFT) && !KKeyServer::isShiftAsModifierAllowed( keyCodeQt ) ) { | | |||
279 | #ifdef KDEDGLOBALACCEL_TRACE | | |||
280 | qCDebug(KGLOBALACCELD) << "removing shift modifier"; | | |||
281 | #endif | | |||
282 | if (keyCodeQt != Qt::Key_Tab) { // KKeySequenceWidget does not map shift+tab to backtab | | |||
283 | static const int FirstLevelShift = 1; | | |||
284 | keySymX = xcb_key_symbols_get_keysym(m_keySymbols, keyCodeX, FirstLevelShift); | | |||
285 | KKeyServer::symXToKeyQt(keySymX, &keyCodeQt); | | |||
286 | } | | |||
287 | keyModQt &= ~Qt::SHIFT; | | |||
graesslin: The shift handling code has shown regressions whenever it was touched. Also on Wayland I needed… | |||||
I did not change one inch of that logic, I just moved it to KKeyServer::xcbKeyPressEventToQt. dfaure: I did not change one inch of that logic, I just moved it to KKeyServer::xcbKeyPressEventToQt. | |||||
I'm sorry I didn't notice. I first noticed this review and it has no dependency set. It looked like the code got dropped. graesslin: I'm sorry I didn't notice. I first noticed this review and it has no dependency set. It looked… | |||||
288 | } | 251 | } | ||
289 | 252 | //qDebug() << "keyQt=" << QString::number(keyQt, 16); | |||
290 | int keyQt = keyCodeQt | keyModQt; | | |||
291 | 253 | | |||
292 | // All that work for this hey... argh... | 254 | // All that work for this hey... argh... | ||
293 | if (NET::timestampCompare(pEvent->time, QX11Info::appTime()) > 0) { | 255 | if (NET::timestampCompare(pEvent->time, QX11Info::appTime()) > 0) { | ||
294 | QX11Info::setAppTime(pEvent->time); | 256 | QX11Info::setAppTime(pEvent->time); | ||
295 | } | 257 | } | ||
296 | return keyPressed(keyQt); | 258 | return keyPressed(keyQt); | ||
297 | } | 259 | } | ||
298 | 260 | | |||
Show All 16 Lines |
The shift handling code has shown regressions whenever it was touched. Also on Wayland I needed several tries to get it right. I would prefer if it were not touched any more.
This is not as simple as it looks. There are besties out there like Alt+Shift+Backtab as a global shortcut and a generic implementation breaks quickly there. It is quite likely that this change would break Alt+(Shift)+Tab in KWin.