qtbase/src/plugins/platforms/wasm/qwasmcompositor.h

202 lines
6.3 KiB
C
Raw Normal View History

// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QWASMCOMPOSITOR_H
#define QWASMCOMPOSITOR_H
#include "qwasmwindowstack.h"
#include <QtGui/qregion.h>
#include <qpa/qplatformwindow.h>
#include <QMap>
#include <QtOpenGL/qopengltextureblitter.h>
#include <QtGui/qpalette.h>
#include <QtGui/qpainter.h>
#include <QtGui/qinputdevice.h>
#include <QtCore/private/qstdweb_p.h>
#include <QPointer>
#include <QPointingDevice>
#include <emscripten/html5.h>
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
QT_BEGIN_NAMESPACE
struct PointerEvent;
class QWasmWindow;
class QWasmScreen;
class QOpenGLContext;
class QOpenGLTexture;
class QWasmEventTranslator;
class QWasmCompositor : public QObject
{
Q_OBJECT
public:
QWasmCompositor(QWasmScreen *screen);
~QWasmCompositor();
void initEventHandlers();
void deregisterEventHandlers();
void destroy();
enum QWasmStateFlag {
State_None = 0x00000000,
State_Enabled = 0x00000001,
State_Raised = 0x00000002,
State_Sunken = 0x00000004
};
Q_DECLARE_FLAGS(StateFlags, QWasmStateFlag)
struct QWasmFrameOptions {
QRect rect;
int lineWidth;
QPalette palette;
};
void setEnabled(bool enabled);
void addWindow(QWasmWindow *window);
void removeWindow(QWasmWindow *window);
void setVisible(QWasmWindow *window, bool visible);
void raise(QWasmWindow *window);
void lower(QWasmWindow *window);
int windowCount() const;
QWindow *windowAt(QPoint globalPoint, int padding = 0) const;
QWindow *keyWindow() const;
QWasmScreen *screen();
QOpenGLContext *context();
enum UpdateRequestDeliveryType { ExposeEventDelivery, UpdateRequestDelivery };
void requestUpdateAllWindows();
void requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType = ExposeEventDelivery);
void requestUpdate();
void deliverUpdateRequests();
void deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType);
void handleBackingStoreFlush();
bool processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent);
bool processWheel(int eventType, const EmscriptenWheelEvent *wheelEvent);
int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent);
void setCapture(QWasmWindow *window);
void releaseCapture();
bool processMouseEnter(const EmscriptenMouseEvent *mouseEvent);
bool processMouseLeave();
void enterWindow(QWindow* window, const QPoint &localPoint, const QPoint &globalPoint);
void leaveWindow(QWindow* window);
private slots:
void frame();
private:
class WindowManipulation {
public:
enum class Operation {
None,
Move,
Resize,
};
WindowManipulation(QWasmScreen* screen);
void onPointerDown(const PointerEvent& event, QWindow* windowAtPoint);
void onPointerMove(const PointerEvent& event);
void onPointerUp(const PointerEvent& event);
Operation operation() const;
private:
struct ResizeState {
Qt::Edges m_resizeEdges;
QPoint m_originInScreenCoords;
QRect m_initialWindowBounds;
const QPoint m_minShrink;
const QPoint m_maxGrow;
};
struct MoveState {
QPoint m_lastPointInScreenCoords;
};
struct OperationState
{
int pointerId;
QPointer<QWindow> window;
std::variant<ResizeState, MoveState> operationSpecific;
};
void resizeWindow(const QPoint& amount);
QWasmScreen *m_screen;
std::unique_ptr<OperationState> m_state;
};
void onTopWindowChanged();
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QWasmWindow *window);
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen,
const QWasmWindow *window);
void blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry);
void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen,
const QWasmWindow *window);
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
void drawFrameWindow(QWasmFrameOptions options, QPainter *painter);
static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
static int focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData);
static int wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData);
bool processPointer(const PointerEvent& event);
bool deliverEventToTarget(const PointerEvent& event, QWindow *eventTarget);
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData);
WindowManipulation m_windowManipulation;
QWasmWasmWindowStack m_windowStack;
QScopedPointer<QOpenGLContext> m_context;
QScopedPointer<QOpenGLTextureBlitter> m_blitter;
QHash<const QWasmWindow *, bool> m_windowVisibility;
QRegion m_globalDamage; // damage caused by expose, window close, etc.
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
bool m_needComposit = false;
bool m_inFlush = false;
bool m_isEnabled = true;
QSize m_targetSize;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
qreal m_targetDevicePixelRatio = 1;
QMap<QWasmWindow *, UpdateRequestDeliveryType> m_requestUpdateWindows;
bool m_requestUpdateAllWindows = false;
int m_requestAnimationFrameId = -1;
bool m_inDeliverUpdateRequest = false;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
QPointer<QWindow> m_pressedWindow;
QPointer<QWindow> m_lastMouseTargetWindow;
QPointer<QWindow> m_mouseCaptureWindow;
std::unique_ptr<qstdweb::EventCallback> m_pointerDownCallback;
std::unique_ptr<qstdweb::EventCallback> m_pointerMoveCallback;
std::unique_ptr<qstdweb::EventCallback> m_pointerUpCallback;
std::unique_ptr<qstdweb::EventCallback> m_pointerLeaveCallback;
std::unique_ptr<qstdweb::EventCallback> m_pointerEnterCallback;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
std::unique_ptr<QPointingDevice> m_touchDevice;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
QMap <int, QPointF> m_pressedTouchIds;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
bool m_isResizeCursorDisplayed = false;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
std::unique_ptr<QWasmEventTranslator> m_eventTranslator;
Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland <david.skoland@qt.io>
2022-07-14 13:56:38 +00:00
bool m_mouseInCanvas = false;
QPointer<QWindow> m_windowUnderMouse;
};
QT_END_NAMESPACE
#endif