12#include <emscripten/bind.h>
13#include <emscripten/val.h>
15#include <qpa/qwindowsysteminterface.h>
16#include <QtCore/qcoreapplication.h>
17#include <QtGui/qguiapplication.h>
18#include <private/qhighdpiscaling_p.h>
26const char *QWasmScreen::m_canvasResizeObserverCallbackContextPropertyName =
27 "data-qtCanvasResizeObserverCallbackContext";
30 : m_container(containerOrCanvas),
31 m_intermediateContainer(
emscripten::val::undefined()),
32 m_shadowContainer(
emscripten::val::undefined()),
36 auto document = m_container[
"ownerDocument"];
40 if (m_container[
"tagName"].call<std::string>(
"toLowerCase") ==
"canvas") {
41 qWarning() <<
"Support for canvas elements as an element backing screen is deprecated. The "
42 "canvas provided for the screen will be transformed into a div.";
43 auto container = document.call<emscripten::val>(
"createElement", emscripten::val(
"div"));
44 m_container[
"parentNode"].call<
void>(
"replaceChild", container, m_container);
45 m_container = container;
51 m_intermediateContainer = document.call<emscripten::val>(
"createElement", emscripten::val(
"div"));
52 m_intermediateContainer.set(
"id", std::string(
"qt-shadow-container"));
53 emscripten::val intermediateContainerStyle = m_intermediateContainer[
"style"];
54 intermediateContainerStyle.set(
"width", std::string(
"100%"));
55 intermediateContainerStyle.set(
"height", std::string(
"100%"));
56 m_container.call<
void>(
"appendChild", m_intermediateContainer);
58 auto shadowOptions = emscripten::val::object();
59 shadowOptions.set(
"mode",
"open");
60 auto shadow = m_intermediateContainer.call<emscripten::val>(
"attachShadow", shadowOptions);
62 m_shadowContainer = document.call<emscripten::val>(
"createElement", emscripten::val(
"div"));
66 shadow.call<
void>(
"appendChild", m_shadowContainer);
68 m_shadowContainer.set(
"id", std::string(
"qt-screen-") + std::to_string(uintptr_t(
this)));
70 m_shadowContainer[
"classList"].call<
void>(
"add", std::string(
"qt-screen"));
74 m_onContextMenu = std::make_unique<qstdweb::EventCallback>(
75 m_shadowContainer,
"contextmenu",
76 [](emscripten::val
event) {
event.call<
void>(
"preventDefault"); });
80 emscripten::val::module_property(
"specialHTMLTargets")
83 emscripten::val::module_property(
"specialHTMLTargets")
87 m_shadowContainer.call<
void>(
"focus");
89 m_touchDevice = std::make_unique<QPointingDevice>(
95 m_tabletDevice = std::make_unique<QPointingDevice>(
111 m_intermediateContainer.call<
void>(
"remove");
113 emscripten::val::module_property(
"specialHTMLTargets")
114 .set(
eventTargetId().toStdString(), emscripten::val::undefined());
116 m_shadowContainer.set(m_canvasResizeObserverCallbackContextPropertyName,
140 return m_compositor.get();
145 return m_shadowContainer;
152 return QString(
"!qtcanvas_%1").
arg(uintptr_t(
this));
157 return QString(
"!outerscreen_%1").
arg(uintptr_t(
this));
177 emscripten::val dpi = emscripten::val::module_property(
"qtFontDpi");
178 if (!dpi.isUndefined()) {
180 return QDpi(dpiValue, dpiValue);
182 const qreal defaultDpi = 96;
183 return QDpi(defaultDpi, defaultDpi);
200 double dpr = emscripten::val::global(
"window")[
"devicePixelRatio"].as<
double>();
201 emscripten::val visualViewport = emscripten::val::global(
"window")[
"visualViewport"];
202 double scale = visualViewport.isUndefined() ? 1.0 : visualViewport[
"scale"].as<
double>();
203 double effectiveDevicePixelRatio = std::min(
dpr *
scale,
dpr);
204 return qreal(effectiveDevicePixelRatio);
209 return QString::fromEcmaString(m_shadowContainer[
"id"]);
237 return found !=
childStack().
end() ? (*found)->window() :
nullptr;
248 return QPointF(
qBound(geometryF.left(),
p.x(), geometryF.right()),
249 qBound(geometryF.top(),
p.y(), geometryF.bottom()));
254 m_geometry =
QRect();
274 m_compositor->onWindowTreeChanged(changeType,
child);
287 emscripten_get_element_css_size(
outerScreenId().toUtf8().constData(), &css_width, &css_height);
288 QSizeF cssSize(css_width, css_height);
292 m_shadowContainer.set(
"width", canvasSize.
width());
293 m_shadowContainer.set(
"height", canvasSize.
height());
296 auto getElementBodyPosition = [](
const emscripten::val &
element) ->
QPoint {
297 emscripten::val bodyRect =
298 element[
"ownerDocument"][
"body"].call<emscripten::val>(
"getBoundingClientRect");
299 emscripten::val canvasRect =
element.call<emscripten::val>(
"getBoundingClientRect");
300 return QPoint(canvasRect[
"left"].as<int>() - bodyRect[
"left"].as<int>(),
301 canvasRect[
"top"].as<int>() - bodyRect[
"top"].as<int>());
304 setGeometry(
QRect(getElementBodyPosition(m_shadowContainer), cssSize.toSize()));
309 int count = entries[
"length"].as<
int>();
312 emscripten::val
entry = entries[0];
314 entry[
"target"][m_canvasResizeObserverCallbackContextPropertyName].as<
intptr_t>());
316 qWarning() <<
"QWasmScreen::canvasResizeObserverCallback: missing screen pointer";
323 screen->updateQScreenAndCanvasRenderSize();
328 emscripten::function(
"qtCanvasResizeObserverCallback",
334 emscripten::val ResizeObserver = emscripten::val::global(
"ResizeObserver");
335 if (ResizeObserver == emscripten::val::undefined())
337 emscripten::val resizeObserver =
338 ResizeObserver.new_(emscripten::val::module_property(
"qtCanvasResizeObserverCallback"));
339 if (resizeObserver == emscripten::val::undefined())
344 m_shadowContainer.set(m_canvasResizeObserverCallbackContextPropertyName,
347 resizeObserver.call<
void>(
"observe", m_shadowContainer);
352 return m_shadowContainer;
Format
The following image formats are available in Qt.
void push_back(parameter_type t)
QObject * parent() const
Returns a pointer to the parent object.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr QRectF toRectF() const noexcept
The QScreen class is used to query screen properties. \inmodule QtGui.
QRect geometry
the screen's geometry in pixels
QPlatformScreen * handle() const
Get the platform screen handle.
constexpr qreal width() const noexcept
Returns the width.
constexpr qreal height() const noexcept
Returns the height.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
static QWasmScreen * get(QPlatformScreen *screen)
QString name() const override
void installCanvasResizeObserver()
emscripten::val element() const
QPointF mapFromLocal(const QPointF &p) const
QWindow * topLevelAt(const QPoint &p) const override
Return the given top level window for a given position.
void setGeometry(const QRect &rect)
QPointF clipPoint(const QPointF &p) const
QWasmCompositor * compositor()
void updateQScreenAndCanvasRenderSize()
QPlatformCursor * cursor() const override
Reimplement this function in subclass to return the cursor of the screen.
QImage::Format format() const override
Reimplement in subclass to return the image format which corresponds to the screen format.
QWasmWindowTreeNode * parentNode() final
qreal devicePixelRatio() const override
Reimplement this function in subclass to return the device pixel ratio for the screen.
QWasmScreen(const emscripten::val &containerOrCanvas)
void resizeMaximizedWindows()
void onSubtreeChanged(QWasmWindowTreeNodeChangeType changeType, QWasmWindowTreeNode *parent, QWasmWindow *child) final
QString eventTargetId() const
QString outerScreenId() const
int depth() const override
Reimplement in subclass to return current depth of the screen.
QWindow * topWindow() const
QDpi logicalDpi() const override
Reimplement this function in subclass to return the logical horizontal and vertical dots per inch met...
static void canvasResizeObserverCallback(emscripten::val entries, emscripten::val)
emscripten::val containerElement() final
QList< QWasmWindow * > allWindows()
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
QWasmWindow * activeChild() const
virtual void onSubtreeChanged(QWasmWindowTreeNodeChangeType changeType, QWasmWindowTreeNode *parent, QWasmWindow *child)
const QWasmWindowStack & childStack() const
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry)
static void registerInputDevice(const QInputDevice *device)
static void handleScreenRemoved(QPlatformScreen *screen)
Should be called by the implementation whenever a screen is removed.
Combined button and popup list for selecting options.
emscripten::val createStyleElement(emscripten::val parent)
@ FindChildrenRecursively
@ WindowStaysOnBottomHint
QPair< qreal, qreal > QDpi
constexpr const T & qBound(const T &min, const T &val, const T &max)
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLenum GLenum GLenum GLenum GLenum scale
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
EMSCRIPTEN_BINDINGS(qtCanvasResizeObserverCallback)
QWasmWindowTreeNodeChangeType