diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs
index a90b83c5fe..253ec17c28 100644
--- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs
+++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs
@@ -3,6 +3,7 @@
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
+using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
@@ -42,4 +43,26 @@ namespace osu.Game.Screens.Menu
}
}
}
+
+ ///
+ /// An that behaves as if the is always 0.
+ ///
+ /// This is useful for mobile devices using gesture navigation, where holding to confirm is not possible.
+ public class NoHoldExitConfirmOverlay : ExitConfirmOverlay, IKeyBindingHandler
+ {
+ public new bool OnPressed(KeyBindingPressEvent e)
+ {
+ if (e.Repeat)
+ return false;
+
+ if (e.Action == GlobalAction.Back)
+ {
+ Progress.Value = 1;
+ Confirm();
+ return true;
+ }
+
+ return false;
+ }
+ }
}
diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs
index 8b1bab52b3..7bc0cb48bf 100644
--- a/osu.Game/Screens/Menu/MainMenu.cs
+++ b/osu.Game/Screens/Menu/MainMenu.cs
@@ -3,6 +3,7 @@
using System;
using osu.Framework.Allocation;
+using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Platform;
@@ -89,6 +90,14 @@ namespace osu.Game.Screens.Menu
}
});
}
+ else if (host.CanSuspendToBackground)
+ {
+ AddInternal(exitConfirmOverlay = new NoHoldExitConfirmOverlay
+ {
+ // treat as if the UIHoldActivationDelay is always 0. see NoHoldExitConfirmOverlay xmldoc for more info.
+ Action = this.Exit
+ });
+ }
AddRangeInternal(new[]
{
@@ -148,6 +157,24 @@ namespace osu.Game.Screens.Menu
private void confirmAndExit()
{
+ if (host.CanSuspendToBackground)
+ {
+ // cancel the overlay as we're not actually exiting.
+ // this is the same action as 'onCancel' in `ConfirmExitDialog`.
+ exitConfirmOverlay.Abort();
+
+ // fade the track so the Bass.Pause() on suspend isn't as jarring.
+ const double fade_time = 500;
+ musicController.CurrentTrack
+ .VolumeTo(0, fade_time, Easing.Out).Then()
+ .VolumeTo(1, fade_time, Easing.In);
+
+ host.SuspendToBackground();
+
+ // on hosts that can only suspend, we don't ever want to exit the game.
+ return;
+ }
+
if (exitConfirmed) return;
exitConfirmed = true;