aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-05-13 21:33:41 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-05-13 21:33:41 -0500
commit7133cf6308fb5c1c156bae9f182a1dafcb11f715 (patch)
tree17732e68f7a647c88a3d007b294a535a2d788217
parentbe37c33b6657060232555d17386557145f3b6666 (diff)
nxm: stop launcher .desktop from claiming nxm:// + clear stale portal pick
The Fluorine Manager launcher .desktop declared MimeType=x-scheme-handler/nxm;x-scheme-handler/modl;, advertising itself as a handler alongside the real mo2-nxm-handler.desktop. The launcher's Exec line has no %u, so when xdg-desktop-portal launched it the URL was dropped and MO2 came up with no args — which then hit the "instance already running" path against the live primary. Drop the bad MimeType from both the tarball template (data/icons/) and the .bin installer's inline desktop entry in docker/build-inner.sh. That alone fixes new installs, but xdg-desktop-portal remembers user picks in its permission store: anyone who'd already selected Fluorine Manager in the chooser dialog had it stuck as their always-use app (count=3/3 = silent always-launch), and the bad pick survived removing the MimeType. On startup the nxm handler now fires a DBus DeletePermission against PermissionStore for com.fluorine.manager on both schemes, so existing users self-heal on the next launch. The call is fire-and-forget — a missing entry is the expected steady state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
-rw-r--r--data/icons/com.fluorine.manager.desktop1
-rwxr-xr-xdocker/build-inner.sh1
-rw-r--r--src/src/CMakeLists.txt3
-rw-r--r--src/src/nxmhandler_linux.cpp26
4 files changed, 28 insertions, 3 deletions
diff --git a/data/icons/com.fluorine.manager.desktop b/data/icons/com.fluorine.manager.desktop
index 5d85cf8..fbe4d30 100644
--- a/data/icons/com.fluorine.manager.desktop
+++ b/data/icons/com.fluorine.manager.desktop
@@ -8,7 +8,6 @@ Icon=com.fluorine.manager
Terminal=false
Categories=Game;Utility;
Keywords=mod;organizer;modding;skyrim;fallout;
-MimeType=x-scheme-handler/nxm;x-scheme-handler/modl;
Actions=create-portable;list-instances;
[Desktop Action create-portable]
diff --git a/docker/build-inner.sh b/docker/build-inner.sh
index 8a4f9cb..cd6c3e1 100755
--- a/docker/build-inner.sh
+++ b/docker/build-inner.sh
@@ -618,7 +618,6 @@ Icon=com.fluorine.manager
Terminal=false
Categories=Game;Utility;
StartupWMClass=ModOrganizer
-MimeType=x-scheme-handler/nxm;x-scheme-handler/nxm-hierarchical;
DESKTOP_EOF
chmod +x "${DESKTOP_DIR}/com.fluorine.manager.desktop"
diff --git a/src/src/CMakeLists.txt b/src/src/CMakeLists.txt
index ef9f696..ed43c8f 100644
--- a/src/src/CMakeLists.txt
+++ b/src/src/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
find_package(Qt6 REQUIRED COMPONENTS
- Widgets WebSockets Network NetworkAuth Concurrent)
+ Widgets WebSockets Network NetworkAuth Concurrent DBus)
option(MO2_ENABLE_WEBENGINE "Build optional Qt WebEngine browser support" OFF)
if(MO2_ENABLE_WEBENGINE)
find_package(Qt6 QUIET COMPONENTS WebEngineWidgets)
@@ -190,6 +190,7 @@ target_link_libraries(organizer PRIVATE
Qt6::WebSockets
Qt6::Network
Qt6::NetworkAuth
+ Qt6::DBus
# Boost
Boost::program_options
# spdlog
diff --git a/src/src/nxmhandler_linux.cpp b/src/src/nxmhandler_linux.cpp
index 7b70ff4..aaf942e 100644
--- a/src/src/nxmhandler_linux.cpp
+++ b/src/src/nxmhandler_linux.cpp
@@ -4,6 +4,8 @@
#include <log.h>
#include <QCoreApplication>
+#include <QDBusConnection>
+#include <QDBusMessage>
#include <QDir>
#include <QFile>
#include <QFileInfo>
@@ -39,6 +41,27 @@ bool writeTextFile(const QString& path, const QString& content)
return stream.status() == QTextStream::Ok;
}
+// xdg-desktop-portal remembers chooser picks in its permission store. An
+// earlier build registered both com.fluorine.manager.desktop and
+// mo2-nxm-handler.desktop for nxm:// — anyone who picked Fluorine Manager
+// from the chooser had it persisted as their always-use app, which kept
+// routing nxm:// to the wrong handler (full MO2 launch with no URL) even
+// after the bad MimeType was removed. Strip the stale com.fluorine.manager
+// entry so existing users self-heal on next launch.
+void clearStalePortalChoice(const QString& mimeType)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall(
+ "org.freedesktop.impl.portal.PermissionStore",
+ "/org/freedesktop/impl/portal/PermissionStore",
+ "org.freedesktop.impl.portal.PermissionStore", "DeletePermission");
+ msg << QStringLiteral("desktop-used-apps") << mimeType
+ << QStringLiteral("com.fluorine.manager");
+
+ // Fire-and-forget on the session bus. The reply is uninteresting: a missing
+ // entry returns an error and we don't want to log on every clean startup.
+ QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
+}
+
void updateMimeAppsList(const QString& path, const QString& mimeType,
const QString& desktopFile)
{
@@ -245,6 +268,9 @@ void NxmHandlerLinux::registerHandler()
if (result != 0) {
log::warn("update-desktop-database exited with code {}", result);
}
+
+ clearStalePortalChoice("x-scheme-handler/nxm");
+ clearStalePortalChoice("x-scheme-handler/modl");
}
bool NxmHandlerLinux::startListener()