xcb: update WM_TRANSIENT_FOR on transientParent native window recreation
It follows f9e4402ffeef791e66b7b2f2cc332000df7f5cd4. Fixes: QTBUG-105395 Pick-to: 6.5 Change-Id: I399c448517b7dbdc28ba33f75ae43102836a8998 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit f2c5b846e092270e1f43b0625db26789a5f77ba6) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
d79e52be22
commit
eb7df2d77b
@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||||
|
Q_LOGGING_CATEGORY(lcQpaXcbWindow, "qt.qpa.xcb.window");
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
|
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
|
||||||
|
|
||||||
@ -224,6 +225,7 @@ enum : quint32 {
|
|||||||
|
|
||||||
void QXcbWindow::create()
|
void QXcbWindow::create()
|
||||||
{
|
{
|
||||||
|
xcb_window_t old_m_window = m_window;
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
m_windowState = Qt::WindowNoState;
|
m_windowState = Qt::WindowNoState;
|
||||||
@ -491,6 +493,17 @@ void QXcbWindow::create()
|
|||||||
|
|
||||||
if (m_trayIconWindow)
|
if (m_trayIconWindow)
|
||||||
m_embedded = requestSystemTrayWindowDock();
|
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()
|
QXcbWindow::~QXcbWindow()
|
||||||
@ -679,6 +692,44 @@ void QXcbWindow::setVisible(bool visible)
|
|||||||
hide();
|
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()
|
void QXcbWindow::show()
|
||||||
{
|
{
|
||||||
if (window()->isTopLevel()) {
|
if (window()->isTopLevel()) {
|
||||||
@ -692,23 +743,7 @@ void QXcbWindow::show()
|
|||||||
propagateSizeHints();
|
propagateSizeHints();
|
||||||
|
|
||||||
// update WM_TRANSIENT_FOR
|
// update WM_TRANSIENT_FOR
|
||||||
xcb_window_t transientXcbParent = 0;
|
updateWmTransientFor();
|
||||||
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);
|
|
||||||
|
|
||||||
// update _NET_WM_STATE
|
// update _NET_WM_STATE
|
||||||
setNetWmStateOnUnmappedWindow();
|
setNetWmStateOnUnmappedWindow();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <qpa/qplatformwindow.h>
|
#include <qpa/qplatformwindow.h>
|
||||||
#include <qpa/qplatformwindow_p.h>
|
#include <qpa/qplatformwindow_p.h>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QPointer>
|
||||||
#include <QtGui/QSurfaceFormat>
|
#include <QtGui/QSurfaceFormat>
|
||||||
#include <QtGui/QImage>
|
#include <QtGui/QImage>
|
||||||
|
|
||||||
@ -120,6 +121,8 @@ public:
|
|||||||
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
|
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
|
||||||
|
|
||||||
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
||||||
|
void updateWmTransientFor();
|
||||||
|
void registerWmTransientForChild(QXcbWindow *);
|
||||||
|
|
||||||
WindowTypes wmWindowTypes() const;
|
WindowTypes wmWindowTypes() const;
|
||||||
void setWmWindowType(WindowTypes types, Qt::WindowFlags flags);
|
void setWmWindowType(WindowTypes types, Qt::WindowFlags flags);
|
||||||
@ -255,6 +258,8 @@ protected:
|
|||||||
qreal m_sizeHintsScaleFactor = 1.0;
|
qreal m_sizeHintsScaleFactor = 1.0;
|
||||||
|
|
||||||
RecreationReasons m_recreationReasons = RecreationNotNeeded;
|
RecreationReasons m_recreationReasons = RecreationNotNeeded;
|
||||||
|
|
||||||
|
QList<QPointer<QXcbWindow>> m_wmTransientForChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QXcbForeignWindow : public QXcbWindow
|
class QXcbForeignWindow : public QXcbWindow
|
||||||
|
Loading…
x
Reference in New Issue
Block a user