Commit cfa4b2aa authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

views: makes WidgetFocusManager per Env on aura

As we may have two envs, WidgetFocusManager needs some context to know which
WidgetFocusManager to return.

BUG=874554
TEST=covered by tests

Change-Id: I397e14496351fc9839273aa7284c55cdb35555c8
Reviewed-on: https://chromium-review.googlesource.com/1212088Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589593}
parent f32173fc
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/accessibility/focus_ring_controller.h" #include "ash/accessibility/focus_ring_controller.h"
#include "ash/accessibility/focus_ring_layer.h" #include "ash/accessibility/focus_ring_layer.h"
#include "ash/shell.h"
#include "ash/system/tray/actionable_view.h" #include "ash/system/tray/actionable_view.h"
#include "ash/system/tray/tray_background_view.h" #include "ash/system/tray/tray_background_view.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
...@@ -28,13 +29,15 @@ void FocusRingController::SetVisible(bool visible) { ...@@ -28,13 +29,15 @@ void FocusRingController::SetVisible(bool visible) {
visible_ = visible; visible_ = visible;
if (visible_) { if (visible_) {
views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this); views::WidgetFocusManager::GetInstance(Shell::GetPrimaryRootWindow())
->AddFocusChangeListener(this);
aura::Window* active_window = wm::GetActiveWindow(); aura::Window* active_window = wm::GetActiveWindow();
if (active_window) if (active_window)
SetWidget(views::Widget::GetWidgetForNativeWindow(active_window)); SetWidget(views::Widget::GetWidgetForNativeWindow(active_window));
} else { } else {
views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this); views::WidgetFocusManager::GetInstance(Shell::GetPrimaryRootWindow())
SetWidget(NULL); ->RemoveFocusChangeListener(this);
SetWidget(nullptr);
} }
} }
......
...@@ -4,17 +4,63 @@ ...@@ -4,17 +4,63 @@
#include "ui/views/focus/widget_focus_manager.h" #include "ui/views/focus/widget_focus_manager.h"
#include "base/memory/singleton.h" #include "base/supports_user_data.h"
#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#endif
namespace views { namespace views {
#if defined(USE_AURA)
namespace {
const char kWidgetFocusManagerKey[] = "WidgetFocusManager";
} // namespace
class WidgetFocusManager::Owner : public base::SupportsUserData::Data {
public:
explicit Owner(std::unique_ptr<WidgetFocusManager> focus_manager)
: focus_manager_(std::move(focus_manager)) {}
~Owner() override = default;
WidgetFocusManager* focus_manager() { return focus_manager_.get(); }
private:
std::unique_ptr<WidgetFocusManager> focus_manager_;
DISALLOW_COPY_AND_ASSIGN(Owner);
};
#endif
// WidgetFocusManager ---------------------------------------------------------- // WidgetFocusManager ----------------------------------------------------------
// static // static
WidgetFocusManager* WidgetFocusManager::GetInstance() { WidgetFocusManager* WidgetFocusManager::GetInstance(gfx::NativeWindow context) {
return base::Singleton<WidgetFocusManager>::get(); #if defined(USE_AURA)
// With aura there may be multiple Envs, in such a situation the
// WidgetFocusManager needs to be per Env.
aura::Env* env = context ? context->env() : aura::Env::GetInstance();
DCHECK(env);
Owner* owner = static_cast<Owner*>(env->GetUserData(kWidgetFocusManagerKey));
if (!owner) {
std::unique_ptr<Owner> owner_ptr =
std::make_unique<Owner>(base::WrapUnique(new WidgetFocusManager()));
owner = owner_ptr.get();
env->SetUserData(kWidgetFocusManagerKey, std::move(owner_ptr));
}
return owner->focus_manager();
#else
static base::NoDestructor<WidgetFocusManager> instance;
return instance.get();
#endif
} }
WidgetFocusManager::~WidgetFocusManager() = default;
void WidgetFocusManager::AddFocusChangeListener( void WidgetFocusManager::AddFocusChangeListener(
WidgetFocusChangeListener* listener) { WidgetFocusChangeListener* listener) {
focus_change_listeners_.AddObserver(listener); focus_change_listeners_.AddObserver(listener);
...@@ -34,8 +80,6 @@ void WidgetFocusManager::OnNativeFocusChanged(gfx::NativeView focused_now) { ...@@ -34,8 +80,6 @@ void WidgetFocusManager::OnNativeFocusChanged(gfx::NativeView focused_now) {
WidgetFocusManager::WidgetFocusManager() : enabled_(true) {} WidgetFocusManager::WidgetFocusManager() : enabled_(true) {}
WidgetFocusManager::~WidgetFocusManager() {}
// AutoNativeNotificationDisabler ---------------------------------------------- // AutoNativeNotificationDisabler ----------------------------------------------
AutoNativeNotificationDisabler::AutoNativeNotificationDisabler() { AutoNativeNotificationDisabler::AutoNativeNotificationDisabler() {
......
...@@ -6,14 +6,11 @@ ...@@ -6,14 +6,11 @@
#define UI_VIEWS_FOCUS_WIDGET_FOCUS_MANAGER_H_ #define UI_VIEWS_FOCUS_WIDGET_FOCUS_MANAGER_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/no_destructor.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h" #include "ui/views/views_export.h"
namespace base {
template <typename T> struct DefaultSingletonTraits;
}
namespace views { namespace views {
// This interface should be implemented by classes that want to be notified when // This interface should be implemented by classes that want to be notified when
...@@ -32,7 +29,9 @@ class WidgetFocusChangeListener { ...@@ -32,7 +29,9 @@ class WidgetFocusChangeListener {
class VIEWS_EXPORT WidgetFocusManager { class VIEWS_EXPORT WidgetFocusManager {
public: public:
// Returns the singleton instance. // Returns the singleton instance.
static WidgetFocusManager* GetInstance(); static WidgetFocusManager* GetInstance(gfx::NativeWindow context = nullptr);
~WidgetFocusManager();
// Adds/removes a WidgetFocusChangeListener |listener| to the set of // Adds/removes a WidgetFocusChangeListener |listener| to the set of
// active listeners. // active listeners.
...@@ -50,10 +49,10 @@ class VIEWS_EXPORT WidgetFocusManager { ...@@ -50,10 +49,10 @@ class VIEWS_EXPORT WidgetFocusManager {
void DisableNotifications() { enabled_ = false; } void DisableNotifications() { enabled_ = false; }
private: private:
friend struct base::DefaultSingletonTraits<WidgetFocusManager>; class Owner;
friend class base::NoDestructor<WidgetFocusManager>;
WidgetFocusManager(); WidgetFocusManager();
~WidgetFocusManager();
base::ObserverList<WidgetFocusChangeListener>::Unchecked base::ObserverList<WidgetFocusChangeListener>::Unchecked
focus_change_listeners_; focus_change_listeners_;
......
...@@ -1058,11 +1058,13 @@ bool Widget::OnNativeWidgetActivationChanged(bool active) { ...@@ -1058,11 +1058,13 @@ bool Widget::OnNativeWidgetActivationChanged(bool active) {
} }
void Widget::OnNativeFocus() { void Widget::OnNativeFocus() {
WidgetFocusManager::GetInstance()->OnNativeFocusChanged(GetNativeView()); WidgetFocusManager::GetInstance(GetNativeWindow())
->OnNativeFocusChanged(GetNativeView());
} }
void Widget::OnNativeBlur() { void Widget::OnNativeBlur() {
WidgetFocusManager::GetInstance()->OnNativeFocusChanged(nullptr); WidgetFocusManager::GetInstance(GetNativeWindow())
->OnNativeFocusChanged(nullptr);
} }
void Widget::OnNativeWidgetVisibilityChanging(bool visible) { void Widget::OnNativeWidgetVisibilityChanging(bool visible) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment