diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 18351c20ce..710ca9ace7 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -57,17 +57,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor [BackgroundDependencyLoader] private void load() { - InternalChild = cursorScaleContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - } - }; + InternalChild = CreateCursorContent(); userCursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); userCursorScale.ValueChanged += _ => cursorScale.Value = CalculateCursorScale(); @@ -84,6 +74,18 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor cursorScale.Value = CalculateCursorScale(); } + protected virtual Drawable CreateCursorContent() => cursorScaleContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + }, + }; + protected virtual float CalculateCursorScale() { float scale = userCursorScale.Value; diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index f5e83f46f2..8a84fe14e5 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -65,17 +65,24 @@ namespace osu.Game.Rulesets.Osu.UI public override bool HandlePositionalInput => true; public Action ResumeRequested; + private Container scaleTransitionContainer; public OsuClickToResumeCursor() { RelativePositionAxes = Axes.Both; } - protected override float CalculateCursorScale() + protected override Container CreateCursorContent() => scaleTransitionContainer = new Container { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Child = base.CreateCursorContent(), + }; + + protected override float CalculateCursorScale() => // Force minimum cursor size so it's easily clickable - return Math.Max(1f, base.CalculateCursorScale()); - } + Math.Max(1f, base.CalculateCursorScale()); protected override bool OnHover(HoverEvent e) { @@ -98,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.UI if (!IsHovered) return false; - this.ScaleTo(2, TRANSITION_TIME, Easing.OutQuint); + scaleTransitionContainer.ScaleTo(2, TRANSITION_TIME, Easing.OutQuint); ResumeRequested?.Invoke(); return true; @@ -114,7 +121,10 @@ namespace osu.Game.Rulesets.Osu.UI public void Appear() => Schedule(() => { updateColour(); - this.ScaleTo(4).Then().ScaleTo(1, 1000, Easing.OutQuint); + + // importantly, we perform the scale transition on an underlying container rather than the whole cursor + // to prevent attempts of abuse by the scale change in the cursor's hitbox (see: https://github.com/ppy/osu/issues/26477). + scaleTransitionContainer.ScaleTo(4).Then().ScaleTo(1, 1000, Easing.OutQuint); }); private void updateColour()