From 3a599c4714d3d2a74b4ea020df107f5c28bebf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 6 May 2026 00:06:14 +0200 Subject: [PATCH] Fix audio focus issue by tracking the cause of lost focus. Fixes #21643 --- Common/UI/PopupScreens.cpp | 16 +++++++------- Common/UI/Root.cpp | 16 +++++++------- Common/UI/Root.h | 3 ++- Common/UI/Screen.cpp | 4 ++-- Common/UI/Screen.h | 1 - Common/UI/UIScreen.cpp | 2 +- Common/UI/View.cpp | 44 ++++++++++++++++++++++--------------- Common/UI/View.h | 27 ++++++++++++++++------- Common/UI/ViewGroup.cpp | 4 ++-- Common/UI/ViewGroup.h | 2 +- UI/ChatScreen.cpp | 2 +- UI/ControlMappingScreen.cpp | 19 ++++++++-------- UI/EmuScreen.cpp | 2 +- UI/GameBrowser.cpp | 8 +++---- UI/MainScreen.cpp | 13 +++++++---- UI/MiscViews.cpp | 2 +- 16 files changed, 95 insertions(+), 70 deletions(-) diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index 248169f9fe..42f8feb693 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -416,7 +416,7 @@ void PopupMultiChoice::ChoiceCallback(int num) { OnChoice.Trigger(e); if (restoreFocus_) { - SetFocusedView(this); + SetFocusedView(this, FocusFlags::CAUSE_SCREEN_CHANGE); } } } @@ -489,7 +489,7 @@ void PopupSliderChoice::HandleChange(EventParams &e) { OnChange.Trigger(e); if (restoreFocus_) { - SetFocusedView(this); + SetFocusedView(this, FocusFlags::CAUSE_SCREEN_CHANGE); } } @@ -552,7 +552,7 @@ void PopupSliderChoiceFloat::HandleChange(EventParams &e) { OnChange.Trigger(e); if (restoreFocus_) { - SetFocusedView(this); + SetFocusedView(this, FocusFlags::CAUSE_SCREEN_CHANGE); } } @@ -665,7 +665,7 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { vert->Add(new CheckBox(&disabled_, negativeLabel_)); if (IsFocusMovementEnabled()) - UI::SetFocusedView(slider_); + UI::SetFocusedView(slider_, FocusFlags::CAUSE_SCREEN_CHANGE); } void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { @@ -706,7 +706,7 @@ void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { // slider_ = parent->Add(new SliderFloat(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(UI::Margins(10, 5)))); if (IsFocusMovementEnabled()) - UI::SetFocusedView(slider_); + UI::SetFocusedView(slider_, FocusFlags::CAUSE_SCREEN_CHANGE); } void SliderFloatPopupScreen::OnDecrease(EventParams ¶ms) { @@ -802,7 +802,7 @@ void AskForInput(ScreenManager *screenManager, RequesterToken token, UI::View *s popupScreen->OnChange.Add([callback, sourceView](EventParams &e) { callback(SanitizeString(StripSpaces(e.s), StringRestriction::None, 0, 0), true); if (sourceView) { - SetFocusedView(sourceView); + SetFocusedView(sourceView, FocusFlags::CAUSE_SCREEN_CHANGE); } }); if (sourceView) @@ -841,7 +841,7 @@ void PopupTextInputChoice::HandleClick(EventParams &e) { params.s = *value_; OnChange.Trigger(params); if (restoreFocus_) { - SetFocusedView(this); + SetFocusedView(this, FocusFlags::CAUSE_SCREEN_CHANGE); } }); if (e.v) @@ -984,7 +984,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { }); } - UI::SetFocusedView(edit_); + UI::SetFocusedView(edit_, FocusFlags::CAUSE_SCREEN_CHANGE); } void TextEditPopupScreen::OnCompleted(DialogResult result) { diff --git a/Common/UI/Root.cpp b/Common/UI/Root.cpp index b396400fb1..0dee325ef3 100644 --- a/Common/UI/Root.cpp +++ b/Common/UI/Root.cpp @@ -101,13 +101,13 @@ View *GetFocusedView() { return focusedView; } -void SetFocusedView(View *view, bool force) { +void SetFocusedView(View *view, FocusFlags cause, bool force) { if (focusedView) { - focusedView->FocusChanged(FF_LOSTFOCUS); + focusedView->FocusChanged(FocusFlags::LOST_FOCUS | cause); } focusedView = view; if (focusedView) { - focusedView->FocusChanged(FF_GOTFOCUS); + focusedView->FocusChanged(FocusFlags::GOT_FOCUS | cause); if (force) { focusForced = true; } @@ -119,7 +119,7 @@ void EnableFocusMovement(bool enable) { focusMovementEnabled = enable; if (!enable) { if (focusedView) { - focusedView->FocusChanged(FF_LOSTFOCUS); + focusedView->FocusChanged(FocusFlags::LOST_FOCUS | FocusFlags::CAUSE_KB_FOCUS_DISABLED); } focusMoves.clear(); heldKeys.clear(); @@ -152,7 +152,7 @@ static void MoveFocus(ViewGroup *root, FocusMove direction) { View *focusedView = GetFocusedView(); if (!focusedView) { // Nothing was focused when we got in here. Focus the first non-group in the hierarchy. - root->SetFocus(); + root->SetFocus(FocusFlags::CAUSE_FOCUS_MOVE); return; } @@ -162,7 +162,7 @@ static void MoveFocus(ViewGroup *root, FocusMove direction) { NeighborResult neigh = root->FindNeighbor(focusedView, direction, NeighborResult()); if (neigh.view) { - neigh.view->SetFocus(); + neigh.view->SetFocus(FocusFlags::CAUSE_FOCUS_MOVE); root->SubviewFocused(neigh.view); // INFO_LOG(Log::UI, "Focus moved from %s to %s", focusedView->DescribeText().c_str(), neigh.view->DescribeText().c_str()); @@ -398,9 +398,9 @@ DialogResult UpdateViewHierarchy(ViewGroup *root) { View *defaultView = root->GetDefaultFocusView(); // Can't focus what you can't see. if (defaultView && defaultView->GetVisibility() == V_VISIBLE) { - root->GetDefaultFocusView()->SetFocus(); + root->GetDefaultFocusView()->SetFocus(UI::FocusFlags::CAUSE_FOCUS_MOVE); } else { - root->SetFocus(); + root->SetFocus(UI::FocusFlags::CAUSE_FOCUS_MOVE); } root->SubviewFocused(GetFocusedView()); } else { diff --git a/Common/UI/Root.h b/Common/UI/Root.h index 0063af72d1..74a280b072 100644 --- a/Common/UI/Root.h +++ b/Common/UI/Root.h @@ -9,13 +9,14 @@ namespace UI { struct Margins; +enum class FocusFlags; // The ONLY global is the currently focused item. // Can be and often is null. void EnableFocusMovement(bool enable); bool IsFocusMovementEnabled(); View *GetFocusedView(); -void SetFocusedView(View *view, bool force = false); +void SetFocusedView(View *view, FocusFlags cause, bool force = false); void RemoveQueuedEventsByEvent(Event *e); void RemoveQueuedEventsByView(View * v); diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index 733cdb3293..552651e126 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -150,7 +150,7 @@ void ScreenManager::switchToNext() { stack_.push_back(nextStack_.front()); nextStack_.front().screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP); delete temp.screen; - UI::SetFocusedView(nullptr); + UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE); // When will this ever happen? Should handle focus here too? for (size_t i = 1; i < nextStack_.size(); ++i) { @@ -378,7 +378,7 @@ void ScreenManager::push(Screen *screen, int layerFlags) { } // Release touches and unfocus. - UI::SetFocusedView(nullptr); + UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE); TouchInput input{}; input.x = -50000.0f; input.y = -50000.0f; diff --git a/Common/UI/Screen.h b/Common/UI/Screen.h index 8d4dd3f546..4542b9e7e0 100644 --- a/Common/UI/Screen.h +++ b/Common/UI/Screen.h @@ -62,7 +62,6 @@ enum class ScreenRenderFlags { }; ENUM_CLASS_BITOPS(ScreenRenderFlags); - enum class ScreenRenderRole { NONE = 0, CAN_BE_BACKGROUND = 1, diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index df885a7d3b..694212f353 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -46,7 +46,7 @@ void UIScreen::DoRecreateViews() { CreateViews(); UI::View *defaultView = root_ ? root_->GetDefaultFocusView() : nullptr; if (defaultView && defaultView->GetVisibility() == UI::V_VISIBLE) { - defaultView->SetFocus(); + defaultView->SetFocus(UI::FocusFlags::CAUSE_OTHER); } recreateViews_ = false; diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 73f8804d8e..9b12e72e5b 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -85,8 +85,10 @@ Event::~Event() { } View::~View() { - if (HasFocus()) - SetFocusedView(0); + if (HasFocus()) { + // The view with focus was destroyed. + SetFocusedView(nullptr, FocusFlags::CAUSE_VIEW_REMOVED); + } RemoveQueuedEventsByView(this); // Could use unique_ptr, but then we have to include tween everywhere. @@ -150,7 +152,7 @@ void View::PersistData(PersistStatus status, std::string anonId, PersistMap &sto break; case UI::PERSIST_RESTORE: if (storage.find(focusedKey) != storage.end()) { - SetFocus(); + SetFocus(UI::FocusFlags::CAUSE_RESTORE); } break; } @@ -184,10 +186,10 @@ Point2D CollapsibleHeader::GetFocusPosition(FocusMove dir) const { } } -bool View::SetFocus() { +bool View::SetFocus(FocusFlags cause) { if (IsFocusMovementEnabled()) { if (CanBeFocused()) { - SetFocusedView(this); + SetFocusedView(this, cause); return true; } } @@ -225,8 +227,8 @@ void Clickable::ClickInternal() { OnClick.Trigger(e); }; -void Clickable::FocusChanged(int focusFlags) { - if (focusFlags & FF_LOSTFOCUS) { +void Clickable::FocusChanged(FocusFlags focusFlags) { + if (focusFlags & FocusFlags::LOST_FOCUS) { down_ = false; dragging_ = false; } @@ -248,8 +250,10 @@ bool Clickable::Touch(const TouchInput &input) { if (input.flags & TouchInputFlags::DOWN) { if (bounds_.Contains(input.x, input.y)) { - if (IsFocusMovementEnabled()) - SetFocusedView(this); + if (IsFocusMovementEnabled()) { + // Can this even happen? Touch cancels focus movement. + SetFocusedView(this, UI::FocusFlags::CAUSE_OTHER); + } dragging_ = true; down_ = true; } else { @@ -356,8 +360,10 @@ bool StickyChoice::Touch(const TouchInput &touch) { } if (touch.flags & TouchInputFlags::UP) { if (dragging_ && contains && !(touch.flags & TouchInputFlags::CANCEL)) { - if (IsFocusMovementEnabled()) - SetFocusedView(this); + if (IsFocusMovementEnabled()) { + // Can this even happen? Touch cancels focus movement. + SetFocusedView(this, UI::FocusFlags::CAUSE_OTHER); + } ClickInternal(); dragging_ = false; down_ = true; @@ -385,7 +391,7 @@ bool StickyChoice::Key(const KeyInput &key) { return false; } -void StickyChoice::FocusChanged(int focusFlags) { +void StickyChoice::FocusChanged(FocusFlags focusFlags) { // Override Clickable's FocusChanged to do nothing. } @@ -1186,8 +1192,10 @@ bool ClickableTextView::Touch(const TouchInput &input) { if (input.flags & TouchInputFlags::DOWN) { if (bounds_.Contains(input.x, input.y)) { - if (IsFocusMovementEnabled()) - SetFocusedView(this); + if (IsFocusMovementEnabled()) { + // Can this even happen? Touch cancels focus movement. + SetFocusedView(this, UI::FocusFlags::CAUSE_OTHER); + } dragging_ = true; down_ = true; } else { @@ -1246,11 +1254,11 @@ TextEdit::TextEdit(std::string_view text, std::string_view title, std::string_vi caret_ = (int)text_.size(); } -void TextEdit::FocusChanged(int focusFlags) { - if (focusFlags == FF_GOTFOCUS) { +void TextEdit::FocusChanged(FocusFlags focusFlags) { + if (focusFlags & FocusFlags::GOT_FOCUS) { System_NotifyUIEvent(UIEventNotification::TEXT_GOTFOCUS); } - else { + if (focusFlags & FocusFlags::LOST_FOCUS) { System_NotifyUIEvent(UIEventNotification::TEXT_LOSTFOCUS); } } @@ -1352,7 +1360,7 @@ static std::string FirstLine(const std::string &text) { bool TextEdit::Touch(const TouchInput &touch) { if (touch.flags & TouchInputFlags::DOWN) { if (bounds_.Contains(touch.x, touch.y)) { - SetFocusedView(this, true); + SetFocusedView(this, UI::FocusFlags::CAUSE_FORCED, true); Bounds textBounds = bounds_.Inset(padding_.left, padding_.top, padding_.right, padding_.bottom); if (textBounds.Contains(touch.x, touch.y)) { int relativeX = touch.x - textBounds.x + scrollPos_; diff --git a/Common/UI/View.h b/Common/UI/View.h index c1295a1846..e732cb2487 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -45,6 +45,7 @@ namespace Draw { namespace UI { class View; +enum class FocusFlags; enum DrawableType { DRAW_NOTHING, @@ -203,10 +204,20 @@ enum MeasureSpecType { AT_MOST, }; -enum FocusFlags { - FF_LOSTFOCUS = 1, - FF_GOTFOCUS = 2 +enum class FocusFlags { + LOST_FOCUS = 1 << 0, + GOT_FOCUS = 1 << 1, + + // TODO: These can be collapsed into fewer bits if needed. + CAUSE_FOCUS_MOVE = 1 << 2, // Focus changed because of a focus move (e.g. dpad or tab). Otherwise, it was probably a programmatic change. + CAUSE_SCREEN_CHANGE = 1 << 3, + CAUSE_KB_FOCUS_DISABLED = 1 << 4, + CAUSE_VIEW_REMOVED = 1 << 5, + CAUSE_FORCED = 1 << 6, + CAUSE_RESTORE = 1 << 7, + CAUSE_OTHER = 1 << 8, }; +ENUM_CLASS_BITOPS(FocusFlags); enum PersistStatus { PERSIST_SAVE, @@ -386,7 +397,7 @@ public: // Accessible/searchable description. virtual std::string DescribeText() const { return ""; } - virtual void FocusChanged(int focusFlags) {} + virtual void FocusChanged(FocusFlags focusFlags) {} virtual void PersistData(PersistStatus status, std::string anonId, PersistMap &storage); void Move(Bounds bounds) { @@ -411,7 +422,7 @@ public: virtual void ReplaceLayoutParams(LayoutParams *newLayoutParams) { layoutParams_.reset(newLayoutParams); } const Bounds &GetBounds() const { return bounds_; } - virtual bool SetFocus(); + virtual bool SetFocus(FocusFlags cause); virtual bool CanBeFocused() const { return true; } virtual bool SubviewFocused(View *view) { return false; } @@ -534,7 +545,7 @@ public: bool Key(const KeyInput &input) override; bool Touch(const TouchInput &input) override; - void FocusChanged(int focusFlags) override; + void FocusChanged(FocusFlags focusFlags) override; Event OnClick; @@ -814,7 +825,7 @@ public: bool Key(const KeyInput &key) override; bool Touch(const TouchInput &touch) override; - void FocusChanged(int focusFlags) override; + void FocusChanged(FocusFlags focusFlags) override; void Press() { down_ = true; dragging_ = false; } void Release() { down_ = false; dragging_ = false; } @@ -1124,7 +1135,7 @@ public: padding_ = padding; } - void FocusChanged(int focusFlags) override; + void FocusChanged(FocusFlags focusFlags) override; bool CanMoveFocus(FocusMove dir) const override { return dir != FocusMove::LEFT && dir != FocusMove::RIGHT; } void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index 17c1ae6c45..d39a36f848 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -266,10 +266,10 @@ void ViewGroup::Update() { } } -bool ViewGroup::SetFocus() { +bool ViewGroup::SetFocus(FocusFlags cause) { if (!CanBeFocused() && !views_.empty()) { for (View *view : views_) { - if (view->SetFocus()) + if (view->SetFocus(cause)) return true; } } diff --git a/Common/UI/ViewGroup.h b/Common/UI/ViewGroup.h index 538bfd9c32..37c54dec9e 100644 --- a/Common/UI/ViewGroup.h +++ b/Common/UI/ViewGroup.h @@ -55,7 +55,7 @@ public: // If it fails, the newView is deleted. bool ReplaceSubview(View *view, View *newView); - bool SetFocus() override; + bool SetFocus(FocusFlags cause) override; bool SubviewFocused(View *view) override; virtual void RemoveSubview(View *view); diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 9e9da43917..6b086ed561 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -104,7 +104,7 @@ void ChatMenu::CreateSubviews(const Bounds &screenBounds) { void ChatMenu::OnSubmitMessage(UI::EventParams &e) { std::string chat = chatEdit_->GetText(); chatEdit_->SetText(""); - chatEdit_->SetFocus(); + chatEdit_->SetFocus(UI::FocusFlags::CAUSE_FORCED); sendChat(chat); } diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 41729763da..48f2a771e6 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -153,15 +153,16 @@ void SingleControlMapper::Refresh() { void SingleControlMapper::OnReplace(UI::EventParams ¶ms) { const int index = atoi(params.v->Tag().c_str()); scrm_->push(new KeyMappingNewKeyDialog(pspKey_, true, [this, index](KeyMap::MultiInputMapping mapping) { + using namespace UI; if (mapping.empty()) return; bool success = KeyMap::ReplaceSingleKeyMapping(pspKey_, index, mapping); if (!success) { - replaceAllButton_->SetFocus(); // Last got removed as a duplicate + replaceAllButton_->SetFocus(FocusFlags::CAUSE_FORCED); // Last got removed as a duplicate } else if (index < (int)rows_.size()) { - rows_[index]->SetFocus(); + rows_[index]->SetFocus(FocusFlags::CAUSE_FORCED); } else { - SetFocus(); + SetFocus(FocusFlags::CAUSE_FORCED); } KeyMap::UpdateNativeMenuKeys(); g_IsMappingMouseInput = false; @@ -173,7 +174,7 @@ void SingleControlMapper::OnReplaceAll(UI::EventParams ¶ms) { if (mapping.empty()) return; KeyMap::SetInputMapping(pspKey_, mapping, true); - replaceAllButton_->SetFocus(); + replaceAllButton_->SetFocus(UI::FocusFlags::CAUSE_FORCED); KeyMap::UpdateNativeMenuKeys(); g_IsMappingMouseInput = false; }, I18NCat::KEYMAPPING)); @@ -184,7 +185,7 @@ void SingleControlMapper::OnAdd(UI::EventParams ¶ms) { if (mapping.empty()) return; KeyMap::SetInputMapping(pspKey_, mapping, false); - addButton_->SetFocus(); + addButton_->SetFocus(UI::FocusFlags::CAUSE_FORCED); KeyMap::UpdateNativeMenuKeys(); g_IsMappingMouseInput = false; }, I18NCat::KEYMAPPING)); @@ -196,7 +197,7 @@ void SingleControlMapper::OnAddMouse(UI::EventParams ¶ms) { if (mapping.empty()) return; KeyMap::SetInputMapping(pspKey_, mapping, false); - addButton_->SetFocus(); + addButton_->SetFocus(UI::FocusFlags::CAUSE_FORCED); KeyMap::UpdateNativeMenuKeys(); g_IsMappingMouseInput = false; }, I18NCat::KEYMAPPING)); @@ -206,9 +207,9 @@ void SingleControlMapper::OnDelete(UI::EventParams ¶ms) { int index = atoi(params.v->Tag().c_str()); KeyMap::DeleteNthMapping(pspKey_, index); if (index + 1 < (int)rows_.size()) - rows_[index]->SetFocus(); + rows_[index]->SetFocus(UI::FocusFlags::CAUSE_FORCED); else - SetFocus(); + SetFocus(UI::FocusFlags::CAUSE_FORCED); } struct BindingCategory { @@ -807,7 +808,7 @@ void MockPSP::SelectButton(int btn) { void MockPSP::FocusButton(int btn) { MockButton *view = buttons_[btn]; if (view) { - view->SetFocus(); + view->SetFocus(UI::FocusFlags::CAUSE_FORCED); } else { labelView_->SetVisibility(UI::V_GONE); } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 33ee469814..aef18b5a7c 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1418,7 +1418,7 @@ void EmuScreen::OpenChat(bool focus) { UI::EnableFocusMovement(true); root_->SetDefaultFocusView(chatMenu_); - chatMenu_->SetFocus(); + chatMenu_->SetFocus(UI::FocusFlags::CAUSE_FORCED); UI::View *focused = UI::GetFocusedView(); if (focused) { root_->SubviewFocused(focused); diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index d458edbe31..8de3362e11 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -172,7 +172,7 @@ public: } } - void FocusChanged(int focusFlags) override { + void FocusChanged(UI::FocusFlags focusFlags) override { UI::Clickable::FocusChanged(focusFlags); TriggerOnHighlight(focusFlags); } @@ -189,11 +189,11 @@ private: down_ = false; OnHoldClick.Trigger(e); } - void TriggerOnHighlight(int focusFlags) { + void TriggerOnHighlight(UI::FocusFlags focusFlags) { UI::EventParams e{}; e.v = this; e.s = gamePath_.ToString(); - e.a = focusFlags; + e.a = (u32)focusFlags; OnHighlight.Trigger(e); } @@ -925,7 +925,7 @@ void GameBrowser::Refresh() { b->OnHighlight.Handle(this, &GameBrowser::GameButtonHighlight); if (!focusGamePath_.empty() && b->GamePath() == focusGamePath_) { - b->SetFocus(); + b->SetFocus(FocusFlags::CAUSE_RESTORE); } } diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index b4cdb6fb97..e346502c42 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -665,12 +665,14 @@ void MainScreen::OnGameHighlight(UI::EventParams &e) { Path path(e.s); - if (path == highlightedGamePath_ && e.a == FF_GOTFOCUS) { + const FocusFlags focusFlags = (FocusFlags)e.a; + + if (path == highlightedGamePath_ && (focusFlags & FocusFlags::GOT_FOCUS)) { // Already highlighted, nothing to do. return; } - if (e.a == FF_LOSTFOCUS) { + if (focusFlags & FocusFlags::LOST_FOCUS) { // Lost focus, so we want to fade out the background. // Trigger fadeouts on any active highlights. @@ -680,7 +682,10 @@ void MainScreen::OnGameHighlight(UI::EventParams &e) { } } highlightedGamePath_.clear(); - g_BackgroundAudio.SetGame(Path()); + if ((focusFlags & FocusFlags::CAUSE_FOCUS_MOVE) || (focusFlags & FocusFlags::CAUSE_KB_FOCUS_DISABLED)) { + // Focus moved to another game, so we want to fade out so we can fade in the new one. + g_BackgroundAudio.SetGame(Path()); + } return; } @@ -695,7 +700,7 @@ void MainScreen::OnGameHighlight(UI::EventParams &e) { // Add a new entry to the highlight list. highlightedBackgrounds_.push_back({path, time_now_d(), -1.0}); - if ((!highlightedGamePath_.empty() || e.a == FF_LOSTFOCUS) && !lockBackgroundAudio_) { + if ((!highlightedGamePath_.empty() || (focusFlags & FocusFlags::LOST_FOCUS)) && !lockBackgroundAudio_) { g_BackgroundAudio.SetGame(highlightedGamePath_); } diff --git a/UI/MiscViews.cpp b/UI/MiscViews.cpp index 1907ed4ae2..9df563f64b 100644 --- a/UI/MiscViews.cpp +++ b/UI/MiscViews.cpp @@ -431,7 +431,7 @@ void ViewSearch::ApplySearchFilter(UI::ViewGroup *viewGroup, bool setKeyboardFoc if (firstMatch) { if (setKeyboardFocus) { UI::EnableFocusMovement(true); - UI::SetFocusedView(firstMatch); + UI::SetFocusedView(firstMatch, UI::FocusFlags::CAUSE_OTHER); } } }