Skip to content

Add a setting to delay or skip hiding Pegasus after launching a game - #1191

Open
PaleThunder18 wants to merge 2 commits into
mmatyas:masterfrom
PaleThunder18:hide-after-launch
Open

PaleThunder18 wants to merge 2 commits into
mmatyas:masterfrom
PaleThunder18:hide-after-launch

Conversation

@PaleThunder18

Copy link
Copy Markdown

Closes #648.

What

Adds "Hide Pegasus after launching a game" to the Gaming section of the settings menu, saved as general.hide-delay-after-launch in settings.txt:

Choice Value Behavior
Immediately (default) 0 Current behavior, unchanged
After 2 / 5 / 10 seconds 2, 5, 10 (any positive number works in the file) Keep the frontend visible for that long, then tear it down. If the program exits first, the existing window is brought back to the front without a rebuild
Never -1 (any negative number) Keep the frontend alive while the program runs

As discussed in #648, the delay doesn't apply where only one program can draw to the screen. On Android, and when Qt runs on eglfs, linuxfb, vkkhrdisplay or minimal*, Pegasus always hides immediately and logs why.

Why

Many programs take a few seconds to show their window, and on desktop setups the desktop is exposed during that time. It is a long-standing complaint in #648 and breaks the console-like experience, especially on HTPCs and streamed setups (Moonlight/Sunshine).

How

  • Backend::onProcessLaunched() either tears down immediately (the stock path), starts a single-shot timer, or keeps the frontend. Backend::onProcessFinished() stops the timer, then either rebuilds the frontend or calls the new FrontendLayer::bringToFront().
  • ProcessLauncher now emits processFinished itself when no teardown is waiting on the program. onTeardownComplete() no longer assumes the program is still running. This also avoids dereferencing a null process if a program exits before a teardown completes.
  • The setting follows the same pattern as scan-on-launch (AppSettings → Settings property → SettingsFile → SettingsMain.qml).
  • Info log lines record when the frontend is kept visible and when the delayed hide happens, so users can see the behavior in lastrun.log.

Default behavior is unchanged: with the default value, the code path is the same as before, apart from the ProcessLauncher bookkeeping above.

Testing

Ubuntu 26.04, Qt 5.15.18, GNOME on Wayland, launching RetroDECK (Flatpak) with a DualSense controller, streamed over Moonlight:

  • Immediately: frontend torn down at launch and rebuilt on exit, as before.
  • Never: frontend window and render thread stayed alive during the whole session, and there was no rebuild on exit.
  • After 10 seconds: frontend hid exactly 10 s after launch and was rebuilt on exit. When the program exited before 10 s, there was no teardown, and the frontend was brought back without a rebuild.
  • After 5 seconds, exiting right around the 5 s mark: clean, no errors.
  • Settings menu: the new entry shows the current value, and the choice is saved to and loaded from settings.txt.
  • ctest: all tests pass except test_KeyEditor, test_Blurhash and test_SortFilter, which fail on this machine only because the QtTest QML module isn't installed (unrelated).

Not tested on real hardware: Android, and Linux without a compositor (eglfs/KMS). The forced-immediate path there is a short platform check, reviewed but not run.

Notes

  • New UI strings use QT_TR_NOOP/qsTr, so they can go through the usual translation update.
  • In the picker popup, the option names show untranslated, since MultivalueBox displays model.name as-is (the same as the existing language and theme lists, which show native names). The selected value on the settings row is translated.

🤖 Generated with Claude Code

@PaleThunder18

Copy link
Copy Markdown
Author

The Android failure doesn't come from this change. Both Android jobs compile the C++ fine, then fail at Package (debug) with:

Could not compile build file '.../installdir/build.gradle'
Unsupported class file major version 69

Major version 69 is Java 25. The ubuntu runner image now defaults to JDK 25, which this project's Gradle version can't run on. Master's last green Android build was on Oct 2, so the next Android run on master will probably fail the same way. Pinning an older JDK in the Android workflow (e.g. via actions/setup-java) should fix it.

@mmatyas

mmatyas commented Oct 26, 2026

Copy link
Copy Markdown
Owner

The code looks good, but the CI had some issues. Could you rebase to the current master branch?

Pegasus tears down its frontend as soon as the launched program has
started. Many programs take a while to show their window, so the desktop
is exposed in between, which breaks the console-like experience on
desktop setups (see mmatyas#648).

Add a "Hide Pegasus after launching a game" option in the Gaming section
of the settings menu, stored as general.hide-delay-after-launch in
settings.txt:

- 0 (Immediately, the default): the current behavior, unchanged.
- N > 0 (the menu offers 2, 5 and 10 seconds): keep the frontend visible
  for N seconds, then tear it down. If the program exits before that,
  the frontend is simply brought back to the front without a rebuild.
- Negative (Never): keep the frontend alive while the program runs.

On Android, and on Qt platforms that only allow one program on the
screen (eglfs, linuxfb, vkkhrdisplay, minimal*), Pegasus always hides
immediately regardless of this setting.

ProcessLauncher now reports processFinished itself when no teardown is
waiting on the program, and onTeardownComplete no longer assumes the
program is still running. This also avoids dereferencing a null process
if a program exits before a teardown has completed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The patch no longer applied after the changes to onTeardownComplete().
Keep the waiting flag around the start-and-wait so the finish is only
reported once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PaleThunder18

Copy link
Copy Markdown
Author

Rebased onto current master. The buster-pi4 failure was from this change: etc/rpi4/kms_launch_fix.diff no longer applied to ProcessLauncher.cpp. I've updated it, keeping the new waiting flag around the start-and-wait in the Pi 4 onTeardownComplete() so the finish is only reported once. The AppVeyor failure also happens on master.

This branch has not been deployed

No deployments
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.

Option to not have Pegasus hide when game is launched

2 participants