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:
Dyami Caliri 2014-06-18 22:20:05 -07:00 committed by Gatis Paeglis
parent 8688dfcd7c
commit 07c34fcc8a
3 changed files with 18 additions and 17 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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;