mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Use synchrone component loading instead of asynchrone to avoid concurrent bug
This commit is contained in:
parent
4dec0e8c1d
commit
3e0677b78e
2 changed files with 54 additions and 64 deletions
|
|
@ -82,6 +82,50 @@ QVariant QuickSettingsModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant::fromValue<QObject *>(obj);
|
return QVariant::fromValue<QObject *>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QuickSetting *QuickSettingsModel::loadQuickSettingComponent(KPluginMetaData metaData)
|
||||||
|
{
|
||||||
|
// Load KPackage
|
||||||
|
const KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData.fileName()).path());
|
||||||
|
if (!package.isValid()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create translation context
|
||||||
|
QQmlEngine *engine = qmlEngine(this);
|
||||||
|
KLocalizedContext *i18nContext = new KLocalizedContext(engine);
|
||||||
|
i18nContext->setTranslationDomain(QLatin1String("plasma_") + metaData.pluginId());
|
||||||
|
engine->rootContext()->setContextObject(i18nContext);
|
||||||
|
|
||||||
|
// Create component synchronously
|
||||||
|
QQmlComponent component(engine, package.fileUrl("mainscript"));
|
||||||
|
if (component.isError()) {
|
||||||
|
qWarning() << "Unable to load quick setting element:" << metaData.pluginId();
|
||||||
|
for (auto error : component.errors()) {
|
||||||
|
qWarning() << error;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create object
|
||||||
|
QObject *object = component.create(engine->rootContext());
|
||||||
|
if (!object) {
|
||||||
|
qWarning() << "Unable to create quick setting element:" << metaData.pluginId();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto createdSetting = qobject_cast<QuickSetting *>(object);
|
||||||
|
if (createdSetting && createdSetting->isAvailable()) {
|
||||||
|
// Connect availability signal
|
||||||
|
connect(createdSetting, &QuickSetting::availableChanged, this, [this, metaData, createdSetting]() {
|
||||||
|
availabilityChanged(metaData, createdSetting);
|
||||||
|
});
|
||||||
|
return createdSetting;
|
||||||
|
} else {
|
||||||
|
object->deleteLater();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QuickSettingsModel::loadQuickSettings()
|
void QuickSettingsModel::loadQuickSettings()
|
||||||
{
|
{
|
||||||
if (!m_loaded) {
|
if (!m_loaded) {
|
||||||
|
|
@ -96,10 +140,12 @@ void QuickSettingsModel::loadQuickSettings()
|
||||||
m_quickSettings.clear();
|
m_quickSettings.clear();
|
||||||
m_quickSettingsMetaData.clear();
|
m_quickSettingsMetaData.clear();
|
||||||
|
|
||||||
// Loop through enabled quick settings and start loading them
|
// Loop through enabled quick settings and load them synchronously
|
||||||
for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
|
for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
|
||||||
// false - Ensure row insertion signals aren't emitted (since we are resetting the model)
|
if (auto *setting = loadQuickSettingComponent(metaData)) {
|
||||||
loadQuickSetting(metaData, false);
|
m_quickSettings.append(setting);
|
||||||
|
m_quickSettingsMetaData.append(metaData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
@ -112,31 +158,8 @@ void QuickSettingsModel::loadQuickSetting(KPluginMetaData metaData, bool emitIns
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load KPackage
|
if (auto *setting = loadQuickSettingComponent(metaData)) {
|
||||||
const KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData.fileName()).path());
|
insertQuickSettingToModel(metaData, setting, emitInsertSignal);
|
||||||
if (!package.isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create translation context
|
|
||||||
QQmlEngine *engine = qmlEngine(this);
|
|
||||||
KLocalizedContext *i18nContext = new KLocalizedContext(engine);
|
|
||||||
i18nContext->setTranslationDomain(QLatin1String("plasma_") + metaData.pluginId());
|
|
||||||
engine->rootContext()->setContextObject(i18nContext);
|
|
||||||
|
|
||||||
QQmlComponent *component = new QQmlComponent(engine, this);
|
|
||||||
|
|
||||||
// Load QML from KPackage async
|
|
||||||
component->loadUrl(package.fileUrl("mainscript"), QQmlComponent::Asynchronous);
|
|
||||||
|
|
||||||
if (component->isLoading()) {
|
|
||||||
// Listen to load completion
|
|
||||||
connect(component, &QQmlComponent::statusChanged, this, [this, metaData, component, engine]() {
|
|
||||||
afterQuickSettingLoad(engine, metaData, component, true);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Only emit insertion signal if we aren't resetting the model
|
|
||||||
afterQuickSettingLoad(engine, metaData, component, emitInsertSignal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,41 +174,6 @@ void QuickSettingsModel::removeQuickSetting(int index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickSettingsModel::afterQuickSettingLoad(QQmlEngine *engine, KPluginMetaData metaData, QQmlComponent *component, bool emitInsertSignal)
|
|
||||||
{
|
|
||||||
// Create quicksetting component
|
|
||||||
QObject *object = component->create(engine->rootContext());
|
|
||||||
if (!object) {
|
|
||||||
qWarning() << "Unable to load quick setting element:" << metaData.pluginId();
|
|
||||||
component->deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component->isError()) {
|
|
||||||
// Print errors
|
|
||||||
qWarning() << "Unable to load quick setting element:" << metaData.pluginId();
|
|
||||||
for (auto error : component->errors()) {
|
|
||||||
qWarning() << error;
|
|
||||||
}
|
|
||||||
|
|
||||||
component->deleteLater();
|
|
||||||
} else if (component->isReady()) {
|
|
||||||
component->deleteLater();
|
|
||||||
|
|
||||||
auto createdSetting = qobject_cast<QuickSetting *>(object);
|
|
||||||
|
|
||||||
// Connect availability signal to insert/remove quicksetting into model
|
|
||||||
connect(createdSetting, &QuickSetting::availableChanged, this, [this, metaData, createdSetting]() {
|
|
||||||
availabilityChanged(metaData, createdSetting);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add quicksetting to model if available
|
|
||||||
if (createdSetting->isAvailable()) {
|
|
||||||
insertQuickSettingToModel(metaData, createdSetting, emitInsertSignal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuickSettingsModel::insertQuickSettingToModel(KPluginMetaData metaData, QuickSetting *quickSetting, bool emitInsertSignal)
|
void QuickSettingsModel::insertQuickSettingToModel(KPluginMetaData metaData, QuickSetting *quickSetting, bool emitInsertSignal)
|
||||||
{
|
{
|
||||||
// Insert into correct position based on the saved quick settings order
|
// Insert into correct position based on the saved quick settings order
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@
|
||||||
#include "savedquicksettings.h"
|
#include "savedquicksettings.h"
|
||||||
#include "savedquicksettingsmodel.h"
|
#include "savedquicksettingsmodel.h"
|
||||||
|
|
||||||
|
#include <KPluginMetaData>
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QQmlComponent>
|
#include <QQmlComponent>
|
||||||
#include <QQmlListProperty>
|
#include <QQmlListProperty>
|
||||||
|
#include <qqmlregistration.h>
|
||||||
|
|
||||||
class QuickSettingsModel : public QAbstractListModel, public QQmlParserStatus
|
class QuickSettingsModel : public QAbstractListModel, public QQmlParserStatus
|
||||||
{
|
{
|
||||||
|
|
@ -44,8 +46,8 @@ private:
|
||||||
void loadQuickSetting(KPluginMetaData metaData, bool emitInsertSignal);
|
void loadQuickSetting(KPluginMetaData metaData, bool emitInsertSignal);
|
||||||
void removeQuickSetting(int index);
|
void removeQuickSetting(int index);
|
||||||
|
|
||||||
void afterQuickSettingLoad(QQmlEngine *engine, KPluginMetaData metaData, QQmlComponent *component, bool emitInsertSignal);
|
|
||||||
void insertQuickSettingToModel(KPluginMetaData metaData, QuickSetting *quickSetting, bool emitInsertSignal);
|
void insertQuickSettingToModel(KPluginMetaData metaData, QuickSetting *quickSetting, bool emitInsertSignal);
|
||||||
|
QuickSetting *loadQuickSettingComponent(KPluginMetaData metaData);
|
||||||
|
|
||||||
bool m_loaded{false};
|
bool m_loaded{false};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue