From 283d9b01dc3ab6c95c688b0e5f5c98c41ca22d30 Mon Sep 17 00:00:00 2001 From: JiDe Zhang Date: Sat, 1 Jun 2019 16:56:49 +0800 Subject: xcb: Fix logic for minimized state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When _NET_WM_STATE_HIDDEN is not contains in the _NET_WM_STATE window property, the window should not be considered to be minimized According to https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would not be visible on the screen if its desktop/viewport were active and its coordinates were within the screen bounds. The canonical example is that minimized windows should be in the _NET_WM_STATE_HIDDEN state. Pagers and similar applications should use _NET_WM_STATE_HIDDEN instead of WM_STATE to decide whether to display a window in miniature representations of the windows on a desktop. For mutter/GNOME Shell, without _NET_WM_STATE_HIDDEN, window manager will not reply XCB_ICCCM_WM_STATE_ICONIC settings in WM_CHANGE_STATE client message. Task-number: QTBUG-76147 Task-number: QTBUG-76354 Task-number: QTBUG-68864 Done-With: Liang Qi Change-Id: Ic9d26d963979b7f0ef4d1cf322c54ef8c40fa004 Reviewed-by: Uli Schlachter Reviewed-by: Tor Arne Vestbø (cherry picked from commit 4f370d36ec5caa02f78545ceee5704d94edf0530) --- src/plugins/platforms/xcb/qxcbatom.cpp | 1 + src/plugins/platforms/xcb/qxcbatom.h | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 17 +++++++++++++++-- src/plugins/platforms/xcb/qxcbwindow.h | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp index ecb73cb90b..d366564dd6 100644 --- a/src/plugins/platforms/xcb/qxcbatom.cpp +++ b/src/plugins/platforms/xcb/qxcbatom.cpp @@ -122,6 +122,7 @@ static const char *xcb_atomnames = { "_NET_WM_STATE_MODAL\0" "_NET_WM_STATE_STAYS_ON_TOP\0" "_NET_WM_STATE_DEMANDS_ATTENTION\0" + "_NET_WM_STATE_HIDDEN\0" "_NET_WM_USER_TIME\0" "_NET_WM_USER_TIME_WINDOW\0" diff --git a/src/plugins/platforms/xcb/qxcbatom.h b/src/plugins/platforms/xcb/qxcbatom.h index 233d2eadb7..80b5887395 100644 --- a/src/plugins/platforms/xcb/qxcbatom.h +++ b/src/plugins/platforms/xcb/qxcbatom.h @@ -123,6 +123,7 @@ public: _NET_WM_STATE_MODAL, _NET_WM_STATE_STAYS_ON_TOP, _NET_WM_STATE_DEMANDS_ATTENTION, + _NET_WM_STATE_HIDDEN, _NET_WM_USER_TIME, _NET_WM_USER_TIME_WINDOW, diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3bfcbf2adb..d7d5bd3958 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -933,6 +933,8 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() result |= NetWmStateStaysOnTop; if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) result |= NetWmStateDemandsAttention; + if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_HIDDEN))) + result |= NetWmStateHidden; } else { qCDebug(lcQpaXcb, "getting net wm state (%x), empty\n", m_window); } @@ -1104,6 +1106,9 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow() states |= NetWmStateBelow; } + if (window()->windowStates() & Qt::WindowMinimized) + states |= NetWmStateHidden; + if (window()->windowStates() & Qt::WindowFullScreen) states |= NetWmStateFullScreen; @@ -1137,6 +1142,8 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow() 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 & NetWmStateHidden && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_HIDDEN))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_HIDDEN)); 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))) @@ -2236,10 +2243,16 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized)); } } - if (m_minimized) - newState = Qt::WindowMinimized; const NetWmStates states = netWmStates(); + // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would + // not be visible on the screen if its desktop/viewport were active and its coordinates were + // within the screen bounds. The canonical example is that minimized windows should be in + // the _NET_WM_STATE_HIDDEN state. + if (m_minimized && (!connection()->wmSupport()->isSupportedByWM(NetWmStateHidden) + || states.testFlag(NetWmStateHidden))) + newState = Qt::WindowMinimized; + if (states & NetWmStateFullScreen) newState |= Qt::WindowFullScreen; if ((states & NetWmStateMaximizedHorz) && (states & NetWmStateMaximizedVert)) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 8258cc2dfa..7f86fc6bb6 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -68,7 +68,8 @@ public: NetWmStateMaximizedVert = 0x10, NetWmStateModal = 0x20, NetWmStateStaysOnTop = 0x40, - NetWmStateDemandsAttention = 0x80 + NetWmStateDemandsAttention = 0x80, + NetWmStateHidden = 0x100 }; Q_DECLARE_FLAGS(NetWmStates, NetWmState) -- cgit v1.2.3