From ce3d8d37c5821b98709004b3f692ecf151de9144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 28 Sep 2026 11:50:28 -0600 Subject: [PATCH] Game browser search: also match the filename, minus extension Works before the game's metadata has loaded. Co-Authored-By: Claude Opus 5.5 (1M context) --- Common/UI/View.h | 2 ++ UI/GameBrowser.cpp | 10 ++++++++++ UI/MiscViews.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/Common/UI/View.h b/Common/UI/View.h index 8782e36243..0a2b4b4137 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -396,6 +396,8 @@ public: virtual std::string DescribeLog() const; // Accessible/searchable description. virtual std::string DescribeText() const { return ""; } + // Extra text that search also matches against, available even before DescribeText is (like a filename). + virtual std::string SearchAlias() const { return ""; } virtual void FocusChanged(FocusFlags focusFlags) {} virtual void PersistData(PersistStatus status, std::string anonId, PersistMap &storage); diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index ddf91bf7c3..ef9be81dfb 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -108,6 +108,16 @@ public: void Draw(UIContext &dc) override; std::string DescribeText() const override; + std::string SearchAlias() const override { + // Without the extension, or searching for "iso" would match every ISO. Only three or more + // letters counts as one, so a folder like "Game v1.2" keeps its version number. + std::string filename = gamePath_.GetFilename(); + const std::string ext = gamePath_.GetFileExtension(); + if (ext.size() >= 4 && ext.size() <= filename.size() && std::all_of(ext.begin() + 1, ext.end(), [](char c) { return c >= 'a' && c <= 'z'; })) { + filename.resize(filename.size() - ext.size()); + } + return filename; + } void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { if (gridStyle_) { w = 144 * g_Config.fGameGridScale; diff --git a/UI/MiscViews.cpp b/UI/MiscViews.cpp index 6fe54781d3..4beaf311e4 100644 --- a/UI/MiscViews.cpp +++ b/UI/MiscViews.cpp @@ -397,6 +397,11 @@ void ViewSearch::ApplySearchFilter(UI::ViewGroup *viewGroup, bool setKeyboardFoc if (v->CanBeFocused() && !firstMatch) { firstMatch = v; } + } else if (v->CanBeFocused() && NormalizeForSearch(v->SearchAlias()).find(filter) != std::string::npos) { + match = true; + if (!firstMatch) { + firstMatch = v; + } } else { std::string label = v->DescribeText(); // This is a bit of a hack to recognize a pending game title.