core/reloader: add reload signals for visual notifications

This commit is contained in:
outfoxxed 2024-05-30 02:39:37 -07:00
parent 569c40494d
commit 7feae55ebe
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
5 changed files with 48 additions and 6 deletions

View file

@ -265,12 +265,16 @@ void EngineGeneration::assignIncubationController() {
this->engine->setIncubationController(controller); this->engine->setIncubationController(controller);
} }
EngineGeneration* EngineGeneration::findEngineGeneration(QQmlEngine* engine) {
return g_generations.value(engine);
}
EngineGeneration* EngineGeneration::findObjectGeneration(QObject* object) { EngineGeneration* EngineGeneration::findObjectGeneration(QObject* object) {
while (object != nullptr) { while (object != nullptr) {
auto* context = QQmlEngine::contextForObject(object); auto* context = QQmlEngine::contextForObject(object);
if (context != nullptr) { if (context != nullptr) {
if (auto* generation = g_generations.value(context->engine())) { if (auto* generation = EngineGeneration::findEngineGeneration(context->engine())) {
return generation; return generation;
} }
} }

View file

@ -5,6 +5,7 @@
#include <qfilesystemwatcher.h> #include <qfilesystemwatcher.h>
#include <qobject.h> #include <qobject.h>
#include <qpair.h> #include <qpair.h>
#include <qqmlengine.h>
#include <qqmlincubator.h> #include <qqmlincubator.h>
#include <qtclasshelpermacros.h> #include <qtclasshelpermacros.h>
@ -15,6 +16,7 @@
#include "singleton.hpp" #include "singleton.hpp"
class RootWrapper; class RootWrapper;
class QuickshellGlobal;
class EngineGeneration: public QObject { class EngineGeneration: public QObject {
Q_OBJECT; Q_OBJECT;
@ -31,6 +33,7 @@ public:
void registerIncubationController(QQmlIncubationController* controller); void registerIncubationController(QQmlIncubationController* controller);
void deregisterIncubationController(QQmlIncubationController* controller); void deregisterIncubationController(QQmlIncubationController* controller);
static EngineGeneration* findEngineGeneration(QQmlEngine* engine);
static EngineGeneration* findObjectGeneration(QObject* object); static EngineGeneration* findObjectGeneration(QObject* object);
RootWrapper* wrapper = nullptr; RootWrapper* wrapper = nullptr;
@ -45,6 +48,7 @@ public:
QVector<QString> deletedWatchedFiles; QVector<QString> deletedWatchedFiles;
DelayedQmlIncubationController delayedIncubationController; DelayedQmlIncubationController delayedIncubationController;
bool reloadComplete = false; bool reloadComplete = false;
QuickshellGlobal* qsgInstance = nullptr;
void destroy(); void destroy();

View file

@ -187,3 +187,14 @@ QVariant QuickshellGlobal::env(const QString& variable) { // NOLINT
return qEnvironmentVariable(vstr.data()); return qEnvironmentVariable(vstr.data());
} }
QuickshellGlobal* QuickshellGlobal::create(QQmlEngine* engine, QJSEngine* /*unused*/) {
auto* qsg = new QuickshellGlobal();
auto* generation = EngineGeneration::findEngineGeneration(engine);
if (generation->qsgInstance == nullptr) {
generation->qsgInstance = qsg;
}
return qsg;
}

View file

@ -110,8 +110,6 @@ class QuickshellGlobal: public QObject {
public: public:
[[nodiscard]] qint32 processId() const; [[nodiscard]] qint32 processId() const;
QuickshellGlobal(QObject* parent = nullptr);
QQmlListProperty<QuickshellScreenInfo> screens(); QQmlListProperty<QuickshellScreenInfo> screens();
/// Reload the shell from the [ShellRoot]. /// Reload the shell from the [ShellRoot].
@ -133,17 +131,25 @@ public:
[[nodiscard]] bool watchFiles() const; [[nodiscard]] bool watchFiles() const;
void setWatchFiles(bool watchFiles); void setWatchFiles(bool watchFiles);
static QuickshellGlobal* create(QQmlEngine* engine, QJSEngine* /*unused*/);
signals: signals:
/// Sent when the last window is closed. /// Sent when the last window is closed.
/// ///
/// To make the application exit when the last window is closed run `Qt.quit()`. /// To make the application exit when the last window is closed run `Qt.quit()`.
void lastWindowClosed(); void lastWindowClosed();
/// The reload sequence has completed successfully.
void reloadCompleted();
/// The reload sequence has failed.
void reloadFailed(QString errorString);
void screensChanged(); void screensChanged();
void workingDirectoryChanged(); void workingDirectoryChanged();
void watchFilesChanged(); void watchFilesChanged();
private: private:
QuickshellGlobal(QObject* parent = nullptr);
static qsizetype screensCount(QQmlListProperty<QuickshellScreenInfo>* prop); static qsizetype screensCount(QQmlListProperty<QuickshellScreenInfo>* prop);
static QuickshellScreenInfo* screenAt(QQmlListProperty<QuickshellScreenInfo>* prop, qsizetype i); static QuickshellScreenInfo* screenAt(QQmlListProperty<QuickshellScreenInfo>* prop, qsizetype i);
}; };

View file

@ -8,6 +8,7 @@
#include <qobject.h> #include <qobject.h>
#include <qqmlcomponent.h> #include <qqmlcomponent.h>
#include <qqmlengine.h> #include <qqmlengine.h>
#include <qtmetamacros.h>
#include <qurl.h> #include <qurl.h>
#include "generation.hpp" #include "generation.hpp"
@ -64,17 +65,28 @@ void RootWrapper::reloadGraph(bool hard) {
auto* obj = component.beginCreate(generation->engine->rootContext()); auto* obj = component.beginCreate(generation->engine->rootContext());
if (obj == nullptr) { if (obj == nullptr) {
qWarning() << component.errorString().toStdString().c_str(); QString error = "failed to create root component\n" + component.errorString();
qWarning() << "failed to create root component"; qWarning().noquote() << error;
delete generation; delete generation;
if (this->generation != nullptr && this->generation->qsgInstance != nullptr) {
emit this->generation->qsgInstance->reloadFailed(error);
}
return; return;
} }
auto* newRoot = qobject_cast<ShellRoot*>(obj); auto* newRoot = qobject_cast<ShellRoot*>(obj);
if (newRoot == nullptr) { if (newRoot == nullptr) {
qWarning() << "root component was not a Quickshell.ShellRoot"; QString error = "root component was not a Quickshell.ShellRoot";
qWarning().noquote() << error;
delete obj; delete obj;
delete generation; delete generation;
if (this->generation != nullptr && this->generation->qsgInstance != nullptr) {
emit this->generation->qsgInstance->reloadFailed(error);
}
return; return;
} }
@ -82,6 +94,7 @@ void RootWrapper::reloadGraph(bool hard) {
component.completeCreate(); component.completeCreate();
auto isReload = this->generation != nullptr;
generation->onReload(hard ? nullptr : this->generation); generation->onReload(hard ? nullptr : this->generation);
if (hard) delete this->generation; if (hard) delete this->generation;
this->generation = generation; this->generation = generation;
@ -96,6 +109,10 @@ void RootWrapper::reloadGraph(bool hard) {
); );
this->onWatchFilesChanged(); this->onWatchFilesChanged();
if (isReload && this->generation->qsgInstance != nullptr) {
emit this->generation->qsgInstance->reloadCompleted();
}
} }
void RootWrapper::onWatchFilesChanged() { void RootWrapper::onWatchFilesChanged() {