Skip to content

fix(app): second launch shows the window; keep running in the background when closed - #171

Open
schultz-dev0 wants to merge 3 commits into
mmaher88:masterfrom
schultz-dev0:fix/second-launch-shows-window
Open

schultz-dev0 wants to merge 3 commits into
mmaher88:masterfrom
schultz-dev0:fix/second-launch-shows-window

Conversation

@schultz-dev0

@schultz-dev0 schultz-dev0 commented Nov 3, 2026 •

Copy link
Copy Markdown

Closing the window doesn't close it. In src/app/qml/Main.qml:77-80, onClosing rejects the close and calls hide(), and setQuitOnLastWindowClosed(false) in src/app/main.cpp:60 keeps the process alive with no window. The next launch then fails lockFile.tryLock() in src/app/main.cpp:93-99, because the hidden instance still holds the lock. It logs "Another instance of Logitune is already running" and returns 1. If you're on a system with no tray, the only way to open the app again is to pkill it first.

The first commit keeps the QLockFile and adds a QLocalServer next to it in the first instance (src/app/SingleInstance.*). A second launch connects, sends a show command and exits with 0, and the window comes back up. The tray's "Show" and the second launch share the same code. The lock file moved from the temp directory to the per-user runtime directory, next to the new socket.

Since a second launch can now always bring the window back, the second commit makes Logitune keep running when its window is closed, tray or not:

  • Closing the window destroys the UI (src/app/MainWindowController.*). Devices, profiles, the tray and the single-instance server keep running.
  • A second launch, or the tray's "Show", builds the window again.
  • --minimized starts without building the window at all.
  • logitune --quit ends the running instance, and there's a Quit button in Settings, so you can quit without a tray. The tray's Quit stays.

Memory (PSS, Hyprland, after an 8 s settle): about 120 MiB with the window open, about 80 MiB after closing it (88 MiB after repeated open/close cycles, then flat), and about 32 MiB when started with --minimized. Closing frees the window's objects and calls malloc_trim(0) on glibc, but Qt keeps some caches once the UI has been built, so it doesn't get back down to the --minimized figure.

Tests: second launch sends show and exits 0; --quit reaches the primary and exits 0, and does nothing when no instance is running; closing destroys the window and a show request builds a new one; the Quit button quits. logitune-tests (762), logitune-tray-tests (9) and the QML tests (79) pass. Smoke-tested on Hyprland with and without a tray host: closing keeps the process, a second launch brings the window back, device notifications keep being handled with no window, and --quit ends it.

A second launch used to fail the instance lock and exit silently while the first instance sat hidden. It now asks the running instance to show its window and exits 0. Without a tray, closing the window quits instead of hiding.
Closing the window destroys the UI and keeps devices, profiles, the tray and the single-instance server running, with or without a tray. Launching again rebuilds the window. --minimized starts without building it at all. Add --quit and a Quit button in Settings so the app can be ended without a tray.
@schultz-dev0 schultz-dev0 changed the title fix(app): show the running window on a second launch fix(app): second launch shows the window; keep running in the background when closed Nov 3, 2026

@mmaher88 mmaher88 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is a solid change, and the diagnosis is right: Main.qml's onClosing rejects the close, so the no-tray quit from #72 never fired. A few things before merge:

  1. A second launch with --minimized (autostart while already running) currently sends show and pops the window up. It should be a no-op that exits 0.
  2. If QStandardPaths::RuntimeLocation is empty or unusable, the lock path becomes /logitune.lock, tryLock fails with PermissionError, and the app exits 1 after the 2 s retry, where master would have started. Please fall back to TempLocation, check QLockFile::error(), and keep running lock-only if listen() fails.
  3. test_main_window loads Main.qml in the gtest binary. On Qt 6.4 (Ubuntu 24.04, the only CI job that runs tests), Theme has to be registered by hand the way main.cpp does it; please make sure the test passes there.
  4. Small things: the HomeView tray banner still says "restart Logitune", and the explicit QQmlApplicationEngine::quit connect duplicates Qt's built-in one. Forwarding XDG_ACTIVATION_TOKEN over the socket would help raise the window on GNOME/KDE Wayland; a follow-up is fine.

Also, #166 adds live theme switching, which assumes a root window exists. Whichever lands second needs to route theme updates through MainWindowController (or a C++ theme property) so they still apply when the window is closed or not built yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants