diff options
author | ben <ben@chromium.org> | 2015-09-02 12:04:40 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-02 19:05:15 +0000 |
commit | 56277a08351ced858d3a81e97f72c98dd61db6d5 (patch) | |
tree | cb3cda332e37f7eb6afa1f667cef78b6fd618b98 /components/view_manager | |
parent | edc611a7138a34968108406b456fa3c1bed4efc9 (diff) | |
download | chromium_src-56277a08351ced858d3a81e97f72c98dd61db6d5.zip chromium_src-56277a08351ced858d3a81e97f72c98dd61db6d5.tar.gz chromium_src-56277a08351ced858d3a81e97f72c98dd61db6d5.tar.bz2 |
Move FocusController to ViewTreeHost.
R=sky@chromium.org
BUG=none
Review URL: https://codereview.chromium.org/1321413003
Cr-Commit-Position: refs/heads/master@{#346984}
Diffstat (limited to 'components/view_manager')
-rw-r--r-- | components/view_manager/connection_manager.cc | 144 | ||||
-rw-r--r-- | components/view_manager/connection_manager.h | 20 | ||||
-rw-r--r-- | components/view_manager/event_dispatcher.cc | 36 | ||||
-rw-r--r-- | components/view_manager/public/cpp/lib/view_tree_client_impl.cc | 2 | ||||
-rw-r--r-- | components/view_manager/public/interfaces/view_tree.mojom | 2 | ||||
-rw-r--r-- | components/view_manager/view_tree_host_connection.cc | 3 | ||||
-rw-r--r-- | components/view_manager/view_tree_host_impl.cc | 95 | ||||
-rw-r--r-- | components/view_manager/view_tree_host_impl.h | 19 | ||||
-rw-r--r-- | components/view_manager/view_tree_impl.cc | 28 | ||||
-rw-r--r-- | components/view_manager/view_tree_impl.h | 5 | ||||
-rw-r--r-- | components/view_manager/view_tree_unittest.cc | 8 |
11 files changed, 181 insertions, 181 deletions
diff --git a/components/view_manager/connection_manager.cc b/components/view_manager/connection_manager.cc index ae5ddfe..144acd8 100644 --- a/components/view_manager/connection_manager.cc +++ b/components/view_manager/connection_manager.cc @@ -10,7 +10,6 @@ #include "cc/quads/shared_quad_state.h" #include "components/view_manager/client_connection.h" #include "components/view_manager/connection_manager_delegate.h" -#include "components/view_manager/focus_controller.h" #include "components/view_manager/server_view.h" #include "components/view_manager/view_coordinate_conversions.h" #include "components/view_manager/view_tree_host_connection.h" @@ -48,18 +47,12 @@ ConnectionManager::ConnectionManager( next_host_id_(0), event_dispatcher_(this), current_change_(nullptr), - in_destructor_(false), - focus_controller_(new FocusController(this)) { + in_destructor_(false) { } ConnectionManager::~ConnectionManager() { in_destructor_ = true; - // Deleting views will attempt to advance focus. When we're being destroyed - // that is not necessary. Additionally |focus_controller_| needs to be - // destroyed before |host_|. - focus_controller_.reset(); - // Copy the HostConnectionMap because it will be mutated as the connections // are closed. HostConnectionMap host_connection_map(host_connection_map_); @@ -110,9 +103,6 @@ void ConnectionManager::OnConnectionError(ClientConnection* connection) { connection_map_.erase(connection->service()->id()); - // TODO(sky): I may want to advance focus differently if focus is in - // |connection|. - // Notify remaining connections so that they can cleanup. for (auto& pair : connection_map_) { pair.second->service()->OnWillDestroyViewTreeImpl( @@ -125,10 +115,6 @@ void ConnectionManager::OnHostConnectionClosed( auto it = host_connection_map_.find(connection->view_tree_host()); DCHECK(it != host_connection_map_.end()); - // Clear focus if the focused view is in this viewport. - if (GetRootView(GetFocusedView()) == it->first->root_view()) - SetFocusedView(nullptr); - // Get the ClientConnection by ViewTreeImpl ID. ConnectionMap::iterator service_connection_it = connection_map_.find(it->first->GetViewTree()->id()); @@ -202,22 +188,6 @@ ServerView* ConnectionManager::GetView(const ViewId& id) { return service ? service->GetView(id) : nullptr; } -void ConnectionManager::SetFocusedView(ServerView* view) { - if (!focus_controller_) - return; - ServerView* old_focused = GetFocusedView(); - if (old_focused == view) - return; - focus_controller_->SetFocusedView(view); - OnFocusChanged(old_focused, view); -} - -ServerView* ConnectionManager::GetFocusedView() { - if (!focus_controller_) - return nullptr; - return focus_controller_->GetFocusedView(); -} - bool ConnectionManager::IsViewAttachedToRoot(const ServerView* view) const { for (auto& pair : host_connection_map_) { if (pair.first->IsViewAttachedToRoot(view)) @@ -267,6 +237,23 @@ const ViewTreeImpl* ConnectionManager::GetConnectionWithRoot( return nullptr; } +ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView( + const ServerView* view) { + return const_cast<ViewTreeHostImpl*>( + static_cast<const ConnectionManager*>(this)->GetViewTreeHostByView(view)); +} + +const ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView( + const ServerView* view) const { + while (view && view->parent()) + view = view->parent(); + for (auto& pair : host_connection_map_) { + if (view == pair.first->root_view()) + return pair.first; + } + return nullptr; +} + ViewTreeImpl* ConnectionManager::GetEmbedRoot(ViewTreeImpl* service) { while (service) { const ViewId* root_id = service->root(); @@ -309,15 +296,6 @@ void ConnectionManager::RemoveAccelerator(ViewTreeHostImpl* host, uint32_t id) { event_dispatcher_.RemoveAccelerator(id); } -void ConnectionManager::SetImeVisibility(ServerView* view, bool visible) { - // Do not need to show or hide IME for unfocused view. - if (focus_controller_->GetFocusedView() != view) - return; - - ViewTreeHostImpl* host = GetViewTreeHostByView(view); - host->SetImeVisibility(visible); -} - void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { @@ -390,17 +368,6 @@ void ConnectionManager::AddConnection(ClientConnection* connection) { connection_map_[connection->service()->id()] = connection; } -ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView( - const ServerView* view) const { - while (view && view->parent()) - view = view->parent(); - for (auto& pair : host_connection_map_) { - if (view == pair.first->root_view()) - return pair.first; - } - return nullptr; -} - scoped_ptr<cc::CompositorFrame> ConnectionManager::UpdateViewTreeFromCompositorFrame( const mojo::CompositorFramePtr& input) { @@ -417,7 +384,7 @@ void ConnectionManager::OnScheduleViewPaint(const ServerView* view) { } const ServerView* ConnectionManager::GetRootView(const ServerView* view) const { - ViewTreeHostImpl* host = GetViewTreeHostByView(view); + const ViewTreeHostImpl* host = GetViewTreeHostByView(view); return host ? host->root_view() : nullptr; } @@ -502,79 +469,8 @@ void ConnectionManager::OnViewSharedPropertyChanged( void ConnectionManager::OnViewTextInputStateChanged( ServerView* view, const ui::TextInputState& state) { - // Do not need to update text input for unfocused views. - if (focus_controller_->GetFocusedView() != view) - return; - ViewTreeHostImpl* host = GetViewTreeHostByView(view); - host->UpdateTextInputState(state); -} - -void ConnectionManager::OnFocusChanged(ServerView* old_focused_view, - ServerView* new_focused_view) { - // There are up to four connections that need to be notified: - // . the connection containing |old_focused_view|. - // . the connection with |old_focused_view| as its root. - // . the connection containing |new_focused_view|. - // . the connection with |new_focused_view| as its root. - // Some of these connections may be the same. The following takes care to - // notify each only once. - ViewTreeImpl* owning_connection_old = nullptr; - ViewTreeImpl* embedded_connection_old = nullptr; - - if (old_focused_view) { - owning_connection_old = GetConnection(old_focused_view->id().connection_id); - if (owning_connection_old) { - owning_connection_old->ProcessFocusChanged(old_focused_view, - new_focused_view); - } - embedded_connection_old = GetConnectionWithRoot(old_focused_view->id()); - if (embedded_connection_old) { - DCHECK_NE(owning_connection_old, embedded_connection_old); - embedded_connection_old->ProcessFocusChanged(old_focused_view, - new_focused_view); - } - } - ViewTreeImpl* owning_connection_new = nullptr; - ViewTreeImpl* embedded_connection_new = nullptr; - if (new_focused_view) { - owning_connection_new = GetConnection(new_focused_view->id().connection_id); - if (owning_connection_new && - owning_connection_new != owning_connection_old && - owning_connection_new != embedded_connection_old) { - owning_connection_new->ProcessFocusChanged(old_focused_view, - new_focused_view); - } - embedded_connection_new = GetConnectionWithRoot(new_focused_view->id()); - if (embedded_connection_new && - embedded_connection_new != owning_connection_old && - embedded_connection_new != embedded_connection_old) { - DCHECK_NE(owning_connection_new, embedded_connection_new); - embedded_connection_new->ProcessFocusChanged(old_focused_view, - new_focused_view); - } - } - - for (auto& pair : host_connection_map_) { - ViewTreeImpl* service = pair.first->GetViewTree(); - if (service != owning_connection_old && - service != embedded_connection_old && - service != owning_connection_new && - service != embedded_connection_new) { - service->ProcessFocusChanged(old_focused_view, new_focused_view); - } - } - - ViewTreeHostImpl* old_host = - old_focused_view ? GetViewTreeHostByView(old_focused_view) : nullptr; - - ViewTreeHostImpl* new_host = - new_focused_view ? GetViewTreeHostByView(new_focused_view) : nullptr; - - if (new_host) - new_host->UpdateTextInputState(new_focused_view->text_input_state()); - else if (old_host) - old_host->UpdateTextInputState(ui::TextInputState()); + host->UpdateTextInputState(view, state); } bool ConnectionManager::ConvertSurfaceDrawQuad( diff --git a/components/view_manager/connection_manager.h b/components/view_manager/connection_manager.h index 49cf0fd..1eb3538 100644 --- a/components/view_manager/connection_manager.h +++ b/components/view_manager/connection_manager.h @@ -28,7 +28,6 @@ namespace view_manager { class ClientConnection; class ConnectionManagerDelegate; -class FocusController; class ServerView; class ViewTreeHostConnection; class ViewTreeImpl; @@ -37,7 +36,6 @@ class ViewTreeImpl; // ViewTreeImpl) as well as providing the root of the hierarchy. class ConnectionManager : public ServerViewDelegate, public ServerViewObserver, - public FocusControllerDelegate, public mojo::CustomSurfaceConverter { public: // Create when a ViewTreeImpl is about to make a change. Ensures clients are @@ -118,9 +116,6 @@ class ConnectionManager : public ServerViewDelegate, // Returns the View identified by |id|. ServerView* GetView(const ViewId& id); - void SetFocusedView(ServerView* view); - ServerView* GetFocusedView(); - // Returns whether |view| is a descendant of some root view but not itself a // root view. bool IsViewAttachedToRoot(const ServerView* view) const; @@ -154,6 +149,9 @@ class ConnectionManager : public ServerViewDelegate, } const ViewTreeImpl* GetConnectionWithRoot(const ViewId& id) const; + ViewTreeHostImpl* GetViewTreeHostByView(const ServerView* view); + const ViewTreeHostImpl* GetViewTreeHostByView(const ServerView* view) const; + // Returns the first ancestor of |service| that is marked as an embed root. ViewTreeImpl* GetEmbedRoot(ViewTreeImpl* service); @@ -171,10 +169,6 @@ class ConnectionManager : public ServerViewDelegate, mojo::EventFlags flags); void RemoveAccelerator(ViewTreeHostImpl* host, uint32_t id); - // Set IME's visibility for the specified view. If the view is not the current - // focused view, this function will do nothing. - void SetImeVisibility(ServerView* view, bool visible); - // These functions trivially delegate to all ViewTreeImpls, which in // term notify their clients. void ProcessViewDestroyed(ServerView* view); @@ -218,8 +212,6 @@ class ConnectionManager : public ServerViewDelegate, // Adds |connection| to internal maps. void AddConnection(ClientConnection* connection); - ViewTreeHostImpl* GetViewTreeHostByView(const ServerView* view) const; - // Overridden from ServerViewDelegate: scoped_ptr<cc::CompositorFrame> UpdateViewTreeFromCompositorFrame( const mojo::CompositorFramePtr& input) override; @@ -249,10 +241,6 @@ class ConnectionManager : public ServerViewDelegate, void OnViewTextInputStateChanged(ServerView* view, const ui::TextInputState& state) override; - // FocusControllerDelegate: - void OnFocusChanged(ServerView* old_focused_view, - ServerView* new_focused_view) override; - // Overriden from CustomSurfaceConverter: bool ConvertSurfaceDrawQuad(const mojo::QuadPtr& input, const mojo::CompositorFrameMetadataPtr& metadata, @@ -284,8 +272,6 @@ class ConnectionManager : public ServerViewDelegate, bool in_destructor_; - scoped_ptr<FocusController> focus_controller_; - DISALLOW_COPY_AND_ASSIGN(ConnectionManager); }; diff --git a/components/view_manager/event_dispatcher.cc b/components/view_manager/event_dispatcher.cc index 3819415..3bc5477 100644 --- a/components/view_manager/event_dispatcher.cc +++ b/components/view_manager/event_dispatcher.cc @@ -24,12 +24,11 @@ void EventDispatcher::AddAccelerator(uint32_t id, mojo::KeyboardCode keyboard_code, mojo::EventFlags flags) { #if !defined(NDEBUG) - std::for_each(accelerators_.begin(), accelerators_.end(), - [id, keyboard_code, flags](const Entry& entry) { - DCHECK(entry.first != id); - DCHECK(entry.second.keyboard_code != keyboard_code || - entry.second.flags != flags); - }); + for (const auto& pair : accelerators_) { + DCHECK(pair.first != id); + DCHECK(pair.second.keyboard_code != keyboard_code || + pair.second.flags != flags); + } #endif accelerators_.insert(Entry(id, Accelerator(keyboard_code, flags))); } @@ -41,15 +40,17 @@ void EventDispatcher::RemoveAccelerator(uint32_t id) { } void EventDispatcher::OnEvent(ServerView* root, mojo::EventPtr event) { + ViewTreeHostImpl* host = connection_manager_->GetViewTreeHostByView(root); + ServerView* focused_view = host->GetFocusedView(); if (event->pointer_data) { const gfx::Point root_point(static_cast<int>(event->pointer_data->x), static_cast<int>(event->pointer_data->y)); - ServerView* target = connection_manager_->GetFocusedView(); + ServerView* target = focused_view; if (event->action == mojo::EVENT_TYPE_POINTER_DOWN || !target || !root->Contains(target)) { target = FindDeepestVisibleView(root, root_point); CHECK(target); - connection_manager_->SetFocusedView(target); + host->SetFocusedView(target); } const gfx::PointF local_point(ConvertPointFBetweenViews( root, target, @@ -66,7 +67,7 @@ void EventDispatcher::OnEvent(ServerView* root, mojo::EventPtr event) { connection_manager_->OnAccelerator(root, accelerator_id, event.Pass()); return; } - ServerView* focused_view = connection_manager_->GetFocusedView(); + if (focused_view) connection_manager_->DispatchInputEventToView(focused_view, event.Pass()); } @@ -75,15 +76,14 @@ void EventDispatcher::OnEvent(ServerView* root, mojo::EventPtr event) { bool EventDispatcher::HandleAccelerator(mojo::KeyboardCode keyboard_code, mojo::EventFlags flags, uint32_t* accelerator_id) { - auto it = std::find_if(accelerators_.begin(), accelerators_.end(), - [keyboard_code, flags](const Entry& entry) { - return entry.second.keyboard_code == keyboard_code && - entry.second.flags == flags; - }); - bool found = it != accelerators_.end(); - if (found) - *accelerator_id = it->first; - return found; + for (const auto& pair : accelerators_) { + if (pair.second.keyboard_code == keyboard_code && + pair.second.flags == flags) { + *accelerator_id = pair.first; + return true; + } + } + return false; } } // namespace view_manager diff --git a/components/view_manager/public/cpp/lib/view_tree_client_impl.cc b/components/view_manager/public/cpp/lib/view_tree_client_impl.cc index 9639a73..216f16b 100644 --- a/components/view_manager/public/cpp/lib/view_tree_client_impl.cc +++ b/components/view_manager/public/cpp/lib/view_tree_client_impl.cc @@ -150,7 +150,7 @@ void ViewTreeClientImpl::SetFocus(Id view_id) { // In order for us to get here we had to have exposed a view, which implies we // got a connection. DCHECK(tree_); - tree_->SetFocus(view_id, ActionCompletedCallback()); + tree_->SetFocus(view_id); } void ViewTreeClientImpl::SetVisible(Id view_id, bool visible) { diff --git a/components/view_manager/public/interfaces/view_tree.mojom b/components/view_manager/public/interfaces/view_tree.mojom index 1aa3b6d..008f5dc 100644 --- a/components/view_manager/public/interfaces/view_tree.mojom +++ b/components/view_manager/public/interfaces/view_tree.mojom @@ -139,7 +139,7 @@ interface ViewTree { // embed roots see the complete tree at their embed point. Embed(uint32 view_id, ViewTreeClient client) => (bool success); - SetFocus(uint32 view_id) => (bool success); + SetFocus(uint32 view_id); // Set text input state for the given view. SetViewTextInputState(uint32 view_id, TextInputState state); diff --git a/components/view_manager/view_tree_host_connection.cc b/components/view_manager/view_tree_host_connection.cc index 1c9f1b5..429143c 100644 --- a/components/view_manager/view_tree_host_connection.cc +++ b/components/view_manager/view_tree_host_connection.cc @@ -30,6 +30,9 @@ void ViewTreeHostConnection::CloseConnection() { // sure we signal the ConnectionManager only once. if (connection_closed_) return; + // We have to shut down the focus system for this host before destroying the + // host, as destruction of the view tree will attempt to change focus. + host_->DestroyFocusController(); connection_manager()->OnHostConnectionClosed(this); connection_closed_ = true; delete this; diff --git a/components/view_manager/view_tree_host_impl.cc b/components/view_manager/view_tree_host_impl.cc index 279dc4b..243b39c 100644 --- a/components/view_manager/view_tree_host_impl.cc +++ b/components/view_manager/view_tree_host_impl.cc @@ -6,8 +6,10 @@ #include "components/view_manager/connection_manager.h" #include "components/view_manager/display_manager.h" +#include "components/view_manager/focus_controller.h" #include "components/view_manager/public/cpp/types.h" #include "components/view_manager/view_tree_host_delegate.h" +#include "components/view_manager/view_tree_impl.h" #include "mojo/converters/geometry/geometry_type_converters.h" namespace view_manager { @@ -26,7 +28,8 @@ ViewTreeHostImpl::ViewTreeHostImpl( DisplayManager::Create(is_headless, app_impl, gpu_state, - surfaces_state)) { + surfaces_state)), + focus_controller_(new FocusController(this)) { display_manager_->Init(this); if (client_) { client_.set_connection_error_handler( @@ -65,13 +68,36 @@ const mojo::ViewportMetrics& ViewTreeHostImpl::GetViewportMetrics() const { return display_manager_->GetViewportMetrics(); } -void ViewTreeHostImpl::UpdateTextInputState(const ui::TextInputState& state) { - if (!display_manager_) +void ViewTreeHostImpl::SetFocusedView(ServerView* new_focused_view) { + ServerView* old_focused_view = focus_controller_->GetFocusedView(); + if (old_focused_view == new_focused_view) + return; + DCHECK(root_view()->Contains(new_focused_view)); + focus_controller_->SetFocusedView(new_focused_view); + // TODO(beng): have the FocusController notify us via FocusControllerDelegate. + OnFocusChanged(old_focused_view, new_focused_view); +} + +ServerView* ViewTreeHostImpl::GetFocusedView() { + return focus_controller_->GetFocusedView(); +} + +void ViewTreeHostImpl::DestroyFocusController() { + focus_controller_.reset(); +} + +void ViewTreeHostImpl::UpdateTextInputState(ServerView* view, + const ui::TextInputState& state) { + // Do not need to update text input for unfocused views. + if (!display_manager_ || focus_controller_->GetFocusedView() != view) return; display_manager_->UpdateTextInputState(state); } -void ViewTreeHostImpl::SetImeVisibility(bool visible) { +void ViewTreeHostImpl::SetImeVisibility(ServerView* view, bool visible) { + // Do not need to show or hide IME for unfocused view. + if (focus_controller_->GetFocusedView() != view) + return; display_manager_->SetImeVisibility(visible); } @@ -129,4 +155,65 @@ void ViewTreeHostImpl::OnViewportMetricsChanged( connection_manager_->ProcessViewportMetricsChanged(old_metrics, new_metrics); } +void ViewTreeHostImpl::OnFocusChanged(ServerView* old_focused_view, + ServerView* new_focused_view) { + // There are up to four connections that need to be notified: + // . the connection containing |old_focused_view|. + // . the connection with |old_focused_view| as its root. + // . the connection containing |new_focused_view|. + // . the connection with |new_focused_view| as its root. + // Some of these connections may be the same. The following takes care to + // notify each only once. + ViewTreeImpl* owning_connection_old = nullptr; + ViewTreeImpl* embedded_connection_old = nullptr; + + if (old_focused_view) { + owning_connection_old = connection_manager_->GetConnection( + old_focused_view->id().connection_id); + if (owning_connection_old) { + owning_connection_old->ProcessFocusChanged(old_focused_view, + new_focused_view); + } + embedded_connection_old = + connection_manager_->GetConnectionWithRoot(old_focused_view->id()); + if (embedded_connection_old) { + DCHECK_NE(owning_connection_old, embedded_connection_old); + embedded_connection_old->ProcessFocusChanged(old_focused_view, + new_focused_view); + } + } + ViewTreeImpl* owning_connection_new = nullptr; + ViewTreeImpl* embedded_connection_new = nullptr; + if (new_focused_view) { + owning_connection_new = connection_manager_->GetConnection( + new_focused_view->id().connection_id); + if (owning_connection_new && + owning_connection_new != owning_connection_old && + owning_connection_new != embedded_connection_old) { + owning_connection_new->ProcessFocusChanged(old_focused_view, + new_focused_view); + } + embedded_connection_new = + connection_manager_->GetConnectionWithRoot(new_focused_view->id()); + if (embedded_connection_new && + embedded_connection_new != owning_connection_old && + embedded_connection_new != embedded_connection_old) { + DCHECK_NE(owning_connection_new, embedded_connection_new); + embedded_connection_new->ProcessFocusChanged(old_focused_view, + new_focused_view); + } + } + + // Ensure that we always notify the root connection of a focus change. + ViewTreeImpl* root_tree = GetViewTree(); + if (root_tree != owning_connection_old && + root_tree != embedded_connection_old && + root_tree != owning_connection_new && + root_tree != embedded_connection_new) { + root_tree->ProcessFocusChanged(old_focused_view, new_focused_view); + } + + UpdateTextInputState(new_focused_view, new_focused_view->text_input_state()); +} + } // namespace view_manager diff --git a/components/view_manager/view_tree_host_impl.h b/components/view_manager/view_tree_host_impl.h index 83e25ad..95a39bd 100644 --- a/components/view_manager/view_tree_host_impl.h +++ b/components/view_manager/view_tree_host_impl.h @@ -7,6 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "components/view_manager/display_manager.h" +#include "components/view_manager/focus_controller_delegate.h" #include "components/view_manager/public/cpp/types.h" #include "components/view_manager/public/interfaces/view_tree_host.mojom.h" #include "components/view_manager/server_view.h" @@ -22,6 +23,7 @@ class SurfacesScheduler; namespace view_manager { class ConnectionManager; +class FocusController; class ViewTreeHostDelegate; class ViewTreeImpl; @@ -31,7 +33,8 @@ class ViewTreeImpl; // closes the associated window, then this object and related state will be // deleted. class ViewTreeHostImpl : public DisplayManagerDelegate, - public mojo::ViewTreeHost { + public mojo::ViewTreeHost, + public FocusControllerDelegate { public: // TODO(fsamuel): All these parameters are just plumbing for creating // DisplayManagers. We should probably just store these common parameters @@ -68,9 +71,14 @@ class ViewTreeHostImpl : public DisplayManagerDelegate, // Returns the root ServerView of this viewport. ServerView* root_view() { return root_.get(); } + const ServerView* root_view() const { return root_.get(); } - void UpdateTextInputState(const ui::TextInputState& state); - void SetImeVisibility(bool visible); + void SetFocusedView(ServerView* view); + ServerView* GetFocusedView(); + void DestroyFocusController(); + + void UpdateTextInputState(ServerView* view, const ui::TextInputState& state); + void SetImeVisibility(ServerView* view, bool visible); // ViewTreeHost: void SetSize(mojo::SizePtr size) override; @@ -90,11 +98,16 @@ class ViewTreeHostImpl : public DisplayManagerDelegate, const mojo::ViewportMetrics& old_metrics, const mojo::ViewportMetrics& new_metrics) override; + // FocusControllerDelegate: + void OnFocusChanged(ServerView* old_focused_view, + ServerView* new_focused_view) override; + ViewTreeHostDelegate* delegate_; ConnectionManager* const connection_manager_; mojo::ViewTreeHostClientPtr client_; scoped_ptr<ServerView> root_; scoped_ptr<DisplayManager> display_manager_; + scoped_ptr<FocusController> focus_controller_; DISALLOW_COPY_AND_ASSIGN(ViewTreeHostImpl); }; diff --git a/components/view_manager/view_tree_impl.cc b/components/view_manager/view_tree_impl.cc index 12aadb7..1439c7f 100644 --- a/components/view_manager/view_tree_impl.cc +++ b/components/view_manager/view_tree_impl.cc @@ -10,6 +10,7 @@ #include "components/view_manager/default_access_policy.h" #include "components/view_manager/display_manager.h" #include "components/view_manager/server_view.h" +#include "components/view_manager/view_tree_host_impl.h" #include "components/view_manager/window_manager_access_policy.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "mojo/converters/ime/ime_type_converters.h" @@ -59,7 +60,9 @@ void ViewTreeImpl::Init(mojo::ViewTreeClient* client, mojo::ViewTreePtr tree) { if (root_.get()) GetUnknownViewsFrom(GetView(*root_), &to_send); - const ServerView* focused_view = connection_manager_->GetFocusedView(); + // TODO(beng): verify that host can actually be nullptr here. + ViewTreeHostImpl* host = GetHost(); + const ServerView* focused_view = host ? host->GetFocusedView() : nullptr; if (focused_view) focused_view = access_policy_->GetViewForFocusChange(focused_view); const mojo::Id focused_view_transport_id( @@ -81,6 +84,11 @@ bool ViewTreeImpl::IsRoot(const ViewId& id) const { return root_.get() && *root_ == id; } +ViewTreeHostImpl* ViewTreeImpl::GetHost() { + return root_.get() ? + connection_manager_->GetViewTreeHostByView(GetView(*root_)) : nullptr; +} + void ViewTreeImpl::OnWillDestroyViewTreeImpl( ViewTreeImpl* connection) { if (creator_id_ == connection->id()) @@ -626,7 +634,10 @@ void ViewTreeImpl::SetImeVisibility(uint32_t view_id, if (success) { if (!state.is_null()) view->SetTextInputState(state.To<ui::TextInputState>()); - connection_manager_->SetImeVisibility(view, visible); + + ViewTreeHostImpl* host = GetHost(); + if (host) + host->SetImeVisibility(view, visible); } } @@ -640,15 +651,16 @@ void ViewTreeImpl::Embed(mojo::Id transport_view_id, callback.Run(Embed(ViewIdFromTransportId(transport_view_id), client.Pass())); } -void ViewTreeImpl::SetFocus(uint32_t view_id, - const SetFocusCallback& callback) { +void ViewTreeImpl::SetFocus(uint32_t view_id) { ServerView* view = GetView(ViewIdFromTransportId(view_id)); - bool success = view && view->IsDrawn() && access_policy_->CanSetFocus(view); - if (success) { + // TODO(beng): consider shifting non-policy drawn check logic to VTH's + // FocusController. + if (view && view->IsDrawn() && access_policy_->CanSetFocus(view)) { ConnectionManager::ScopedChange change(this, connection_manager_, false); - connection_manager_->SetFocusedView(view); + ViewTreeHostImpl* host = GetHost(); + if (host) + host->SetFocusedView(view); } - callback.Run(success); } bool ViewTreeImpl::IsRootForAccessPolicy(const ViewId& id) const { diff --git a/components/view_manager/view_tree_impl.h b/components/view_manager/view_tree_impl.h index 3db118c..8e0dac9 100644 --- a/components/view_manager/view_tree_impl.h +++ b/components/view_manager/view_tree_impl.h @@ -27,6 +27,7 @@ namespace view_manager { class AccessPolicy; class ConnectionManager; class ServerView; +class ViewTreeHostImpl; // An instance of ViewTreeImpl is created for every ViewTree request. // ViewTreeImpl tracks all the state and views created by a client. ViewTreeImpl @@ -64,6 +65,8 @@ class ViewTreeImpl : public mojo::ViewTree, public AccessPolicyDelegate { bool is_embed_root() const { return is_embed_root_; } + ViewTreeHostImpl* GetHost(); + // Invoked when a connection is about to be destroyed. void OnWillDestroyViewTreeImpl(ViewTreeImpl* connection); @@ -198,7 +201,7 @@ class ViewTreeImpl : public mojo::ViewTree, public AccessPolicyDelegate { void Embed(mojo::Id transport_view_id, mojo::ViewTreeClientPtr client, const mojo::Callback<void(bool)>& callback) override; - void SetFocus(uint32_t view_id, const SetFocusCallback& callback) override; + void SetFocus(uint32_t view_id) override; void SetViewTextInputState(uint32_t view_id, mojo::TextInputStatePtr state) override; void SetImeVisibility(uint32_t view_id, diff --git a/components/view_manager/view_tree_unittest.cc b/components/view_manager/view_tree_unittest.cc index e467740..bdb67c5 100644 --- a/components/view_manager/view_tree_unittest.cc +++ b/components/view_manager/view_tree_unittest.cc @@ -357,9 +357,9 @@ TEST_F(ViewTreeTest, FocusOnPointer) { connection_manager()->OnEvent(host_connection()->view_tree_host(), CreatePointerDownEvent(21, 22)); - // Focus should go to child1. This results in notifying both the window + // Focus should go to child1. This result in notifying both the window // manager and client connection being notified. - EXPECT_EQ(v1, connection_manager()->GetFocusedView()); + EXPECT_EQ(v1, connection1->GetHost()->GetFocusedView()); ASSERT_GE(wm_client()->tracker()->changes()->size(), 1u); EXPECT_EQ("Focused id=2,1", ChangesToDescription1(*wm_client()->tracker()->changes())[0]); @@ -379,7 +379,7 @@ TEST_F(ViewTreeTest, FocusOnPointer) { connection_manager()->OnEvent(host_connection()->view_tree_host(), CreatePointerDownEvent(61, 22)); EXPECT_EQ(host_connection()->view_tree_host()->root_view(), - connection_manager()->GetFocusedView()); + host_connection()->view_tree_host()->GetFocusedView()); ASSERT_GE(wm_client()->tracker()->changes()->size(), 1u); EXPECT_EQ("Focused id=0,2", ChangesToDescription1(*wm_client()->tracker()->changes())[0]); @@ -398,7 +398,7 @@ TEST_F(ViewTreeTest, FocusOnPointer) { connection_manager()->OnEvent(host_connection()->view_tree_host(), CreatePointerDownEvent(61, 22)); EXPECT_EQ(host_connection()->view_tree_host()->root_view(), - connection_manager()->GetFocusedView()); + host_connection()->view_tree_host()->GetFocusedView()); ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u); EXPECT_EQ("InputEvent view=0,2 event_action=4", ChangesToDescription1(*wm_client()->tracker()->changes())[0]); |