1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-14 17:17:24 +08:00

Merge pull request #12225 from peppy/fix-overzealousmouse-button-blocking

Ensure GlobalActions are handled before anything else game-wide
This commit is contained in:
Dan Balasescu 2021-04-06 17:36:32 +09:00 committed by GitHub
commit c5e5f02fbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 20 deletions

View File

@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuGameBase game) private void load(OsuGameBase game)
{ {
Child = globalActionContainer = new GlobalActionContainer(game); Child = globalActionContainer = new GlobalActionContainer(game, null);
} }
[SetUp] [SetUp]

View File

@ -36,6 +36,8 @@ namespace osu.Game.Tests.Visual.Navigation
protected override bool UseFreshStoragePerRun => true; protected override bool UseFreshStoragePerRun => true;
protected override bool CreateNestedActionContainer => false;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
{ {

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Overlays.Toolbar; using osu.Game.Overlays.Toolbar;
@ -146,7 +147,7 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition));
// BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered. // BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered.
AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == Game.BackButton)); AddUntilStep("Back button is hovered", () => Game.ChildrenOfType<BackButton>().First().Children.Any(c => c.IsHovered));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left)); AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);

View File

@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
@ -12,11 +13,16 @@ namespace osu.Game.Input.Bindings
{ {
public class GlobalActionContainer : DatabasedKeyBindingContainer<GlobalAction>, IHandleGlobalKeyboardInput public class GlobalActionContainer : DatabasedKeyBindingContainer<GlobalAction>, IHandleGlobalKeyboardInput
{ {
[CanBeNull]
private readonly GlobalInputManager globalInputManager;
private readonly Drawable handler; private readonly Drawable handler;
public GlobalActionContainer(OsuGameBase game) public GlobalActionContainer(OsuGameBase game, [CanBeNull] GlobalInputManager globalInputManager)
: base(matchingMode: KeyCombinationMatchingMode.Modifiers) : base(matchingMode: KeyCombinationMatchingMode.Modifiers)
{ {
this.globalInputManager = globalInputManager;
if (game is IKeyBindingHandler<GlobalAction>) if (game is IKeyBindingHandler<GlobalAction>)
handler = game; handler = game;
} }
@ -91,8 +97,15 @@ namespace osu.Game.Input.Bindings
new KeyBinding(InputKey.F3, GlobalAction.MusicPlay) new KeyBinding(InputKey.F3, GlobalAction.MusicPlay)
}; };
protected override IEnumerable<Drawable> KeyBindingInputQueue => protected override IEnumerable<Drawable> KeyBindingInputQueue
handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler); {
get
{
var inputQueue = globalInputManager?.NonPositionalInputQueue ?? base.KeyBindingInputQueue;
return handler != null ? inputQueue.Prepend(handler) : inputQueue;
}
}
} }
public enum GlobalAction public enum GlobalAction

View 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
namespace osu.Game.Input.Bindings
{
public class GlobalInputManager : PassThroughInputManager
{
public readonly GlobalActionContainer GlobalBindings;
protected override Container<Drawable> Content { get; }
public GlobalInputManager(OsuGameBase game)
{
InternalChildren = new Drawable[]
{
Content = new Container
{
RelativeSizeAxes = Axes.Both,
},
// to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything.
GlobalBindings = new GlobalActionContainer(game, this)
};
}
}
}

View File

@ -27,7 +27,6 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Collections; using osu.Game.Collections;
@ -879,13 +878,6 @@ namespace osu.Game
return component; return component;
} }
protected override bool OnScroll(ScrollEvent e)
{
// forward any unhandled mouse scroll events to the volume control.
volume.Adjust(GlobalAction.IncreaseVolume, e.ScrollDelta.Y, e.IsPrecise);
return true;
}
public bool OnPressed(GlobalAction action) public bool OnPressed(GlobalAction action)
{ {
if (introScreen == null) return false; if (introScreen == null) return false;

View File

@ -310,9 +310,9 @@ namespace osu.Game
MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }; MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both };
GlobalActionContainer globalBindings; GlobalInputManager globalInput;
MenuCursorContainer.Child = globalBindings = new GlobalActionContainer(this) MenuCursorContainer.Child = globalInput = new GlobalInputManager(this)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both } Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both }
@ -320,8 +320,8 @@ namespace osu.Game
base.Content.Add(CreateScalingContainer().WithChild(MenuCursorContainer)); base.Content.Add(CreateScalingContainer().WithChild(MenuCursorContainer));
KeyBindingStore.Register(globalBindings); KeyBindingStore.Register(globalInput.GlobalBindings);
dependencies.Cache(globalBindings); dependencies.Cache(globalInput.GlobalBindings);
PreviewTrackManager previewTrackManager; PreviewTrackManager previewTrackManager;
dependencies.Cache(previewTrackManager = new PreviewTrackManager()); dependencies.Cache(previewTrackManager = new PreviewTrackManager());

View File

@ -5,6 +5,7 @@ using System;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
namespace osu.Game.Overlays.Volume namespace osu.Game.Overlays.Volume
@ -17,6 +18,13 @@ namespace osu.Game.Overlays.Volume
public bool OnPressed(GlobalAction action) => public bool OnPressed(GlobalAction action) =>
ActionRequested?.Invoke(action) ?? false; ActionRequested?.Invoke(action) ?? false;
protected override bool OnScroll(ScrollEvent e)
{
// forward any unhandled mouse scroll events to the volume control.
ScrollActionRequested?.Invoke(GlobalAction.IncreaseVolume, e.ScrollDelta.Y, e.IsPrecise);
return true;
}
public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => public bool OnScroll(GlobalAction action, float amount, bool isPrecise) =>
ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false; ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false;

View File

@ -24,18 +24,31 @@ namespace osu.Game.Tests.Visual
private readonly TriangleButton buttonTest; private readonly TriangleButton buttonTest;
private readonly TriangleButton buttonLocal; private readonly TriangleButton buttonLocal;
/// <summary>
/// Whether to create a nested container to handle <see cref="GlobalAction"/>s that result from local (manual) test input.
/// This should be disabled when instantiating an <see cref="OsuGame"/> instance else actions will be lost.
/// </summary>
protected virtual bool CreateNestedActionContainer => true;
protected OsuManualInputManagerTestScene() protected OsuManualInputManagerTestScene()
{ {
MenuCursorContainer cursorContainer; MenuCursorContainer cursorContainer;
CompositeDrawable mainContent =
(cursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both })
.WithChild(content = new OsuTooltipContainer(cursorContainer.Cursor) { RelativeSizeAxes = Axes.Both });
if (CreateNestedActionContainer)
{
mainContent = new GlobalActionContainer(null, null).WithChild(mainContent);
}
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {
InputManager = new ManualInputManager InputManager = new ManualInputManager
{ {
UseParentInput = true, UseParentInput = true,
Child = new GlobalActionContainer(null) Child = mainContent
.WithChild((cursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both })
.WithChild(content = new OsuTooltipContainer(cursorContainer.Cursor) { RelativeSizeAxes = Axes.Both }))
}, },
new Container new Container
{ {