diff --git a/osu.Android.props b/osu.Android.props
index dd11804b90..d684b73d8d 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -54,6 +54,6 @@
-
+
diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs
index 8818cef8eb..80bb82c769 100644
--- a/osu.Desktop/DiscordRichPresence.cs
+++ b/osu.Desktop/DiscordRichPresence.cs
@@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
+using System.Text;
using DiscordRPC;
using DiscordRPC.Message;
using osu.Framework.Allocation;
@@ -43,6 +45,10 @@ namespace osu.Desktop
};
client.OnReady += onReady;
+
+ // safety measure for now, until we performance test / improve backoff for failed connections.
+ client.OnConnectionFailed += (_, __) => client.Deinitialize();
+
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
(user = provider.LocalUser.GetBoundCopy()).BindValueChanged(u =>
@@ -77,8 +83,8 @@ namespace osu.Desktop
if (status.Value is UserStatusOnline && activity.Value != null)
{
- presence.State = activity.Value.Status;
- presence.Details = getDetails(activity.Value);
+ presence.State = truncate(activity.Value.Status);
+ presence.Details = truncate(getDetails(activity.Value));
}
else
{
@@ -96,6 +102,27 @@ namespace osu.Desktop
client.SetPresence(presence);
}
+ private static readonly int ellipsis_length = Encoding.UTF8.GetByteCount(new[] { '…' });
+
+ private string truncate(string str)
+ {
+ if (Encoding.UTF8.GetByteCount(str) <= 128)
+ return str;
+
+ ReadOnlyMemory strMem = str.AsMemory();
+
+ do
+ {
+ strMem = strMem[..^1];
+ } while (Encoding.UTF8.GetByteCount(strMem.Span) + ellipsis_length > 128);
+
+ return string.Create(strMem.Length + 1, strMem, (span, mem) =>
+ {
+ mem.Span.CopyTo(span);
+ span[^1] = '…';
+ });
+ }
+
private string getDetails(UserActivity activity)
{
switch (activity)
diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
index 1cac4d76ab..f5b7bc3073 100644
--- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
@@ -12,10 +12,12 @@ using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
- public class OsuTextBox : TextBox
+ public class OsuTextBox : BasicTextBox
{
protected override float LeftRightPadding => 10;
+ protected override float CaretWidth => 3;
+
protected override SpriteText CreatePlaceholder() => new OsuSpriteText
{
Font = OsuFont.GetFont(italics: true),
@@ -41,6 +43,8 @@ namespace osu.Game.Graphics.UserInterface
BackgroundCommit = BorderColour = colour.Yellow;
}
+ protected override Color4 SelectionColour => new Color4(249, 90, 255, 255);
+
protected override void OnFocus(FocusEvent e)
{
BorderThickness = 3;
diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs
index 231115d1e1..b28d572b5c 100644
--- a/osu.Game/Screens/Menu/MainMenu.cs
+++ b/osu.Game/Screens/Menu/MainMenu.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Linq;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
@@ -132,6 +133,8 @@ namespace osu.Game.Screens.Menu
private void confirmAndExit()
{
+ if (exitConfirmed) return;
+
exitConfirmed = true;
this.Exit();
}
@@ -244,10 +247,18 @@ namespace osu.Game.Screens.Menu
public override bool OnExiting(IScreen next)
{
- if (!exitConfirmed && dialogOverlay != null && !(dialogOverlay.CurrentDialog is ConfirmExitDialog))
+ if (!exitConfirmed && dialogOverlay != null)
{
- dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort()));
- return true;
+ if (dialogOverlay.CurrentDialog is ConfirmExitDialog exitDialog)
+ {
+ exitConfirmed = true;
+ exitDialog.Buttons.First().Click();
+ }
+ else
+ {
+ dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort()));
+ return true;
+ }
}
buttons.State = ButtonSystemState.Exit;
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 5dfdeb5ebc..8970f9ac88 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -562,7 +562,7 @@ namespace osu.Game.Screens.Play
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.
// as we are no longer the current screen, we cannot guarantee the track is still usable.
- GameplayClockContainer.StopUsingBeatmapClock();
+ GameplayClockContainer?.StopUsingBeatmapClock();
fadeOut();
return base.OnExiting(next);
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 757e0e11fa..4c5f3e0f38 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 0dba92b975..ccfbee9a62 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -74,7 +74,7 @@
-
+
@@ -82,7 +82,7 @@
-
+