summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmcompositor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmcompositor.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp141
1 files changed, 42 insertions, 99 deletions
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
index 1fafd5d9e8..ef460f666f 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -4,29 +4,17 @@
#include "qwasmcompositor.h"
#include "qwasmwindow.h"
+#include <private/qeventdispatcher_wasm_p.h>
+
#include <qpa/qwindowsysteminterface.h>
#include <emscripten/html5.h>
-namespace {
-QWasmWindow *asWasmWindow(QWindow *window)
-{
- return static_cast<QWasmWindow*>(window->handle());
-}
-
-QWasmWindowStack::PositionPreference positionPreferenceFromWindowFlags(Qt::WindowFlags flags)
-{
- if (flags.testFlag(Qt::WindowStaysOnTopHint))
- return QWasmWindowStack::PositionPreference::StayOnTop;
- if (flags.testFlag(Qt::WindowStaysOnBottomHint))
- return QWasmWindowStack::PositionPreference::StayOnBottom;
- return QWasmWindowStack::PositionPreference::Regular;
-}
+using namespace emscripten;
-} // namespace
+bool QWasmCompositor::m_requestUpdateHoldEnabled = true;
-QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
- : QObject(screen), m_windowStack(std::bind(&QWasmCompositor::onTopWindowChanged, this))
+QWasmCompositor::QWasmCompositor(QWasmScreen *screen) : QObject(screen)
{
QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
}
@@ -41,80 +29,30 @@ QWasmCompositor::~QWasmCompositor()
m_isEnabled = false; // prevent frame() from creating a new m_context
}
-void QWasmCompositor::addWindow(QWasmWindow *window)
-{
- if (m_windowStack.empty())
- window->window()->setFlag(Qt::WindowStaysOnBottomHint);
- m_windowStack.pushWindow(window, positionPreferenceFromWindowFlags(window->window()->flags()));
- window->requestActivateWindow();
- setActive(window);
-
- updateEnabledState();
-}
-
-void QWasmCompositor::removeWindow(QWasmWindow *window)
+void QWasmCompositor::onWindowTreeChanged(QWasmWindowTreeNodeChangeType changeType,
+ QWasmWindow *window)
{
- m_requestUpdateWindows.remove(window);
- m_windowStack.removeWindow(window);
- if (m_windowStack.topWindow()) {
- m_windowStack.topWindow()->requestActivateWindow();
- setActive(m_windowStack.topWindow());
- }
-
- updateEnabledState();
-}
-
-void QWasmCompositor::setActive(QWasmWindow *window)
-{
- m_activeWindow = window;
-
- auto it = m_windowStack.begin();
- if (it == m_windowStack.end()) {
- return;
- }
- for (; it != m_windowStack.end(); ++it) {
- (*it)->onActivationChanged(*it == m_activeWindow);
- }
+ auto allWindows = screen()->allWindows();
+ setEnabled(std::any_of(allWindows.begin(), allWindows.end(), [](QWasmWindow *element) {
+ return !element->context2d().isUndefined();
+ }));
+ if (changeType == QWasmWindowTreeNodeChangeType::NodeRemoval)
+ m_requestUpdateWindows.remove(window);
}
-void QWasmCompositor::updateEnabledState()
+void QWasmCompositor::setEnabled(bool enabled)
{
- m_isEnabled = std::any_of(m_windowStack.begin(), m_windowStack.end(), [](QWasmWindow *window) {
- return !window->context2d().isUndefined();
- });
+ m_isEnabled = enabled;
}
-void QWasmCompositor::raise(QWasmWindow *window)
+// requestUpdate delivery is initially disabled at startup, while Qt completes
+// startup tasks such as font loading. This function enables requestUpdate delivery
+// again.
+bool QWasmCompositor::releaseRequestUpdateHold()
{
- m_windowStack.raise(window);
-}
-
-void QWasmCompositor::lower(QWasmWindow *window)
-{
- m_windowStack.lower(window);
-}
-
-void QWasmCompositor::windowPositionPreferenceChanged(QWasmWindow *window, Qt::WindowFlags flags)
-{
- m_windowStack.windowPositionPreferenceChanged(window, positionPreferenceFromWindowFlags(flags));
-}
-
-QWindow *QWasmCompositor::windowAt(QPoint targetPointInScreenCoords, int padding) const
-{
- const auto found = std::find_if(
- m_windowStack.begin(), m_windowStack.end(),
- [padding, &targetPointInScreenCoords](const QWasmWindow *window) {
- const QRect geometry = window->windowFrameGeometry().adjusted(-padding, -padding,
- padding, padding);
-
- return window->isVisible() && geometry.contains(targetPointInScreenCoords);
- });
- return found != m_windowStack.end() ? (*found)->window() : nullptr;
-}
-
-QWindow *QWasmCompositor::keyWindow() const
-{
- return m_activeWindow ? m_activeWindow->window() : nullptr;
+ const bool wasEnabled = m_requestUpdateHoldEnabled;
+ m_requestUpdateHoldEnabled = false;
+ return wasEnabled;
}
void QWasmCompositor::requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType)
@@ -138,6 +76,9 @@ void QWasmCompositor::requestUpdate()
if (m_requestAnimationFrameId != -1)
return;
+ if (m_requestUpdateHoldEnabled)
+ return;
+
static auto frame = [](double frameTime, void *context) -> int {
Q_UNUSED(frameTime);
@@ -163,7 +104,6 @@ void QWasmCompositor::deliverUpdateRequests()
// update type: QWindow subclasses expect that requested and delivered updateRequests matches
// exactly.
m_inDeliverUpdateRequest = true;
-
for (auto it = requestUpdateWindows.constBegin(); it != requestUpdateWindows.constEnd(); ++it) {
auto *window = it.key();
UpdateRequestDeliveryType updateType = it.value();
@@ -176,13 +116,23 @@ void QWasmCompositor::deliverUpdateRequests()
void QWasmCompositor::deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType)
{
- // update by deliverUpdateRequest and expose event accordingly.
+ QWindow *qwindow = window->window();
+
+ // Make sure the DPR value for the window is up to date on expose/repaint.
+ // FIXME: listen to native DPR change events instead, if/when available.
+ QWindowSystemInterface::handleWindowDevicePixelRatioChanged(qwindow);
+
+ // Update by deliverUpdateRequest and expose event according to requested update
+ // type. If the window has not yet been exposed then we must expose it first regardless
+ // of update type. The deliverUpdateRequest must still be sent in this case in order
+ // to maintain correct window update state.
+ QRect updateRect(QPoint(0, 0), qwindow->geometry().size());
if (updateType == UpdateRequestDelivery) {
+ if (qwindow->isExposed() == false)
+ QWindowSystemInterface::handleExposeEvent(qwindow, updateRect);
window->deliverUpdateRequest();
} else {
- QWindow *qwindow = window->window();
- QWindowSystemInterface::handleExposeEvent(
- qwindow, QRect(QPoint(0, 0), qwindow->geometry().size()));
+ QWindowSystemInterface::handleExposeEvent(qwindow, updateRect);
}
}
@@ -191,7 +141,7 @@ void QWasmCompositor::handleBackingStoreFlush(QWindow *window)
// Request update to flush the updated backing store content, unless we are currently
// processing an update, in which case the new content will flushed as a part of that update.
if (!m_inDeliverUpdateRequest)
- requestUpdateWindow(asWasmWindow(window));
+ requestUpdateWindow(static_cast<QWasmWindow *>(window->handle()));
}
void QWasmCompositor::frame(const QList<QWasmWindow *> &windows)
@@ -199,15 +149,8 @@ void QWasmCompositor::frame(const QList<QWasmWindow *> &windows)
if (!m_isEnabled || !screen())
return;
- std::for_each(windows.begin(), windows.end(), [](QWasmWindow *window) { window->paint(); });
-}
-
-void QWasmCompositor::onTopWindowChanged()
-{
- constexpr int zOrderForElementInFrontOfScreen = 3;
- int z = zOrderForElementInFrontOfScreen;
- std::for_each(m_windowStack.rbegin(), m_windowStack.rend(),
- [&z](QWasmWindow *window) { window->setZOrder(z++); });
+ for (QWasmWindow *window : windows)
+ window->paint();
}
QWasmScreen *QWasmCompositor::screen()