| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/views/interaction/widget_focus_observer.h" |
| |
| #include <iterator> |
| |
| #include "base/functional/bind.h" |
| #include "base/logging.h" |
| |
| namespace views::test { |
| |
| namespace internal { |
| |
| namespace { |
| WidgetFocusSupplierFrame* g_current_supplier_frame = nullptr; |
| } |
| |
| WidgetFocusSupplier::WidgetFocusSupplier() = default; |
| WidgetFocusSupplier::~WidgetFocusSupplier() = default; |
| |
| base::CallbackListSubscription |
| WidgetFocusSupplier::AddWidgetFocusChangedCallback( |
| WidgetFocusChangedCallback callback) { |
| return callbacks_.Add(callback); |
| } |
| |
| void WidgetFocusSupplier::OnWidgetFocusChanged(Widget* focused_now) { |
| callbacks_.Notify(focused_now); |
| } |
| |
| WidgetFocusSupplierFrame::WidgetFocusSupplierFrame() { |
| LOG_IF(ERROR, g_current_supplier_frame) |
| << "Old WidgetFocusSupplierFrame was not cleaned up."; |
| g_current_supplier_frame = this; |
| } |
| |
| WidgetFocusSupplierFrame::~WidgetFocusSupplierFrame() { |
| if (g_current_supplier_frame == this) { |
| g_current_supplier_frame = nullptr; |
| } |
| } |
| |
| Widget* WidgetFocusSupplierFrame::GetActiveWidget() { |
| Widget::Widgets all_widgets; |
| for (const auto& supplier : supplier_list_) { |
| for (auto& widget : supplier.GetAllWidgets()) { |
| if (widget->IsActive()) { |
| return widget; |
| } |
| } |
| } |
| return nullptr; |
| } |
| |
| // static |
| WidgetFocusSupplierFrame* WidgetFocusSupplierFrame::GetCurrentFrame() { |
| return g_current_supplier_frame; |
| } |
| |
| } // namespace internal |
| |
| WidgetFocusObserver::WidgetFocusObserver() { |
| for (auto& supplier : |
| internal::WidgetFocusSupplierFrame::GetCurrentFrame()->supplier_list()) { |
| subscriptions_.emplace_back(supplier.AddWidgetFocusChangedCallback( |
| base::BindRepeating(&WidgetFocusObserver::OnWidgetFocusChanged, |
| base::Unretained(this)))); |
| } |
| } |
| WidgetFocusObserver::~WidgetFocusObserver() = default; |
| |
| Widget* WidgetFocusObserver::GetStateObserverInitialState() const { |
| return internal::WidgetFocusSupplierFrame::GetCurrentFrame() |
| ->GetActiveWidget(); |
| } |
| |
| void WidgetFocusObserver::OnWidgetFocusChanged(Widget* focused_now) { |
| OnStateObserverStateChanged(focused_now); |
| } |
| |
| DEFINE_STATE_IDENTIFIER_VALUE(WidgetFocusObserver, kCurrentWidgetFocus); |
| |
| } // namespace views::test |