forked from quickshell/quickshell
root: recreate the qml engine on reload instead of clearing it
This causes singletons to be recreated instead of kept alive.
This commit is contained in:
parent
9f6ef37f61
commit
463f9a297f
|
@ -70,21 +70,26 @@ file(GENERATE
|
|||
CONTENT ""
|
||||
)
|
||||
|
||||
add_library(qt-pch ${CMAKE_CURRENT_BINARY_DIR}/pchstub.cpp)
|
||||
target_link_libraries(qt-pch PRIVATE ${QT_DEPS})
|
||||
target_precompile_headers(qt-pch PUBLIC
|
||||
<memory>
|
||||
<qobject.h>
|
||||
<qqmlengine.h>
|
||||
<qlist.h>
|
||||
<qcolor.h>
|
||||
<qquickitem.h>
|
||||
<qevent.h>
|
||||
)
|
||||
# pch breaks clang-tidy..... somehow
|
||||
if (NOT NO_PCH)
|
||||
add_library(qt-pch ${CMAKE_CURRENT_BINARY_DIR}/pchstub.cpp)
|
||||
target_link_libraries(qt-pch PRIVATE ${QT_DEPS})
|
||||
target_precompile_headers(qt-pch PUBLIC
|
||||
<memory>
|
||||
<qobject.h>
|
||||
<qqmlengine.h>
|
||||
<qlist.h>
|
||||
<qcolor.h>
|
||||
<qquickitem.h>
|
||||
<qevent.h>
|
||||
)
|
||||
endif()
|
||||
|
||||
function (qs_pch target)
|
||||
target_precompile_headers(${target} REUSE_FROM qt-pch)
|
||||
target_link_libraries(${target} PRIVATE ${QT_DEPS}) # required for gcc to accept the pch on plugin targets
|
||||
if (NOT NO_PCH)
|
||||
target_precompile_headers(${target} REUSE_FROM qt-pch)
|
||||
target_link_libraries(${target} PRIVATE ${QT_DEPS}) # required for gcc to accept the pch on plugin targets
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "main.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <qcommandlineoption.h>
|
||||
|
|
|
@ -57,38 +57,81 @@ void QuickshellSettings::setWatchFiles(bool watchFiles) {
|
|||
emit this->watchFilesChanged();
|
||||
}
|
||||
|
||||
QuickshellGlobal::QuickshellGlobal(QObject* parent): QObject(parent) {
|
||||
// clang-format off
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::workingDirectoryChanged, this, &QuickshellGlobal::workingDirectoryChanged);
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &QuickshellGlobal::watchFilesChanged);
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::lastWindowClosed, this, &QuickshellGlobal::lastWindowClosed);
|
||||
// clang-format on
|
||||
|
||||
QuickshellTracked::QuickshellTracked() {
|
||||
auto* app = QCoreApplication::instance();
|
||||
auto* guiApp = qobject_cast<QGuiApplication*>(app);
|
||||
|
||||
if (guiApp != nullptr) {
|
||||
// clang-format off
|
||||
QObject::connect(guiApp, &QGuiApplication::primaryScreenChanged, this, &QuickshellGlobal::updateScreens);
|
||||
QObject::connect(guiApp, &QGuiApplication::screenAdded, this, &QuickshellGlobal::updateScreens);
|
||||
QObject::connect(guiApp, &QGuiApplication::screenRemoved, this, &QuickshellGlobal::updateScreens);
|
||||
QObject::connect(guiApp, &QGuiApplication::primaryScreenChanged, this, &QuickshellTracked::updateScreens);
|
||||
QObject::connect(guiApp, &QGuiApplication::screenAdded, this, &QuickshellTracked::updateScreens);
|
||||
QObject::connect(guiApp, &QGuiApplication::screenRemoved, this, &QuickshellTracked::updateScreens);
|
||||
// clang-format on
|
||||
|
||||
this->updateScreens();
|
||||
}
|
||||
}
|
||||
|
||||
QuickshellTracked* QuickshellTracked::instance() {
|
||||
static QuickshellTracked* instance = nullptr; // NOLINT
|
||||
if (instance == nullptr) {
|
||||
QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership);
|
||||
instance = new QuickshellTracked();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void QuickshellTracked::updateScreens() {
|
||||
auto screens = QGuiApplication::screens();
|
||||
auto newScreens = QList<QuickshellScreenInfo*>();
|
||||
|
||||
for (auto* newScreen: screens) {
|
||||
for (auto i = 0; i < this->screens.length(); i++) {
|
||||
auto* oldScreen = this->screens[i];
|
||||
if (newScreen == oldScreen->screen) {
|
||||
newScreens.push_back(oldScreen);
|
||||
this->screens.remove(i);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto* si = new QuickshellScreenInfo(this, newScreen);
|
||||
QQmlEngine::setObjectOwnership(si, QQmlEngine::CppOwnership);
|
||||
newScreens.push_back(si);
|
||||
}
|
||||
next:;
|
||||
}
|
||||
|
||||
for (auto* oldScreen: this->screens) {
|
||||
oldScreen->deleteLater();
|
||||
}
|
||||
|
||||
this->screens = newScreens;
|
||||
emit this->screensChanged();
|
||||
}
|
||||
|
||||
QuickshellGlobal::QuickshellGlobal(QObject* parent): QObject(parent) {
|
||||
// clang-format off
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::workingDirectoryChanged, this, &QuickshellGlobal::workingDirectoryChanged);
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &QuickshellGlobal::watchFilesChanged);
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::lastWindowClosed, this, &QuickshellGlobal::lastWindowClosed);
|
||||
|
||||
QObject::connect(QuickshellTracked::instance(), &QuickshellTracked::screensChanged, this, &QuickshellGlobal::screensChanged);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
qint32 QuickshellGlobal::processId() const { // NOLINT
|
||||
return getpid();
|
||||
}
|
||||
|
||||
qsizetype QuickshellGlobal::screensCount(QQmlListProperty<QuickshellScreenInfo>* prop) {
|
||||
return static_cast<QuickshellGlobal*>(prop->object)->mScreens.size(); // NOLINT
|
||||
qsizetype QuickshellGlobal::screensCount(QQmlListProperty<QuickshellScreenInfo>* /*unused*/) {
|
||||
return QuickshellTracked::instance()->screens.size();
|
||||
}
|
||||
|
||||
QuickshellScreenInfo*
|
||||
QuickshellGlobal::screenAt(QQmlListProperty<QuickshellScreenInfo>* prop, qsizetype i) {
|
||||
return static_cast<QuickshellGlobal*>(prop->object)->mScreens.at(i); // NOLINT
|
||||
QuickshellGlobal::screenAt(QQmlListProperty<QuickshellScreenInfo>* /*unused*/, qsizetype i) {
|
||||
return QuickshellTracked::instance()->screens.at(i);
|
||||
}
|
||||
|
||||
QQmlListProperty<QuickshellScreenInfo> QuickshellGlobal::screens() {
|
||||
|
@ -128,36 +171,6 @@ void QuickshellGlobal::setWatchFiles(bool watchFiles) { // NOLINT
|
|||
QuickshellSettings::instance()->setWatchFiles(watchFiles);
|
||||
}
|
||||
|
||||
void QuickshellGlobal::updateScreens() {
|
||||
auto screens = QGuiApplication::screens();
|
||||
auto newScreens = QList<QuickshellScreenInfo*>();
|
||||
|
||||
for (auto* newScreen: screens) {
|
||||
for (auto i = 0; i < this->mScreens.length(); i++) {
|
||||
auto* oldScreen = this->mScreens[i];
|
||||
if (newScreen == oldScreen->screen) {
|
||||
newScreens.push_back(oldScreen);
|
||||
this->mScreens.remove(i);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto* si = new QuickshellScreenInfo(this, newScreen);
|
||||
QQmlEngine::setObjectOwnership(si, QQmlEngine::CppOwnership);
|
||||
newScreens.push_back(si);
|
||||
}
|
||||
next:;
|
||||
}
|
||||
|
||||
for (auto* oldScreen: this->mScreens) {
|
||||
oldScreen->deleteLater();
|
||||
}
|
||||
|
||||
this->mScreens = newScreens;
|
||||
emit this->screensChanged();
|
||||
}
|
||||
|
||||
QVariant QuickshellGlobal::env(const QString& variable) { // NOLINT
|
||||
auto vstr = variable.toStdString();
|
||||
if (!qEnvironmentVariableIsSet(vstr.data())) return QVariant::fromValue(nullptr);
|
||||
|
|
|
@ -53,6 +53,23 @@ private:
|
|||
bool mWatchFiles = true;
|
||||
};
|
||||
|
||||
class QuickshellTracked: public QObject {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
QuickshellTracked();
|
||||
|
||||
QVector<QuickshellScreenInfo*> screens;
|
||||
|
||||
static QuickshellTracked* instance();
|
||||
|
||||
private slots:
|
||||
void updateScreens();
|
||||
|
||||
signals:
|
||||
void screensChanged();
|
||||
};
|
||||
|
||||
class QuickshellGlobal: public QObject {
|
||||
Q_OBJECT;
|
||||
// clang-format off
|
||||
|
@ -124,12 +141,7 @@ signals:
|
|||
void workingDirectoryChanged();
|
||||
void watchFilesChanged();
|
||||
|
||||
public slots:
|
||||
void updateScreens();
|
||||
|
||||
private:
|
||||
static qsizetype screensCount(QQmlListProperty<QuickshellScreenInfo>* prop);
|
||||
static QuickshellScreenInfo* screenAt(QQmlListProperty<QuickshellScreenInfo>* prop, qsizetype i);
|
||||
|
||||
QVector<QuickshellScreenInfo*> mScreens;
|
||||
};
|
||||
|
|
|
@ -21,12 +21,7 @@
|
|||
RootWrapper::RootWrapper(QString rootPath)
|
||||
: QObject(nullptr)
|
||||
, rootPath(std::move(rootPath))
|
||||
, engine(this)
|
||||
, originalWorkingDirectory(QDir::current().absolutePath()) {
|
||||
auto* app = QCoreApplication::instance();
|
||||
QObject::connect(&this->engine, &QQmlEngine::quit, app, &QCoreApplication::quit);
|
||||
QObject::connect(&this->engine, &QQmlEngine::exit, app, &QCoreApplication::exit);
|
||||
|
||||
// clang-format off
|
||||
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &RootWrapper::onWatchFilesChanged);
|
||||
// clang-format on
|
||||
|
@ -45,16 +40,22 @@ RootWrapper::~RootWrapper() {
|
|||
}
|
||||
|
||||
void RootWrapper::reloadGraph(bool hard) {
|
||||
auto* oldEngine = this->engine;
|
||||
this->engine = new QQmlEngine(this);
|
||||
|
||||
auto* app = QCoreApplication::instance();
|
||||
QObject::connect(this->engine, &QQmlEngine::quit, app, &QCoreApplication::quit);
|
||||
QObject::connect(this->engine, &QQmlEngine::exit, app, &QCoreApplication::exit);
|
||||
|
||||
if (this->root != nullptr) {
|
||||
QuickshellSettings::reset();
|
||||
this->engine.clearComponentCache();
|
||||
}
|
||||
|
||||
QDir::setCurrent(this->originalWorkingDirectory);
|
||||
|
||||
auto component = QQmlComponent(&this->engine, QUrl::fromLocalFile(this->rootPath));
|
||||
auto component = QQmlComponent(this->engine, QUrl::fromLocalFile(this->rootPath));
|
||||
|
||||
auto* obj = component.beginCreate(this->engine.rootContext());
|
||||
auto* obj = component.beginCreate(this->engine->rootContext());
|
||||
|
||||
if (obj == nullptr) {
|
||||
qWarning() << component.errorString().toStdString().c_str();
|
||||
|
@ -90,6 +91,8 @@ void RootWrapper::reloadGraph(bool hard) {
|
|||
QuickshellPlugin::runOnReload();
|
||||
}
|
||||
|
||||
delete oldEngine;
|
||||
|
||||
this->onWatchFilesChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ private slots:
|
|||
|
||||
private:
|
||||
QString rootPath;
|
||||
QQmlEngine engine;
|
||||
QQmlEngine* engine = nullptr;
|
||||
ShellRoot* root = nullptr;
|
||||
FiletreeWatcher* configWatcher = nullptr;
|
||||
QString originalWorkingDirectory;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include "core/main.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
return qs_main(argc, argv);
|
||||
}
|
||||
int main(int argc, char** argv) { return qs_main(argc, argv); }
|
||||
|
|
|
@ -78,7 +78,8 @@ void WlSessionLock::updateSurfaces(WlSessionLock* old) {
|
|||
auto* instance = qobject_cast<WlSessionLockSurface*>(instanceObj);
|
||||
|
||||
if (instance == nullptr) {
|
||||
qWarning() << "WlSessionLock.surface does not create a WlSessionLockSurface. Aborting lock.";
|
||||
qWarning(
|
||||
) << "WlSessionLock.surface does not create a WlSessionLockSurface. Aborting lock.";
|
||||
if (instanceObj != nullptr) instanceObj->deleteLater();
|
||||
this->unlock();
|
||||
return;
|
||||
|
|
|
@ -26,7 +26,7 @@ enum Enum {
|
|||
};
|
||||
Q_ENUM_NS(Enum);
|
||||
|
||||
} // namespace Layer
|
||||
} // namespace WlrLayer
|
||||
|
||||
///! WlrLayershell keyboard focus mode
|
||||
namespace WlrKeyboardFocus { // NOLINT
|
||||
|
@ -47,7 +47,7 @@ enum Enum {
|
|||
};
|
||||
Q_ENUM_NS(Enum);
|
||||
|
||||
} // namespace KeyboardFocus
|
||||
} // namespace WlrKeyboardFocus
|
||||
|
||||
class QSWaylandLayerSurface;
|
||||
|
||||
|
|
Loading…
Reference in a new issue