xcb: use keyboard event source window to determine auto-repeat value
The xcb auto-repeat checking code checks for queued events on the target (focused) window. This breaks down if you have a native child widget, and QKeyEvent::autoRepeat is never true. Task-number: QTBUG-21500 Change-Id: Ia979edfa8a3afce07a3e1cbaa778541ffb9ce5dc Reviewed-by: Gatis Paeglis <gatis.paeglis@digia.com>
This commit is contained in:
parent
8688dfcd7c
commit
07c34fcc8a
@ -466,7 +466,7 @@ break;
|
||||
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
|
||||
handled = eventListener->handleGenericEvent(event, &result); \
|
||||
if (!handled) \
|
||||
m_keyboard->handler(m_focusWindow ? m_focusWindow : eventListener, e); \
|
||||
m_keyboard->handler(e); \
|
||||
} \
|
||||
} \
|
||||
break;
|
||||
|
@ -1295,7 +1295,7 @@ private:
|
||||
bool m_release;
|
||||
};
|
||||
|
||||
void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code,
|
||||
void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
|
||||
quint16 state, xcb_timestamp_t time)
|
||||
{
|
||||
Q_XCB_NOOP(connection());
|
||||
@ -1303,6 +1303,13 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
||||
if (!m_config)
|
||||
return;
|
||||
|
||||
QXcbWindow *source = connection()->platformWindowFromId(sourceWindow);
|
||||
QXcbWindow *targetWindow = connection()->focusWindow() ? connection()->focusWindow() : source;
|
||||
if (!targetWindow || !source)
|
||||
return;
|
||||
if (type == QEvent::KeyPress)
|
||||
targetWindow->updateNetWmUserTime(time);
|
||||
|
||||
// It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed!
|
||||
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
|
||||
|
||||
@ -1343,7 +1350,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
||||
}
|
||||
} else {
|
||||
// look ahead for auto-repeat
|
||||
KeyChecker checker(((QXcbWindow *)window->handle())->xcb_window(), code, time);
|
||||
KeyChecker checker(source->xcb_window(), code, time);
|
||||
xcb_generic_event_t *event = connection()->checkEvent(checker);
|
||||
if (event) {
|
||||
isAutoRepeat = true;
|
||||
@ -1359,6 +1366,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
||||
filtered = inputContext->filterEvent(&event);
|
||||
}
|
||||
|
||||
QWindow *window = targetWindow->window();
|
||||
if (!filtered) {
|
||||
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
|
||||
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
|
||||
@ -1401,21 +1409,14 @@ QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code)
|
||||
return QString::fromUtf8(chars);
|
||||
}
|
||||
|
||||
void QXcbKeyboard::handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event)
|
||||
void QXcbKeyboard::handleKeyPressEvent(const xcb_key_press_event_t *event)
|
||||
{
|
||||
QXcbWindow *window = eventListener->toWindow();
|
||||
if (!window)
|
||||
return;
|
||||
window->updateNetWmUserTime(event->time);
|
||||
handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time);
|
||||
handleKeyEvent(event->event, QEvent::KeyPress, event->detail, event->state, event->time);
|
||||
}
|
||||
|
||||
void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event)
|
||||
void QXcbKeyboard::handleKeyReleaseEvent(const xcb_key_release_event_t *event)
|
||||
{
|
||||
QXcbWindow *window = eventListener->toWindow();
|
||||
if (!window)
|
||||
return;
|
||||
handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
|
||||
handleKeyEvent(event->event, QEvent::KeyRelease, event->detail, event->state, event->time);
|
||||
}
|
||||
|
||||
void QXcbKeyboard::handleMappingNotifyEvent(const void *event)
|
||||
|
@ -64,8 +64,8 @@ public:
|
||||
|
||||
~QXcbKeyboard();
|
||||
|
||||
void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event);
|
||||
void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event);
|
||||
void handleKeyPressEvent(const xcb_key_press_event_t *event);
|
||||
void handleKeyReleaseEvent(const xcb_key_release_event_t *event);
|
||||
void handleMappingNotifyEvent(const void *event);
|
||||
|
||||
Qt::KeyboardModifiers translateModifiers(int s) const;
|
||||
@ -83,7 +83,7 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
|
||||
void handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
|
||||
|
||||
void resolveMaskConflicts();
|
||||
QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
|
||||
|
Loading…
Reference in New Issue
Block a user