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.
// exitText
// 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 = {}
@ -227,6 +231,8 @@ function QtLoader(config)
publicAPI.canLoadApplication = canLoadQt();
publicAPI.status = undefined;
publicAPI.loadEmscriptenModule = loadEmscriptenModule;
publicAPI.addCanvasElement = addCanvasElement;
publicAPI.removeCanvasElement = removeCanvasElement;
restartCount = 0;
@ -528,6 +534,20 @@ function QtLoader(config)
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");
return publicAPI;

View File

@ -61,9 +61,23 @@ static void browserBeforeUnload(emscripten::val)
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)
{
function("qtBrowserBeforeUnload", &browserBeforeUnload);
function("qtAddCanvasElement", &addCanvasElement);
function("qtRemoveCanvasElement", &removeCanvasElement);
}
QWasmIntegration *QWasmIntegration::s_instance;
@ -99,8 +113,9 @@ QWasmIntegration::~QWasmIntegration()
{
delete m_fontDb;
while (!m_screens.isEmpty())
QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast());
for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
QWindowSystemInterface::handleScreenRemoved(*it);
m_screens.clear();
s_instance = nullptr;
}
@ -184,17 +199,17 @@ QPlatformClipboard* QWasmIntegration::clipboard() const
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);
m_screens.insert(canvasId, screen);
QWindowSystemInterface::handleScreenAdded(screen);
}
void QWasmIntegration::removeScreen(const QString &canvasId)
{
QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
}
QT_END_NAMESPACE

View File

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