Fix window states and transitions in wasm

Window states and their transitions do not currently work
correctly in wasm (eg. showFullScreen -> showNormal).

In order to fix this, we need to conform to Qt's way of
handling windows and their geometry, which involves
deferring much of the actual geometry changes to when
it actually becomes visible, or else the QWidget code
interferes with what we're trying to do.

Change-Id: I8c7da0be76760363e444dc5dc676036e70863f6e
Fixes: QTBUG-102190
Pick-to: 6.3
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
David Skoland 2022-04-26 10:15:41 +02:00
parent 3bcd6026ed
commit 70898c144c
2 changed files with 53 additions and 27 deletions

View File

@ -109,30 +109,21 @@ void QWasmWindow::setGeometry(const QRect &rect)
if (r.y() < yMin)
r.moveTop(yMin);
}
QWindowSystemInterface::handleGeometryChange(window(), r);
QPlatformWindow::setGeometry(r);
QWindowSystemInterface::handleGeometryChange(window(), r);
invalidate();
}
void QWasmWindow::setVisible(bool visible)
{
QRect newGeom;
if (visible) {
const bool forceFullScreen = !m_needsCompositor;//make gl apps fullscreen for now
if (forceFullScreen || (m_windowState & Qt::WindowFullScreen))
newGeom = platformScreen()->geometry();
else if (m_windowState & Qt::WindowMaximized)
newGeom = platformScreen()->availableGeometry();
}
if (visible)
applyWindowState();
m_compositor->setVisible(this, visible);
}
if (!newGeom.isEmpty())
setGeometry(newGeom); // may or may not generate an expose
invalidate();
bool QWasmWindow::isVisible()
{
return window()->isVisible();
}
QMargins QWasmWindow::frameMargins() const
@ -215,12 +206,10 @@ void QWasmWindow::injectMouseReleased(const QPoint &local, const QPoint &global,
if (maxButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarMaxButton) {
window()->setWindowState(Qt::WindowMaximized);
platformScreen()->resizeMaximizedWindows();
}
if (normButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarNormalButton) {
window()->setWindowState(Qt::WindowNoState);
setGeometry(normalGeometry());
}
m_activeControl = QWasmCompositor::SC_None;
@ -371,15 +360,49 @@ QWasmCompositor::SubControls QWasmWindow::activeSubControl() const
return m_activeControl;
}
void QWasmWindow::setWindowState(Qt::WindowStates states)
void QWasmWindow::setWindowState(Qt::WindowStates newState)
{
m_windowState = Qt::WindowNoState;
if (states & Qt::WindowMinimized)
m_windowState = Qt::WindowMinimized;
else if (states & Qt::WindowFullScreen)
m_windowState = Qt::WindowFullScreen;
else if (states & Qt::WindowMaximized)
m_windowState = Qt::WindowMaximized;
const Qt::WindowStates oldState = m_windowState;
bool isActive = oldState.testFlag(Qt::WindowActive);
if (newState.testFlag(Qt::WindowMinimized)) {
newState.setFlag(Qt::WindowMinimized, false);
qWarning("Qt::WindowMinimized is not implemented in wasm");
}
// Always keep OpenGL apps fullscreen
if (!m_needsCompositor && !newState.testFlag(Qt::WindowFullScreen)) {
newState.setFlag(Qt::WindowFullScreen, true);
qWarning("Qt::WindowFullScreen must be set for OpenGL surfaces");
}
// Ignore WindowActive flag in comparison, as we want to preserve it either way
if ((newState & ~Qt::WindowActive) == (oldState & ~Qt::WindowActive))
return;
newState.setFlag(Qt::WindowActive, isActive);
m_previousWindowState = oldState;
m_windowState = newState;
if (isVisible()) {
applyWindowState();
}
}
void QWasmWindow::applyWindowState()
{
QRect newGeom;
if (m_windowState.testFlag(Qt::WindowFullScreen))
newGeom = platformScreen()->geometry();
else if (m_windowState.testFlag(Qt::WindowMaximized))
newGeom = platformScreen()->availableGeometry();
else
newGeom = normalGeometry();
QWindowSystemInterface::handleWindowStateChanged(window(), m_windowState, m_previousWindowState);
setGeometry(newGeom);
}
QRect QWasmWindow::normalGeometry() const

View File

@ -50,6 +50,7 @@ public:
void setGeometry(const QRect &) override;
void setVisible(bool visible) override;
bool isVisible();
QMargins frameMargins() const override;
WId winId() const override;
@ -88,6 +89,7 @@ public:
QWasmCompositor::SubControls activeSubControl() const;
void setWindowState(Qt::WindowStates state) override;
void applyWindowState();
bool setKeyboardGrabEnabled(bool) override { return false; }
bool setMouseGrabEnabled(bool) override { return false; }
@ -103,7 +105,8 @@ protected:
QWasmBackingStore *m_backingStore = nullptr;
QRect m_normalGeometry {0, 0, 0 ,0};
Qt::WindowState m_windowState = Qt::WindowNoState;
Qt::WindowStates m_windowState = Qt::WindowNoState;
Qt::WindowStates m_previousWindowState = Qt::WindowNoState;
QWasmCompositor::SubControls m_activeControl = QWasmCompositor::SC_None;
WId m_winid = 0;
bool m_hasTitle = false;