diff options
author | Gatis Paeglis <gatis.paeglis@qt.io> | 2018-09-19 11:40:31 +0200 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2018-10-16 06:57:01 +0000 |
commit | 00ae1e6b7bf6efa5f5e57d37844e44d521604fb6 (patch) | |
tree | 7e6c8177f2f9796b30df490f8d582d6668d9f9fa /src/plugins/platforms/xcb/qxcbconnection.cpp | |
parent | dd8a66daa497f0547f2fcddc0ee1e722d13ab98b (diff) |
xcb: respect QEventLoop::ExcludeUserInputEvents in native event handlers
This was a regression from Qt 4.
Before this patch, we supported filtering events only at QWindowSystemInterface
level, but to properly support filtering in QAbstractEventDispatcher::filterNativeEvent,
we have to filter the events earlier. Now it is possible to enable/disable this
feature for platforms that support native event filtering.
The mapping of which events are user input events were taken from
QWindowSystemInterfacePrivate::EventType.
Task-number: QTBUG-69687
Change-Id: I9a5fb9f999451c47abcdc83fdcc129b5eeb55447
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index c1f0b71414..a4294956c1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1020,11 +1020,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) printXcbEvent(lcQpaEvents(), "Event", event); long result = 0; // Used only by MS Windows - QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); - bool handledByNativeEventFilter = dispatcher && dispatcher->filterNativeEvent( - m_nativeInterface->nativeEventType(), event, &result); - if (handledByNativeEventFilter) - return; + if (QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance()) { + if (dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), event, &result)) + return; + } uint response_type = event->response_type & ~0x80; @@ -1451,7 +1450,47 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const return false; } -void QXcbConnection::processXcbEvents() +bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const +{ + auto eventType = event->response_type & ~0x80; + bool isInputEvent = eventType == XCB_BUTTON_PRESS || + eventType == XCB_BUTTON_RELEASE || + eventType == XCB_KEY_PRESS || + eventType == XCB_KEY_RELEASE || + eventType == XCB_MOTION_NOTIFY || + eventType == XCB_ENTER_NOTIFY || + eventType == XCB_LEAVE_NOTIFY; + if (isInputEvent) + return true; + +#if QT_CONFIG(xcb_xinput) + if (connection()->hasXInput2()) { + isInputEvent = isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_PRESS) || + isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_RELEASE) || + isXIType(event, m_xiOpCode, XCB_INPUT_MOTION) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_BEGIN) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_END) || + isXIType(event, m_xiOpCode, XCB_INPUT_ENTER) || + isXIType(event, m_xiOpCode, XCB_INPUT_LEAVE) || + // wacom driver's way of reporting tool proximity + isXIType(event, m_xiOpCode, XCB_INPUT_PROPERTY); + } + if (isInputEvent) + return true; +#endif + + if (eventType == XCB_CLIENT_MESSAGE) { + auto clientMessage = reinterpret_cast<const xcb_client_message_event_t *>(event); + if (clientMessage->format == 32 && clientMessage->type == atom(QXcbAtom::WM_PROTOCOLS)) + if (clientMessage->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) + isInputEvent = true; + } + + return isInputEvent; +} + +void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) { int connection_error = xcb_connection_has_error(xcb_connection()); if (connection_error) { @@ -1461,13 +1500,14 @@ void QXcbConnection::processXcbEvents() m_eventQueue->flushBufferedEvents(); - while (xcb_generic_event_t *event = m_eventQueue->takeFirst()) { + while (xcb_generic_event_t *event = m_eventQueue->takeFirst(flags)) { QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event); if (!(event->response_type & ~0x80)) { handleXcbError(reinterpret_cast<xcb_generic_error_t *>(event)); continue; } + if (compressEvent(event)) continue; |