Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package vermouth for openSUSE:Factory checked in at 2026-04-20 16:11:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/vermouth (Old) and /work/SRC/openSUSE:Factory/.vermouth.new.11940 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "vermouth" Mon Apr 20 16:11:45 2026 rev:2 rq:1348068 version:1.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/vermouth/vermouth.changes 2026-04-17 21:25:35.874516807 +0200 +++ /work/SRC/openSUSE:Factory/.vermouth.new.11940/vermouth.changes 2026-04-20 16:12:00.758920118 +0200 @@ -1,0 +2,14 @@ +Sun Apr 19 19:23:00 UTC 2026 - Jehu Marcos Herrera Puentes <[email protected]> + +- Bump to version 1.3.2 +- Upstream changes: + * UMU prefix fixes and single instance + * Add discord badge + * Updated the README, changed screenshots + +------------------------------------------------------------------- +Fri Apr 17 20:16:31 UTC 2026 - Jehu Marcos Herrera Puentes <[email protected]> + +- Added proper checks for .desktop files + +------------------------------------------------------------------- Old: ---- vermouth-1.3.1.tar.xz New: ---- vermouth-1.3.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ vermouth.spec ++++++ --- /var/tmp/diff_new_pack.jJhcjc/_old 2026-04-20 16:12:02.871007081 +0200 +++ /var/tmp/diff_new_pack.jJhcjc/_new 2026-04-20 16:12:02.899008234 +0200 @@ -17,7 +17,7 @@ Name: vermouth -Version: 1.3.1 +Version: 1.3.2 Release: 0 Summary: A Wine/Proton game launcher for KDE License: MIT @@ -36,6 +36,7 @@ BuildRequires: cmake >= 3.20 BuildRequires: extra-cmake-modules >= 6.0.0 BuildRequires: fdupes +BuildRequires: desktop-file-utils BuildRequires: cmake(KF6CoreAddons) >= 6.0.0 BuildRequires: cmake(KF6I18n) >= 6.0.0 BuildRequires: cmake(KF6Kirigami) >= 6.0.0 @@ -89,6 +90,8 @@ %fdupes %{buildroot}%{_datadir} %check +# Checks for desktop files and appstream metadata +desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop appstreamcli validate --no-net %{buildroot}%{_datadir}/metainfo/*.xml %files ++++++ _service ++++++ --- /var/tmp/diff_new_pack.jJhcjc/_old 2026-04-20 16:12:03.147018446 +0200 +++ /var/tmp/diff_new_pack.jJhcjc/_new 2026-04-20 16:12:03.191020257 +0200 @@ -3,7 +3,7 @@ <service name="tar_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/dekomote/vermouth.git</param> - <param name="revision">v1.3.1</param> + <param name="revision">v1.3.2</param> <param name="match-tag">v[0-9]*</param> <param name="filename">vermouth</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.jJhcjc/_old 2026-04-20 16:12:03.399028822 +0200 +++ /var/tmp/diff_new_pack.jJhcjc/_new 2026-04-20 16:12:03.451030963 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/dekomote/vermouth.git</param> - <param name="changesrevision">935ab694570cbde362e4fd6d4cf3812ed6bc7c88</param></service></servicedata> + <param name="changesrevision">a71963b74a4b0f7a23745263633e845eef816b36</param></service></servicedata> (No newline at EOF) ++++++ vermouth-1.3.1.tar.xz -> vermouth-1.3.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/CMakeLists.txt new/vermouth-1.3.2/CMakeLists.txt --- old/vermouth-1.3.1/CMakeLists.txt 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/CMakeLists.txt 2026-04-19 13:13:48.000000000 +0200 @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.20) -project(vermouth VERSION 1.3.1 LANGUAGES CXX) +project(vermouth VERSION 1.3.2 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -46,6 +46,7 @@ src/settingsmanager.cpp src/protondownloader.cpp src/umudownloader.cpp + src/singleinstance.cpp resources.qrc ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/README.md new/vermouth-1.3.2/README.md --- old/vermouth-1.3.1/README.md 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/README.md 2026-04-19 13:13:48.000000000 +0200 @@ -3,6 +3,7 @@ [](https://github.com/dekomote/vermouth/actions/workflows/build-rpm.yml) [](https://github.com/dekomote/vermouth/actions/workflows/build-flatpak.yml) [](https://github.com/dekomote/vermouth/actions/workflows/build-arch.yml) +[](https://discord.gg/RmppukhVYq) <p align="center"> @@ -15,10 +16,10 @@ Point it at Windows executables and run them with Proton or Wine.</p> <p align="center"> - <img src="assets/screen1.png?t=1.0" alt="Vermouth screenshot" width="400"> - <img src="assets/screen2.png?t=1.0" alt="Vermouth screenshot" width="400"><br> - <img src="assets/screen3.png?t=1.0" alt="Vermouth screenshot" width="400"> - <img src="assets/screen4.png?t=1.0" alt="Vermouth screenshot" width="400"> + <img src="assets/screen1.png?t=1.3" alt="Vermouth screenshot" width="400"> + <img src="assets/screen2.png?t=1.3" alt="Vermouth screenshot" width="400"><br> + <img src="assets/screen3.png?t=1.3" alt="Vermouth screenshot" width="400"> + <img src="assets/screen4.png?t=1.3" alt="Vermouth screenshot" width="400"> </p> ## What it does @@ -51,15 +52,10 @@ ## Installing -Download the latest package from the [releases page](https://github.com/dekomote/vermouth/releases/latest). ### Fedora and Nobara -```bash -sudo dnf install ./vermouth-*.rpm -``` - -Vermouth is also available on [COPR](https://copr.fedorainfracloud.org/coprs/dekomote/vermouth/): +Vermouth is available on [COPR](https://copr.fedorainfracloud.org/coprs/dekomote/vermouth/): ```bash sudo dnf copr enable dekomote/vermouth @@ -73,6 +69,12 @@ sudo rpm-ostree -y install vermouth ``` +Also, you can download the latest package from the [releases page](https://github.com/dekomote/vermouth/releases/latest). + +```bash +sudo dnf install ./vermouth-*.rpm +``` + ### OpenSUSE Tumbleweed Install via COPR: @@ -91,6 +93,7 @@ ### Ubuntu / Debian Requires Ubuntu 25.04 / Debian Trixie or newer (Qt 6.8+ and KF6 are required). +Download the latest deb package from the [releases page](https://github.com/dekomote/vermouth/releases/latest). ```bash sudo apt install ./vermouth-*.deb @@ -118,21 +121,17 @@ ### Flatpak -```bash -flatpak install ./vermouth-*.flatpak -``` - -Or install from Flathub (once available): +Download the latest flatpak package from the [releases page](https://github.com/dekomote/vermouth/releases/latest). ```bash -flatpak install flathub com.dekomote.vermouth +flatpak install ./vermouth-*.flatpak ``` See [FLATPAK NOTES](#flatpak-notes) for filesystem permissions required to access your games and Steam installation. ### AppImage -Download `Vermouth-*.AppImage`, make it executable and run it: +Download `Vermouth-*.AppImage` from the [releases page](https://github.com/dekomote/vermouth/releases/latest), make it executable and run it: ```bash chmod +x Vermouth-*.AppImage @@ -143,7 +142,6 @@ For icon extraction from .exe files, install `icoutils` (provides `wrestool` and `icotool`). -I have limited testing capabilities at the moment, so please report any bugs you find. ## Building from source @@ -177,6 +175,10 @@ ./build/bin/vermouth ``` +## Bug reporting and feature requests + +Please use the [issue tracker](https://github.com/dekomote/vermouth/issues) for bug reports and feature requests. + ## How to use it Open the app, click **Add App/Game**, browse for the .exe file, choose a Proton version from the dropdown (click **Download GE Proton** if you don't have any), and launch from the grid. Binary files old/vermouth-1.3.1/assets/screen1.png and new/vermouth-1.3.2/assets/screen1.png differ Binary files old/vermouth-1.3.1/assets/screen2.png and new/vermouth-1.3.2/assets/screen2.png differ Binary files old/vermouth-1.3.1/assets/screen3.png and new/vermouth-1.3.2/assets/screen3.png differ Binary files old/vermouth-1.3.1/assets/screen4.png and new/vermouth-1.3.2/assets/screen4.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/com.dekomote.vermouth.flathub.yml new/vermouth-1.3.2/com.dekomote.vermouth.flathub.yml --- old/vermouth-1.3.1/com.dekomote.vermouth.flathub.yml 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/com.dekomote.vermouth.flathub.yml 2026-04-19 13:13:48.000000000 +0200 @@ -20,4 +20,4 @@ sources: - type: git url: https://github.com/dekomote/vermouth.git - tag: v1.3.1 + tag: v1.3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/packaging/.SRCINFO new/vermouth-1.3.2/packaging/.SRCINFO --- old/vermouth-1.3.1/packaging/.SRCINFO 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/packaging/.SRCINFO 2026-04-19 13:13:48.000000000 +0200 @@ -1,6 +1,6 @@ pkgbase = vermouth pkgdesc = A no-frills Wine/Proton game launcher for Linux - pkgver = 1.2.1 + pkgver = 1.3.1 pkgrel = 1 url = https://github.com/dekomote/vermouth arch = x86_64 @@ -15,7 +15,7 @@ depends = kcoreaddons depends = qqc2-desktop-style optdepends = icoutils: Windows icon extraction - source = vermouth-1.2.1.tar.gz::https://github.com/dekomote/vermouth/archive/refs/tags/v1.2.1.tar.gz - sha256sums = c0f5e05018c9cbe86350e3334a385f14eef5a05845158fe4f1e33b73d739633a + source = vermouth-1.3.1.tar.gz::https://github.com/dekomote/vermouth/archive/refs/tags/v1.3.1.tar.gz + sha256sums = e6cb0ee4616d6c7485d5fb73f6c1f25b7563747bcd731be045c148391b51a730 pkgname = vermouth diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/packaging/PKGBUILD new/vermouth-1.3.2/packaging/PKGBUILD --- old/vermouth-1.3.1/packaging/PKGBUILD 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/packaging/PKGBUILD 2026-04-19 13:13:48.000000000 +0200 @@ -1,6 +1,6 @@ # Maintainer: Dejan Noveski <[email protected]> pkgname=vermouth -pkgver=1.3.1 +pkgver=1.3.2 pkgrel=1 pkgdesc="A no-frills Wine/Proton game launcher for Linux" arch=('x86_64') @@ -21,7 +21,7 @@ ) optdepends=('icoutils: Windows icon extraction') source=("${pkgname}-${pkgver}.tar.gz::https://github.com/dekomote/vermouth/archive/refs/tags/v${pkgver}.tar.gz") -sha256sums=('c0f5e05018c9cbe86350e3334a385f14eef5a05845158fe4f1e33b73d739633a') +sha256sums=('e6cb0ee4616d6c7485d5fb73f6c1f25b7563747bcd731be045c148391b51a730') build() { cd "${pkgname}-${pkgver}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/packaging/vermouth.spec new/vermouth-1.3.2/packaging/vermouth.spec --- old/vermouth-1.3.1/packaging/vermouth.spec 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/packaging/vermouth.spec 2026-04-19 13:13:48.000000000 +0200 @@ -1,5 +1,5 @@ Name: vermouth -Version: 1.3.1 +Version: 1.3.2 Release: 1%{?dist} Summary: A no-frills Wine/Proton game launcher for KDE License: MIT @@ -69,6 +69,8 @@ %{_datadir}/metainfo/com.dekomote.vermouth.metainfo.xml %changelog +* Fri Apr 17 2026 Dejan Noveski <[email protected]> - 1.3.2-1 +- UMU prefix fixed, added single instance support * Fri Apr 17 2026 Dejan Noveski <[email protected]> - 1.3.1-1 - Update to 1.3.1 - HDR and UMU * Tue Apr 14 2026 Dejan Noveski <[email protected]> - 1.2.1-1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/qml/AddAppDialog.qml new/vermouth-1.3.2/qml/AddAppDialog.qml --- old/vermouth-1.3.1/qml/AddAppDialog.qml 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/qml/AddAppDialog.qml 2026-04-19 13:13:48.000000000 +0200 @@ -49,6 +49,31 @@ dialog.open(); } + function applyExePath(path) { + exeField.text = path; + if (iconField.text === "") { + var extracted = iconExtractor.extractIcon(path); + if (extracted !== "") + iconField.text = extracted; + } + if (nameField.text === "") { + var parts = path.split("/"); + var filename = parts[parts.length - 1]; + nameField.text = filename.replace(/\.exe$/i, ""); + } + var safeName = nameField.text.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase(); + var prefixBase = dialog.prefixBasePath + "/" + safeName; + if (protonPrefixField.text === "") + protonPrefixField.text = prefixBase; + if (winePrefixField.text === "") + winePrefixField.text = prefixBase; + } + + function openForNewWithExe(exePath) { + openForNew(); + applyExePath(exePath); + } + function openForEdit(index) { editMode = true; editIndex = index; @@ -211,23 +236,7 @@ nameFilters: [i18n("Executables (*.exe)"), i18n("All files (*)")] onAccepted: { var path = decodeURIComponent(selectedFile.toString().replace("file://", "")); - exeField.text = path; - if (iconField.text === "") { - var extracted = iconExtractor.extractIcon(path); - if (extracted !== "") - iconField.text = extracted; - } - if (nameField.text === "") { - var parts = path.split("/"); - var filename = parts[parts.length - 1]; - nameField.text = filename.replace(/\.exe$/i, ""); - } - var safeName = nameField.text.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase(); - var prefixBase = dialog.prefixBasePath + "/" + safeName; - if (protonPrefixField.text === "") - protonPrefixField.text = prefixBase; - if (winePrefixField.text === "") - winePrefixField.text = prefixBase; + dialog.applyExePath(path); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/qml/Main.qml new/vermouth-1.3.2/qml/Main.qml --- old/vermouth-1.3.1/qml/Main.qml 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/qml/Main.qml 2026-04-19 13:13:48.000000000 +0200 @@ -5,6 +5,7 @@ import com.dekomote.vermouth 1.0 Kirigami.ApplicationWindow { + id: root width: 800 height: 800 minimumWidth: settingsManager.drawerPinned ? 900 : 700 @@ -174,6 +175,32 @@ id: runExeStandaloneDialog } + Kirigami.PromptDialog { + id: openExeChoiceDialog + property string exePath: "" + title: i18n("Open Executable") + subtitle: exePath + standardButtons: Kirigami.Dialog.NoButton + customFooterActions: [ + Kirigami.Action { + text: i18n("Run Standalone") + icon.name: "media-playback-start" + onTriggered: { + openExeChoiceDialog.close(); + runExeStandaloneDialog.openDialog(openExeChoiceDialog.exePath); + } + }, + Kirigami.Action { + text: i18n("Add to Library") + icon.name: "list-add" + onTriggered: { + openExeChoiceDialog.close(); + addDialog.openForNewWithExe(openExeChoiceDialog.exePath); + } + } + ] + } + SettingsDialog { id: settingsDialog } @@ -202,14 +229,29 @@ } else if (drop.hasText) { path = decodeURIComponent(drop.text.trim().replace("file://", "")); } - if (path !== "") - runExeStandaloneDialog.openDialog(path); + if (path !== "") { + openExeChoiceDialog.exePath = path; + openExeChoiceDialog.open(); + } } } Component.onCompleted: { if (typeof openExePath !== "undefined" && openExePath !== "") { - runExeStandaloneDialog.openDialog(openExePath); + openExeChoiceDialog.exePath = openExePath; + openExeChoiceDialog.open(); + } + } + + Connections { + target: singleInstance + function onOpenExeRequested(path) { + openExeChoiceDialog.exePath = path; + openExeChoiceDialog.open(); + } + function onRaiseRequested() { + root.raise(); + root.requestActivate(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/scripts/build-packages.sh new/vermouth-1.3.2/scripts/build-packages.sh --- old/vermouth-1.3.1/scripts/build-packages.sh 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/scripts/build-packages.sh 2026-04-19 13:13:48.000000000 +0200 @@ -270,19 +270,125 @@ fi } +# --- Flatpak --- +build_flatpak() { + echo -e "\n${BOLD}=== Flatpak ===${RESET}" + echo "Image: fedora:43" + + if ! "$CONTAINER_RT" pull --quiet "fedora:43" 2>/dev/null; then + skip "Flatpak (could not pull image)" + return + fi + + local log rc + log=$("$CONTAINER_RT" run --rm --privileged \ + -v "$PROJECT_DIR":/src:ro \ + -v "$OUTPUT_DIR":/out \ + fedora:43 \ + bash -c " + set -euo pipefail + dnf upgrade --refresh -y --quiet + dnf install -y --quiet flatpak-builder + flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + + cp -r /src /build + cd /build + rm -rf build _build dist + + flatpak-builder --force-clean --repo=flatpakrepo build-dir com.dekomote.vermouth.yml \ + --install-deps-from=flathub --disable-rofiles-fuse + flatpak build-bundle flatpakrepo vermouth-${VERSION}.flatpak com.dekomote.vermouth + cp vermouth-*.flatpak /out/ + " 2>&1) && rc=0 || rc=$? + + if [ $rc -eq 0 ] && find "$OUTPUT_DIR" -maxdepth 1 -name "*.flatpak" | grep -q .; then + pass "Flatpak — package written to dist/" + else + fail "Flatpak build failed" + echo "$log" | tail -20 | sed 's/^/ /' + fi +} + +# --- AppImage --- +build_appimage() { + echo -e "\n${BOLD}=== AppImage ===${RESET}" + echo "Image: ubuntu:25.10" + + if ! "$CONTAINER_RT" pull --quiet "ubuntu:25.10" 2>/dev/null; then + skip "AppImage (could not pull image)" + return + fi + + local log rc + log=$("$CONTAINER_RT" run --rm \ + -e DEBIAN_FRONTEND=noninteractive \ + -v "$PROJECT_DIR":/src:ro \ + -v "$OUTPUT_DIR":/out \ + ubuntu:25.10 \ + bash -c " + set -euo pipefail + apt-get update -qq + apt-get install -y -qq build-essential cmake extra-cmake-modules file wget fuse3 \ + qt6-base-dev qt6-declarative-dev qt6-tools-dev-tools qmake6 \ + libkirigami-dev libkf6coreaddons-dev libkf6i18n-dev libkf6qqc2desktopstyle-dev \ + qml6-module-org-kde-kirigami qml6-module-org-kde-desktop \ + qml6-module-org-kde-iconthemes qml6-module-org-kde-sonnet \ + qt6-wayland breeze + + cp -r /src /build + cd /build + rm -rf build _build dist + + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -Wno-dev + cmake --build build --parallel \$(nproc) + DESTDIR=AppDir cmake --install build + + wget -q -O linuxdeploy 'https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage' + wget -q -O linuxdeploy-plugin-qt 'https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage' + chmod +x linuxdeploy linuxdeploy-plugin-qt + ./linuxdeploy --appimage-extract && mv squashfs-root linuxdeploy-extracted + ./linuxdeploy-plugin-qt --appimage-extract && mv squashfs-root linuxdeploy-plugin-qt-extracted + ln -s \"\$PWD/linuxdeploy-plugin-qt-extracted/AppRun\" linuxdeploy-extracted/plugins/linuxdeploy-plugin-qt + + export QML_SOURCES_PATHS=/build/qml + export QMAKE=/usr/bin/qmake6 + export EXTRA_QT_PLUGINS='svg;wayland-shell-integration;wayland-graphics-integration-client' + export APPIMAGE_EXTRACT_AND_RUN=1 + export VERSION=${VERSION} + + ./linuxdeploy-extracted/AppRun --appdir AppDir \ + --desktop-file AppDir/usr/share/applications/com.dekomote.vermouth.desktop \ + --icon-file AppDir/usr/share/icons/hicolor/scalable/apps/com.dekomote.vermouth.svg \ + --plugin qt \ + --output appimage + cp Vermouth-*.AppImage /out/ + " 2>&1) && rc=0 || rc=$? + + if [ $rc -eq 0 ] && find "$OUTPUT_DIR" -maxdepth 1 -name "*.AppImage" | grep -q .; then + pass "AppImage — package written to dist/" + else + fail "AppImage build failed" + echo "$log" | tail -20 | sed 's/^/ /' + fi +} + case "$TARGETS" in all) build_rpm_fedora build_rpm_opensuse build_deb build_arch + build_flatpak + build_appimage ;; fedora) build_rpm_fedora ;; opensuse) build_rpm_opensuse ;; deb) build_deb ;; arch) build_arch ;; + flatpak) build_flatpak ;; + appimage) build_appimage ;; *) - echo "Usage: $0 [all|fedora|opensuse|deb|arch]" + echo "Usage: $0 [all|fedora|opensuse|deb|arch|flatpak|appimage]" exit 1 ;; esac diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/src/launcher.cpp new/vermouth-1.3.2/src/launcher.cpp --- old/vermouth-1.3.1/src/launcher.cpp 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/src/launcher.cpp 2026-04-19 13:13:48.000000000 +0200 @@ -146,6 +146,7 @@ env.insert(QStringLiteral("PROTONPATH"), protonPath); env.insert(QStringLiteral("STEAM_COMPAT_DATA_PATH"), prefix); env.insert(QStringLiteral("GAMEID"), QStringLiteral("0")); + env.insert(QStringLiteral("WINEPREFIX"), prefix); launch(umoBin, {}, exePath, env, opts, logging, name); } else { env.insert(QStringLiteral("STEAM_COMPAT_CLIENT_INSTALL_PATH"), QDir::homePath() + QStringLiteral("/.steam/steam")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/src/main.cpp new/vermouth-1.3.2/src/main.cpp --- old/vermouth-1.3.1/src/main.cpp 2026-04-17 10:08:42.000000000 +0200 +++ new/vermouth-1.3.2/src/main.cpp 2026-04-19 13:13:48.000000000 +0200 @@ -5,6 +5,7 @@ #include "protondownloader.h" #include "protonscanner.h" #include "settingsmanager.h" +#include "singleinstance.h" #include "umudownloader.h" #include <KAboutData> #include <KLocalizedContext> @@ -109,6 +110,22 @@ return app.exec(); } + // Check for positional args early so we can forward them if already running. + QStringList positionalArgs = parser.positionalArguments(); + QString openExePath; + if (!positionalArgs.isEmpty()) { + QString arg = positionalArgs.first(); + if (arg.startsWith(QStringLiteral("file://"))) + arg = QUrl(arg).toLocalFile(); + openExePath = arg; + } + + SingleInstance singleInstance; + if (!singleInstance.tryRegister()) { + singleInstance.forwardToRunning(openExePath); + return 0; + } + AppModel appModel; ProtonScanner protonScanner; DesktopFileWriter desktopWriter; @@ -147,17 +164,7 @@ engine.rootContext()->setContextProperty(QStringLiteral("settingsManager"), &settingsManager); engine.rootContext()->setContextProperty(QStringLiteral("protonDownloader"), &protonDownloader); engine.rootContext()->setContextProperty(QStringLiteral("umuDownloader"), &umuDownloader); - - // Check for positional args (file association: vermouth /path/to/game.exe) - QStringList positionalArgs = parser.positionalArguments(); - QString openExePath; - if (!positionalArgs.isEmpty()) { - QString arg = positionalArgs.first(); - // Strip file:// URI scheme if present - if (arg.startsWith(QStringLiteral("file://"))) - arg = QUrl(arg).toLocalFile(); - openExePath = arg; - } + engine.rootContext()->setContextProperty(QStringLiteral("singleInstance"), &singleInstance); engine.rootContext()->setContextProperty(QStringLiteral("openExePath"), openExePath); engine.load(QUrl(QStringLiteral("qrc:/qml/Main.qml"))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/src/singleinstance.cpp new/vermouth-1.3.2/src/singleinstance.cpp --- old/vermouth-1.3.1/src/singleinstance.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/vermouth-1.3.2/src/singleinstance.cpp 2026-04-19 13:13:48.000000000 +0200 @@ -0,0 +1,39 @@ +#include "singleinstance.h" +#include <QDBusConnection> +#include <QDBusInterface> + +#define VERMOUTH_SERVICE "com.dekomote.vermouth" +#define VERMOUTH_PATH "/com/dekomote/vermouth" +#define VERMOUTH_INTERFACE "com.dekomote.vermouth.App" + +SingleInstance::SingleInstance(QObject *parent) + : QObject(parent) +{ +} + +bool SingleInstance::tryRegister() +{ + QDBusConnection bus = QDBusConnection::sessionBus(); + if (!bus.registerService(QStringLiteral(VERMOUTH_SERVICE))) + return false; + bus.registerObject(QStringLiteral(VERMOUTH_PATH), this, QDBusConnection::ExportScriptableSlots); + return true; +} + +void SingleInstance::forwardToRunning(const QString &exePath) +{ + QDBusInterface iface(QStringLiteral(VERMOUTH_SERVICE), QStringLiteral(VERMOUTH_PATH), QStringLiteral(VERMOUTH_INTERFACE), QDBusConnection::sessionBus()); + if (!exePath.isEmpty()) + iface.call(QStringLiteral("openExe"), exePath); + iface.call(QStringLiteral("raise")); +} + +void SingleInstance::openExe(const QString &path) +{ + Q_EMIT openExeRequested(path); +} + +void SingleInstance::raise() +{ + Q_EMIT raiseRequested(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vermouth-1.3.1/src/singleinstance.h new/vermouth-1.3.2/src/singleinstance.h --- old/vermouth-1.3.1/src/singleinstance.h 1970-01-01 01:00:00.000000000 +0100 +++ new/vermouth-1.3.2/src/singleinstance.h 2026-04-19 13:13:48.000000000 +0200 @@ -0,0 +1,25 @@ +#pragma once +#include <QObject> + +class SingleInstance : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.dekomote.vermouth.App") + +public: + explicit SingleInstance(QObject *parent = nullptr); + + // Returns true if this process is the primary instance. + bool tryRegister(); + + // Called by a secondary instance to hand off work to the primary. + void forwardToRunning(const QString &exePath); + +public Q_SLOTS: + Q_SCRIPTABLE void openExe(const QString &path); + Q_SCRIPTABLE void raise(); + +Q_SIGNALS: + void openExeRequested(const QString &path); + void raiseRequested(); +};
