From ca8107ee48396b39599f1e766f8799c65c487b1b Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sun, 3 May 2026 09:53:25 -0500 Subject: fix portable rename + route external links through xdg-open scrubber MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #70: rename button was disabled for portable instances; the upstream restriction assumed portable = MO2-binary dir, which doesn't apply here (binary lives in ~/.local/share/fluorine/bin, instance dir is separate). Allow rename when not active, and update the portable registry so the renamed dir keeps showing up. Issue #67: QLabel::setOpenExternalLinks(true) and friends route through QDesktopServices::openUrl, which forks xdg-open with our bundled Qt env inherited — silently fails. Install a global url handler that defers to shell::Open, which already scrubs LD_LIBRARY_PATH/QT_PLUGIN_PATH. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/src/instancemanagerdialog.cpp | 14 +++++++++++--- src/src/moapplication.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/src/instancemanagerdialog.cpp b/src/src/instancemanagerdialog.cpp index b7a232e..f7b9bb1 100644 --- a/src/src/instancemanagerdialog.cpp +++ b/src/src/instancemanagerdialog.cpp @@ -518,7 +518,8 @@ void InstanceManagerDialog::rename() } // renaming - const QString src = i->directory(); + const QString src = i->directory(); + const bool wasPortable = i->isPortable(); const QString dest = QDir::toNativeSeparators(QFileInfo(src).dir().path() + "/" + newName); @@ -536,8 +537,15 @@ void InstanceManagerDialog::rename() return; } + // portable instances are tracked by absolute path in GlobalSettings; update + // the registry so the renamed dir keeps showing up in the list. + if (wasPortable) { + InstanceManager::unregisterPortableInstance(src); + InstanceManager::registerPortableInstance(dest); + } + // updating ui - auto newInstance = std::make_unique(dest, false); + auto newInstance = std::make_unique(dest, wasPortable); i = newInstance.get(); m_model->item(selIndex)->setText(newName); @@ -864,7 +872,7 @@ void InstanceManagerDialog::fillData(const Instance& ii) const auto& m = InstanceManager::singleton(); - ui->rename->setEnabled(!ii.isPortable()); + ui->rename->setEnabled(!ii.isActive()); if (ii.isPortable()) { ui->convertToPortable->setVisible(false); diff --git a/src/src/moapplication.cpp b/src/src/moapplication.cpp index aac387f..ce05b3a 100644 --- a/src/src/moapplication.cpp +++ b/src/src/moapplication.cpp @@ -41,6 +41,7 @@ along with Mod Organizer. If not, see . #include "thread_utils.h" #include "tutorialmanager.h" #include +#include #include #include #include @@ -48,6 +49,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -58,6 +60,19 @@ along with Mod Organizer. If not, see . using namespace MOBase; using namespace MOShared; +// Forward QDesktopServices::openUrl() (used by QLabel::setOpenExternalLinks +// and QTextBrowser auto-open) through shell::Open, which scrubs our bundled +// LD_LIBRARY_PATH / QT_PLUGIN_PATH before forking xdg-open. Without this the +// child inherits our runtime env and silently fails to launch a browser. +class UrlHandlerProxy : public QObject +{ + Q_OBJECT +public: + using QObject::QObject; +public slots: + void open(const QUrl& url) { MOBase::shell::Open(url); } +}; + // style proxy that changes the appearance of drop indicators // class ProxyStyle : public QProxyStyle @@ -225,6 +240,13 @@ MOApplication::MOApplication(int& argc, char** argv) : QApplication(argc, argv) // (Qt resource lookup, relative QFile paths, QtWebEngine sandbox helper) // behaves the same as a normal launch. Upstream PR #2379. QDir::setCurrent(QCoreApplication::applicationDirPath()); + + auto* urlProxy = new UrlHandlerProxy(this); + for (const auto& scheme : + {QStringLiteral("http"), QStringLiteral("https"), + QStringLiteral("file"), QStringLiteral("mailto")}) { + QDesktopServices::setUrlHandler(scheme, urlProxy, "open"); + } } OrganizerCore& MOApplication::core() @@ -956,3 +978,5 @@ QString MOSplash::getSplashPath(const Settings& settings, const QString& dataPat return splashPath; } + +#include "moapplication.moc" -- cgit v1.3.1