xcb: recreate xcb window under some conditions
Some netWmState needs to be set during unmap/hide(), which is too
difficult to follow, and causes m_mapped status out of sync very easily
sometimes, which we had tried in
e946e6895a .
Destroy the xcb window and recreate new could make the thing
much easier. This practice is also used in other platforms, such
as cocoa plugin.
In Qt 4, the platform window was destoryed and re-created in this
situation on all platforms, which was not ported into Qt5.
See also the code between setWinId(0) and createWinId() in
QWidgetPrivate::setParent_sys() in qwidget_x11.cpp/qwidget_win.cpp/
qwidget_mac.mm.
Fixes: QTBUG-69515
Fixes: QTBUG-73485
Fixes: QTBUG-81341
Pick-to: 6.3 6.2 5.15
Change-Id: If55c57a198bc785719b61b8748dabd8281c9639d
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
bb10
parent
d27a623524
commit
f9e4402ffe
|
|
@ -92,6 +92,8 @@ enum {
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||
|
||||
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
|
||||
|
||||
#undef FocusIn
|
||||
|
|
@ -539,6 +541,7 @@ void QXcbWindow::destroy()
|
|||
}
|
||||
|
||||
m_mapped = false;
|
||||
m_recreationReasons = RecreationNotNeeded;
|
||||
|
||||
if (m_pendingSyncRequest)
|
||||
m_pendingSyncRequest->invalidate();
|
||||
|
|
@ -673,6 +676,11 @@ void QXcbWindow::setVisible(bool visible)
|
|||
void QXcbWindow::show()
|
||||
{
|
||||
if (window()->isTopLevel()) {
|
||||
if (m_recreationReasons != RecreationNotNeeded) {
|
||||
qCDebug(lcQpaWindow) << "QXcbWindow: need to recreate window" << window() << m_recreationReasons;
|
||||
create();
|
||||
m_recreationReasons = RecreationNotNeeded;
|
||||
}
|
||||
|
||||
// update WM_NORMAL_HINTS
|
||||
propagateSizeHints();
|
||||
|
|
@ -888,6 +896,12 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
|
|||
if (type == Qt::Popup)
|
||||
flags |= Qt::X11BypassWindowManagerHint;
|
||||
|
||||
Qt::WindowFlags oldflags = window()->flags();
|
||||
if ((oldflags & Qt::WindowStaysOnTopHint) != (flags & Qt::WindowStaysOnTopHint))
|
||||
m_recreationReasons |= WindowStaysOnTopHintChanged;
|
||||
if ((oldflags & Qt::WindowStaysOnBottomHint) != (flags & Qt::WindowStaysOnBottomHint))
|
||||
m_recreationReasons |= WindowStaysOnBottomHintChanged;
|
||||
|
||||
const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
||||
const quint32 values[] = {
|
||||
// XCB_CW_OVERRIDE_REDIRECT
|
||||
|
|
|
|||
|
|
@ -74,6 +74,13 @@ public:
|
|||
|
||||
Q_DECLARE_FLAGS(NetWmStates, NetWmState)
|
||||
|
||||
enum RecreationReason {
|
||||
RecreationNotNeeded = 0,
|
||||
WindowStaysOnTopHintChanged = 0x1,
|
||||
WindowStaysOnBottomHintChanged = 0x2
|
||||
};
|
||||
Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
|
||||
|
||||
QXcbWindow(QWindow *window);
|
||||
~QXcbWindow();
|
||||
|
||||
|
|
@ -280,6 +287,8 @@ protected:
|
|||
int m_swapInterval = -1;
|
||||
|
||||
qreal m_sizeHintsScaleFactor = 1.0;
|
||||
|
||||
RecreationReasons m_recreationReasons = RecreationNotNeeded;
|
||||
};
|
||||
|
||||
class QXcbForeignWindow : public QXcbWindow
|
||||
|
|
|
|||
Loading…
Reference in New Issue