Commit 8db59418 authored by sky's avatar sky Committed by Commit bot

Converts focusmanager from delegate to observer

I'm going to need more than one object to detect focus changes.

BUG=548424
TEST=covered by tests
R=ben@chromium.org

Review URL: https://codereview.chromium.org/1465143004

Cr-Commit-Position: refs/heads/master@{#361150}
parent 4114e089
// Copyright 2015 The Chromium Authors. All rights reserved. // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
//
#include "components/mus/gles2/gpu_state.h" #include "components/mus/gles2/gpu_state.h"
......
...@@ -27,7 +27,7 @@ source_set("lib") { ...@@ -27,7 +27,7 @@ source_set("lib") {
"event_dispatcher_delegate.h", "event_dispatcher_delegate.h",
"focus_controller.cc", "focus_controller.cc",
"focus_controller.h", "focus_controller.h",
"focus_controller_delegate.h", "focus_controller_observer.h",
"forwarding_window_manager.cc", "forwarding_window_manager.cc",
"forwarding_window_manager.h", "forwarding_window_manager.h",
"operation.cc", "operation.cc",
...@@ -64,7 +64,7 @@ source_set("lib") { ...@@ -64,7 +64,7 @@ source_set("lib") {
"//cc/surfaces", "//cc/surfaces",
"//cc/surfaces:surface_id", "//cc/surfaces:surface_id",
"//components/mus/common", "//components/mus/common",
"//components/mus/gles2:gles2", "//components/mus/gles2",
"//components/mus/public/interfaces", "//components/mus/public/interfaces",
"//components/mus/surfaces", "//components/mus/surfaces",
"//mojo/application/public/cpp", "//mojo/application/public/cpp",
...@@ -79,10 +79,10 @@ source_set("lib") { ...@@ -79,10 +79,10 @@ source_set("lib") {
"//ui/events/platform", "//ui/events/platform",
"//ui/gfx", "//ui/gfx",
"//ui/gfx/geometry", "//ui/gfx/geometry",
"//ui/gl:gl", "//ui/gl",
"//ui/mojo/geometry:interfaces", "//ui/mojo/geometry:interfaces",
"//ui/platform_window",
"//ui/platform_window:platform_impls", "//ui/platform_window:platform_impls",
"//ui/platform_window:platform_window",
] ]
} }
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "components/mus/public/interfaces/window_tree.mojom.h" #include "components/mus/public/interfaces/window_tree.mojom.h"
#include "components/mus/public/interfaces/window_tree_host.mojom.h" #include "components/mus/public/interfaces/window_tree_host.mojom.h"
#include "components/mus/surfaces/surfaces_state.h" #include "components/mus/surfaces/surfaces_state.h"
#include "components/mus/ws/focus_controller_delegate.h"
#include "components/mus/ws/ids.h" #include "components/mus/ws/ids.h"
#include "components/mus/ws/operation.h" #include "components/mus/ws/operation.h"
#include "components/mus/ws/server_window_delegate.h" #include "components/mus/ws/server_window_delegate.h"
...@@ -25,7 +24,6 @@ ...@@ -25,7 +24,6 @@
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
namespace mus { namespace mus {
namespace ws { namespace ws {
class ClientConnection; class ClientConnection;
...@@ -265,7 +263,6 @@ class ConnectionManager : public ServerWindowDelegate, ...@@ -265,7 +263,6 @@ class ConnectionManager : public ServerWindowDelegate,
}; };
} // namespace ws } // namespace ws
} // namespace mus } // namespace mus
#endif // COMPONENTS_MUS_WS_CONNECTION_MANAGER_H_ #endif // COMPONENTS_MUS_WS_CONNECTION_MANAGER_H_
...@@ -4,16 +4,14 @@ ...@@ -4,16 +4,14 @@
#include "components/mus/ws/focus_controller.h" #include "components/mus/ws/focus_controller.h"
#include "components/mus/ws/focus_controller_delegate.h" #include "components/mus/ws/focus_controller_observer.h"
#include "components/mus/ws/server_window.h" #include "components/mus/ws/server_window.h"
#include "components/mus/ws/server_window_drawn_tracker.h" #include "components/mus/ws/server_window_drawn_tracker.h"
namespace mus { namespace mus {
namespace ws { namespace ws {
FocusController::FocusController(FocusControllerDelegate* delegate) FocusController::FocusController() {}
: delegate_(delegate) {}
FocusController::~FocusController() {} FocusController::~FocusController() {}
...@@ -21,13 +19,21 @@ void FocusController::SetFocusedWindow(ServerWindow* window) { ...@@ -21,13 +19,21 @@ void FocusController::SetFocusedWindow(ServerWindow* window) {
if (GetFocusedWindow() == window) if (GetFocusedWindow() == window)
return; return;
SetFocusedWindowImpl(window, CHANGE_SOURCE_EXPLICIT); SetFocusedWindowImpl(FocusControllerChangeSource::EXPLICIT, window);
} }
ServerWindow* FocusController::GetFocusedWindow() { ServerWindow* FocusController::GetFocusedWindow() {
return drawn_tracker_ ? drawn_tracker_->window() : nullptr; return drawn_tracker_ ? drawn_tracker_->window() : nullptr;
} }
void FocusController::AddObserver(FocusControllerObserver* observer) {
observers_.AddObserver(observer);
}
void FocusController::RemoveObserver(FocusControllerObserver* observer) {
observers_.RemoveObserver(observer);
}
bool FocusController::CanBeFocused(ServerWindow* window) const { bool FocusController::CanBeFocused(ServerWindow* window) const {
// All ancestors of |window| must be drawn, and be focusable. // All ancestors of |window| must be drawn, and be focusable.
for (ServerWindow* w = window; w; w = w->parent()) { for (ServerWindow* w = window; w; w = w->parent()) {
...@@ -51,8 +57,9 @@ bool FocusController::CanBeActivated(ServerWindow* window) const { ...@@ -51,8 +57,9 @@ bool FocusController::CanBeActivated(ServerWindow* window) const {
return true; return true;
} }
void FocusController::SetFocusedWindowImpl(ServerWindow* window, void FocusController::SetFocusedWindowImpl(
ChangeSource change_source) { FocusControllerChangeSource change_source,
ServerWindow* window) {
if (window && !CanBeFocused(window)) if (window && !CanBeFocused(window))
return; return;
ServerWindow* old = GetFocusedWindow(); ServerWindow* old = GetFocusedWindow();
...@@ -65,17 +72,17 @@ void FocusController::SetFocusedWindowImpl(ServerWindow* window, ...@@ -65,17 +72,17 @@ void FocusController::SetFocusedWindowImpl(ServerWindow* window,
else else
drawn_tracker_.reset(); drawn_tracker_.reset();
if (change_source == CHANGE_SOURCE_DRAWN_STATE_CHANGED) FOR_EACH_OBSERVER(FocusControllerObserver, observers_,
delegate_->OnFocusChanged(old, window); OnFocusChanged(change_source, old, window));
} }
void FocusController::OnDrawnStateChanged(ServerWindow* ancestor, void FocusController::OnDrawnStateChanged(ServerWindow* ancestor,
ServerWindow* window, ServerWindow* window,
bool is_drawn) { bool is_drawn) {
DCHECK(!is_drawn); // We only observe when drawn. DCHECK(!is_drawn); // We only observe when drawn.
SetFocusedWindowImpl(ancestor, CHANGE_SOURCE_DRAWN_STATE_CHANGED); SetFocusedWindowImpl(FocusControllerChangeSource::DRAWN_STATE_CHANGED,
ancestor);
} }
} // namespace ws } // namespace ws
} // namespace mus } // namespace mus
...@@ -6,21 +6,28 @@ ...@@ -6,21 +6,28 @@
#define COMPONENTS_MUS_WS_FOCUS_CONTROLLER_H_ #define COMPONENTS_MUS_WS_FOCUS_CONTROLLER_H_
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "components/mus/ws/server_window_drawn_tracker_observer.h" #include "components/mus/ws/server_window_drawn_tracker_observer.h"
namespace mus { namespace mus {
namespace ws { namespace ws {
class FocusControllerDelegate; class FocusControllerObserver;
class ServerWindow; class ServerWindow;
class ServerWindowDrawnTracker; class ServerWindowDrawnTracker;
// Tracks a focused window. Focus is moved to another window when the drawn // Describes the source of the change.
// state of the focused window changes and the delegate is notified. enum class FocusControllerChangeSource {
EXPLICIT,
DRAWN_STATE_CHANGED,
};
// Tracks the focused window. Focus is moved to another window when the drawn
// state of the focused window changes.
class FocusController : public ServerWindowDrawnTrackerObserver { class FocusController : public ServerWindowDrawnTrackerObserver {
public: public:
explicit FocusController(FocusControllerDelegate* delegate); FocusController();
~FocusController() override; ~FocusController() override;
// Sets the focused window. Does nothing if |window| is currently focused. // Sets the focused window. Does nothing if |window| is currently focused.
...@@ -31,26 +38,24 @@ class FocusController : public ServerWindowDrawnTrackerObserver { ...@@ -31,26 +38,24 @@ class FocusController : public ServerWindowDrawnTrackerObserver {
// Moves activation to the next activatable window. // Moves activation to the next activatable window.
void CycleActivationForward(); void CycleActivationForward();
private: void AddObserver(FocusControllerObserver* observer);
// Describes the source of the change. void RemoveObserver(FocusControllerObserver* observer);
enum ChangeSource {
CHANGE_SOURCE_EXPLICIT,
CHANGE_SOURCE_DRAWN_STATE_CHANGED,
};
private:
// Returns whether |window| can be focused or activated. // Returns whether |window| can be focused or activated.
bool CanBeFocused(ServerWindow* window) const; bool CanBeFocused(ServerWindow* window) const;
bool CanBeActivated(ServerWindow* window) const; bool CanBeActivated(ServerWindow* window) const;
// Implementation of SetFocusedWindow(). // Implementation of SetFocusedWindow().
void SetFocusedWindowImpl(ServerWindow* window, ChangeSource change_source); void SetFocusedWindowImpl(FocusControllerChangeSource change_source,
ServerWindow* window);
// ServerWindowDrawnTrackerObserver: // ServerWindowDrawnTrackerObserver:
void OnDrawnStateChanged(ServerWindow* ancestor, void OnDrawnStateChanged(ServerWindow* ancestor,
ServerWindow* window, ServerWindow* window,
bool is_drawn) override; bool is_drawn) override;
FocusControllerDelegate* delegate_; base::ObserverList<FocusControllerObserver> observers_;
scoped_ptr<ServerWindowDrawnTracker> drawn_tracker_; scoped_ptr<ServerWindowDrawnTracker> drawn_tracker_;
DISALLOW_COPY_AND_ASSIGN(FocusController); DISALLOW_COPY_AND_ASSIGN(FocusController);
......
...@@ -6,22 +6,22 @@ ...@@ -6,22 +6,22 @@
#define COMPONENTS_MUS_WS_FOCUS_CONTROLLER_DELEGATE_H_ #define COMPONENTS_MUS_WS_FOCUS_CONTROLLER_DELEGATE_H_
namespace mus { namespace mus {
namespace ws { namespace ws {
enum class FocusControllerChangeSource;
class ServerWindow; class ServerWindow;
class FocusControllerDelegate { class FocusControllerObserver {
public: public:
virtual void OnFocusChanged(ServerWindow* old_focused_window, virtual void OnFocusChanged(FocusControllerChangeSource change_source,
ServerWindow* old_focused_window,
ServerWindow* new_focused_window) = 0; ServerWindow* new_focused_window) = 0;
protected: protected:
~FocusControllerDelegate() {} ~FocusControllerObserver() {}
}; };
} // namespace ws } // namespace ws
} // namespace mus } // namespace mus
#endif // COMPONENTS_MUS_WS_FOCUS_CONTROLLER_DELEGATE_H_ #endif // COMPONENTS_MUS_WS_FOCUS_CONTROLLER_DELEGATE_H_
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "components/mus/ws/focus_controller.h" #include "components/mus/ws/focus_controller.h"
#include "components/mus/ws/focus_controller_delegate.h" #include "components/mus/ws/focus_controller_observer.h"
#include "components/mus/ws/server_window.h" #include "components/mus/ws/server_window.h"
#include "components/mus/ws/test_server_window_delegate.h" #include "components/mus/ws/test_server_window_delegate.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -14,9 +14,9 @@ namespace mus { ...@@ -14,9 +14,9 @@ namespace mus {
namespace ws { namespace ws {
namespace { namespace {
class TestFocusControllerDelegate : public FocusControllerDelegate { class TestFocusControllerObserver : public FocusControllerObserver {
public: public:
TestFocusControllerDelegate() TestFocusControllerObserver()
: change_count_(0u), : change_count_(0u),
old_focused_window_(nullptr), old_focused_window_(nullptr),
new_focused_window_(nullptr) {} new_focused_window_(nullptr) {}
...@@ -31,9 +31,13 @@ class TestFocusControllerDelegate : public FocusControllerDelegate { ...@@ -31,9 +31,13 @@ class TestFocusControllerDelegate : public FocusControllerDelegate {
ServerWindow* new_focused_window() { return new_focused_window_; } ServerWindow* new_focused_window() { return new_focused_window_; }
private: private:
// FocusControllerDelegate: // FocusControllerObserver:
void OnFocusChanged(ServerWindow* old_focused_window, void OnFocusChanged(FocusControllerChangeSource source,
ServerWindow* old_focused_window,
ServerWindow* new_focused_window) override { ServerWindow* new_focused_window) override {
if (source == FocusControllerChangeSource::EXPLICIT)
return;
change_count_++; change_count_++;
old_focused_window_ = old_focused_window; old_focused_window_ = old_focused_window;
new_focused_window_ = new_focused_window; new_focused_window_ = new_focused_window;
...@@ -43,7 +47,7 @@ class TestFocusControllerDelegate : public FocusControllerDelegate { ...@@ -43,7 +47,7 @@ class TestFocusControllerDelegate : public FocusControllerDelegate {
ServerWindow* old_focused_window_; ServerWindow* old_focused_window_;
ServerWindow* new_focused_window_; ServerWindow* new_focused_window_;
DISALLOW_COPY_AND_ASSIGN(TestFocusControllerDelegate); DISALLOW_COPY_AND_ASSIGN(TestFocusControllerObserver);
}; };
} // namespace } // namespace
...@@ -60,50 +64,52 @@ TEST(FocusControllerTest, Basic) { ...@@ -60,50 +64,52 @@ TEST(FocusControllerTest, Basic) {
child_child.SetVisible(true); child_child.SetVisible(true);
child.Add(&child_child); child.Add(&child_child);
TestFocusControllerDelegate focus_delegate; TestFocusControllerObserver focus_observer;
FocusController focus_controller(&focus_delegate); FocusController focus_controller;
focus_controller.AddObserver(&focus_observer);
focus_controller.SetFocusedWindow(&child_child); focus_controller.SetFocusedWindow(&child_child);
EXPECT_EQ(0u, focus_delegate.change_count()); EXPECT_EQ(0u, focus_observer.change_count());
// Remove the ancestor of the focused window, focus should go to the |root|. // Remove the ancestor of the focused window, focus should go to the |root|.
root.Remove(&child); root.Remove(&child);
EXPECT_EQ(1u, focus_delegate.change_count()); EXPECT_EQ(1u, focus_observer.change_count());
EXPECT_EQ(&root, focus_delegate.new_focused_window()); EXPECT_EQ(&root, focus_observer.new_focused_window());
EXPECT_EQ(&child_child, focus_delegate.old_focused_window()); EXPECT_EQ(&child_child, focus_observer.old_focused_window());
focus_delegate.ClearAll(); focus_observer.ClearAll();
// Make the focused window invisible. Focus is lost in this case (as no one // Make the focused window invisible. Focus is lost in this case (as no one
// to give focus to). // to give focus to).
root.SetVisible(false); root.SetVisible(false);
EXPECT_EQ(1u, focus_delegate.change_count()); EXPECT_EQ(1u, focus_observer.change_count());
EXPECT_EQ(nullptr, focus_delegate.new_focused_window()); EXPECT_EQ(nullptr, focus_observer.new_focused_window());
EXPECT_EQ(&root, focus_delegate.old_focused_window()); EXPECT_EQ(&root, focus_observer.old_focused_window());
focus_delegate.ClearAll(); focus_observer.ClearAll();
// Go back to initial state and focus |child_child|. // Go back to initial state and focus |child_child|.
root.SetVisible(true); root.SetVisible(true);
root.Add(&child); root.Add(&child);
focus_controller.SetFocusedWindow(&child_child); focus_controller.SetFocusedWindow(&child_child);
EXPECT_EQ(0u, focus_delegate.change_count()); EXPECT_EQ(0u, focus_observer.change_count());
// Hide the focused window, focus should go to parent. // Hide the focused window, focus should go to parent.
child_child.SetVisible(false); child_child.SetVisible(false);
EXPECT_EQ(1u, focus_delegate.change_count()); EXPECT_EQ(1u, focus_observer.change_count());
EXPECT_EQ(&child, focus_delegate.new_focused_window()); EXPECT_EQ(&child, focus_observer.new_focused_window());
EXPECT_EQ(&child_child, focus_delegate.old_focused_window()); EXPECT_EQ(&child_child, focus_observer.old_focused_window());
focus_delegate.ClearAll(); focus_observer.ClearAll();
child_child.SetVisible(true); child_child.SetVisible(true);
focus_controller.SetFocusedWindow(&child_child); focus_controller.SetFocusedWindow(&child_child);
EXPECT_EQ(0u, focus_delegate.change_count()); EXPECT_EQ(0u, focus_observer.change_count());
// Hide the parent of the focused window. // Hide the parent of the focused window.
child.SetVisible(false); child.SetVisible(false);
EXPECT_EQ(1u, focus_delegate.change_count()); EXPECT_EQ(1u, focus_observer.change_count());
EXPECT_EQ(&root, focus_delegate.new_focused_window()); EXPECT_EQ(&root, focus_observer.new_focused_window());
EXPECT_EQ(&child_child, focus_delegate.old_focused_window()); EXPECT_EQ(&child_child, focus_observer.old_focused_window());
focus_delegate.ClearAll(); focus_observer.ClearAll();
focus_controller.RemoveObserver(&focus_observer);
} }
} // namespace ws } // namespace ws
......
...@@ -30,8 +30,9 @@ WindowTreeHostImpl::WindowTreeHostImpl( ...@@ -30,8 +30,9 @@ WindowTreeHostImpl::WindowTreeHostImpl(
event_dispatcher_(this), event_dispatcher_(this),
display_manager_( display_manager_(
DisplayManager::Create(app_impl, gpu_state, surfaces_state)), DisplayManager::Create(app_impl, gpu_state, surfaces_state)),
focus_controller_(new FocusController(this)), focus_controller_(new FocusController),
window_manager_(window_manager.Pass()) { window_manager_(window_manager.Pass()) {
focus_controller_->AddObserver(this);
display_manager_->Init(this); display_manager_->Init(this);
if (client_) { if (client_) {
client_.set_connection_error_handler(base::Bind( client_.set_connection_error_handler(base::Bind(
...@@ -40,6 +41,7 @@ WindowTreeHostImpl::WindowTreeHostImpl( ...@@ -40,6 +41,7 @@ WindowTreeHostImpl::WindowTreeHostImpl(
} }
WindowTreeHostImpl::~WindowTreeHostImpl() { WindowTreeHostImpl::~WindowTreeHostImpl() {
DestroyFocusController();
for (ServerWindow* window : windows_needing_frame_destruction_) for (ServerWindow* window : windows_needing_frame_destruction_)
window->RemoveObserver(this); window->RemoveObserver(this);
} }
...@@ -89,8 +91,6 @@ void WindowTreeHostImpl::SetFocusedWindow(ServerWindow* new_focused_window) { ...@@ -89,8 +91,6 @@ void WindowTreeHostImpl::SetFocusedWindow(ServerWindow* new_focused_window) {
return; return;
DCHECK(root_window()->Contains(new_focused_window)); DCHECK(root_window()->Contains(new_focused_window));
focus_controller_->SetFocusedWindow(new_focused_window); focus_controller_->SetFocusedWindow(new_focused_window);
// TODO(beng): have the FocusController notify us via FocusControllerDelegate.
OnFocusChanged(old_focused_window, new_focused_window);
} }
ServerWindow* WindowTreeHostImpl::GetFocusedWindow() { ServerWindow* WindowTreeHostImpl::GetFocusedWindow() {
...@@ -98,6 +98,10 @@ ServerWindow* WindowTreeHostImpl::GetFocusedWindow() { ...@@ -98,6 +98,10 @@ ServerWindow* WindowTreeHostImpl::GetFocusedWindow() {
} }
void WindowTreeHostImpl::DestroyFocusController() { void WindowTreeHostImpl::DestroyFocusController() {
if (!focus_controller_)
return;
focus_controller_->RemoveObserver(this);
focus_controller_.reset(); focus_controller_.reset();
} }
...@@ -185,7 +189,9 @@ void WindowTreeHostImpl::OnCompositorFrameDrawn() { ...@@ -185,7 +189,9 @@ void WindowTreeHostImpl::OnCompositorFrameDrawn() {
} }
} }
void WindowTreeHostImpl::OnFocusChanged(ServerWindow* old_focused_window, void WindowTreeHostImpl::OnFocusChanged(
FocusControllerChangeSource change_source,
ServerWindow* old_focused_window,
ServerWindow* new_focused_window) { ServerWindow* new_focused_window) {
// There are up to four connections that need to be notified: // There are up to four connections that need to be notified:
// . the connection containing |old_focused_window|. // . the connection containing |old_focused_window|.
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "components/mus/ws/display_manager.h" #include "components/mus/ws/display_manager.h"
#include "components/mus/ws/event_dispatcher.h" #include "components/mus/ws/event_dispatcher.h"
#include "components/mus/ws/event_dispatcher_delegate.h" #include "components/mus/ws/event_dispatcher_delegate.h"
#include "components/mus/ws/focus_controller_delegate.h" #include "components/mus/ws/focus_controller_observer.h"
#include "components/mus/ws/server_window.h" #include "components/mus/ws/server_window.h"
#include "components/mus/ws/server_window_observer.h" #include "components/mus/ws/server_window_observer.h"
...@@ -31,7 +31,7 @@ class WindowTreeImpl; ...@@ -31,7 +31,7 @@ class WindowTreeImpl;
// deleted. // deleted.
class WindowTreeHostImpl : public DisplayManagerDelegate, class WindowTreeHostImpl : public DisplayManagerDelegate,
public mojom::WindowTreeHost, public mojom::WindowTreeHost,
public FocusControllerDelegate, public FocusControllerObserver,
public EventDispatcherDelegate, public EventDispatcherDelegate,
public ServerWindowObserver { public ServerWindowObserver {
public: public:
...@@ -108,8 +108,9 @@ class WindowTreeHostImpl : public DisplayManagerDelegate, ...@@ -108,8 +108,9 @@ class WindowTreeHostImpl : public DisplayManagerDelegate,
void OnTopLevelSurfaceChanged(cc::SurfaceId surface_id) override; void OnTopLevelSurfaceChanged(cc::SurfaceId surface_id) override;
void OnCompositorFrameDrawn() override; void OnCompositorFrameDrawn() override;
// FocusControllerDelegate: // FocusControllerObserver:
void OnFocusChanged(ServerWindow* old_focused_window, void OnFocusChanged(FocusControllerChangeSource change_source,
ServerWindow* old_focused_window,
ServerWindow* new_focused_window) override; ServerWindow* new_focused_window) override;
// EventDispatcherDelegate: // EventDispatcherDelegate:
......
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