4#include <qpa/qwindowsysteminterface.h>
5#include <private/qguiapplication_p.h>
6#include <QtCore/qfile.h>
7#include <QtGui/private/qwindow_p.h>
8#include <QtGui/private/qhighdpiscaling_p.h>
9#include <private/qpixmapcache_p.h>
10#include <QtGui/qopenglfunctions.h>
30#include <emscripten/val.h>
32#include <QtCore/private/qstdweb_p.h>
54 m_backingStore(backingStore),
55 m_deadKeySupport(deadKeySupport),
56 m_document(
dom::document()),
63 m_qtWindow.set(
"className",
"qt-window");
64 m_qtWindow[
"style"].set(
"display", std::string(
"none"));
66 m_nonClientArea = std::make_unique<NonClientArea>(
this, m_qtWindow);
67 m_nonClientArea->titleBar()->setTitle(
window()->
title());
69 m_clientArea = std::make_unique<ClientArea>(
this,
compositor->screen(), m_windowContents);
71 m_windowContents.set(
"className",
"qt-window-contents");
72 m_qtWindow.call<
void>(
"appendChild", m_windowContents);
74 m_canvas[
"classList"].call<
void>(
"add", emscripten::val(
"qt-window-content"));
78 m_canvas.set(
"contentEditable", std::string(
"true"));
79 m_canvas[
"style"].set(
"outline", std::string(
"none"));
85 m_canvas.set(
"inputMode", std::string(
"none"));
88 m_canvas.call<
void>(
"setAttribute", std::string(
"aria-hidden"), std::string(
"true"));
90 m_windowContents.call<
void>(
"appendChild", m_canvasContainer);
92 m_canvasContainer[
"classList"].call<
void>(
"add", emscripten::val(
"qt-window-canvas-container"));
93 m_canvasContainer.call<
void>(
"appendChild", m_canvas);
95 m_canvasContainer.call<
void>(
"appendChild", m_a11yContainer);
96 m_a11yContainer[
"classList"].call<
void>(
"add", emscripten::val(
"qt-window-a11y-container"));
99 if (rendersTo2dContext)
100 m_context2d = m_canvas.call<emscripten::val>(
"getContext", emscripten::val(
"2d"));
101 static int serialNo = 0;
102 m_winId = ++serialNo;
103 m_qtWindow.set(
"id",
"qt-window-" + std::to_string(m_winId));
104 emscripten::val::module_property(
"specialHTMLTargets").set(
canvasSelector(), m_canvas);
108 const auto pointerCallback = std::function([
this](emscripten::val
event) {
110 event.call<
void>(
"preventDefault");
113 m_pointerEnterCallback =
114 std::make_unique<qstdweb::EventCallback>(m_qtWindow,
"pointerenter", pointerCallback);
115 m_pointerLeaveCallback =
116 std::make_unique<qstdweb::EventCallback>(m_qtWindow,
"pointerleave", pointerCallback);
118 m_wheelEventCallback = std::make_unique<qstdweb::EventCallback>(
119 m_qtWindow,
"wheel", [
this](emscripten::val
event) {
121 event.call<
void>(
"preventDefault");
124 const auto keyCallback = std::function([
this](emscripten::val
event) {
126 event.call<
void>(
"preventDefault");
127 event.call<
void>(
"stopPropagation");
130 emscripten::val keyFocusWindow;
138 keyFocusWindow = m_qtWindow;
142 std::make_unique<qstdweb::EventCallback>(keyFocusWindow,
"keydown", keyCallback);
143 m_keyUpCallback = std::make_unique<qstdweb::EventCallback>(keyFocusWindow,
"keyup", keyCallback);
150 emscripten::val::module_property(
"specialHTMLTargets").delete_(
canvasSelector());
151 m_canvasContainer.call<
void>(
"removeChild", m_canvas);
152 m_context2d = emscripten::val::undefined();
153 commitParent(
nullptr);
154 if (m_requestAnimationFrameId > -1)
155 emscripten_cancel_animation_frame(m_requestAnimationFrameId);
156#if QT_CONFIG(accessibility)
157 QWasmAccessibility::removeAccessibilityEnableButton(
window());
163 return window()->requestedFormat();
204 pointInScreen,
event.mouseButtons,
event.mouseButton,
220 if (
window()->isTopLevel())
224#if QT_CONFIG(accessibility)
227 if (
window()->isTopLevel())
228 QWasmAccessibility::addAccessibilityEnableButton(
window());
239 if (!m_backingStore || !
isVisible() || m_context2d.isUndefined())
243 if (
image.isUndefined())
245 m_context2d.call<
void>(
"putImageData",
image, emscripten::val(0), emscripten::val(0));
250 m_qtWindow[
"style"].set(
"zIndex", std::to_string(
z));
255 m_windowContents[
"style"].set(
"cursor", emscripten::val(cssCursorName.constData()));
262 const QRect clientAreaRect = ([
this, &
rect, &margins]() {
271 auto containerGeometryInViewport =
273 "getBoundingClientRect"))
276 auto rectInViewport =
QRect(containerGeometryInViewport.topLeft() +
offset,
rect.size());
278 QRect cappedGeometry(rectInViewport);
281 cappedGeometry.moveTop(
282 std::max(std::min(rectInViewport.y(), containerGeometryInViewport.bottom()),
283 containerGeometryInViewport.y() + margins.top()));
285 cappedGeometry.setSize(
290 m_nonClientArea->onClientAreaWidthChange(clientAreaRect.width());
292 const auto frameRect =
294 .adjusted(-margins.left(), -margins.top(), margins.right(), margins.bottom())
297 m_qtWindow[
"style"].set(
"left", std::to_string(frameRect.left()) +
"px");
298 m_qtWindow[
"style"].set(
"top", std::to_string(frameRect.top()) +
"px");
299 m_canvasContainer[
"style"].set(
"width", std::to_string(clientAreaRect.width()) +
"px");
300 m_canvasContainer[
"style"].set(
"height", std::to_string(clientAreaRect.height()) +
"px");
301 m_a11yContainer[
"style"].set(
"width", std::to_string(clientAreaRect.width()) +
"px");
302 m_a11yContainer[
"style"].set(
"height", std::to_string(clientAreaRect.height()) +
"px");
305 m_windowContents[
"style"].set(
"width", std::to_string(clientAreaRect.width()) +
"px");
309 m_canvas.set(
"width", canvasSize.
width());
310 m_canvas.set(
"height", canvasSize.
height());
312 bool shouldInvalidate =
true;
314 shouldInvalidate = m_normalGeometry.
size() != clientAreaRect.size();
315 m_normalGeometry = clientAreaRect;
318 if (shouldInvalidate)
327 const bool nowVisible = m_qtWindow[
"style"][
"display"].as<std::string>() ==
"block";
328 if (visible == nowVisible)
332 m_qtWindow[
"style"].set(
"display", visible ?
"block" :
"none");
334 m_canvas.call<
void>(
"focus");
341 return window()->isVisible();
346 const auto frameRect =
347 QRectF::fromDOMRect(m_qtWindow.call<emscripten::val>(
"getBoundingClientRect"));
348 const auto canvasRect =
349 QRectF::fromDOMRect(m_windowContents.call<emscripten::val>(
"getBoundingClientRect"));
350 return QMarginsF(canvasRect.left() - frameRect.left(), canvasRect.top() - frameRect.top(),
351 frameRect.right() - canvasRect.right(),
352 frameRect.bottom() - canvasRect.bottom())
361 m_canvas.call<
void>(
"focus");
379 m_nonClientArea->propagateSizeHints();
384 m_qtWindow[
"style"].set(
"opacity",
qBound(0.0,
level, 1.0));
387void QWasmWindow::invalidate()
412 m_nonClientArea->titleBar()->setMaximizeVisible(hasMaximizeButton());
422 const Qt::WindowStates oldState = m_state;
426 qWarning(
"Qt::WindowMinimized is not implemented in wasm");
435 m_previousWindowState = oldState;
442 m_nonClientArea->titleBar()->setTitle(
title);
450 m_nonClientArea->titleBar()->setIcon(
461void QWasmWindow::applyWindowState()
469 else if (isMaximized)
477 m_nonClientArea->titleBar()->setRestoreVisible(isMaximized);
478 m_nonClientArea->titleBar()->setMaximizeVisible(hasMaximizeButton());
488 m_commitedParent =
parent;
493 constexpr bool ProceedToNativeEvent =
false;
496 const auto clipboardResult =
500 if (clipboardResult == ProcessKeyboardResult::NativeClipboardEventNeeded)
501 return ProceedToNativeEvent;
506 return clipboardResult == ProcessKeyboardResult::NativeClipboardEventAndCopiedDataNeeded
507 ? ProceedToNativeEvent
516 switch (
event.type) {
521 window(), m_window->mapFromGlobal(pointInScreen), pointInScreen);
537 const int scrollFactor = -([&
event]() {
538 switch (
event.deltaMode) {
553 pointInScreen, (
event.delta * scrollFactor).toPoint(),
560 return m_normalGeometry;
573bool QWasmWindow::hasFrame()
const
578bool QWasmWindow::hasBorder()
const
581 && !windowIsPopupType(m_flags) && !
parent();
584bool QWasmWindow::hasTitleBar()
const
589bool QWasmWindow::hasShadow()
const
594bool QWasmWindow::hasMaximizeButton()
const
599bool QWasmWindow::windowIsPopupType(Qt::WindowFlags
flags)
const
619 m_canvas.call<
void>(
"focus");
632 switch (
event->type()) {
634 m_qtWindow[
"classList"].call<
void>(
"add", emscripten::val(
"blocked"));
637 m_qtWindow[
"classList"].call<
void>(
"remove", emscripten::val(
"blocked"));
647 m_qtWindow[
"style"].set(
"clipPath", emscripten::val(
""));
651 std::ostringstream cssClipPath;
652 cssClipPath <<
"path('";
653 for (
const auto &
rect : region) {
654 const auto cssRect =
rect.adjusted(0, 0, 1, 1);
655 cssClipPath <<
"M " << cssRect.left() <<
" " << cssRect.top() <<
" ";
656 cssClipPath <<
"L " << cssRect.right() <<
" " << cssRect.top() <<
" ";
657 cssClipPath <<
"L " << cssRect.right() <<
" " << cssRect.bottom() <<
" ";
658 cssClipPath <<
"L " << cssRect.left() <<
" " << cssRect.bottom() <<
" z ";
661 m_qtWindow[
"style"].set(
"clipPath", emscripten::val(cssClipPath.str()));
671 return "!qtwindow" + std::to_string(m_winId);
676 return m_windowContents;
static Base64IconStore * get()
\inmodule QtCore \reentrant
std::string toStdString() const
QByteArray toBase64(Base64Options options=Base64Encoding) const
static QGuiApplicationPrivate * instance()
The QIcon class provides scalable icons in different modes and states.
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
constexpr QMargins toMargins() const noexcept
Returns an integer-based copy of this margins object.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr QSize size() const noexcept
Returns the size of the rectangle.
The QRegion class specifies a clip region for a painter.
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
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
emscripten::val getUpdatedWebImage(QWasmWindow *window)
static void installEventHandlers(const emscripten::val &target)
void requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType=ExposeEventDelivery)
emscripten::val m_inputElement
static QWasmIntegration * get()
static quint64 getTimestamp()
QPointF mapFromLocal(const QPointF &p) const
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
virtual void onParentChanged(QWasmWindowTreeNode *previous, QWasmWindowTreeNode *current, QWasmWindowStack::PositionPreference positionPreference)
virtual emscripten::val containerElement()=0
void onPositionPreferenceChanged(QWasmWindowStack::PositionPreference positionPreference)
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
qreal devicePixelRatio() const override
Reimplement this function in subclass to return the device pixel ratio for the window.
QRect normalGeometry() const override
Returns the geometry of a window in 'normal' state (neither maximized, fullscreen nor minimized) for ...
static QWasmWindow * fromWindow(QWindow *window)
QSurfaceFormat format() const override
Returns the actual surface format of the window.
void setParent(const QPlatformWindow *window) final
This function is called to enable native child window in QPA.
void raise() override
Reimplement to be able to let Qt raise windows to the top of the desktop.
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport, QWasmCompositor *compositor, QWasmBackingStore *backingStore)
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
WId winId() const override
Reimplement in subclasses to return a handle to the native window.
std::string canvasSelector() const
void onParentChanged(QWasmWindowTreeNode *previous, QWasmWindowTreeNode *current, QWasmWindowStack::PositionPreference positionPreference) final
void onNonClientAreaInteraction()
void setGeometry(const QRect &) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
bool setMouseGrabEnabled(bool grab) final
bool onNonClientEvent(const PointerEvent &event)
void setWindowCursor(QByteArray cssCursorName)
void setZOrder(int order)
void setMask(const QRegion ®ion) final
Reimplement to be able to let Qt set the mask of a window.
QWasmWindowTreeNode * parentNode() final
void initialize() override
Called as part of QWindow::create(), after constructing the window.
void requestUpdate() override
Requests an QEvent::UpdateRequest event.
void lower() override
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
void setOpacity(qreal level) override
Reimplement to be able to let Qt set the opacity level of a window.
void onActivationChanged(bool active)
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
void setWindowIcon(const QIcon &icon) override
Reimplement to set the window icon to icon.
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
QMargins frameMargins() const override
QWasmWindow * asWasmWindow() final
bool windowEvent(QEvent *event) final
Reimplement this method to be able to do any platform specific event handling.
QWasmScreen * platformScreen() const
emscripten::val containerElement() final
void setWindowFlags(Qt::WindowFlags flags) override
Requests setting the window flags of this surface to flags.
static void handleLeaveEvent(QWindow *window)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void handleGeometryChange(QWindow *window, const QRect &newRect)
static bool handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
static void handleEnterEvent(QWindow *window, const QPointF &local=QPointF(), const QPointF &global=QPointF())
static bool handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::ScrollPhase phase=Qt::NoScrollPhase, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState=-1)
Qt::WindowFlags flags
the window flags of the window
bool close()
Close the window.
EGLImageKHR int int EGLuint64KHR * modifiers
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
Combined button and popup list for selecting options.
QWasmWindowStack::PositionPreference positionPreferenceFromWindowFlags(Qt::WindowFlags flags)
@ MouseEventNotSynthesized
@ WindowStaysOnBottomHint
@ WindowMaximizeButtonHint
@ WindowTransparentForInput
void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag)
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point)
constexpr const T & qBound(const T &min, const T &val, const T &max)
static QOpenGLCompositor * compositor
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Q_GUI_EXPORT int qt_defaultDpiX()
static std::optional< KeyEvent > fromWebWithDeadKeyTranslation(emscripten::val webEvent, QWasmDeadKeySupport *deadKeySupport)
static constexpr QEvent::Type mouseEventTypeFromEventType(EventType eventType, WindowArea windowArea)
static std::optional< PointerEvent > fromWeb(emscripten::val webEvent)
static std::optional< WheelEvent > fromWeb(emscripten::val webEvent)