wasm: support rendering to multiple canvases
Qt (via the the qtloader.js API) now supports rendering to multiple canvases. The application sees each canvas as a QScreen. Make qtloader.js support multiple canvases: var qtloader = QtLoader({ canvasElements : [array-of-canvas], showCanvas: function() { // make canvas(es) visible }, }); The canvases were previously created/returned by showCanvas(), however this function is called after the Qt app has been started and adding screens that that point is too late. (This worked before since there was only one screen, and no need to connect each screen instance to specific canvas.) Remove QWasmScreen, QWasmCompositor, and QWasmEventTranslator singletons from QWasmIntegration. These are are now crated per-screen and are owned by the QWasmScreen. Task-number: QTBUG-64079 Change-Id: I24689929fd5bfb7ff0ba076f66937728fa4bc4e4 Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
parent
452c644c5c
commit
caa74f16d4
@ -50,6 +50,7 @@
|
|||||||
// External mode.usage:
|
// External mode.usage:
|
||||||
//
|
//
|
||||||
// var config = {
|
// var config = {
|
||||||
|
// canvasElements : [$("canvas-id")],
|
||||||
// showLoader: function() {
|
// showLoader: function() {
|
||||||
// loader.style.display = 'block'
|
// loader.style.display = 'block'
|
||||||
// canvas.style.display = 'hidden'
|
// canvas.style.display = 'hidden'
|
||||||
@ -69,6 +70,8 @@
|
|||||||
// One or more HTML elements. QtLoader will display loader elements
|
// One or more HTML elements. QtLoader will display loader elements
|
||||||
// on these while loading the applicaton, and replace the loader with a
|
// on these while loading the applicaton, and replace the loader with a
|
||||||
// canvas on load complete.
|
// canvas on load complete.
|
||||||
|
// canvasElements : [canvas-element, ...]
|
||||||
|
// One or more canvas elements.
|
||||||
// showLoader : function(status, containerElement)
|
// showLoader : function(status, containerElement)
|
||||||
// Optional loading element constructor function. Implement to create
|
// Optional loading element constructor function. Implement to create
|
||||||
// a custom loading screen. This function may be called multiple times,
|
// a custom loading screen. This function may be called multiple times,
|
||||||
@ -146,8 +149,25 @@ function QtLoader(config)
|
|||||||
while (element.firstChild) element.removeChild(element.firstChild);
|
while (element.firstChild) element.removeChild(element.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default state handler functions if needed
|
function createCanvas() {
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
canvas.className = "QtCanvas";
|
||||||
|
canvas.style.height = "100%";
|
||||||
|
canvas.style.width = "100%";
|
||||||
|
|
||||||
|
// Set contentEditable in order to enable clipboard events; hide the resulting focus frame.
|
||||||
|
canvas.contentEditable = true;
|
||||||
|
canvas.style.outline = "0px solid transparent";
|
||||||
|
canvas.style.cursor = "default";
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default state handler functions and create canvases if needed
|
||||||
if (config.containerElements !== undefined) {
|
if (config.containerElements !== undefined) {
|
||||||
|
|
||||||
|
config.canvasElements = config.containerElements.map(createCanvas);
|
||||||
|
|
||||||
config.showError = config.showError || function(errorText, container) {
|
config.showError = config.showError || function(errorText, container) {
|
||||||
removeChildren(container);
|
removeChildren(container);
|
||||||
var errorTextElement = document.createElement("text");
|
var errorTextElement = document.createElement("text");
|
||||||
@ -164,19 +184,8 @@ function QtLoader(config)
|
|||||||
return loadingText;
|
return loadingText;
|
||||||
};
|
};
|
||||||
|
|
||||||
config.showCanvas = config.showCanvas || function(container) {
|
config.showCanvas = config.showCanvas || function(canvas, container) {
|
||||||
removeChildren(container);
|
removeChildren(container);
|
||||||
var canvas = document.createElement("canvas");
|
|
||||||
canvas.className = "QtCanvas"
|
|
||||||
canvas.style.height = "100%"
|
|
||||||
canvas.style.width = "100%"
|
|
||||||
|
|
||||||
// Set contentEditable in order to enable clipboard events; hide the resulting focus frame.
|
|
||||||
canvas.contentEditable = true;
|
|
||||||
canvas.style.outline = "0px solid transparent";
|
|
||||||
canvas.style.cursor = "default";
|
|
||||||
|
|
||||||
return canvas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.showExit = config.showExit || function(crashed, exitCode, container) {
|
config.showExit = config.showExit || function(crashed, exitCode, container) {
|
||||||
@ -391,6 +400,8 @@ function QtLoader(config)
|
|||||||
|
|
||||||
Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
|
Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
|
||||||
|
|
||||||
|
Module.qtCanvasElements = config.canvasElements;
|
||||||
|
|
||||||
config.restart = function() {
|
config.restart = function() {
|
||||||
|
|
||||||
// Restart by reloading the page. This will wipe all state which means
|
// Restart by reloading the page. This will wipe all state which means
|
||||||
@ -445,19 +456,17 @@ function QtLoader(config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCanvasContent() {
|
function setCanvasContent() {
|
||||||
var firstCanvas;
|
|
||||||
if (config.containerElements === undefined) {
|
if (config.containerElements === undefined) {
|
||||||
firstCanvas = config.showCanvas();
|
if (config.showCanvas !== undefined)
|
||||||
} else {
|
config.showCanvas();
|
||||||
for (container of config.containerElements) {
|
return;
|
||||||
var canvasElement = config.showCanvas(container);
|
|
||||||
container.appendChild(canvasElement);
|
|
||||||
}
|
|
||||||
firstCanvas = config.containerElements[0].firstChild;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Module.canvas === undefined) {
|
for (var i = 0; i < config.containerElements.length; ++i) {
|
||||||
Module.canvas = firstCanvas;
|
var container = config.containerElements[i];
|
||||||
|
var canvas = config.canvasElements[i];
|
||||||
|
config.showCanvas(canvas, container);
|
||||||
|
container.appendChild(canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +123,11 @@ EMSCRIPTEN_BINDINGS(clipboard_module) {
|
|||||||
function("qClipboardPasteTo", &qClipboardPasteTo);
|
function("qClipboardPasteTo", &qClipboardPasteTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmClipboard::QWasmClipboard() :
|
QWasmClipboard::QWasmClipboard()
|
||||||
hasClipboardApi(false)
|
|
||||||
{
|
{
|
||||||
|
val clipboard = val::global("navigator")["clipboard"];
|
||||||
|
hasClipboardApi = (!clipboard.isUndefined() && !clipboard["readText"].isUndefined());
|
||||||
|
|
||||||
initClipboardEvents();
|
initClipboardEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,29 +179,32 @@ void QWasmClipboard::qWasmClipboardPaste(QMimeData *mData)
|
|||||||
|
|
||||||
void QWasmClipboard::initClipboardEvents()
|
void QWasmClipboard::initClipboardEvents()
|
||||||
{
|
{
|
||||||
val navigator = val::global("navigator");
|
if (!hasClipboardApi)
|
||||||
val permissions = navigator["permissions"];
|
return;
|
||||||
val clipboard = navigator["clipboard"];
|
|
||||||
|
|
||||||
hasClipboardApi = (!clipboard.isUndefined() && !clipboard["readText"].isUndefined());
|
val permissions = val::global("navigator")["permissions"];
|
||||||
if (hasClipboardApi) {
|
val readPermissionsMap = val::object();
|
||||||
val readPermissionsMap = val::object();
|
readPermissionsMap.set("name", val("clipboard-read"));
|
||||||
readPermissionsMap.set("name", val("clipboard-read"));
|
permissions.call<val>("query", readPermissionsMap);
|
||||||
permissions.call<val>("query", readPermissionsMap);
|
|
||||||
|
|
||||||
val writePermissionsMap = val::object();
|
val writePermissionsMap = val::object();
|
||||||
writePermissionsMap.set("name", val("clipboard-write"));
|
writePermissionsMap.set("name", val("clipboard-write"));
|
||||||
permissions.call<val>("query", writePermissionsMap);
|
permissions.call<val>("query", writePermissionsMap);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
void QWasmClipboard::installEventHandlers(const QString &canvasId)
|
||||||
val canvas = val::module_property("canvas");
|
{
|
||||||
canvas.call<void>("addEventListener", std::string("cut"),
|
if (hasClipboardApi)
|
||||||
val::module_property("qClipboardCutTo"));
|
return;
|
||||||
canvas.call<void>("addEventListener", std::string("copy"),
|
|
||||||
val::module_property("qClipboardCopyTo"));
|
// Fallback path for browsers which do not support direct clipboard access
|
||||||
canvas.call<void>("addEventListener", std::string("paste"),
|
val canvas = val::global(canvasId.toUtf8().constData());
|
||||||
val::module_property("qClipboardPasteTo"));
|
canvas.call<void>("addEventListener", std::string("cut"),
|
||||||
}
|
val::module_property("qClipboardCutTo"));
|
||||||
|
canvas.call<void>("addEventListener", std::string("copy"),
|
||||||
|
val::module_property("qClipboardCopyTo"));
|
||||||
|
canvas.call<void>("addEventListener", std::string("paste"),
|
||||||
|
val::module_property("qClipboardPasteTo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmClipboard::readTextFromClipboard()
|
void QWasmClipboard::readTextFromClipboard()
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
|
|
||||||
static void qWasmClipboardPaste(QMimeData *mData);
|
static void qWasmClipboardPaste(QMimeData *mData);
|
||||||
void initClipboardEvents();
|
void initClipboardEvents();
|
||||||
|
void installEventHandlers(const QString &canvasId);
|
||||||
bool hasClipboardApi;
|
bool hasClipboardApi;
|
||||||
void readTextFromClipboard();
|
void readTextFromClipboard();
|
||||||
void writeTextToClipboard();
|
void writeTextToClipboard();
|
||||||
|
@ -56,8 +56,9 @@ QWasmCompositedWindow::QWasmCompositedWindow()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmCompositor::QWasmCompositor()
|
QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
|
||||||
: m_frameBuffer(nullptr)
|
:QObject(screen)
|
||||||
|
, m_frameBuffer(nullptr)
|
||||||
, m_blitter(new QOpenGLTextureBlitter)
|
, m_blitter(new QOpenGLTextureBlitter)
|
||||||
, m_needComposit(false)
|
, m_needComposit(false)
|
||||||
, m_inFlush(false)
|
, m_inFlush(false)
|
||||||
@ -107,11 +108,6 @@ void QWasmCompositor::removeWindow(QWasmWindow *window)
|
|||||||
notifyTopWindowChanged(window);
|
notifyTopWindowChanged(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmCompositor::setScreen(QWasmScreen *screen)
|
|
||||||
{
|
|
||||||
m_screen = screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWasmCompositor::setVisible(QWasmWindow *window, bool visible)
|
void QWasmCompositor::setVisible(QWasmWindow *window, bool visible)
|
||||||
{
|
{
|
||||||
QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
|
QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
|
||||||
@ -654,7 +650,7 @@ void QWasmCompositor::frame()
|
|||||||
|
|
||||||
m_needComposit = false;
|
m_needComposit = false;
|
||||||
|
|
||||||
if (m_windowStack.empty() || !m_screen)
|
if (m_windowStack.empty() || !screen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QWasmWindow *someWindow = nullptr;
|
QWasmWindow *someWindow = nullptr;
|
||||||
@ -673,7 +669,7 @@ void QWasmCompositor::frame()
|
|||||||
if (m_context.isNull()) {
|
if (m_context.isNull()) {
|
||||||
m_context.reset(new QOpenGLContext());
|
m_context.reset(new QOpenGLContext());
|
||||||
//mContext->setFormat(mScreen->format());
|
//mContext->setFormat(mScreen->format());
|
||||||
m_context->setScreen(m_screen->screen());
|
m_context->setScreen(screen()->screen());
|
||||||
m_context->create();
|
m_context->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,8 +678,8 @@ void QWasmCompositor::frame()
|
|||||||
if (!m_blitter->isCreated())
|
if (!m_blitter->isCreated())
|
||||||
m_blitter->create();
|
m_blitter->create();
|
||||||
|
|
||||||
qreal dpr = m_screen->devicePixelRatio();
|
qreal dpr = screen()->devicePixelRatio();
|
||||||
glViewport(0, 0, m_screen->geometry().width() * dpr, m_screen->geometry().height() * dpr);
|
glViewport(0, 0, screen()->geometry().width() * dpr, screen()->geometry().height() * dpr);
|
||||||
|
|
||||||
m_context->functions()->glClearColor(0.2, 0.2, 0.2, 1.0);
|
m_context->functions()->glClearColor(0.2, 0.2, 0.2, 1.0);
|
||||||
m_context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
m_context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
@ -697,7 +693,7 @@ void QWasmCompositor::frame()
|
|||||||
if (!compositedWindow.visible)
|
if (!compositedWindow.visible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
drawWindow(m_blitter.data(), m_screen, window);
|
drawWindow(m_blitter.data(), screen(), window);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_blitter->release();
|
m_blitter->release();
|
||||||
@ -719,3 +715,8 @@ void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window)
|
|||||||
requestRedraw();
|
requestRedraw();
|
||||||
QWindowSystemInterface::handleWindowActivated(window->window());
|
QWindowSystemInterface::handleWindowActivated(window->window());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWasmScreen *QWasmCompositor::screen()
|
||||||
|
{
|
||||||
|
return static_cast<QWasmScreen *>(parent());
|
||||||
|
}
|
||||||
|
@ -62,7 +62,7 @@ class QWasmCompositor : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QWasmCompositor();
|
QWasmCompositor(QWasmScreen *screen);
|
||||||
~QWasmCompositor();
|
~QWasmCompositor();
|
||||||
|
|
||||||
enum QWasmSubControl {
|
enum QWasmSubControl {
|
||||||
@ -103,7 +103,6 @@ public:
|
|||||||
|
|
||||||
void addWindow(QWasmWindow *window, QWasmWindow *parentWindow = nullptr);
|
void addWindow(QWasmWindow *window, QWasmWindow *parentWindow = nullptr);
|
||||||
void removeWindow(QWasmWindow *window);
|
void removeWindow(QWasmWindow *window);
|
||||||
void setScreen(QWasmScreen *screen);
|
|
||||||
|
|
||||||
void setVisible(QWasmWindow *window, bool visible);
|
void setVisible(QWasmWindow *window, bool visible);
|
||||||
void raise(QWasmWindow *window);
|
void raise(QWasmWindow *window);
|
||||||
@ -129,8 +128,7 @@ private slots:
|
|||||||
void frame();
|
void frame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createFrameBuffer();
|
QWasmScreen *screen();
|
||||||
void flushCompletedCallback(int32_t);
|
|
||||||
void notifyTopWindowChanged(QWasmWindow *window);
|
void notifyTopWindowChanged(QWasmWindow *window);
|
||||||
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
|
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
|
||||||
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
|
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
|
||||||
@ -142,7 +140,6 @@ private:
|
|||||||
QImage *m_frameBuffer;
|
QImage *m_frameBuffer;
|
||||||
QScopedPointer<QOpenGLContext> m_context;
|
QScopedPointer<QOpenGLContext> m_context;
|
||||||
QScopedPointer<QOpenGLTextureBlitter> m_blitter;
|
QScopedPointer<QOpenGLTextureBlitter> m_blitter;
|
||||||
QWasmScreen *m_screen;
|
|
||||||
|
|
||||||
QHash<QWasmWindow *, QWasmCompositedWindow> m_compositedWindows;
|
QHash<QWasmWindow *, QWasmCompositedWindow> m_compositedWindows;
|
||||||
QList<QWasmWindow *> m_windowStack;
|
QList<QWasmWindow *> m_windowStack;
|
||||||
|
@ -28,20 +28,21 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qwasmcursor.h"
|
#include "qwasmcursor.h"
|
||||||
|
#include "qwasmscreen.h"
|
||||||
|
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtGui/qwindow.h>
|
||||||
|
|
||||||
#include <emscripten/emscripten.h>
|
#include <emscripten/emscripten.h>
|
||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
|
|
||||||
void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||||
{
|
{
|
||||||
if (windowCursor == nullptr)
|
if (!windowCursor || !window)
|
||||||
|
return;
|
||||||
|
QScreen *screen = window->screen();
|
||||||
|
if (!screen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// FIXME: The HTML5 plugin sets the cursor on the native canvas; when using multiple windows
|
|
||||||
// multiple cursors need to be managed taking mouse postion and stacking into account.
|
|
||||||
Q_UNUSED(window);
|
|
||||||
|
|
||||||
// Bitmap and custom cursors are not implemented (will fall back to "auto")
|
// Bitmap and custom cursors are not implemented (will fall back to "auto")
|
||||||
if (windowCursor->shape() == Qt::BitmapCursor || windowCursor->shape() >= Qt::CustomCursor)
|
if (windowCursor->shape() == Qt::BitmapCursor || windowCursor->shape() >= Qt::CustomCursor)
|
||||||
@ -52,8 +53,9 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
|||||||
if (htmlCursorName.isEmpty())
|
if (htmlCursorName.isEmpty())
|
||||||
htmlCursorName = "auto";
|
htmlCursorName = "auto";
|
||||||
|
|
||||||
// Set cursor on the main canvas
|
// Set cursor on the canvas
|
||||||
emscripten::val canvasStyle = emscripten::val::module_property("canvas")["style"];
|
QString canvasId = QWasmScreen::get(screen)->canvasId();
|
||||||
|
emscripten::val canvasStyle = emscripten::val::global(canvasId.toUtf8().constData())["style"];
|
||||||
canvasStyle.set("cursor", emscripten::val(htmlCursorName.constData()));
|
canvasStyle.set("cursor", emscripten::val(htmlCursorName.constData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,8 +320,8 @@ EMSCRIPTEN_BINDINGS(mouse_module) {
|
|||||||
function("mouseWheelEvent", &mouseWheelEvent);
|
function("mouseWheelEvent", &mouseWheelEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
|
QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
|
||||||
: QObject(parent)
|
: QObject(screen)
|
||||||
, draggedWindow(nullptr)
|
, draggedWindow(nullptr)
|
||||||
, lastWindow(nullptr)
|
, lastWindow(nullptr)
|
||||||
, pressedButtons(Qt::NoButton)
|
, pressedButtons(Qt::NoButton)
|
||||||
@ -332,13 +332,16 @@ QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
|
|||||||
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
|
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
|
||||||
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
||||||
|
|
||||||
QWasmScreen *wasmScreen = QWasmIntegration::get()->screen();
|
initEventHandlers();
|
||||||
initEventHandlers(wasmScreen->m_canvasId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmEventTranslator::initEventHandlers(const QString &canvas)
|
void QWasmEventTranslator::initEventHandlers()
|
||||||
{
|
{
|
||||||
const char *canvasId = canvas.toLocal8Bit().constData();
|
qDebug() << "QWasmEventTranslator::initEventHandlers";
|
||||||
|
|
||||||
|
QByteArray _canvasId = screen()->canvasId().toUtf8();
|
||||||
|
const char *canvasId = _canvasId.constData();
|
||||||
|
|
||||||
// The Platform Detect: expand coverage and move as needed
|
// The Platform Detect: expand coverage and move as needed
|
||||||
enum Platform {
|
enum Platform {
|
||||||
GenericPlatform,
|
GenericPlatform,
|
||||||
@ -375,7 +378,7 @@ void QWasmEventTranslator::initEventHandlers(const QString &canvas)
|
|||||||
emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback);
|
emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback);
|
||||||
emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback);
|
emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback);
|
||||||
|
|
||||||
emscripten_set_resize_callback(canvasId, (void *)this, 1, uiEvent_cb);
|
emscripten_set_resize_callback(nullptr, (void *)this, 1, uiEvent_cb); // Note: handles browser window resize
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +428,11 @@ int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEve
|
|||||||
return accepted ? 1 : 0;
|
return accepted ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWasmScreen *QWasmEventTranslator::screen()
|
||||||
|
{
|
||||||
|
return static_cast<QWasmScreen *>(parent());
|
||||||
|
}
|
||||||
|
|
||||||
Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey)
|
Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey)
|
||||||
{
|
{
|
||||||
Qt::Key qtKey = Qt::Key_unknown;
|
Qt::Key qtKey = Qt::Key_unknown;
|
||||||
@ -541,14 +549,14 @@ void resizeWindow(QWindow *window, QWasmWindow::ResizeMode mode,
|
|||||||
void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
|
void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
|
||||||
{
|
{
|
||||||
auto timestamp = mouseEvent->timestamp;
|
auto timestamp = mouseEvent->timestamp;
|
||||||
QPoint point(mouseEvent->canvasX, mouseEvent->canvasY);
|
QPoint point(mouseEvent->targetX, mouseEvent->targetY);
|
||||||
|
|
||||||
QEvent::Type buttonEventType = QEvent::None;
|
QEvent::Type buttonEventType = QEvent::None;
|
||||||
|
|
||||||
Qt::MouseButton button = translateMouseButton(mouseEvent->button);
|
Qt::MouseButton button = translateMouseButton(mouseEvent->button);
|
||||||
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
|
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
|
||||||
|
|
||||||
QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
|
QWindow *window2 = screen()->compositor()->windowAt(point, 5);
|
||||||
if (window2 != nullptr)
|
if (window2 != nullptr)
|
||||||
lastWindow = window2;
|
lastWindow = window2;
|
||||||
|
|
||||||
@ -645,6 +653,7 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
|
|||||||
{
|
{
|
||||||
Q_UNUSED(eventType)
|
Q_UNUSED(eventType)
|
||||||
|
|
||||||
|
QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData);
|
||||||
EmscriptenMouseEvent mouseEvent = wheelEvent->mouse;
|
EmscriptenMouseEvent mouseEvent = wheelEvent->mouse;
|
||||||
|
|
||||||
int scrollFactor = 0;
|
int scrollFactor = 0;
|
||||||
@ -668,7 +677,7 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
|
|||||||
auto timestamp = mouseEvent.timestamp;
|
auto timestamp = mouseEvent.timestamp;
|
||||||
QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);
|
QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);
|
||||||
|
|
||||||
QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(globalPoint, 5);
|
QWindow *window2 = eventTranslator->screen()->compositor()->windowAt(globalPoint, 5);
|
||||||
|
|
||||||
QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y());
|
QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y());
|
||||||
|
|
||||||
@ -686,6 +695,7 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
|
|||||||
|
|
||||||
int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
|
int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
|
||||||
{
|
{
|
||||||
|
QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData);
|
||||||
QList<QWindowSystemInterface::TouchPoint> touchPointList;
|
QList<QWindowSystemInterface::TouchPoint> touchPointList;
|
||||||
touchPointList.reserve(touchEvent->numTouches);
|
touchPointList.reserve(touchEvent->numTouches);
|
||||||
QWindow *window2;
|
QWindow *window2;
|
||||||
@ -695,7 +705,7 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven
|
|||||||
const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
|
const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
|
||||||
|
|
||||||
QPoint point(touches->canvasX, touches->canvasY);
|
QPoint point(touches->canvasX, touches->canvasY);
|
||||||
window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
|
window2 = eventTranslator->screen()->compositor()->windowAt(point, 5);
|
||||||
|
|
||||||
QWindowSystemInterface::TouchPoint touchPoint;
|
QWindowSystemInterface::TouchPoint touchPoint;
|
||||||
|
|
||||||
@ -878,15 +888,13 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa
|
|||||||
int QWasmEventTranslator::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
|
int QWasmEventTranslator::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
|
||||||
{
|
{
|
||||||
Q_UNUSED(e)
|
Q_UNUSED(e)
|
||||||
Q_UNUSED(userData)
|
QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData);
|
||||||
|
|
||||||
if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
|
if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
|
||||||
// This resize event is called when the HTML window is resized. Depending
|
// This resize event is called when the HTML window is resized. Depending
|
||||||
// on the page layout the the canvas might also have been resized, so we
|
// on the page layout the the canvas might also have been resized, so we
|
||||||
// update the Qt screen size (and canvas render size).
|
// update the Qt screen size (and canvas render size).
|
||||||
QWasmScreen *wasmScreen = QWasmIntegration::get()->screen();
|
eventTranslator->screen()->updateQScreenAndCanvasRenderSize();
|
||||||
|
|
||||||
wasmScreen->updateQScreenAndCanvasRenderSize(wasmScreen->m_canvasId.toLocal8Bit().constData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -48,7 +48,7 @@ class QWasmEventTranslator : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit QWasmEventTranslator(QObject *parent = 0);
|
explicit QWasmEventTranslator(QWasmScreen *screen);
|
||||||
|
|
||||||
static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
|
static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
|
||||||
static int mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
|
static int mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
|
||||||
@ -60,12 +60,12 @@ public:
|
|||||||
static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData);
|
static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData);
|
||||||
|
|
||||||
void processEvents();
|
void processEvents();
|
||||||
void initEventHandlers(const QString &);
|
void initEventHandlers();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void getWindowAt(const QPoint &point, QWindow **window);
|
void getWindowAt(const QPoint &point, QWindow **window);
|
||||||
private:
|
private:
|
||||||
|
QWasmScreen *screen();
|
||||||
Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey);
|
Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey);
|
||||||
template <typename Event>
|
template <typename Event>
|
||||||
QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event);
|
QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event);
|
||||||
|
@ -70,36 +70,35 @@ QWasmIntegration *QWasmIntegration::s_instance;
|
|||||||
|
|
||||||
QWasmIntegration::QWasmIntegration()
|
QWasmIntegration::QWasmIntegration()
|
||||||
: m_fontDb(nullptr),
|
: m_fontDb(nullptr),
|
||||||
m_compositor(new QWasmCompositor),
|
|
||||||
m_screen(new QWasmScreen(m_compositor)),
|
|
||||||
m_eventDispatcher(nullptr),
|
m_eventDispatcher(nullptr),
|
||||||
m_clipboard(new QWasmClipboard)
|
m_clipboard(new QWasmClipboard)
|
||||||
{
|
{
|
||||||
|
|
||||||
globalHtml5Integration = this;
|
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
|
|
||||||
emscripten::val defaultCanvasId = emscripten::val::global("canvas");
|
// We expect that qtloader.js has populated Module.qtCanvasElements with one or more canvases.
|
||||||
canvasIds.append(QString::fromStdString(defaultCanvasId["id"].as<std::string>()));
|
// Also check Module.canvas, which may be set if the emscripen or a custom loader is used.
|
||||||
m_screen->setCanvas(canvasIds.at(0));
|
emscripten::val qtCanvaseElements = val::module_property("qtCanvasElements");
|
||||||
|
emscripten::val canvas = val::module_property("canvas");
|
||||||
|
|
||||||
globalHtml5Integration = this;
|
if (!qtCanvaseElements.isUndefined()) {
|
||||||
|
int screenCount = qtCanvaseElements["length"].as<int>();
|
||||||
screen()->updateQScreenAndCanvasRenderSize(m_screen->m_canvasId);
|
for (int i = 0; i < screenCount; ++i) {
|
||||||
screenAdded(m_screen);
|
emscripten::val canvas = qtCanvaseElements[i].as<emscripten::val>();
|
||||||
|
QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
|
||||||
m_eventTranslator = new QWasmEventTranslator;
|
addScreen(canvasId);
|
||||||
|
}
|
||||||
|
} else if (!canvas.isUndefined()){
|
||||||
|
QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
|
||||||
|
addScreen(canvasId);
|
||||||
|
}
|
||||||
|
|
||||||
emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload"));
|
emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmIntegration::~QWasmIntegration()
|
QWasmIntegration::~QWasmIntegration()
|
||||||
{
|
{
|
||||||
delete m_compositor;
|
|
||||||
destroyScreen(m_screen);
|
|
||||||
delete m_fontDb;
|
delete m_fontDb;
|
||||||
delete m_eventTranslator;
|
qDeleteAll(m_screens);
|
||||||
s_instance = nullptr;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +123,15 @@ bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
|
|||||||
|
|
||||||
QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
|
QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
|
||||||
{
|
{
|
||||||
return new QWasmWindow(window, m_compositor, m_backingStores.value(window));
|
QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
|
||||||
|
return new QWasmWindow(window, compositor, m_backingStores.value(window));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
|
QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
QWasmBackingStore *backingStore = new QWasmBackingStore(m_compositor, window);
|
QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
|
||||||
|
QWasmBackingStore *backingStore = new QWasmBackingStore(compositor, window);
|
||||||
m_backingStores.insert(window, backingStore);
|
m_backingStores.insert(window, backingStore);
|
||||||
return backingStore;
|
return backingStore;
|
||||||
#else
|
#else
|
||||||
@ -177,9 +178,20 @@ QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
|
|||||||
|
|
||||||
QPlatformClipboard* QWasmIntegration::clipboard() const
|
QPlatformClipboard* QWasmIntegration::clipboard() const
|
||||||
{
|
{
|
||||||
if (!m_clipboard)
|
|
||||||
m_clipboard = new QWasmClipboard;
|
|
||||||
return m_clipboard;
|
return m_clipboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QWasmScreen *> QWasmIntegration::screens()
|
||||||
|
{
|
||||||
|
return m_screens;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWasmIntegration::addScreen(const QString &canvasId)
|
||||||
|
{
|
||||||
|
QWasmScreen *screen = new QWasmScreen(canvasId);
|
||||||
|
m_clipboard->installEventHandlers(canvasId);
|
||||||
|
m_screens.append(screen);
|
||||||
|
screenAdded(screen);
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -71,23 +71,20 @@ public:
|
|||||||
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
||||||
QPlatformClipboard *clipboard() const override;
|
QPlatformClipboard *clipboard() const override;
|
||||||
|
|
||||||
QWasmScreen *screen() { return m_screen; }
|
QVector<QWasmScreen *>screens();
|
||||||
QWasmCompositor *compositor() { return m_compositor; }
|
|
||||||
QWasmEventTranslator *eventTranslator() { return m_eventTranslator; }
|
|
||||||
QWasmClipboard *getWasmClipboard() { return m_clipboard; }
|
QWasmClipboard *getWasmClipboard() { return m_clipboard; }
|
||||||
|
|
||||||
static QWasmIntegration *get() { return s_instance; }
|
static QWasmIntegration *get() { return s_instance; }
|
||||||
static void QWasmBrowserExit();
|
static void QWasmBrowserExit();
|
||||||
QStringList canvasIds;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void addScreen(const QString &canvasId);
|
||||||
|
|
||||||
mutable QWasmFontDatabase *m_fontDb;
|
mutable QWasmFontDatabase *m_fontDb;
|
||||||
QWasmCompositor *m_compositor;
|
|
||||||
mutable QWasmScreen *m_screen;
|
|
||||||
mutable QWasmEventTranslator *m_eventTranslator;
|
|
||||||
mutable QWasmEventDispatcher *m_eventDispatcher;
|
mutable QWasmEventDispatcher *m_eventDispatcher;
|
||||||
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
|
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
|
||||||
|
|
||||||
|
QVector<QWasmScreen *> m_screens;
|
||||||
mutable QWasmClipboard *m_clipboard;
|
mutable QWasmClipboard *m_clipboard;
|
||||||
static QWasmIntegration *s_instance;
|
static QWasmIntegration *s_instance;
|
||||||
};
|
};
|
||||||
|
@ -57,9 +57,7 @@ void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surfac
|
|||||||
emscripten_webgl_destroy_context(m_context);
|
emscripten_webgl_destroy_context(m_context);
|
||||||
|
|
||||||
// Create new context
|
// Create new context
|
||||||
QWasmScreen *wasmScreen = QWasmIntegration::get()->screen();
|
const QString canvasId = QWasmScreen::get(surface->screen())->canvasId();
|
||||||
const QString canvasId = wasmScreen->m_canvasId;
|
|
||||||
// FIXME: get the actual canvas from the surface.
|
|
||||||
m_context = createEmscriptenContext(canvasId, m_requestedFormat);
|
m_context = createEmscriptenContext(canvasId, m_requestedFormat);
|
||||||
|
|
||||||
// Register context-lost callback.
|
// Register context-lost callback.
|
||||||
|
@ -29,8 +29,10 @@
|
|||||||
|
|
||||||
#include "qwasmscreen.h"
|
#include "qwasmscreen.h"
|
||||||
#include "qwasmwindow.h"
|
#include "qwasmwindow.h"
|
||||||
|
#include "qwasmeventtranslator.h"
|
||||||
#include "qwasmcompositor.h"
|
#include "qwasmcompositor.h"
|
||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
|
||||||
#include <QtEglSupport/private/qeglconvenience_p.h>
|
#include <QtEglSupport/private/qeglconvenience_p.h>
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
@ -44,12 +46,13 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QWasmScreen::QWasmScreen(QWasmCompositor *compositor)
|
QWasmScreen::QWasmScreen(const QString &canvasId)
|
||||||
: m_compositor(compositor)
|
: m_canvasId(canvasId)
|
||||||
, m_depth(32)
|
|
||||||
, m_format(QImage::Format_RGB32)
|
|
||||||
{
|
{
|
||||||
m_compositor->setScreen(this);
|
m_compositor = new QWasmCompositor(this);
|
||||||
|
m_eventTranslator = new QWasmEventTranslator(this);
|
||||||
|
updateQScreenAndCanvasRenderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmScreen::~QWasmScreen()
|
QWasmScreen::~QWasmScreen()
|
||||||
@ -57,6 +60,31 @@ QWasmScreen::~QWasmScreen()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWasmScreen *QWasmScreen::get(QPlatformScreen *screen)
|
||||||
|
{
|
||||||
|
return static_cast<QWasmScreen *>(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWasmScreen *QWasmScreen::get(QScreen *screen)
|
||||||
|
{
|
||||||
|
return get(screen->handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWasmCompositor *QWasmScreen::compositor()
|
||||||
|
{
|
||||||
|
return m_compositor;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWasmEventTranslator *QWasmScreen::eventTranslator()
|
||||||
|
{
|
||||||
|
return m_eventTranslator;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QWasmScreen::canvasId() const
|
||||||
|
{
|
||||||
|
return m_canvasId;
|
||||||
|
}
|
||||||
|
|
||||||
QRect QWasmScreen::geometry() const
|
QRect QWasmScreen::geometry() const
|
||||||
{
|
{
|
||||||
return m_geometry;
|
return m_geometry;
|
||||||
@ -82,6 +110,11 @@ qreal QWasmScreen::devicePixelRatio() const
|
|||||||
return qreal(htmlWindowDpr);
|
return qreal(htmlWindowDpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QWasmScreen::name() const
|
||||||
|
{
|
||||||
|
return m_canvasId;
|
||||||
|
}
|
||||||
|
|
||||||
QPlatformCursor *QWasmScreen::cursor() const
|
QPlatformCursor *QWasmScreen::cursor() const
|
||||||
{
|
{
|
||||||
return const_cast<QWasmCursor *>(&m_cursor);
|
return const_cast<QWasmCursor *>(&m_cursor);
|
||||||
@ -114,14 +147,7 @@ void QWasmScreen::setGeometry(const QRect &rect)
|
|||||||
resizeMaximizedWindows();
|
resizeMaximizedWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_canvas_size(double width, double height, const char *canvasId)
|
void QWasmScreen::updateQScreenAndCanvasRenderSize()
|
||||||
{
|
|
||||||
emscripten::val canvas = emscripten::val::global(canvasId);
|
|
||||||
canvas.set("width", width);
|
|
||||||
canvas.set("height", height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWasmScreen::updateQScreenAndCanvasRenderSize(const QString &canvasId)
|
|
||||||
{
|
{
|
||||||
// The HTML canvas has two sizes: the CSS size and the canvas render size.
|
// The HTML canvas has two sizes: the CSS size and the canvas render size.
|
||||||
// The CSS size is determined according to standard CSS rules, while the
|
// The CSS size is determined according to standard CSS rules, while the
|
||||||
@ -130,17 +156,22 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize(const QString &canvasId)
|
|||||||
// Setting the render size to a value larger than the CSS size enables high-dpi
|
// Setting the render size to a value larger than the CSS size enables high-dpi
|
||||||
// rendering.
|
// rendering.
|
||||||
|
|
||||||
|
QByteArray canvasId = m_canvasId.toUtf8();
|
||||||
double css_width;
|
double css_width;
|
||||||
double css_height;
|
double css_height;
|
||||||
emscripten_get_element_css_size(canvasId.toLocal8Bit().constData(), &css_width, &css_height);
|
emscripten_get_element_css_size(canvasId.constData(), &css_width, &css_height);
|
||||||
QSizeF cssSize(css_width, css_height);
|
QSizeF cssSize(css_width, css_height);
|
||||||
|
|
||||||
QWasmScreen *screen = QWasmIntegration::get()->screen();
|
QSizeF canvasSize = cssSize * devicePixelRatio();
|
||||||
QSizeF canvasSize = cssSize * screen->devicePixelRatio();
|
emscripten::val canvas = emscripten::val::global(canvasId.constData());
|
||||||
|
canvas.set("width", canvasSize.width());
|
||||||
|
canvas.set("height", canvasSize.height());
|
||||||
|
|
||||||
set_canvas_size(canvasSize.width(), canvasSize.height(), canvasId.toLocal8Bit().constData());
|
emscripten::val rect = canvas.call<emscripten::val>("getBoundingClientRect");
|
||||||
screen->setGeometry(QRect(QPoint(0, 0), cssSize.toSize()));
|
QPoint position(rect["left"].as<int>(), rect["top"].as<int>());
|
||||||
QWasmIntegration::get()->compositor()->redrawWindowContent();
|
|
||||||
|
setGeometry(QRect(position, cssSize.toSize()));
|
||||||
|
m_compositor->redrawWindowContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -43,20 +43,28 @@ class QPlatformOpenGLContext;
|
|||||||
class QWasmWindow;
|
class QWasmWindow;
|
||||||
class QWasmBackingStore;
|
class QWasmBackingStore;
|
||||||
class QWasmCompositor;
|
class QWasmCompositor;
|
||||||
|
class QWasmEventTranslator;
|
||||||
class QOpenGLContext;
|
class QOpenGLContext;
|
||||||
|
|
||||||
class QWasmScreen : public QObject, public QPlatformScreen
|
class QWasmScreen : public QObject, public QPlatformScreen
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
QWasmScreen(const QString &canvasId);
|
||||||
QWasmScreen(QWasmCompositor *compositor);
|
|
||||||
~QWasmScreen();
|
~QWasmScreen();
|
||||||
|
|
||||||
|
static QWasmScreen *get(QPlatformScreen *screen);
|
||||||
|
static QWasmScreen *get(QScreen *screen);
|
||||||
|
QString canvasId() const;
|
||||||
|
|
||||||
|
QWasmCompositor *compositor();
|
||||||
|
QWasmEventTranslator *eventTranslator();
|
||||||
|
|
||||||
QRect geometry() const override;
|
QRect geometry() const override;
|
||||||
int depth() const override;
|
int depth() const override;
|
||||||
QImage::Format format() const override;
|
QImage::Format format() const override;
|
||||||
qreal devicePixelRatio() const override;
|
qreal devicePixelRatio() const override;
|
||||||
|
QString name() const override;
|
||||||
QPlatformCursor *cursor() const override;
|
QPlatformCursor *cursor() const override;
|
||||||
|
|
||||||
void resizeMaximizedWindows();
|
void resizeMaximizedWindows();
|
||||||
@ -64,19 +72,18 @@ public:
|
|||||||
QWindow *topLevelAt(const QPoint &p) const override;
|
QWindow *topLevelAt(const QPoint &p) const override;
|
||||||
|
|
||||||
void invalidateSize();
|
void invalidateSize();
|
||||||
static void updateQScreenAndCanvasRenderSize(const QString &);
|
void updateQScreenAndCanvasRenderSize();
|
||||||
QString m_canvasId;
|
|
||||||
void setCanvas(const QString &canvasId) { m_canvasId = canvasId; }
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setGeometry(const QRect &rect);
|
void setGeometry(const QRect &rect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWasmCompositor *m_compositor;
|
QString m_canvasId;
|
||||||
|
QWasmCompositor *m_compositor = nullptr;
|
||||||
|
QWasmEventTranslator *m_eventTranslator = nullptr;
|
||||||
QRect m_geometry = QRect(0, 0, 100, 100);
|
QRect m_geometry = QRect(0, 0, 100, 100);
|
||||||
int m_depth;
|
int m_depth = 32;
|
||||||
QImage::Format m_format;
|
QImage::Format m_format = QImage::Format_RGB32;
|
||||||
QWasmCursor m_cursor;
|
QWasmCursor m_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,23 +15,24 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="init()">
|
<body onload="init()">
|
||||||
<figure style="overflow:visible;" id="spinner">
|
<figure style="overflow:visible;" id="qtspinner">
|
||||||
<center style="margin-top:1.5em; line-height:150%">
|
<center style="margin-top:1.5em; line-height:150%">
|
||||||
<img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
|
<img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
|
||||||
<strong>Qt for WebAssembly: APPNAME</strong>
|
<strong>Qt for WebAssembly: APPNAME</strong>
|
||||||
<div id="status"></div>
|
<div id="qtstatus"></div>
|
||||||
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
|
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
|
||||||
</center>
|
</center>
|
||||||
</figure>
|
</figure>
|
||||||
<canvas id="canvas" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas>
|
<canvas id="qtcanvas" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas>
|
||||||
|
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
function init() {
|
function init() {
|
||||||
var spinner = document.getElementById('spinner');
|
var spinner = document.getElementById('qtspinner');
|
||||||
var canvas = document.getElementById('canvas');
|
var canvas = document.getElementById('qtcanvas');
|
||||||
var status = document.getElementById('status')
|
var status = document.getElementById('qtstatus')
|
||||||
|
|
||||||
var qtLoader = QtLoader({
|
var qtLoader = QtLoader({
|
||||||
|
canvasElements : [canvas],
|
||||||
showLoader: function(loaderStatus) {
|
showLoader: function(loaderStatus) {
|
||||||
spinner.style.display = 'block';
|
spinner.style.display = 'block';
|
||||||
canvas.style.display = 'none';
|
canvas.style.display = 'none';
|
||||||
@ -54,7 +55,6 @@
|
|||||||
showCanvas: function() {
|
showCanvas: function() {
|
||||||
spinner.style.display = 'none';
|
spinner.style.display = 'none';
|
||||||
canvas.style.display = 'block';
|
canvas.style.display = 'block';
|
||||||
return canvas;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
qtLoader.loadEmscriptenModule("APPNAME");
|
qtLoader.loadEmscriptenModule("APPNAME");
|
||||||
|
Loading…
Reference in New Issue
Block a user