summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmscreen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmscreen.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp105
1 files changed, 91 insertions, 14 deletions
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index cc7c0c43f0..35a95a2131 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -28,6 +28,7 @@ const char *QWasmScreen::m_canvasResizeObserverCallbackContextPropertyName =
QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
: m_container(containerOrCanvas),
+ m_intermediateContainer(emscripten::val::undefined()),
m_shadowContainer(emscripten::val::undefined()),
m_compositor(new QWasmCompositor(this)),
m_deadKeySupport(std::make_unique<QWasmDeadKeySupport>())
@@ -43,9 +44,20 @@ QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
m_container["parentNode"].call<void>("replaceChild", container, m_container);
m_container = container;
}
+
+ // Create an intermediate container which we can remove during cleanup in ~QWasmScreen().
+ // This is required due to the attachShadow() call below; there is no corresponding
+ // "detachShadow()" API to return the container to its previous state.
+ m_intermediateContainer = document.call<emscripten::val>("createElement", emscripten::val("div"));
+ m_intermediateContainer.set("id", std::string("qt-shadow-container"));
+ emscripten::val intermediateContainerStyle = m_intermediateContainer["style"];
+ intermediateContainerStyle.set("width", std::string("100%"));
+ intermediateContainerStyle.set("height", std::string("100%"));
+ m_container.call<void>("appendChild", m_intermediateContainer);
+
auto shadowOptions = emscripten::val::object();
shadowOptions.set("mode", "open");
- auto shadow = m_container.call<emscripten::val>("attachShadow", shadowOptions);
+ auto shadow = m_intermediateContainer.call<emscripten::val>("attachShadow", shadowOptions);
m_shadowContainer = document.call<emscripten::val>("createElement", emscripten::val("div"));
@@ -71,16 +83,33 @@ QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
emscripten::val::module_property("specialHTMLTargets")
.set(outerScreenId().toStdString(), m_container);
- // Install event handlers on the container/canvas. This must be
- // done after the canvas has been created above.
- m_compositor->initEventHandlers();
-
updateQScreenAndCanvasRenderSize();
m_shadowContainer.call<void>("focus");
+
+ m_touchDevice = std::make_unique<QPointingDevice>(
+ "touchscreen", 1, QInputDevice::DeviceType::TouchScreen,
+ QPointingDevice::PointerType::Finger,
+ QPointingDevice::Capability::Position | QPointingDevice::Capability::Area
+ | QPointingDevice::Capability::NormalizedPosition,
+ 10, 0);
+ m_tabletDevice = std::make_unique<QPointingDevice>(
+ "stylus", 2, QInputDevice::DeviceType::Stylus,
+ QPointingDevice::PointerType::Pen,
+ QPointingDevice::Capability::Position | QPointingDevice::Capability::Pressure
+ | QPointingDevice::Capability::NormalizedPosition
+ | QInputDevice::Capability::MouseEmulation
+ | QInputDevice::Capability::Hover | QInputDevice::Capability::Rotation
+ | QInputDevice::Capability::XTilt | QInputDevice::Capability::YTilt
+ | QInputDevice::Capability::TangentialPressure,
+ 0, 0);
+
+ QWindowSystemInterface::registerInputDevice(m_touchDevice.get());
}
QWasmScreen::~QWasmScreen()
{
+ m_intermediateContainer.call<void>("remove");
+
emscripten::val::module_property("specialHTMLTargets")
.set(eventTargetId().toStdString(), emscripten::val::undefined());
@@ -90,7 +119,6 @@ QWasmScreen::~QWasmScreen()
void QWasmScreen::deleteScreen()
{
- m_compositor->onScreenDeleting();
// Deletes |this|!
QWindowSystemInterface::handleScreenRemoved(this);
}
@@ -178,7 +206,7 @@ qreal QWasmScreen::devicePixelRatio() const
QString QWasmScreen::name() const
{
- return QString::fromJsString(m_shadowContainer["id"]);
+ return QString::fromEcmaString(m_shadowContainer["id"]);
}
QPlatformCursor *QWasmScreen::cursor() const
@@ -195,23 +223,30 @@ void QWasmScreen::resizeMaximizedWindows()
QWindow *QWasmScreen::topWindow() const
{
- return m_compositor->keyWindow();
+ return activeChild() ? activeChild()->window() : nullptr;
}
QWindow *QWasmScreen::topLevelAt(const QPoint &p) const
{
- return m_compositor->windowAt(p);
+ const auto found =
+ std::find_if(childStack().begin(), childStack().end(), [&p](const QWasmWindow *window) {
+ const QRect geometry = window->windowFrameGeometry();
+
+ return window->isVisible() && geometry.contains(p);
+ });
+ return found != childStack().end() ? (*found)->window() : nullptr;
}
-QPoint QWasmScreen::mapFromLocal(const QPoint &p) const
+QPointF QWasmScreen::mapFromLocal(const QPointF &p) const
{
return geometry().topLeft() + p;
}
-QPoint QWasmScreen::clipPoint(const QPoint &p) const
+QPointF QWasmScreen::clipPoint(const QPointF &p) const
{
- return QPoint(qBound(screen()->geometry().left(), p.x(), screen()->geometry().right()),
- qBound(screen()->geometry().top(), p.y(), screen()->geometry().bottom()));
+ const auto geometryF = screen()->geometry().toRectF();
+ return QPointF(qBound(geometryF.left(), p.x(), geometryF.right()),
+ qBound(geometryF.top(), p.y(), geometryF.bottom()));
}
void QWasmScreen::invalidateSize()
@@ -227,6 +262,22 @@ void QWasmScreen::setGeometry(const QRect &rect)
resizeMaximizedWindows();
}
+void QWasmScreen::onSubtreeChanged(QWasmWindowTreeNodeChangeType changeType,
+ QWasmWindowTreeNode *parent, QWasmWindow *child)
+{
+ Q_UNUSED(parent);
+
+ QWindow *window = child->window();
+ const bool isMaxFull = (window->windowState() & Qt::WindowMaximized) ||
+ (window->windowState() & Qt::WindowFullScreen);
+ if (changeType == QWasmWindowTreeNodeChangeType::NodeInsertion && parent == this
+ && childStack().size() == 1 && isMaxFull) {
+ window->setFlag(Qt::WindowStaysOnBottomHint);
+ }
+ QWasmWindowTreeNode::onSubtreeChanged(changeType, parent, child);
+ m_compositor->onWindowTreeChanged(changeType, child);
+}
+
void QWasmScreen::updateQScreenAndCanvasRenderSize()
{
// The HTML canvas has two sizes: the CSS size and the canvas render size.
@@ -255,7 +306,6 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize()
};
setGeometry(QRect(getElementBodyPosition(m_shadowContainer), cssSize.toSize()));
- m_compositor->requestUpdateAllWindows();
}
void QWasmScreen::canvasResizeObserverCallback(emscripten::val entries, emscripten::val)
@@ -301,4 +351,31 @@ void QWasmScreen::installCanvasResizeObserver()
resizeObserver.call<void>("observe", m_shadowContainer);
}
+emscripten::val QWasmScreen::containerElement()
+{
+ return m_shadowContainer;
+}
+
+QWasmWindowTreeNode *QWasmScreen::parentNode()
+{
+ return nullptr;
+}
+
+QList<QWasmWindow *> QWasmScreen::allWindows()
+{
+ QList<QWasmWindow *> windows;
+ for (auto *child : childStack()) {
+ const QWindowList list = child->window()->findChildren<QWindow *>(Qt::FindChildrenRecursively);
+ for (auto child : list) {
+ auto handle = child->handle();
+ if (handle) {
+ auto wnd = static_cast<QWasmWindow *>(handle);
+ windows.push_back(wnd);
+ }
+ }
+ windows.push_back(child);
+ }
+ return windows;
+}
+
QT_END_NAMESPACE