From 70898c144c4c3aa3e994b30fae000c62ddc6e596 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Tue, 26 Apr 2022 10:15:41 +0200 Subject: Fix window states and transitions in wasm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ø Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmwindow.cpp | 75 +++++++++++++++++++----------- src/plugins/platforms/wasm/qwasmwindow.h | 5 +- 2 files changed, 53 insertions(+), 27 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index a25b5a262c..947666fc9a 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -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 diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 686a26430e..e0d5a81f4a 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -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; -- cgit v1.2.3