From da681b8d42fe44bd4ec836451d0c0beff15a2d6e Mon Sep 17 00:00:00 2001 From: Seercat3160 <76834828+Seercat3160@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:58:09 +1000 Subject: [PATCH 1/2] Add failing test for dropdown keyboard selection order --- .../Visual/UserInterface/TestSceneDropdown.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/osu.Framework.Tests/Visual/UserInterface/TestSceneDropdown.cs b/osu.Framework.Tests/Visual/UserInterface/TestSceneDropdown.cs index c1d247b409..9b6e604ffa 100644 --- a/osu.Framework.Tests/Visual/UserInterface/TestSceneDropdown.cs +++ b/osu.Framework.Tests/Visual/UserInterface/TestSceneDropdown.cs @@ -312,6 +312,42 @@ void checkOrder(int index, string item) => AddAssert($"item #{index + 1} is '{it () => Is.EqualTo(item)); } + [Test] + public void TestKeyboardSelectionOrder() + { + TestDropdown testDropdown = null!; + BindableList bindableList = null!; + + AddStep("setup dropdown", () => testDropdown = createDropdown()); + + AddStep("bind source", () => testDropdown.ItemSource = bindableList = new BindableList()); + + AddStep("add items to bindable", () => bindableList.AddRange(new[] { "one", "two", "three" }.Select(s => new TestModel(s)))); + + AddStep("hover dropdown", () => InputManager.MoveMouseTo(testDropdown.Header)); + + AddStep("select first item", () => InputManager.Keys(PlatformAction.MoveToListStart)); + AddAssert("'one' is selected", () => testDropdown.Current.Value?.Identifier == "one"); + + AddStep("select next item", () => + { + InputManager.Key(Key.Down); + }); + AddAssert("'two' is selected", () => testDropdown.Current.Value?.Identifier == "two"); + + AddStep("add 'three-halves'", () => bindableList.Add("three-halves")); + AddStep("move 'three-halves'", () => bindableList.Move(3, 1)); + + AddStep("select previous item", () => + { + InputManager.Key(Key.Up); + }); + AddAssert("'three-halves' is selected", () => testDropdown.Current.Value?.Identifier == "three-halves"); + + AddStep("select last item", () => InputManager.Keys(PlatformAction.MoveToListEnd)); + AddAssert("'three' is selected", () => testDropdown.Current.Value?.Identifier == "three"); + } + [Test] public void TestExternalManagement() { From 22035db0562fe54445d7338fa7dff0dbefa3116b Mon Sep 17 00:00:00 2001 From: Seercat3160 <76834828+Seercat3160@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:17:34 +1000 Subject: [PATCH 2/2] Fix dropdown keyboard selection order --- osu.Framework/Graphics/UserInterface/Dropdown.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Framework/Graphics/UserInterface/Dropdown.cs b/osu.Framework/Graphics/UserInterface/Dropdown.cs index 5a17242c4c..ef57cfea7e 100644 --- a/osu.Framework/Graphics/UserInterface/Dropdown.cs +++ b/osu.Framework/Graphics/UserInterface/Dropdown.cs @@ -289,7 +289,7 @@ private void selectionKeyPressed(DropdownHeader.DropdownSelectionAction action) if (!MenuItems.Any()) return; - var dropdownMenuItems = MenuItems.ToList(); + var dropdownMenuItems = Menu.VisibleMenuItems.Select(item => (DropdownMenuItem)item.Item).ToList(); switch (action) { @@ -505,7 +505,7 @@ private void clearPreselection(MenuState obj) PreselectItem(null); } - protected internal IEnumerable VisibleMenuItems => Children.OfType().Where(i => i.MatchingFilter); + protected internal IEnumerable VisibleMenuItems => Children.OrderBy(itemsFlow.GetLayoutPosition).OfType().Where(i => i.MatchingFilter); protected internal IEnumerable MenuItemsInView => VisibleMenuItems.Where(item => !item.IsMaskedAway); public DrawableDropdownMenuItem PreselectedItem => VisibleMenuItems.FirstOrDefault(c => c.IsPreSelected)