xcb: update WM_TRANSIENT_FOR on transientParent native window recreation
It follows f9e4402ffe
.
Fixes: QTBUG-105395
Pick-to: 6.6 6.5
Change-Id: I399c448517b7dbdc28ba33f75ae43102836a8998
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
5896314ff3
commit
f2c5b846e0
@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||
Q_LOGGING_CATEGORY(lcQpaXcbWindow, "qt.qpa.xcb.window");
|
||||
|
||||
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
|
||||
|
||||
@ -224,6 +225,7 @@ enum : quint32 {
|
||||
|
||||
void QXcbWindow::create()
|
||||
{
|
||||
xcb_window_t old_m_window = m_window;
|
||||
destroy();
|
||||
|
||||
m_windowState = Qt::WindowNoState;
|
||||
@ -491,6 +493,17 @@ void QXcbWindow::create()
|
||||
|
||||
if (m_trayIconWindow)
|
||||
m_embedded = requestSystemTrayWindowDock();
|
||||
|
||||
if (m_window != old_m_window) {
|
||||
if (!m_wmTransientForChildren.isEmpty()) {
|
||||
QList<QPointer<QXcbWindow>> transientChildren = m_wmTransientForChildren;
|
||||
m_wmTransientForChildren.clear();
|
||||
for (auto transientChild : transientChildren) {
|
||||
if (transientChild)
|
||||
transientChild->updateWmTransientFor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QXcbWindow::~QXcbWindow()
|
||||
@ -679,6 +692,44 @@ void QXcbWindow::setVisible(bool visible)
|
||||
hide();
|
||||
}
|
||||
|
||||
void QXcbWindow::updateWmTransientFor()
|
||||
{
|
||||
xcb_window_t transientXcbParent = XCB_NONE;
|
||||
if (isTransient(window())) {
|
||||
QWindow *tp = window()->transientParent();
|
||||
if (tp && tp->handle()) {
|
||||
QXcbWindow *handle = static_cast<QXcbWindow *>(tp->handle());
|
||||
transientXcbParent = tp->handle()->winId();
|
||||
if (transientXcbParent) {
|
||||
handle->registerWmTransientForChild(this);
|
||||
qCDebug(lcQpaXcbWindow) << Q_FUNC_INFO << static_cast<QPlatformWindow *>(handle)
|
||||
<< " registerWmTransientForChild " << static_cast<QPlatformWindow *>(this);
|
||||
}
|
||||
}
|
||||
// Default to client leader if there is no transient parent, else modal dialogs can
|
||||
// be hidden by their parents.
|
||||
if (!transientXcbParent)
|
||||
transientXcbParent = connection()->clientLeader();
|
||||
if (transientXcbParent) { // ICCCM 4.1.2.6
|
||||
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
|
||||
XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
|
||||
1, &transientXcbParent);
|
||||
qCDebug(lcQpaXcbWindow, "0x%x added XCB_ATOM_WM_TRANSIENT_FOR 0x%x", m_window, transientXcbParent);
|
||||
}
|
||||
}
|
||||
if (!transientXcbParent)
|
||||
xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR);
|
||||
}
|
||||
|
||||
void QXcbWindow::registerWmTransientForChild(QXcbWindow *child)
|
||||
{
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
if (!m_wmTransientForChildren.contains(child))
|
||||
m_wmTransientForChildren.append(child);
|
||||
}
|
||||
|
||||
void QXcbWindow::show()
|
||||
{
|
||||
if (window()->isTopLevel()) {
|
||||
@ -692,23 +743,7 @@ void QXcbWindow::show()
|
||||
propagateSizeHints();
|
||||
|
||||
// update WM_TRANSIENT_FOR
|
||||
xcb_window_t transientXcbParent = 0;
|
||||
if (isTransient(window())) {
|
||||
const QWindow *tp = window()->transientParent();
|
||||
if (tp && tp->handle())
|
||||
transientXcbParent = tp->handle()->winId();
|
||||
// Default to client leader if there is no transient parent, else modal dialogs can
|
||||
// be hidden by their parents.
|
||||
if (!transientXcbParent)
|
||||
transientXcbParent = connection()->clientLeader();
|
||||
if (transientXcbParent) { // ICCCM 4.1.2.6
|
||||
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
|
||||
XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
|
||||
1, &transientXcbParent);
|
||||
}
|
||||
}
|
||||
if (!transientXcbParent)
|
||||
xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR);
|
||||
updateWmTransientFor();
|
||||
|
||||
// update _NET_WM_STATE
|
||||
setNetWmStateOnUnmappedWindow();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <qpa/qplatformwindow.h>
|
||||
#include <qpa/qplatformwindow_p.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtGui/QSurfaceFormat>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
@ -120,6 +121,8 @@ public:
|
||||
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
|
||||
|
||||
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
||||
void updateWmTransientFor();
|
||||
void registerWmTransientForChild(QXcbWindow *);
|
||||
|
||||
WindowTypes wmWindowTypes() const;
|
||||
void setWmWindowType(WindowTypes types, Qt::WindowFlags flags);
|
||||
@ -255,6 +258,8 @@ protected:
|
||||
qreal m_sizeHintsScaleFactor = 1.0;
|
||||
|
||||
RecreationReasons m_recreationReasons = RecreationNotNeeded;
|
||||
|
||||
QList<QPointer<QXcbWindow>> m_wmTransientForChildren;
|
||||
};
|
||||
|
||||
class QXcbForeignWindow : public QXcbWindow
|
||||
|
Loading…
Reference in New Issue
Block a user