Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close object context menu on tool change #31081

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

kongehund
Copy link
Contributor

@kongehund kongehund commented Dec 11, 2024

fixes #31053

Normally, clicking on a different Toolbox button will ensure focus is changed via https://github.com/ppy/osu-framework/blob/f5900ab07acf7fc11b58b461e037f3222ae0190d/osu.Framework/Input/MouseButtonEventManager.cs#L167 which causes the context menu to close.

However, using number buttons (1-4) to select tools seems not to cause any focus change.

To address the issue, a focus change is forced on any tool change (by setting focused drawable -> null), which ensures that the context menu closes. I am unaware of other means of selection loss that should also close the menu.

Comment on lines +535 to +536
// Prevent object context menu from staying open.
GetContainingFocusManager()?.ChangeFocus(null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dodgy as all hell, and may be broken by future changes that allow multiple simultaneously focused drawables (hi @smoogipoo).

I think we need a proper "close the context menu that I opened" primitive in framework. Maybe something like (VERY UNTESTED, written just to demonstrate general idea):

diff --git a/osu.Framework/Graphics/Cursor/ContextMenuContainer.cs b/osu.Framework/Graphics/Cursor/ContextMenuContainer.cs
index 9ff908d69..0174322cf 100644
--- a/osu.Framework/Graphics/Cursor/ContextMenuContainer.cs
+++ b/osu.Framework/Graphics/Cursor/ContextMenuContainer.cs
@@ -76,6 +76,14 @@ protected override bool OnMouseDown(MouseDownEvent e)
 
                     menuTarget = target;
 
+                    menuTarget.CloseRequested += t =>
+                    {
+                        if (menuTarget != t)
+                            return;
+
+                        menu.Close();
+                    };
+
                     if (menuTarget == null || items.Length == 0)
                     {
                         if (menu.State == MenuState.Open)
diff --git a/osu.Framework/Graphics/Cursor/IHasContextMenu.cs b/osu.Framework/Graphics/Cursor/IHasContextMenu.cs
index 0a214a2f0..c3188e873 100644
--- a/osu.Framework/Graphics/Cursor/IHasContextMenu.cs
+++ b/osu.Framework/Graphics/Cursor/IHasContextMenu.cs
@@ -1,6 +1,7 @@
 // Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using System;
 using osu.Framework.Graphics.UserInterface;
 
 namespace osu.Framework.Graphics.Cursor
@@ -15,5 +16,9 @@ public interface IHasContextMenu : IDrawable
         /// <para>If null, this <see cref="Drawable"/> will not be picked as the menu target and other <see cref="Drawable"/>s underneath may become the menu target.</para>
         /// </remarks>
         MenuItem[]? ContextMenuItems { get; }
+
+        internal Action<IHasContextMenu>? CloseRequested { get; set; }
+
+        public void RequestClose() => CloseRequested?.Invoke(this);
     }
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tool changes and other means of selection loss should close object context menu
2 participants