-
Notifications
You must be signed in to change notification settings - Fork 2
fix: Playnite slow start no longer flips back to the PC #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,7 @@ public void Start(AppConfig config, MonitorInfo? focusInfo, Func<ScreenRect?, bo | |
| State.LaunchTime = null; | ||
| State.AbsenceCount = 0; | ||
| State.CachedBigPictureHandle = 0; | ||
| State.PlayniteWindowMissingSince = null; | ||
| State.CachedXboxHandle = 0; | ||
| State.AudioWatchComplete = false; | ||
| State.BigPictureWatchActive = false; | ||
|
|
@@ -410,9 +411,10 @@ private void MoveToFocus(string monitorName, nint[] handles, ScreenRect? rect) | |
|
|
||
| private bool IsExitSignaled() | ||
| { | ||
| if (NativeWindows.ConsumeBigPictureExitRequest()) return true; | ||
| if (State.CachedBigPictureHandle != 0 && !NativeWindows.IsWindowStillVisible(State.CachedBigPictureHandle)) | ||
| return true; | ||
| var watchedGone = NativeWindows.ConsumeBigPictureExitRequest() || | ||
| (State.CachedBigPictureHandle != 0 && !NativeWindows.IsWindowStillVisible(State.CachedBigPictureHandle)); | ||
| if (State.FullscreenMode == "playnite" && State.HasAppeared) return IsPlayniteExitSignaled(watchedGone); | ||
| if (watchedGone) return true; | ||
| if (!State.HasAppeared) return false; | ||
| if (Launch.IsFullscreenActive(State.FullscreenMode, State)) | ||
| { | ||
|
|
@@ -423,6 +425,28 @@ private bool IsExitSignaled() | |
| return State.AbsenceCount >= 2; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Playnite may replace the window being watched (loading screen → main window). Follow the new | ||
| /// window while the process runs, and end the session only when it exits or stays windowless. | ||
| /// </summary> | ||
| private bool IsPlayniteExitSignaled(bool watchedGone) | ||
| { | ||
| if (watchedGone) State.CachedBigPictureHandle = 0; | ||
| var showing = Launch.IsPlayniteActive(State); | ||
| if (showing && watchedGone) | ||
| { | ||
| var handle = State.CachedBigPictureHandle; | ||
| AppLog.Write("Loop: Playnite trocou de janela; acompanhando a nova"); | ||
| OnUi(() => State.BigPictureWatchActive = NativeWindows.StartBigPictureExitWatch(handle)); | ||
| } | ||
|
|
||
| if (showing) State.PlayniteWindowMissingSince = null; | ||
| else State.PlayniteWindowMissingSince ??= DateTime.Now; | ||
| var exit = PlayniteExitPolicy.IsExit(Launch.IsPlayniteRunning(), showing, State.PlayniteWindowMissingSince, DateTime.Now); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] Technical details# Playnite session is not identified
## Affected sites
- `src/ConsoleMode/Services/LaunchService.cs:104-110` — enumerates any `Playnite.FullscreenApp` process rather than identifying the launched process.
- `src/ConsoleMode/Services/ConsoleEngine.cs:435,443-445` — accepts any matching process window as the active session and uses any same-named process to suppress exit.
## Required outcome
- Keep the tracked Playnite process/window identity associated with the console-mode launch, and use that identity consistently when evaluating replacement windows and process exit. |
||
| if (exit) AppLog.Write("Loop: Playnite fechou"); | ||
| return exit; | ||
| } | ||
|
|
||
| private bool AudioWatchNeeded() | ||
| { | ||
| if (!AppPaths.HasSvv || State.AudioWatchComplete) return false; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| namespace ConsoleMode.Services; | ||
|
|
||
| /// <summary> | ||
| /// When a Playnite session counts as over. Playnite can swap its first big window (a loading | ||
| /// screen on slow starts) for the main one, so a vanished window alone is not an exit. Pure, so it's tested. | ||
| /// </summary> | ||
| public static class PlayniteExitPolicy | ||
| { | ||
| /// <summary>How long Playnite may run without a big window before the session ends anyway.</summary> | ||
| public static readonly TimeSpan WindowGrace = TimeSpan.FromSeconds(20); | ||
|
|
||
| /// <param name="windowMissingSince">When the big window went missing, or null if it is showing.</param> | ||
| public static bool IsExit(bool processRunning, bool bigWindowShowing, DateTime? windowMissingSince, DateTime now) | ||
| { | ||
| if (!processRunning) return true; | ||
| if (bigWindowShowing || windowMissingSince is null) return false; | ||
| return now - windowMissingSince.Value >= WindowGrace; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using ConsoleMode.Services; | ||
|
|
||
| namespace ConsoleMode.Tests; | ||
|
|
||
| public class PlayniteExitPolicyTests | ||
| { | ||
| private static readonly DateTime T0 = new(2026, 1, 1, 12, 0, 0, DateTimeKind.Utc); | ||
|
|
||
| [Fact] | ||
| public void Exits_when_the_process_is_gone() => | ||
| Assert.True(PlayniteExitPolicy.IsExit(processRunning: false, bigWindowShowing: false, windowMissingSince: null, T0)); | ||
|
|
||
| [Fact] | ||
| public void Stays_while_the_big_window_shows() => | ||
| Assert.False(PlayniteExitPolicy.IsExit(processRunning: true, bigWindowShowing: true, windowMissingSince: null, T0)); | ||
|
|
||
| [Fact] | ||
| public void Waits_while_the_loading_window_is_swapped_for_the_main_one() => | ||
| Assert.False(PlayniteExitPolicy.IsExit(processRunning: true, bigWindowShowing: false, windowMissingSince: T0, T0 + TimeSpan.FromSeconds(5))); | ||
|
|
||
| [Fact] | ||
| public void Exits_when_the_process_stays_windowless_past_the_grace() => | ||
| Assert.True(PlayniteExitPolicy.IsExit(processRunning: true, bigWindowShowing: false, windowMissingSince: T0, T0 + PlayniteExitPolicy.WindowGrace)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1] A newly discovered candidate is accepted as active based only on
GetWindowArea; unlike the cached-handle branch inIsPlayniteActive, this path does not requireIsWindowStillVisible. During splash teardown or with a hidden/stale large main window,showingcan remain true while no fullscreen window is present, clearingPlayniteWindowMissingSinceat line 443 and preventing the 20-second fallback, so the desktop is never restored.Technical details