wasm: support adding and removing canvases at runtime

Add qtloader API:
  addCanvasElement()
  removeCanvasElement()

These functions call the corresponding add/remove screen
functions on QWasmIntegration.

Task-number: QTBUG-64079
Change-Id: I537c11f3b5fb9240cca9b6313dd45f803d865ac6
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Morten Johan Sørvig 2019-03-15 19:42:17 +01:00
parent ed49a84e6c
commit 73db765aaf
3 changed files with 46 additions and 12 deletions

View File

@ -118,6 +118,10 @@
// "Exited", iff crashed is false. // "Exited", iff crashed is false.
// exitText // exitText
// Abort/exit message. // Abort/exit message.
// addCanvasElement
// Add canvas at run-time. Adds a corresponding QScreen,
// removeCanvasElement
// Remove canvas at run-time. Removes the corresponding QScreen.
var Module = {} var Module = {}
@ -227,6 +231,8 @@ function QtLoader(config)
publicAPI.canLoadApplication = canLoadQt(); publicAPI.canLoadApplication = canLoadQt();
publicAPI.status = undefined; publicAPI.status = undefined;
publicAPI.loadEmscriptenModule = loadEmscriptenModule; publicAPI.loadEmscriptenModule = loadEmscriptenModule;
publicAPI.addCanvasElement = addCanvasElement;
publicAPI.removeCanvasElement = removeCanvasElement;
restartCount = 0; restartCount = 0;
@ -528,6 +534,20 @@ function QtLoader(config)
window.setTimeout(function() { handleStatusChange(); }, 0); window.setTimeout(function() { handleStatusChange(); }, 0);
} }
function addCanvasElement(element) {
if (publicAPI.status == "Running")
Module.qtAddCanvasElement(element);
else
console.log("Error: addCanvasElement can only be called in the Running state");
}
function removeCanvasElement(element) {
if (publicAPI.status == "Running")
Module.qtRemoveCanvasElement(element);
else
console.log("Error: removeCanvasElement can only be called in the Running state");
}
setStatus("Created"); setStatus("Created");
return publicAPI; return publicAPI;

View File

@ -61,9 +61,23 @@ static void browserBeforeUnload(emscripten::val)
QWasmIntegration::QWasmBrowserExit(); QWasmIntegration::QWasmBrowserExit();
} }
static void addCanvasElement(emscripten::val canvas)
{
QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
QWasmIntegration::get()->addScreen(canvasId);
}
static void removeCanvasElement(emscripten::val canvas)
{
QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
QWasmIntegration::get()->removeScreen(canvasId);
}
EMSCRIPTEN_BINDINGS(qtQWasmIntegraton) EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
{ {
function("qtBrowserBeforeUnload", &browserBeforeUnload); function("qtBrowserBeforeUnload", &browserBeforeUnload);
function("qtAddCanvasElement", &addCanvasElement);
function("qtRemoveCanvasElement", &removeCanvasElement);
} }
QWasmIntegration *QWasmIntegration::s_instance; QWasmIntegration *QWasmIntegration::s_instance;
@ -99,8 +113,9 @@ QWasmIntegration::~QWasmIntegration()
{ {
delete m_fontDb; delete m_fontDb;
while (!m_screens.isEmpty()) for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast()); QWindowSystemInterface::handleScreenRemoved(*it);
m_screens.clear();
s_instance = nullptr; s_instance = nullptr;
} }
@ -184,17 +199,17 @@ QPlatformClipboard* QWasmIntegration::clipboard() const
return m_clipboard; return m_clipboard;
} }
QVector<QWasmScreen *> QWasmIntegration::screens()
{
return m_screens;
}
void QWasmIntegration::addScreen(const QString &canvasId) void QWasmIntegration::addScreen(const QString &canvasId)
{ {
QWasmScreen *screen = new QWasmScreen(canvasId); QWasmScreen *screen = new QWasmScreen(canvasId);
m_clipboard->installEventHandlers(canvasId); m_clipboard->installEventHandlers(canvasId);
m_screens.append(screen); m_screens.insert(canvasId, screen);
QWindowSystemInterface::handleScreenAdded(screen); QWindowSystemInterface::handleScreenAdded(screen);
} }
void QWasmIntegration::removeScreen(const QString &canvasId)
{
QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -70,21 +70,20 @@ public:
QStringList themeNames() const override; QStringList themeNames() const override;
QPlatformTheme *createPlatformTheme(const QString &name) const override; QPlatformTheme *createPlatformTheme(const QString &name) const override;
QPlatformClipboard *clipboard() const override; QPlatformClipboard *clipboard() const override;
QVector<QWasmScreen *>screens();
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();
private:
void addScreen(const QString &canvasId); void addScreen(const QString &canvasId);
void removeScreen(const QString &canvasId);
private:
mutable QWasmFontDatabase *m_fontDb; mutable QWasmFontDatabase *m_fontDb;
mutable QWasmEventDispatcher *m_eventDispatcher; mutable QWasmEventDispatcher *m_eventDispatcher;
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores; mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
QVector<QWasmScreen *> m_screens; QHash<QString, QWasmScreen *> m_screens;
mutable QWasmClipboard *m_clipboard; mutable QWasmClipboard *m_clipboard;
static QWasmIntegration *s_instance; static QWasmIntegration *s_instance;
}; };