From 641ea5b950f6087d79b24b8339e2f5fa9b4bc10a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 30 Jun 2020 13:12:33 +0200 Subject: [PATCH 01/10] Make the disabling of the win key during gameplay a toggleable setting. --- osu.Game/Configuration/OsuConfigManager.cs | 4 +++- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 9d31bc9bba..e7a86e080d 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -98,6 +98,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised); Set(OsuSetting.IncreaseFirstObjectVisibility, true); + Set(OsuSetting.GameplayDisableWinKey, true); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -227,6 +228,7 @@ namespace osu.Game.Configuration IntroSequence, UIHoldActivationDelay, HitLighting, - MenuBackgroundSource + MenuBackgroundSource, + GameplayDisableWinKey } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 93a02ea0e4..60197c62b5 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -76,6 +76,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = "Score display mode", Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + }, + new SettingsCheckbox + { + LabelText = "Disable Win key during gameplay", + Bindable = config.GetBindable(OsuSetting.GameplayDisableWinKey) } }; } From fc1eb42a650fef5497bec37e20b5e2a29f773c07 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 1 Jul 2020 17:15:41 +0200 Subject: [PATCH 02/10] Disable windows key while in gameplay. --- osu.Desktop/OsuGameDesktop.cs | 4 + osu.Desktop/Windows/GameplayWinKeyHandler.cs | 39 ++++++++++ osu.Desktop/Windows/WindowsKey.cs | 82 ++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 osu.Desktop/Windows/GameplayWinKeyHandler.cs create mode 100644 osu.Desktop/Windows/WindowsKey.cs diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index cd31df316a..d05a4af126 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -16,6 +16,7 @@ using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Screens.Menu; using osu.Game.Updater; +using osu.Desktop.Windows; namespace osu.Desktop { @@ -98,6 +99,9 @@ namespace osu.Desktop LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add); LoadComponentAsync(new DiscordRichPresence(), Add); + + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + LoadComponentAsync(new GameplayWinKeyHandler(), Add); } protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs new file mode 100644 index 0000000000..cc0150497b --- /dev/null +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Platform; +using osu.Game.Configuration; + +namespace osu.Desktop.Windows +{ + public class GameplayWinKeyHandler : Component + { + private Bindable winKeyEnabled; + private Bindable disableWinKey; + + private GameHost host; + + [BackgroundDependencyLoader] + private void load(GameHost host, OsuConfigManager config) + { + this.host = host; + + winKeyEnabled = host.AllowScreenSuspension.GetBoundCopy(); + winKeyEnabled.ValueChanged += toggleWinKey; + + disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); + disableWinKey.BindValueChanged(t => winKeyEnabled.TriggerChange()); + } + + private void toggleWinKey(ValueChangedEvent e) + { + if (!e.NewValue && disableWinKey.Value) + host.InputThread.Scheduler.Add(WindowsKey.Disable); + else + host.InputThread.Scheduler.Add(WindowsKey.Enable); + } + } +} diff --git a/osu.Desktop/Windows/WindowsKey.cs b/osu.Desktop/Windows/WindowsKey.cs new file mode 100644 index 0000000000..748d9c55d6 --- /dev/null +++ b/osu.Desktop/Windows/WindowsKey.cs @@ -0,0 +1,82 @@ +// 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.Runtime.InteropServices; + +namespace osu.Desktop.Windows +{ + internal class WindowsKey + { + private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KdDllHookStruct lParam); + + private static bool isBlocked; + + private const int wh_keyboard_ll = 13; + private const int wm_keydown = 256; + private const int wm_syskeyup = 261; + + //Resharper disable once NotAccessedField.Local + private static LowLevelKeyboardProcDelegate keyboardHookDelegate; // keeping a reference alive for the GC + private static IntPtr keyHook; + + [StructLayout(LayoutKind.Explicit)] + private struct KdDllHookStruct + { + [FieldOffset(0)] + public readonly int VkCode; + + [FieldOffset(8)] + public readonly int Flags; + } + + private static int lowLevelKeyboardProc(int nCode, int wParam, ref KdDllHookStruct lParam) + { + if (wParam >= wm_keydown && wParam <= wm_syskeyup) + { + switch (lParam.VkCode) + { + case 0x09 when lParam.Flags == 32: // alt + tab + case 0x1b when lParam.Flags == 32: // alt + esc + case 0x5B: // left windows key + case 0x5C: // right windows key + return 1; + } + } + + return callNextHookEx(0, nCode, wParam, ref lParam); + } + + internal static void Disable() + { + if (keyHook != IntPtr.Zero || isBlocked) + return; + + keyHook = setWindowsHookEx(wh_keyboard_ll, (keyboardHookDelegate = lowLevelKeyboardProc), Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0); + + isBlocked = true; + } + + internal static void Enable() + { + if (keyHook == IntPtr.Zero || !isBlocked) + return; + + keyHook = unhookWindowsHookEx(keyHook); + keyboardHookDelegate = null; + + keyHook = IntPtr.Zero; + + isBlocked = false; + } + + [DllImport(@"user32.dll", EntryPoint = @"SetWindowsHookExA")] + private static extern IntPtr setWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId); + + [DllImport(@"user32.dll", EntryPoint = @"UnhookWindowsHookEx")] + private static extern IntPtr unhookWindowsHookEx(IntPtr hHook); + + [DllImport(@"user32.dll", EntryPoint = @"CallNextHookEx")] + private static extern int callNextHookEx(int hHook, int nCode, int wParam, ref KdDllHookStruct lParam); + } +} From 8869979599b2b79371b0ef2278a5f32f7200e883 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 4 Jul 2020 12:30:09 +0200 Subject: [PATCH 03/10] Trigger hook activation on bind. --- osu.Desktop/Windows/GameplayWinKeyHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs index cc0150497b..394df9dd0c 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -25,7 +25,7 @@ namespace osu.Desktop.Windows winKeyEnabled.ValueChanged += toggleWinKey; disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); - disableWinKey.BindValueChanged(t => winKeyEnabled.TriggerChange()); + disableWinKey.BindValueChanged(t => winKeyEnabled.TriggerChange(), true); } private void toggleWinKey(ValueChangedEvent e) From ce5da5c51b98136503052eb11df547497019e6fb Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 5 Jul 2020 18:52:27 +0200 Subject: [PATCH 04/10] Block CTRL + ESC --- osu.Desktop/Windows/GameplayWinKeyHandler.cs | 8 ++++---- osu.Desktop/Windows/WindowsKey.cs | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs index 394df9dd0c..4f74a4f492 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -11,7 +11,7 @@ namespace osu.Desktop.Windows { public class GameplayWinKeyHandler : Component { - private Bindable winKeyEnabled; + private Bindable allowScreenSuspension; private Bindable disableWinKey; private GameHost host; @@ -21,11 +21,11 @@ namespace osu.Desktop.Windows { this.host = host; - winKeyEnabled = host.AllowScreenSuspension.GetBoundCopy(); - winKeyEnabled.ValueChanged += toggleWinKey; + allowScreenSuspension = host.AllowScreenSuspension.GetBoundCopy(); + allowScreenSuspension.ValueChanged += toggleWinKey; disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); - disableWinKey.BindValueChanged(t => winKeyEnabled.TriggerChange(), true); + disableWinKey.BindValueChanged(t => allowScreenSuspension.TriggerChange(), true); } private void toggleWinKey(ValueChangedEvent e) diff --git a/osu.Desktop/Windows/WindowsKey.cs b/osu.Desktop/Windows/WindowsKey.cs index 748d9c55d6..175401aaed 100644 --- a/osu.Desktop/Windows/WindowsKey.cs +++ b/osu.Desktop/Windows/WindowsKey.cs @@ -38,6 +38,7 @@ namespace osu.Desktop.Windows { case 0x09 when lParam.Flags == 32: // alt + tab case 0x1b when lParam.Flags == 32: // alt + esc + case 0x1b when (getKeyState(0x11) & 0x8000) != 0: //ctrl + esc case 0x5B: // left windows key case 0x5C: // right windows key return 1; @@ -78,5 +79,8 @@ namespace osu.Desktop.Windows [DllImport(@"user32.dll", EntryPoint = @"CallNextHookEx")] private static extern int callNextHookEx(int hHook, int nCode, int wParam, ref KdDllHookStruct lParam); + + [DllImport(@"user32.dll", EntryPoint = @"GetKeyState")] + private static extern int getKeyState(int vkey); } } From 022e4b6335c0ebdfbc48ec4f1764ba04257a01b4 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 6 Jul 2020 11:15:56 +0200 Subject: [PATCH 05/10] Apply review suggestions. --- osu.Desktop/Windows/WindowsKey.cs | 6 ------ .../Settings/Sections/Gameplay/GeneralSettings.cs | 15 ++++++++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Desktop/Windows/WindowsKey.cs b/osu.Desktop/Windows/WindowsKey.cs index 175401aaed..4a815b135e 100644 --- a/osu.Desktop/Windows/WindowsKey.cs +++ b/osu.Desktop/Windows/WindowsKey.cs @@ -36,9 +36,6 @@ namespace osu.Desktop.Windows { switch (lParam.VkCode) { - case 0x09 when lParam.Flags == 32: // alt + tab - case 0x1b when lParam.Flags == 32: // alt + esc - case 0x1b when (getKeyState(0x11) & 0x8000) != 0: //ctrl + esc case 0x5B: // left windows key case 0x5C: // right windows key return 1; @@ -79,8 +76,5 @@ namespace osu.Desktop.Windows [DllImport(@"user32.dll", EntryPoint = @"CallNextHookEx")] private static extern int callNextHookEx(int hHook, int nCode, int wParam, ref KdDllHookStruct lParam); - - [DllImport(@"user32.dll", EntryPoint = @"GetKeyState")] - private static extern int getKeyState(int vkey); } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 60197c62b5..0149e6c3a6 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; @@ -76,13 +77,17 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = "Score display mode", Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) - }, - new SettingsCheckbox - { - LabelText = "Disable Win key during gameplay", - Bindable = config.GetBindable(OsuSetting.GameplayDisableWinKey) } }; + + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + { + Add(new SettingsCheckbox + { + LabelText = "Disable Windows key during gameplay", + Bindable = config.GetBindable(OsuSetting.GameplayDisableWinKey) + }); + } } } } From 939441ae408d5f4eb7ee61dba8da54e5e056d481 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 16 Jul 2020 14:50:11 +0200 Subject: [PATCH 06/10] Disable the windows key only when in gameplay. --- osu.Desktop/Windows/GameplayWinKeyHandler.cs | 14 +++++++------- osu.Game/Configuration/SessionStatics.cs | 4 +++- osu.Game/Screens/Play/ScreenSuspensionHandler.cs | 13 ++++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs index 4f74a4f492..d5ef89c680 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -11,26 +11,26 @@ namespace osu.Desktop.Windows { public class GameplayWinKeyHandler : Component { - private Bindable allowScreenSuspension; private Bindable disableWinKey; + private Bindable disableWinKeySetting; private GameHost host; [BackgroundDependencyLoader] - private void load(GameHost host, OsuConfigManager config) + private void load(GameHost host, OsuConfigManager config, SessionStatics statics) { this.host = host; - allowScreenSuspension = host.AllowScreenSuspension.GetBoundCopy(); - allowScreenSuspension.ValueChanged += toggleWinKey; + disableWinKey = statics.GetBindable(Static.DisableWindowsKey); + disableWinKey.ValueChanged += toggleWinKey; - disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); - disableWinKey.BindValueChanged(t => allowScreenSuspension.TriggerChange(), true); + disableWinKeySetting = config.GetBindable(OsuSetting.GameplayDisableWinKey); + disableWinKeySetting.BindValueChanged(t => disableWinKey.TriggerChange(), true); } private void toggleWinKey(ValueChangedEvent e) { - if (!e.NewValue && disableWinKey.Value) + if (e.NewValue && disableWinKeySetting.Value) host.InputThread.Scheduler.Add(WindowsKey.Disable); else host.InputThread.Scheduler.Add(WindowsKey.Enable); diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 40b2adb867..7aad79b5ad 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -12,12 +12,14 @@ namespace osu.Game.Configuration { Set(Static.LoginOverlayDisplayed, false); Set(Static.MutedAudioNotificationShownOnce, false); + Set(Static.DisableWindowsKey, false); } } public enum Static { LoginOverlayDisplayed, - MutedAudioNotificationShownOnce + MutedAudioNotificationShownOnce, + DisableWindowsKey } } diff --git a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs index 8585a5c309..c2c7f1ac41 100644 --- a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs +++ b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; +using osu.Game.Configuration; namespace osu.Game.Screens.Play { @@ -22,6 +23,9 @@ namespace osu.Game.Screens.Play [Resolved] private GameHost host { get; set; } + [Resolved] + private SessionStatics statics { get; set; } + public ScreenSuspensionHandler([NotNull] GameplayClockContainer gameplayClockContainer) { this.gameplayClockContainer = gameplayClockContainer ?? throw new ArgumentNullException(nameof(gameplayClockContainer)); @@ -36,7 +40,11 @@ namespace osu.Game.Screens.Play Debug.Assert(host.AllowScreenSuspension.Value); isPaused = gameplayClockContainer.IsPaused.GetBoundCopy(); - isPaused.BindValueChanged(paused => host.AllowScreenSuspension.Value = paused.NewValue, true); + isPaused.BindValueChanged(paused => + { + host.AllowScreenSuspension.Value = paused.NewValue; + statics.Set(Static.DisableWindowsKey, !paused.NewValue); + }, true); } protected override void Dispose(bool isDisposing) @@ -46,7 +54,10 @@ namespace osu.Game.Screens.Play isPaused?.UnbindAll(); if (host != null) + { host.AllowScreenSuspension.Value = true; + statics.Set(Static.DisableWindowsKey, false); + } } } } From 396ada7f39fb52a3301398c1cf8d17767da86bf6 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 16 Jul 2020 15:03:25 +0200 Subject: [PATCH 07/10] Enable windows key when a replay is loaded. --- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/ScreenSuspensionHandler.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..e0721d55f7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Play InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); - AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); + AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer, DrawableRuleset.HasReplayLoaded)); dependencies.CacheAs(gameplayBeatmap); diff --git a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs index c2c7f1ac41..6865db5a5e 100644 --- a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs +++ b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Play { private readonly GameplayClockContainer gameplayClockContainer; private Bindable isPaused; + private readonly Bindable hasReplayLoaded; [Resolved] private GameHost host { get; set; } @@ -26,9 +27,10 @@ namespace osu.Game.Screens.Play [Resolved] private SessionStatics statics { get; set; } - public ScreenSuspensionHandler([NotNull] GameplayClockContainer gameplayClockContainer) + public ScreenSuspensionHandler([NotNull] GameplayClockContainer gameplayClockContainer, Bindable hasReplayLoaded) { this.gameplayClockContainer = gameplayClockContainer ?? throw new ArgumentNullException(nameof(gameplayClockContainer)); + this.hasReplayLoaded = hasReplayLoaded.GetBoundCopy(); } protected override void LoadComplete() @@ -43,8 +45,9 @@ namespace osu.Game.Screens.Play isPaused.BindValueChanged(paused => { host.AllowScreenSuspension.Value = paused.NewValue; - statics.Set(Static.DisableWindowsKey, !paused.NewValue); + statics.Set(Static.DisableWindowsKey, !paused.NewValue && !hasReplayLoaded.Value); }, true); + hasReplayLoaded.BindValueChanged(_ => isPaused.TriggerChange(), true); } protected override void Dispose(bool isDisposing) @@ -52,6 +55,7 @@ namespace osu.Game.Screens.Play base.Dispose(isDisposing); isPaused?.UnbindAll(); + hasReplayLoaded.UnbindAll(); if (host != null) { From 4102dae999cb7f63294b033898885d50afbc799b Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 22 Jul 2020 21:45:27 +0200 Subject: [PATCH 08/10] Revert commit 939441ae --- osu.Desktop/Windows/GameplayWinKeyHandler.cs | 14 +++++++------- osu.Game/Configuration/SessionStatics.cs | 4 +--- osu.Game/Screens/Play/Player.cs | 2 +- .../Screens/Play/ScreenSuspensionHandler.cs | 19 ++----------------- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs index d5ef89c680..4f74a4f492 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -11,26 +11,26 @@ namespace osu.Desktop.Windows { public class GameplayWinKeyHandler : Component { + private Bindable allowScreenSuspension; private Bindable disableWinKey; - private Bindable disableWinKeySetting; private GameHost host; [BackgroundDependencyLoader] - private void load(GameHost host, OsuConfigManager config, SessionStatics statics) + private void load(GameHost host, OsuConfigManager config) { this.host = host; - disableWinKey = statics.GetBindable(Static.DisableWindowsKey); - disableWinKey.ValueChanged += toggleWinKey; + allowScreenSuspension = host.AllowScreenSuspension.GetBoundCopy(); + allowScreenSuspension.ValueChanged += toggleWinKey; - disableWinKeySetting = config.GetBindable(OsuSetting.GameplayDisableWinKey); - disableWinKeySetting.BindValueChanged(t => disableWinKey.TriggerChange(), true); + disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); + disableWinKey.BindValueChanged(t => allowScreenSuspension.TriggerChange(), true); } private void toggleWinKey(ValueChangedEvent e) { - if (e.NewValue && disableWinKeySetting.Value) + if (!e.NewValue && disableWinKey.Value) host.InputThread.Scheduler.Add(WindowsKey.Disable); else host.InputThread.Scheduler.Add(WindowsKey.Enable); diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 7aad79b5ad..40b2adb867 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -12,14 +12,12 @@ namespace osu.Game.Configuration { Set(Static.LoginOverlayDisplayed, false); Set(Static.MutedAudioNotificationShownOnce, false); - Set(Static.DisableWindowsKey, false); } } public enum Static { LoginOverlayDisplayed, - MutedAudioNotificationShownOnce, - DisableWindowsKey + MutedAudioNotificationShownOnce } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e0721d55f7..541275cf55 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Play InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); - AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer, DrawableRuleset.HasReplayLoaded)); + AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); dependencies.CacheAs(gameplayBeatmap); diff --git a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs index 6865db5a5e..8585a5c309 100644 --- a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs +++ b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; -using osu.Game.Configuration; namespace osu.Game.Screens.Play { @@ -19,18 +18,13 @@ namespace osu.Game.Screens.Play { private readonly GameplayClockContainer gameplayClockContainer; private Bindable isPaused; - private readonly Bindable hasReplayLoaded; [Resolved] private GameHost host { get; set; } - [Resolved] - private SessionStatics statics { get; set; } - - public ScreenSuspensionHandler([NotNull] GameplayClockContainer gameplayClockContainer, Bindable hasReplayLoaded) + public ScreenSuspensionHandler([NotNull] GameplayClockContainer gameplayClockContainer) { this.gameplayClockContainer = gameplayClockContainer ?? throw new ArgumentNullException(nameof(gameplayClockContainer)); - this.hasReplayLoaded = hasReplayLoaded.GetBoundCopy(); } protected override void LoadComplete() @@ -42,12 +36,7 @@ namespace osu.Game.Screens.Play Debug.Assert(host.AllowScreenSuspension.Value); isPaused = gameplayClockContainer.IsPaused.GetBoundCopy(); - isPaused.BindValueChanged(paused => - { - host.AllowScreenSuspension.Value = paused.NewValue; - statics.Set(Static.DisableWindowsKey, !paused.NewValue && !hasReplayLoaded.Value); - }, true); - hasReplayLoaded.BindValueChanged(_ => isPaused.TriggerChange(), true); + isPaused.BindValueChanged(paused => host.AllowScreenSuspension.Value = paused.NewValue, true); } protected override void Dispose(bool isDisposing) @@ -55,13 +44,9 @@ namespace osu.Game.Screens.Play base.Dispose(isDisposing); isPaused?.UnbindAll(); - hasReplayLoaded.UnbindAll(); if (host != null) - { host.AllowScreenSuspension.Value = true; - statics.Set(Static.DisableWindowsKey, false); - } } } } From 5e6adfff99b1b348897ab4606aef7f910016560c Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 23 Jul 2020 12:45:14 +0200 Subject: [PATCH 09/10] Disable windows key only while in gameplay. --- osu.Desktop/OsuGameDesktop.cs | 2 +- osu.Desktop/Windows/GameplayWinKeyHandler.cs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index d05a4af126..6eefee3b50 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -101,7 +101,7 @@ namespace osu.Desktop LoadComponentAsync(new DiscordRichPresence(), Add); if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - LoadComponentAsync(new GameplayWinKeyHandler(), Add); + LoadComponentAsync(new GameplayWinKeyHandler(ScreenStack), Add); } protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyHandler.cs index 4f74a4f492..96154356d0 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyHandler.cs @@ -1,11 +1,14 @@ // 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 osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; using osu.Game.Configuration; +using osu.Game.Screens; +using osu.Game.Screens.Play; namespace osu.Desktop.Windows { @@ -14,8 +17,16 @@ namespace osu.Desktop.Windows private Bindable allowScreenSuspension; private Bindable disableWinKey; + private readonly OsuScreenStack screenStack; private GameHost host; + private Type currentScreenType => screenStack.CurrentScreen?.GetType(); + + public GameplayWinKeyHandler(OsuScreenStack stack) + { + screenStack = stack; + } + [BackgroundDependencyLoader] private void load(GameHost host, OsuConfigManager config) { @@ -30,7 +41,9 @@ namespace osu.Desktop.Windows private void toggleWinKey(ValueChangedEvent e) { - if (!e.NewValue && disableWinKey.Value) + var isPlayer = typeof(Player).IsAssignableFrom(currentScreenType) && currentScreenType != typeof(ReplayPlayer); + + if (!e.NewValue && disableWinKey.Value && isPlayer) host.InputThread.Scheduler.Add(WindowsKey.Disable); else host.InputThread.Scheduler.Add(WindowsKey.Enable); From dbe9180c55c4e4d6a8991b76aa48a9a4b5f46674 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jul 2020 16:38:48 +0900 Subject: [PATCH 10/10] Rename class and remove screen conditionals --- osu.Desktop/OsuGameDesktop.cs | 2 +- ...KeyHandler.cs => GameplayWinKeyBlocker.cs} | 23 +++++-------------- osu.Desktop/Windows/WindowsKey.cs | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) rename osu.Desktop/Windows/{GameplayWinKeyHandler.cs => GameplayWinKeyBlocker.cs} (55%) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 6eefee3b50..2079f136d2 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -101,7 +101,7 @@ namespace osu.Desktop LoadComponentAsync(new DiscordRichPresence(), Add); if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - LoadComponentAsync(new GameplayWinKeyHandler(ScreenStack), Add); + LoadComponentAsync(new GameplayWinKeyBlocker(), Add); } protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen) diff --git a/osu.Desktop/Windows/GameplayWinKeyHandler.cs b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs similarity index 55% rename from osu.Desktop/Windows/GameplayWinKeyHandler.cs rename to osu.Desktop/Windows/GameplayWinKeyBlocker.cs index 96154356d0..86174ceb90 100644 --- a/osu.Desktop/Windows/GameplayWinKeyHandler.cs +++ b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs @@ -1,49 +1,38 @@ // 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 osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; using osu.Game.Configuration; -using osu.Game.Screens; -using osu.Game.Screens.Play; namespace osu.Desktop.Windows { - public class GameplayWinKeyHandler : Component + public class GameplayWinKeyBlocker : Component { private Bindable allowScreenSuspension; private Bindable disableWinKey; - private readonly OsuScreenStack screenStack; private GameHost host; - private Type currentScreenType => screenStack.CurrentScreen?.GetType(); - - public GameplayWinKeyHandler(OsuScreenStack stack) - { - screenStack = stack; - } - [BackgroundDependencyLoader] private void load(GameHost host, OsuConfigManager config) { this.host = host; allowScreenSuspension = host.AllowScreenSuspension.GetBoundCopy(); - allowScreenSuspension.ValueChanged += toggleWinKey; + allowScreenSuspension.BindValueChanged(_ => updateBlocking()); disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); - disableWinKey.BindValueChanged(t => allowScreenSuspension.TriggerChange(), true); + disableWinKey.BindValueChanged(_ => updateBlocking(), true); } - private void toggleWinKey(ValueChangedEvent e) + private void updateBlocking() { - var isPlayer = typeof(Player).IsAssignableFrom(currentScreenType) && currentScreenType != typeof(ReplayPlayer); + bool shouldDisable = disableWinKey.Value && !allowScreenSuspension.Value; - if (!e.NewValue && disableWinKey.Value && isPlayer) + if (shouldDisable) host.InputThread.Scheduler.Add(WindowsKey.Disable); else host.InputThread.Scheduler.Add(WindowsKey.Enable); diff --git a/osu.Desktop/Windows/WindowsKey.cs b/osu.Desktop/Windows/WindowsKey.cs index 4a815b135e..f19d741107 100644 --- a/osu.Desktop/Windows/WindowsKey.cs +++ b/osu.Desktop/Windows/WindowsKey.cs @@ -21,7 +21,7 @@ namespace osu.Desktop.Windows private static IntPtr keyHook; [StructLayout(LayoutKind.Explicit)] - private struct KdDllHookStruct + private readonly struct KdDllHookStruct { [FieldOffset(0)] public readonly int VkCode;