summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qsettings.cpp15
-rw-r--r--src/corelib/io/qsettings_p.h13
-rw-r--r--src/corelib/io/qsettings_wasm.cpp259
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp19
-rw-r--r--src/gui/kernel/qguiapplication.cpp8
6 files changed, 277 insertions, 38 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index fe81689932..c4c6f41387 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -136,6 +136,7 @@ qtConfig(settings) {
} else: darwin:!nacl {
SOURCES += io/qsettings_mac.cpp
}
+ wasm : SOURCES += io/qsettings_wasm.cpp
}
win32 {
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index fc7122d904..dcc9340473 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -76,10 +76,6 @@
# include <ioLib.h>
#endif
-#ifdef Q_OS_WASM
-#include <emscripten.h>
-#endif
-
#include <algorithm>
#include <stdlib.h>
@@ -295,7 +291,7 @@ after_loop:
// see also qsettings_win.cpp, qsettings_winrt.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_WASM)
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -1185,7 +1181,9 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,
confFiles.append(QConfFile::fromName(systemPath.path + orgFile, false));
}
+#ifndef Q_OS_WASM // wasm needs to delay access until after file sync
initAccess();
+#endif
}
QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName,
@@ -1548,13 +1546,6 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
perms |= QFile::ReadGroup | QFile::ReadOther;
QFile(confFile->name).setPermissions(perms);
}
-#ifdef Q_OS_WASM
- EM_ASM(
- // Sync sandbox filesystem to persistent database filesystem. See QTBUG-70002
- FS.syncfs(false, function(err) {
- });
- );
-#endif
} else {
setStatus(QSettings::AccessError);
}
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index d18c96a06c..c30f099a72 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -57,6 +57,10 @@
#include "QtCore/qiodevice.h"
#include "QtCore/qstack.h"
#include "QtCore/qstringlist.h"
+
+#include <QtCore/qvariant.h>
+#include "qsettings.h"
+
#ifndef QT_NO_QOBJECT
#include "private/qobject_p.h"
#endif
@@ -253,6 +257,10 @@ protected:
mutable QSettings::Status status;
};
+#ifdef Q_OS_WASM
+class QWasmSettingsPrivate;
+#endif
+
class QConfFileSettingsPrivate : public QSettingsPrivate
{
public:
@@ -281,7 +289,7 @@ public:
private:
void initFormat();
- void initAccess();
+ virtual void initAccess();
void syncConfFile(QConfFile *confFile);
bool writeIniFile(QIODevice &device, const ParsedSettingsMap &map);
#ifdef Q_OS_MAC
@@ -297,6 +305,9 @@ private:
QString extension;
Qt::CaseSensitivity caseSensitivity;
int nextPosition;
+#ifdef Q_OS_WASM
+ friend class QWasmSettingsPrivate;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp
new file mode 100644
index 0000000000..8d8f4b505c
--- /dev/null
+++ b/src/corelib/io/qsettings_wasm.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsettings.h"
+#ifndef QT_NO_SETTINGS
+
+#include "qsettings_p.h"
+#ifndef QT_NO_QOBJECT
+#include "qcoreapplication.h"
+#include <QFile>
+#endif // QT_NO_QOBJECT
+#include <QDebug>
+
+#include <QFileInfo>
+#include <QDir>
+#include <emscripten.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool isReadReady = false;
+
+class QWasmSettingsPrivate : public QConfFileSettingsPrivate
+{
+public:
+ QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization,
+ const QString &application);
+ ~QWasmSettingsPrivate();
+
+ bool get(const QString &key, QVariant *value) const override;
+ QStringList children(const QString &prefix, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+
+ void syncToLocal(const char *data, int size);
+ void loadLocal(const QByteArray &filename);
+ void setReady();
+ void initAccess() override;
+
+private:
+ QString databaseName;
+ QString id;
+};
+
+static void QWasmSettingsPrivate_onLoad(void *userData, void *dataPtr, int size)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+
+ QFile file(wasm->fileName());
+ QFileInfo fileInfo(wasm->fileName());
+ QDir dir(fileInfo.path());
+ if (!dir.exists())
+ dir.mkpath(fileInfo.path());
+
+ if (file.open(QFile::WriteOnly)) {
+ file.write(reinterpret_cast<char *>(dataPtr), size);
+ file.close();
+ wasm->setReady();
+ }
+}
+
+static void QWasmSettingsPrivate_onError(void *userData)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm)
+ wasm->setStatus(QSettings::AccessError);
+}
+
+static void QWasmSettingsPrivate_onStore(void *userData)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm)
+ wasm->setStatus(QSettings::NoError);
+}
+
+static void QWasmSettingsPrivate_onCheck(void *userData, int exists)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm) {
+ if (exists)
+ wasm->loadLocal(wasm->fileName().toLocal8Bit());
+ else
+ wasm->setReady();
+ }
+}
+
+QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format,
+ QSettings::Scope scope,
+ const QString &organization,
+ const QString &application)
+{
+ Q_UNUSED(format)
+ if (organization == QLatin1String("Qt"))
+ {
+ QString organizationDomain = QCoreApplication::organizationDomain();
+ QString applicationName = QCoreApplication::applicationName();
+
+ QSettingsPrivate *newSettings;
+ newSettings = new QWasmSettingsPrivate(scope, organizationDomain, applicationName);
+
+ newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(organization)));
+ if (!application.isEmpty())
+ newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(application)));
+
+ return newSettings;
+ }
+ return new QWasmSettingsPrivate(scope, organization, application);
+}
+
+QWasmSettingsPrivate::QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization,
+ const QString &application)
+ : QConfFileSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
+{
+ setStatus(QSettings::AccessError); // access error until sandbox gets loaded
+ databaseName = organization;
+ id = application;
+
+ emscripten_idb_async_exists("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onCheck,
+ QWasmSettingsPrivate_onError);
+}
+
+QWasmSettingsPrivate::~QWasmSettingsPrivate()
+{
+}
+
+ void QWasmSettingsPrivate::initAccess()
+{
+ if (isReadReady)
+ QConfFileSettingsPrivate::initAccess();
+}
+
+bool QWasmSettingsPrivate::get(const QString &key, QVariant *value) const
+{
+ if (isReadReady)
+ return QConfFileSettingsPrivate::get(key, value);
+
+ return false;
+}
+
+QStringList QWasmSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
+{
+ return QConfFileSettingsPrivate::children(prefix, spec);
+}
+
+void QWasmSettingsPrivate::clear()
+{
+ QConfFileSettingsPrivate::clear();
+ emscripten_idb_async_delete("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+}
+
+void QWasmSettingsPrivate::sync()
+{
+ QConfFileSettingsPrivate::sync();
+
+ QFile file(fileName());
+ if (file.open(QFile::ReadOnly)) {
+ QByteArray dataPointer = file.readAll();
+
+ emscripten_idb_async_store("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void *>(dataPointer.data()),
+ dataPointer.length(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+ }
+}
+
+void QWasmSettingsPrivate::flush()
+{
+ sync();
+}
+
+bool QWasmSettingsPrivate::isWritable() const
+{
+ return isReadReady && QConfFileSettingsPrivate::isWritable();
+}
+
+void QWasmSettingsPrivate::syncToLocal(const char *data, int size)
+{
+ QFile file(fileName());
+
+ if (file.open(QFile::WriteOnly)) {
+ file.write(data, size + 1);
+ QByteArray data = file.readAll();
+
+ emscripten_idb_async_store("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void *>(data.data()),
+ data.length(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+ setReady();
+ }
+}
+
+void QWasmSettingsPrivate::loadLocal(const QByteArray &filename)
+{
+ emscripten_idb_async_load("/home/web_user",
+ filename.data(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onLoad,
+ QWasmSettingsPrivate_onError);
+}
+
+void QWasmSettingsPrivate::setReady()
+{
+ isReadReady = true;
+ setStatus(QSettings::NoError);
+ QConfFileSettingsPrivate::initAccess();
+}
+
+QT_END_NAMESPACE
+#endif // QT_NO_SETTINGS
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e25049f821..70f0a5ad4c 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -121,7 +121,6 @@
#endif
#ifdef Q_OS_WASM
-#include <emscripten.h>
#include <emscripten/val.h>
#endif
@@ -497,13 +496,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
-#ifdef Q_OS_WASM
- EM_ASM(
- // unmount persistent directory as IDBFS
- // see also QTBUG-70002
- FS.unmount('/home/web_user');
- );
-#endif
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
@@ -795,17 +787,8 @@ void QCoreApplicationPrivate::init()
Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = q;
-#ifdef Q_OS_WASM
- EM_ASM(
- // mount and sync persistent filesystem to sandbox
- FS.mount(IDBFS, {}, '/home/web_user');
- FS.syncfs(true, function(err) {
- if (err)
- Module.print(err);
- });
- );
-
#if QT_CONFIG(thread)
+#ifdef Q_OS_WASM
QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
#endif
#endif
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 4bb2507521..f1d90f9caa 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1715,13 +1715,7 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
qt_gl_set_global_share_context(0);
}
#endif
-#ifdef Q_OS_WASM
- EM_ASM(
- // unmount persistent directory as IDBFS
- // see QTBUG-70002
- FS.unmount('/home/web_user');
- );
-#endif
+
platform_integration->destroy();
delete platform_theme;