diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 124 |
1 files changed, 35 insertions, 89 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index d42d95f890..52c87ee8a4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -275,11 +275,7 @@ QXcbWindow::QXcbWindow(QWindow *window) setConnection(xcbScreen()->connection()); } -#ifdef Q_COMPILER_CLASS_ENUM enum : quint32 { -#else -enum { -#endif baseEventMask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE, @@ -441,8 +437,6 @@ void QXcbWindow::create() connection()->addWindowEventListener(m_window, this); - xcb_change_window_attributes(xcb_connection(), m_window, mask, values); - propagateSizeHints(); xcb_atom_t properties[5]; @@ -738,13 +732,6 @@ void QXcbWindow::setVisible(bool visible) hide(); } -static inline bool testShowWithoutActivating(const QWindow *window) -{ - // QWidget-attribute Qt::WA_ShowWithoutActivating. - const QVariant showWithoutActivating = window->property("_q_showWithoutActivating"); - return showWithoutActivating.isValid() && showWithoutActivating.toBool(); -} - void QXcbWindow::show() { if (window()->isTopLevel()) { @@ -792,7 +779,9 @@ void QXcbWindow::show() updateNetWmStateBeforeMap(); } - if (testShowWithoutActivating(window())) + // QWidget-attribute Qt::WA_ShowWithoutActivating. + const auto showWithoutActivating = window()->property("_q_showWithoutActivating"); + if (showWithoutActivating.isValid() && showWithoutActivating.toBool()) updateNetWmUserTime(0); else if (connection()->time() != XCB_TIME_CURRENT_TIME) updateNetWmUserTime(connection()->time()); @@ -1813,67 +1802,34 @@ bool QXcbWindow::requestSystemTrayWindowDock() return true; } -class ExposeCompressor -{ -public: - ExposeCompressor(xcb_window_t window, QRegion *region) - : m_window(window) - , m_region(region) - , m_pending(true) - { - } - - bool checkEvent(xcb_generic_event_t *event) - { - if (!event) - return false; - if ((event->response_type & ~0x80) != XCB_EXPOSE) - return false; - xcb_expose_event_t *expose = (xcb_expose_event_t *)event; - if (expose->window != m_window) - return false; - if (expose->count == 0) - m_pending = false; - *m_region |= QRect(expose->x, expose->y, expose->width, expose->height); - return true; - } - - bool pending() const - { - return m_pending; - } - -private: - xcb_window_t m_window; - QRegion *m_region; - bool m_pending; -}; - -bool QXcbWindow::compressExposeEvent(QRegion &exposeRegion) -{ - ExposeCompressor compressor(m_window, &exposeRegion); - xcb_generic_event_t *filter = 0; - do { - filter = connection()->checkEvent(compressor); - free(filter); - } while (filter); - return compressor.pending(); -} - -bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result) +bool QXcbWindow::handleNativeEvent(xcb_generic_event_t *event) { - return QWindowSystemInterface::handleNativeEvent(window(), - connection()->nativeInterface()->genericEventFilterType(), - event, - result); + auto eventType = connection()->nativeInterface()->nativeEventType(); + long result = 0; // Used only by MS Windows + return QWindowSystemInterface::handleNativeEvent(window(), eventType, event, &result); } void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { QRect rect(event->x, event->y, event->width, event->height); - m_exposeRegion |= rect; - bool pending = compressExposeEvent(m_exposeRegion); + + bool pending = true; + xcb_generic_event_t *e = nullptr; + do { // compress expose events + e = connection()->checkEvent([this, &pending](xcb_generic_event_t *event, int type) { + if (type != XCB_EXPOSE) + return false; + auto expose = reinterpret_cast<xcb_expose_event_t *>(event); + if (expose->window != m_window) + return false; + if (expose->count == 0) + pending = false; + m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height); + return true; + }); + free(e); + } while (e); // if count is non-zero there are more expose events pending if (event->count == 0 || !pending) { @@ -2166,24 +2122,6 @@ static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); } -class EnterEventChecker -{ -public: - bool checkEvent(xcb_generic_event_t *event) - { - if (!event) - return false; - if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) - return false; - - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; - if (ignoreEnterEvent(enter->mode, enter->detail)) - return false; - - return true; - } -}; - void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, quint8 mode, quint8 detail, xcb_timestamp_t timestamp) { @@ -2210,9 +2148,17 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow()) return; - EnterEventChecker checker; - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); - QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; + // check if enter event is buffered + auto event = connection()->checkEvent([](xcb_generic_event_t *event, int type) { + if (type != XCB_ENTER_NOTIFY) + return false; + auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event); + if (ignoreEnterEvent(enter->mode, enter->detail)) + return false; + return true; + }); + auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event); + QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : nullptr; if (enterWindow) { QPoint local(enter->event_x, enter->event_y); |