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)) { \
|
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
|
||||||
handled = eventListener->handleGenericEvent(event, &result); \
|
handled = eventListener->handleGenericEvent(event, &result); \
|
||||||
if (!handled) \
|
if (!handled) \
|
||||||
m_keyboard->handler(m_focusWindow ? m_focusWindow : eventListener, e); \
|
m_keyboard->handler(e); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break;
|
break;
|
||||||
|
@ -1295,7 +1295,7 @@ private:
|
|||||||
bool m_release;
|
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)
|
quint16 state, xcb_timestamp_t time)
|
||||||
{
|
{
|
||||||
Q_XCB_NOOP(connection());
|
Q_XCB_NOOP(connection());
|
||||||
@ -1303,6 +1303,13 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
|||||||
if (!m_config)
|
if (!m_config)
|
||||||
return;
|
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!
|
// 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);
|
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 {
|
} else {
|
||||||
// look ahead for auto-repeat
|
// 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);
|
xcb_generic_event_t *event = connection()->checkEvent(checker);
|
||||||
if (event) {
|
if (event) {
|
||||||
isAutoRepeat = true;
|
isAutoRepeat = true;
|
||||||
@ -1359,6 +1366,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
|||||||
filtered = inputContext->filterEvent(&event);
|
filtered = inputContext->filterEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWindow *window = targetWindow->window();
|
||||||
if (!filtered) {
|
if (!filtered) {
|
||||||
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
|
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
|
||||||
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
|
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);
|
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();
|
handleKeyEvent(event->event, QEvent::KeyPress, event->detail, event->state, event->time);
|
||||||
if (!window)
|
|
||||||
return;
|
|
||||||
window->updateNetWmUserTime(event->time);
|
|
||||||
handleKeyEvent(window->window(), 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();
|
handleKeyEvent(event->event, QEvent::KeyRelease, event->detail, event->state, event->time);
|
||||||
if (!window)
|
|
||||||
return;
|
|
||||||
handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbKeyboard::handleMappingNotifyEvent(const void *event)
|
void QXcbKeyboard::handleMappingNotifyEvent(const void *event)
|
||||||
|
@ -64,8 +64,8 @@ public:
|
|||||||
|
|
||||||
~QXcbKeyboard();
|
~QXcbKeyboard();
|
||||||
|
|
||||||
void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event);
|
void handleKeyPressEvent(const xcb_key_press_event_t *event);
|
||||||
void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event);
|
void handleKeyReleaseEvent(const xcb_key_release_event_t *event);
|
||||||
void handleMappingNotifyEvent(const void *event);
|
void handleMappingNotifyEvent(const void *event);
|
||||||
|
|
||||||
Qt::KeyboardModifiers translateModifiers(int s) const;
|
Qt::KeyboardModifiers translateModifiers(int s) const;
|
||||||
@ -83,7 +83,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
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();
|
void resolveMaskConflicts();
|
||||||
QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
|
QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user