mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 04:12:57 +08:00
Merge pull request #18422 from smoogipoo/detect-exclusive-fullscreen
Detect exclusive fullscreen on Windows
This commit is contained in:
commit
5adbf85654
@ -6,6 +6,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
@ -83,7 +84,7 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
AddStep("clear label", () => textBox.LabelText = default);
|
AddStep("clear label", () => textBox.LabelText = default);
|
||||||
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
|
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
|
||||||
|
|
||||||
AddStep("set warning text", () => textBox.WarningText = "This is some very important warning text! Hopefully it doesn't break the alignment of the default value indicator...");
|
AddStep("set warning text", () => textBox.SetNoticeText("This is some very important warning text! Hopefully it doesn't break the alignment of the default value indicator...", true));
|
||||||
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
|
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,16 +130,18 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
SettingsNumberBox numberBox = null;
|
SettingsNumberBox numberBox = null;
|
||||||
|
|
||||||
AddStep("create settings item", () => Child = numberBox = new SettingsNumberBox());
|
AddStep("create settings item", () => Child = numberBox = new SettingsNumberBox());
|
||||||
AddAssert("warning text not created", () => !numberBox.ChildrenOfType<SettingsNoticeText>().Any());
|
AddAssert("warning text not created", () => !numberBox.ChildrenOfType<LinkFlowContainer>().Any());
|
||||||
|
|
||||||
AddStep("set warning text", () => numberBox.WarningText = "this is a warning!");
|
AddStep("set warning text", () => numberBox.SetNoticeText("this is a warning!", true));
|
||||||
AddAssert("warning text created", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 1);
|
AddAssert("warning text created", () => numberBox.ChildrenOfType<LinkFlowContainer>().Single().Alpha == 1);
|
||||||
|
|
||||||
AddStep("unset warning text", () => numberBox.WarningText = default);
|
AddStep("unset warning text", () => numberBox.ClearNoticeText());
|
||||||
AddAssert("warning text hidden", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 0);
|
AddAssert("warning text hidden", () => !numberBox.ChildrenOfType<LinkFlowContainer>().Any());
|
||||||
|
|
||||||
AddStep("set warning text again", () => numberBox.WarningText = "another warning!");
|
AddStep("set warning text again", () => numberBox.SetNoticeText("another warning!", true));
|
||||||
AddAssert("warning text shown again", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 1);
|
AddAssert("warning text shown again", () => numberBox.ChildrenOfType<LinkFlowContainer>().Single().Alpha == 1);
|
||||||
|
|
||||||
|
AddStep("set non warning text", () => numberBox.SetNoticeText("you did good!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
osu.Game/Localisation/LayoutSettingsStrings.cs
Normal file
29
osu.Game/Localisation/LayoutSettingsStrings.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class LayoutSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.LayoutSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Checking for fullscreen capabilities..."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CheckingForFullscreenCapabilities => new TranslatableString(getKey(@"checking_for_fullscreen_capabilities"), @"Checking for fullscreen capabilities...");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "osu! is running exclusive fullscreen, guaranteeing low latency!"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running exclusive fullscreen, guaranteeing low latency!");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Unable to run exclusive fullscreen. You'll still experience some input latency."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString UnableToRunExclusiveFullscreen => new TranslatableString(getKey(@"unable_to_run_exclusive_fullscreen"), @"Unable to run exclusive fullscreen. You'll still experience some input latency.");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Platform.Windows;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -34,10 +35,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
private Bindable<Size> sizeFullscreen;
|
private Bindable<Size> sizeFullscreen;
|
||||||
|
|
||||||
private readonly BindableList<Size> resolutions = new BindableList<Size>(new[] { new Size(9999, 9999) });
|
private readonly BindableList<Size> resolutions = new BindableList<Size>(new[] { new Size(9999, 9999) });
|
||||||
|
private readonly IBindable<FullscreenCapability> fullscreenCapability = new Bindable<FullscreenCapability>(FullscreenCapability.Capable);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase game { get; set; }
|
private OsuGameBase game { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
private SettingsDropdown<Size> resolutionDropdown;
|
private SettingsDropdown<Size> resolutionDropdown;
|
||||||
private SettingsDropdown<Display> displayDropdown;
|
private SettingsDropdown<Display> displayDropdown;
|
||||||
private SettingsDropdown<WindowMode> windowModeDropdown;
|
private SettingsDropdown<WindowMode> windowModeDropdown;
|
||||||
@ -65,6 +70,9 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
windowModes.BindTo(host.Window.SupportedWindowModes);
|
windowModes.BindTo(host.Window.SupportedWindowModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host.Window is WindowsWindow windowsWindow)
|
||||||
|
fullscreenCapability.BindTo(windowsWindow.FullscreenCapability);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
windowModeDropdown = new SettingsDropdown<WindowMode>
|
windowModeDropdown = new SettingsDropdown<WindowMode>
|
||||||
@ -139,6 +147,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fullscreenCapability.BindValueChanged(_ => Schedule(updateScreenModeWarning), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -150,8 +160,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
windowModeDropdown.Current.BindValueChanged(mode =>
|
windowModeDropdown.Current.BindValueChanged(mode =>
|
||||||
{
|
{
|
||||||
updateDisplayModeDropdowns();
|
updateDisplayModeDropdowns();
|
||||||
|
updateScreenModeWarning();
|
||||||
windowModeDropdown.WarningText = mode.NewValue != WindowMode.Fullscreen ? GraphicsSettingsStrings.NotFullscreenNote : default;
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
windowModes.BindCollectionChanged((sender, args) =>
|
windowModes.BindCollectionChanged((sender, args) =>
|
||||||
@ -213,6 +222,38 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateScreenModeWarning()
|
||||||
|
{
|
||||||
|
if (windowModeDropdown.Current.Value != WindowMode.Fullscreen)
|
||||||
|
{
|
||||||
|
windowModeDropdown.SetNoticeText(GraphicsSettingsStrings.NotFullscreenNote, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host.Window is WindowsWindow)
|
||||||
|
{
|
||||||
|
switch (fullscreenCapability.Value)
|
||||||
|
{
|
||||||
|
case FullscreenCapability.Unknown:
|
||||||
|
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.CheckingForFullscreenCapabilities, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FullscreenCapability.Capable:
|
||||||
|
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.OsuIsRunningExclusiveFullscreen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FullscreenCapability.Incapable:
|
||||||
|
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.UnableToRunExclusiveFullscreen, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We can only detect exclusive fullscreen status on windows currently.
|
||||||
|
windowModeDropdown.ClearNoticeText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void bindPreviewEvent(Bindable<float> bindable)
|
private void bindPreviewEvent(Bindable<float> bindable)
|
||||||
{
|
{
|
||||||
bindable.ValueChanged += _ =>
|
bindable.ValueChanged += _ =>
|
||||||
|
@ -48,7 +48,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
|
|
||||||
frameLimiterDropdown.Current.BindValueChanged(limit =>
|
frameLimiterDropdown.Current.BindValueChanged(limit =>
|
||||||
{
|
{
|
||||||
frameLimiterDropdown.WarningText = limit.NewValue == FrameSync.Unlimited ? GraphicsSettingsStrings.UnlimitedFramesNote : default;
|
switch (limit.NewValue)
|
||||||
|
{
|
||||||
|
case FrameSync.Unlimited:
|
||||||
|
frameLimiterDropdown.SetNoticeText(GraphicsSettingsStrings.UnlimitedFramesNote, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
frameLimiterDropdown.ClearNoticeText();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,9 +117,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
||||||
{
|
{
|
||||||
if (highPrecision.NewValue)
|
if (highPrecision.NewValue)
|
||||||
highPrecisionMouse.WarningText = MouseSettingsStrings.HighPrecisionPlatformWarning;
|
highPrecisionMouse.SetNoticeText(MouseSettingsStrings.HighPrecisionPlatformWarning, true);
|
||||||
else
|
else
|
||||||
highPrecisionMouse.WarningText = null;
|
highPrecisionMouse.ClearNoticeText();
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Localisation;
|
|||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
@ -95,11 +96,13 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Text = TabletSettingsStrings.NoTabletDetected,
|
Text = TabletSettingsStrings.NoTabletDetected,
|
||||||
},
|
},
|
||||||
new SettingsNoticeText(colours)
|
new LinkFlowContainer(cp => cp.Colour = colours.Yellow)
|
||||||
{
|
{
|
||||||
TextAnchor = Anchor.TopCentre,
|
TextAnchor = Anchor.TopCentre,
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
}.With(t =>
|
}.With(t =>
|
||||||
{
|
{
|
||||||
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows || RuntimeInfo.OS == RuntimeInfo.Platform.Linux)
|
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows || RuntimeInfo.OS == RuntimeInfo.Platform.Linux)
|
||||||
|
@ -61,7 +61,10 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
|
|
||||||
user.BindValueChanged(u =>
|
user.BindValueChanged(u =>
|
||||||
{
|
{
|
||||||
backgroundSourceDropdown.WarningText = u.NewValue?.IsSupporter != true ? UserInterfaceStrings.NotSupporterNote : default;
|
if (u.NewValue?.IsSupporter != true)
|
||||||
|
backgroundSourceDropdown.SetNoticeText(UserInterfaceStrings.NotSupporterNote, true);
|
||||||
|
else
|
||||||
|
backgroundSourceDropdown.ClearNoticeText();
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
private SpriteText labelText;
|
private SpriteText labelText;
|
||||||
|
|
||||||
private OsuTextFlowContainer warningText;
|
private OsuTextFlowContainer noticeText;
|
||||||
|
|
||||||
public bool ShowsDefaultIndicator = true;
|
public bool ShowsDefaultIndicator = true;
|
||||||
private readonly Container defaultValueIndicatorContainer;
|
private readonly Container defaultValueIndicatorContainer;
|
||||||
@ -70,27 +70,32 @@ namespace osu.Game.Overlays.Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Text to be displayed at the bottom of this <see cref="SettingsItem{T}"/>.
|
/// Clear any warning text.
|
||||||
/// Generally used to recommend the user change their setting as the current one is considered sub-optimal.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LocalisableString? WarningText
|
public void ClearNoticeText()
|
||||||
{
|
{
|
||||||
set
|
noticeText?.Expire();
|
||||||
|
noticeText = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the text to be displayed at the bottom of this <see cref="SettingsItem{T}"/>.
|
||||||
|
/// Generally used to provide feedback to a user about a sub-optimal setting.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text to display.</param>
|
||||||
|
/// <param name="isWarning">Whether the text is in a warning state. Will decide how this is visually represented.</param>
|
||||||
|
public void SetNoticeText(LocalisableString text, bool isWarning = false)
|
||||||
|
{
|
||||||
|
ClearNoticeText();
|
||||||
|
|
||||||
|
// construct lazily for cases where the label is not needed (may be provided by the Control).
|
||||||
|
FlowContent.Add(noticeText = new LinkFlowContainer(cp => cp.Colour = isWarning ? colours.Yellow : colours.Green)
|
||||||
{
|
{
|
||||||
bool hasValue = value != default;
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
if (warningText == null)
|
Margin = new MarginPadding { Bottom = 5 },
|
||||||
{
|
Text = text,
|
||||||
if (!hasValue)
|
});
|
||||||
return;
|
|
||||||
|
|
||||||
// construct lazily for cases where the label is not needed (may be provided by the Control).
|
|
||||||
FlowContent.Add(warningText = new SettingsNoticeText(colours) { Margin = new MarginPadding { Bottom = 5 } });
|
|
||||||
}
|
|
||||||
|
|
||||||
warningText.Alpha = hasValue ? 1 : 0;
|
|
||||||
warningText.Text = value ?? default;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Bindable<T> Current
|
public virtual Bindable<T> Current
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
|
||||||
{
|
|
||||||
public class SettingsNoticeText : LinkFlowContainer
|
|
||||||
{
|
|
||||||
public SettingsNoticeText(OsuColour colours)
|
|
||||||
: base(s => s.Colour = colours.Yellow)
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X;
|
|
||||||
AutoSizeAxes = Axes.Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user