From 67380402ab01ff588d66781183a57f2467a432e9 Mon Sep 17 00:00:00 2001 From: PulkoMandy Date: Sun, 28 Jan 2024 14:29:22 +0100 Subject: [PATCH] BMenu: use std::stable_sort to implement SortItems This fixes two problems: - Use of a stable sorting algorithm makes sure that the relative position between items that compare equal are not modified - More importantly, the compare function in BList passes a pointer-to-pointer (in this case a BMenuItem**) and this was masked by the casts due to BList lack of type safety. So, BMenu::SortItems was not working at all when trying to use it as its prototype would imply. NetworkStatus and Network preferences worked around this by doing the extra dereferencing in their compare functions. I did not find any other places in Haiku where this function is used (it was introduced specifically for this in hrev55562). All 3rd party code that had a similar workaround will have to be fixed to remove it (if there is anything using that function). Change-Id: Ia78fd1363f2c012f6eff6f9a47e8b3aac2752ebd Reviewed-on: https://review.haiku-os.org/c/haiku/+/7356 Reviewed-by: Niels Sascha Reedijk --- src/apps/networkstatus/WirelessNetworkMenuItem.cpp | 4 ++-- src/kits/interface/Menu.cpp | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/apps/networkstatus/WirelessNetworkMenuItem.cpp b/src/apps/networkstatus/WirelessNetworkMenuItem.cpp index e6ea0e423b..940711db66 100644 --- a/src/apps/networkstatus/WirelessNetworkMenuItem.cpp +++ b/src/apps/networkstatus/WirelessNetworkMenuItem.cpp @@ -103,8 +103,8 @@ WirelessNetworkMenuItem::DrawRadioIcon() WirelessNetworkMenuItem::CompareSignalStrength(const BMenuItem* a, const BMenuItem* b) { - WirelessNetworkMenuItem* aItem = *(WirelessNetworkMenuItem**)a; - WirelessNetworkMenuItem* bItem = *(WirelessNetworkMenuItem**)b; + WirelessNetworkMenuItem* aItem = (WirelessNetworkMenuItem*)a; + WirelessNetworkMenuItem* bItem = (WirelessNetworkMenuItem*)b; wireless_network aNetwork = aItem->Network(); wireless_network bNetwork = bItem->Network(); diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 7c97ab6566..1c0fe310fd 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1451,7 +1451,11 @@ BMenu::SetTrackingHook(menu_tracking_hook func, void* state) void BMenu::SortItems(int (*compare)(const BMenuItem*, const BMenuItem*)) { - fItems.SortItems((int (*)(const void*, const void*))compare); + BMenuItem** begin = (BMenuItem**)fItems.Items(); + BMenuItem** end = begin + fItems.CountItems(); + + std::stable_sort(begin, end, compare); + InvalidateLayout(); if (Window() != NULL && !Window()->IsHidden() && LockLooper()) { _LayoutItems(0);