diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-11-06 01:00:56 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-11-06 01:00:56 +0100 |
commit | 290aac23a756522385b3200c84fd6118dc94d132 (patch) | |
tree | 081958c1b8792d90db6ecc105b57dbd0d1e70ab5 /src/plugins | |
parent | 81d8319276f26d399bdff47b49bd69b19bd86c5a (diff) | |
parent | 73e7eb785fbf984e2b964be8c3acad788479dfa6 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: Id1e4664d3c942226b76e2c3b338df3116ff89297
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbeventdispatcher.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 182 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 11 |
3 files changed, 100 insertions, 96 deletions
diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.h b/src/plugins/platforms/xcb/qxcbeventdispatcher.h index 6aadd63a70..ddf448cf87 100644 --- a/src/plugins/platforms/xcb/qxcbeventdispatcher.h +++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.h @@ -107,9 +107,6 @@ class QXcbEventDispatcher { public: static QAbstractEventDispatcher *createEventDispatcher(QXcbConnection *connection); - -private: - QXcbConnection *m_connection; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e56f6b13d8..f553c286f9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -755,7 +755,7 @@ void QXcbWindow::show() xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR); // update _NET_WM_STATE - updateNetWmStateBeforeMap(); + setNetWmStateOnUnmappedWindow(); } // QWidget-attribute Qt::WA_ShowWithoutActivating. @@ -961,46 +961,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() return result; } -void QXcbWindow::setNetWmStates(NetWmStates states) -{ - QVector<xcb_atom_t> atoms; - - auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), - 0, m_window, atom(QXcbAtom::_NET_WM_STATE), - XCB_ATOM_ATOM, 0, 1024); - if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { - const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get())); - atoms.resize(reply->value_len); - memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); - } - - if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); - if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); - if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); - if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); - if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); - if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); - if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); - if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); - - if (atoms.isEmpty()) { - xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)); - } else { - xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32, - atoms.count(), atoms.constData()); - } - xcb_flush(xcb_connection()); -} - void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) { Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); @@ -1027,7 +987,7 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) } setWmWindowType(wmWindowTypes, flags); - setNetWmStateWindowFlags(flags); + setNetWmState(flags); setMotifWmHints(flags); setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput); @@ -1111,7 +1071,7 @@ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags) } } -void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) +void QXcbWindow::setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) { xcb_client_message_event_t event; @@ -1131,6 +1091,96 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) (const char *)&event); } +void QXcbWindow::setNetWmState(Qt::WindowStates state) +{ + if ((m_windowState ^ state) & Qt::WindowMaximized) { + setNetWmState(state & Qt::WindowMaximized, + atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ), + atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); + } + + if ((m_windowState ^ state) & Qt::WindowFullScreen) + setNetWmState(state & Qt::WindowFullScreen, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); +} + +void QXcbWindow::setNetWmState(Qt::WindowFlags flags) +{ + setNetWmState(flags & Qt::WindowStaysOnTopHint, + atom(QXcbAtom::_NET_WM_STATE_ABOVE), + atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); + setNetWmState(flags & Qt::WindowStaysOnBottomHint, atom(QXcbAtom::_NET_WM_STATE_BELOW)); +} + +void QXcbWindow::setNetWmStateOnUnmappedWindow() +{ + if (Q_UNLIKELY(m_mapped)) + qCWarning(lcQpaXcb()) << "internal error: " << Q_FUNC_INFO << "called on mapped window"; + + NetWmStates states(0); + const Qt::WindowFlags flags = window()->flags(); + if (flags & Qt::WindowStaysOnTopHint) { + states |= NetWmStateAbove; + states |= NetWmStateStaysOnTop; + } else if (flags & Qt::WindowStaysOnBottomHint) { + states |= NetWmStateBelow; + } + + if (window()->windowStates() & Qt::WindowFullScreen) + states |= NetWmStateFullScreen; + + if (window()->windowStates() & Qt::WindowMaximized) { + states |= NetWmStateMaximizedHorz; + states |= NetWmStateMaximizedVert; + } + + if (window()->modality() != Qt::NonModal) + states |= NetWmStateModal; + + // According to EWMH: + // "The Window Manager should remove _NET_WM_STATE whenever a window is withdrawn". + // Which means that we don't have to read this property before changing it on a withdrawn + // window. But there are situations where users want to adjust this property as well + // (e4cea305ed2ba3c9f580bf9d16c59a1048af0e8a), so instead of overwriting the property + // we first read it and then merge our hints with the existing values, allowing a user + // to set custom hints. + + QVector<xcb_atom_t> atoms; + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::_NET_WM_STATE), + XCB_ATOM_ATOM, 0, 1024); + if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { + const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get())); + atoms.resize(reply->value_len); + memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); + } + + if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); + if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); + if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); + if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); + if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); + if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); + if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); + if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); + + if (atoms.isEmpty()) { + xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)); + } else { + xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32, + atoms.count(), atoms.constData()); + } + xcb_flush(xcb_connection()); +} + void QXcbWindow::setWindowState(Qt::WindowStates state) { if (state == m_windowState) @@ -1158,14 +1208,7 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) m_minimized = true; } - if ((m_windowState ^ state) & Qt::WindowMaximized) { - changeNetWmState(state & Qt::WindowMaximized, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ), - atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); - } - - if ((m_windowState ^ state) & Qt::WindowFullScreen) { - changeNetWmState(state & Qt::WindowFullScreen, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); - } + setNetWmState(state); xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; @@ -1181,41 +1224,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) m_windowState = state; } -void QXcbWindow::updateNetWmStateBeforeMap() -{ - NetWmStates states(0); - - const Qt::WindowFlags flags = window()->flags(); - if (flags & Qt::WindowStaysOnTopHint) { - states |= NetWmStateAbove; - states |= NetWmStateStaysOnTop; - } else if (flags & Qt::WindowStaysOnBottomHint) { - states |= NetWmStateBelow; - } - - if (window()->windowStates() & Qt::WindowFullScreen) - states |= NetWmStateFullScreen; - - if (window()->windowStates() & Qt::WindowMaximized) { - states |= NetWmStateMaximizedHorz; - states |= NetWmStateMaximizedVert; - } - - if (window()->modality() != Qt::NonModal) - states |= NetWmStateModal; - - setNetWmStates(states); -} - -void QXcbWindow::setNetWmStateWindowFlags(Qt::WindowFlags flags) -{ - changeNetWmState(flags & Qt::WindowStaysOnTopHint, - atom(QXcbAtom::_NET_WM_STATE_ABOVE), - atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); - changeNetWmState(flags & Qt::WindowStaysOnBottomHint, - atom(QXcbAtom::_NET_WM_STATE_BELOW)); -} - void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) { xcb_window_t wid = m_window; @@ -2588,7 +2596,7 @@ void QXcbWindow::setAlertState(bool enabled) m_alertState = enabled; - changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); + setNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); } uint QXcbWindow::visualId() const diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index d2ca9fe0b9..f98cd8a74d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -193,17 +193,16 @@ protected: void setImageFormatForVisual(const xcb_visualtype_t *visual); QXcbScreen *parentScreen(); - QXcbScreen *initialScreen() const; - void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); + + void setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); + void setNetWmState(Qt::WindowFlags flags); + void setNetWmState(Qt::WindowStates state); + void setNetWmStateOnUnmappedWindow(); NetWmStates netWmStates(); - void setNetWmStates(NetWmStates); void setMotifWmHints(Qt::WindowFlags flags); - void setNetWmStateWindowFlags(Qt::WindowFlags flags); - void updateNetWmStateBeforeMap(); - void setTransparentForMouseEvents(bool transparent); void updateDoesNotAcceptFocus(bool doesNotAcceptFocus); |