diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 2b232db274b1..1c5d4dd37d07 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -9,18 +9,19 @@ using Microsoft.Win32; using osu.Desktop.Performance; using osu.Desktop.Security; -using osu.Framework.Platform; -using osu.Game; using osu.Desktop.Updater; -using osu.Framework; -using osu.Framework.Logging; -using osu.Game.Updater; using osu.Desktop.Windows; +using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Logging; +using osu.Framework.Platform; +using osu.Game; +using osu.Game.Configuration; using osu.Game.IO; using osu.Game.IPC; using osu.Game.Online.Multiplayer; using osu.Game.Performance; +using osu.Game.Updater; using osu.Game.Utils; using SDL2; @@ -115,8 +116,10 @@ protected override UpdateManager CreateUpdateManager() } } - public override bool RestartAppWhenExited() + public override bool Restart() { + SessionStatics.SetValue(Static.RestartRequested, true); + switch (RuntimeInfo.OS) { case RuntimeInfo.Platform.Windows: @@ -131,7 +134,9 @@ public override bool RestartAppWhenExited() return true; } - return base.RestartAppWhenExited(); + AttemptExit(); + + return base.Restart(); } protected override void LoadComplete() diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index dba157a6e951..4975e91fba9f 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -35,7 +35,7 @@ public partial class SquirrelUpdateManager : UpdateManager private readonly SquirrelLogger squirrelLogger = new SquirrelLogger(); [Resolved] - private OsuGameBase game { get; set; } = null!; + private OsuGame game { get; set; } = null!; [Resolved] private ILocalUserPlayInfo? localUserInfo { get; set; } @@ -150,7 +150,7 @@ private async Task checkForUpdateAsync(bool useDeltaPatching = true, Updat private bool restartToApplyUpdate() { PrepareUpdateAsync() - .ContinueWith(_ => Schedule(() => game.AttemptExit())); + .ContinueWith(_ => Schedule(() => game.Restart())); return true; } diff --git a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs index e55cbc2dbb4d..dbe51e91070a 100644 --- a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs +++ b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs @@ -29,11 +29,7 @@ private void load(TournamentStorage storage) reloadTournamentsButton.Action = () => dropdown.Items = storage.ListTournaments(); - Action = () => - { - game.RestartAppWhenExited(); - game.AttemptExit(); - }; + Action = () => game.Restart(); folderButton.Action = () => storage.PresentExternally(); ButtonText = "Close osu!"; diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 1548b781a704..537850029249 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -21,6 +21,7 @@ public class SessionStatics : InMemoryConfigManager protected override void InitialiseDefaults() { SetDefault(Static.LoginOverlayDisplayed, false); + SetDefault(Static.RestartRequested, false); SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); SetDefault(Static.FeaturedArtistDisclaimerShownOnce, false); @@ -80,5 +81,11 @@ public enum Static /// Stores the local user's last score (can be completed or aborted). /// LastLocalUserScore, + + /// + /// Whether the game is in the process of being restarted. At the point this flag is set, it is assumed that confirmation + /// is not required from the user on exiting the game. + /// + RestartRequested } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index fb7a238c46df..64c5fdf798e2 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -511,7 +511,7 @@ public virtual void AttemptExit() /// If supported by the platform, the game will automatically restart after the next exit. /// /// Whether a restart operation was queued. - public virtual bool RestartAppWhenExited() => false; + public virtual bool Restart() => false; public bool Migrate(string path) { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index a8b127d5229a..3b48d3810864 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -67,11 +67,7 @@ private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDi if (r.NewValue == RendererType.Automatic && automaticRendererInUse) return; - if (game?.RestartAppWhenExited() == true) - { - game.AttemptExit(); - } - else + if (game?.Restart() != true) { dialogOverlay?.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, () => game?.AttemptExit(), () => { diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 235c5d5c56d0..eac50b2cee6f 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -89,6 +89,7 @@ public partial class MainMenu : OsuScreen, IHandlePresentBeatmap, IKeyBindingHan private Bindable holdDelay; private Bindable loginDisplayed; + private Bindable isRestarting; private HoldToExitGameOverlay holdToExitGameOverlay; @@ -113,6 +114,7 @@ private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings { holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); + isRestarting = statics.GetBindable(Static.RestartRequested); if (host.CanExit) { @@ -388,8 +390,10 @@ public override bool OnExiting(ScreenExitEvent e) dialogOverlay != null // if the dialog has already displayed and been accepted by the user, we are good. && !exitConfirmedViaDialog - // Only require confirmation if there is either an ongoing operation or the user exited via a non-hold escape press. - && (notifications.HasOngoingOperations || !exitConfirmedViaHoldOrClick); + // Only require confirmation if there is either an ongoing operation or the exit process wasn't triggered via user intention. + && (notifications.HasOngoingOperations || (!exitConfirmedViaHoldOrClick && !isRestarting.Value)); + + isRestarting.Value = false; if (requiresConfirmation) {