diff options
author | sky <sky@chromium.org> | 2015-04-23 12:14:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-23 19:15:02 +0000 |
commit | 10a85da648a9556e584036e4b58ac21c0478123d (patch) | |
tree | 184cd6e44a2665fd0a4a6c54a7236a510ed46993 /components | |
parent | 25a6650258dcbcc1d03ed9ed09de123910659613 (diff) | |
download | chromium_src-10a85da648a9556e584036e4b58ac21c0478123d.zip chromium_src-10a85da648a9556e584036e4b58ac21c0478123d.tar.gz chromium_src-10a85da648a9556e584036e4b58ac21c0478123d.tar.bz2 |
Move event dispatch to view manager
This work is motivated by a couple of things:
. Proper event targetting needs to be closely tied with the tree of
views and potentially needs to dispatch to multiple views.
. To decrease the number of apps an event goes through.
. To more narrowly focus the responsibilities of the window manager.
This is the same as https://codereview.chromium.org/1051763005/ , but
in chromium.
BUG=none
TEST=none
R=erg@chromium.org,ben@chromium.org
TBR=erg@chromium.org,ben@chromium.org
Review URL: https://codereview.chromium.org/1093373004
Cr-Commit-Position: refs/heads/master@{#326602}
Diffstat (limited to 'components')
66 files changed, 551 insertions, 3968 deletions
diff --git a/components/kiosk_wm/BUILD.gn b/components/kiosk_wm/BUILD.gn index 0d918df..b7bd5ee 100644 --- a/components/kiosk_wm/BUILD.gn +++ b/components/kiosk_wm/BUILD.gn @@ -26,12 +26,11 @@ mojo_native_application("window_manager") { "//mojo/application", "//mojo/common:common", "//mojo/converters/geometry", - "//mojo/converters/input_events", "//third_party/mojo/src/mojo/public/cpp/bindings", "//third_party/mojo/src/mojo/public/cpp/utility", "//third_party/mojo/src/mojo/public/interfaces/application", "//third_party/mojo_services/src/navigation/public/interfaces", - "//ui/base", + "//ui/gfx/geometry", "//ui/mojo/events:interfaces", ] } diff --git a/components/kiosk_wm/kiosk_wm.cc b/components/kiosk_wm/kiosk_wm.cc index 83331b7..88fe5f5 100644 --- a/components/kiosk_wm/kiosk_wm.cc +++ b/components/kiosk_wm/kiosk_wm.cc @@ -7,7 +7,7 @@ #include "base/command_line.h" #include "base/strings/utf_string_conversions.h" #include "components/kiosk_wm/merged_service_provider.h" -#include "components/window_manager/basic_focus_rules.h" +#include "ui/gfx/geometry/size.h" namespace kiosk_wm { @@ -77,11 +77,8 @@ void KioskWM::OnEmbed( root_->AddChild(content_); content_->SetVisible(true); - window_manager_app_->InitFocus( - make_scoped_ptr(new window_manager::BasicFocusRules(root_))); - window_manager_app_->accelerator_manager()->Register( - ui::Accelerator(ui::VKEY_BROWSER_BACK, 0), - ui::AcceleratorManager::kNormalPriority, this); + window_manager_app_->AddAccelerator(mojo::KEYBOARD_CODE_BROWSER_BACK, + mojo::EVENT_FLAGS_NONE); // Now that we're ready, either load a pending url or the default url. if (!pending_url_.empty()) @@ -109,6 +106,13 @@ void KioskWM::Embed(const mojo::String& url, navigator_host_.RecordNavigation(url); } +void KioskWM::OnAcceleratorPressed(mojo::View* view, + mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + DCHECK_EQ(mojo::KEYBOARD_CODE_BROWSER_BACK, keyboard_code); + navigator_host_.RequestNavigateHistory(-1); +} + void KioskWM::Create(mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::NavigatorHost> request) { navigator_host_.Bind(request.Pass()); @@ -134,15 +138,4 @@ void KioskWM::ReplaceContentWithURL(const mojo::String& url) { Embed(url, nullptr, nullptr); } -bool KioskWM::AcceleratorPressed(const ui::Accelerator& accelerator) { - if (accelerator.key_code() != ui::VKEY_BROWSER_BACK) - return false; - navigator_host_.RequestNavigateHistory(-1); - return true; -} - -bool KioskWM::CanHandleAccelerators() const { - return true; -} - } // namespace kiosk_wm diff --git a/components/kiosk_wm/kiosk_wm.h b/components/kiosk_wm/kiosk_wm.h index 49b3675..4f3527c 100644 --- a/components/kiosk_wm/kiosk_wm.h +++ b/components/kiosk_wm/kiosk_wm.h @@ -17,7 +17,6 @@ #include "third_party/mojo/src/mojo/public/cpp/application/connect.h" #include "third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h" #include "third_party/mojo_services/src/navigation/public/interfaces/navigation.mojom.h" -#include "ui/base/accelerators/accelerator.h" #include "ui/mojo/events/input_events.mojom.h" namespace kiosk_wm { @@ -28,8 +27,7 @@ class KioskWM : public mojo::ApplicationDelegate, public mojo::ViewManagerDelegate, public mojo::ViewObserver, public window_manager::WindowManagerDelegate, - public mojo::InterfaceFactory<mojo::NavigatorHost>, - public ui::AcceleratorTarget { + public mojo::InterfaceFactory<mojo::NavigatorHost> { public: KioskWM(); ~KioskWM() override; @@ -62,15 +60,14 @@ class KioskWM : public mojo::ApplicationDelegate, void Embed(const mojo::String& url, mojo::InterfaceRequest<mojo::ServiceProvider> services, mojo::ServiceProviderPtr exposed_services) override; + void OnAcceleratorPressed(mojo::View* view, + mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) override; // Overridden from mojo::InterfaceFactory<mojo::NavigatorHost>: void Create(mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::NavigatorHost> request) override; - // Overriden from ui::AcceleratorTarget: - bool AcceleratorPressed(const ui::Accelerator& accelerator) override; - bool CanHandleAccelerators() const override; - scoped_ptr<window_manager::WindowManagerApp> window_manager_app_; // Only support being embedded once, so both application-level diff --git a/components/view_manager/BUILD.gn b/components/view_manager/BUILD.gn index 008d19c..d6c95459 100644 --- a/components/view_manager/BUILD.gn +++ b/components/view_manager/BUILD.gn @@ -42,6 +42,8 @@ source_set("view_manager_lib") { "default_access_policy.h", "display_manager.cc", "display_manager.h", + "event_dispatcher.cc", + "event_dispatcher.h", "focus_controller.cc", "focus_controller.h", "focus_controller_delegate.h", @@ -133,7 +135,7 @@ test("view_manager_service_unittests") { "//base", "//base/test:test_config", "//components/native_viewport/public/cpp:args", - "//components/view_manager/public/cpp", + "//components/view_manager/public/cpp:common", "//components/view_manager/public/interfaces", "//components/window_manager/public/interfaces", "//mojo/converters/geometry", diff --git a/components/view_manager/access_policy.h b/components/view_manager/access_policy.h index 1f3927c..1d9148e 100644 --- a/components/view_manager/access_policy.h +++ b/components/view_manager/access_policy.h @@ -37,6 +37,7 @@ class AccessPolicy { virtual bool CanSetViewSurfaceId(const ServerView* view) const = 0; virtual bool CanSetViewBounds(const ServerView* view) const = 0; virtual bool CanSetViewProperties(const ServerView* view) const = 0; + virtual bool CanSetFocus(const ServerView* view) const = 0; // Returns whether the connection should notify on a hierarchy change. // |new_parent| and |old_parent| are initially set to the new and old parents @@ -45,6 +46,10 @@ class AccessPolicy { const ServerView* view, const ServerView** new_parent, const ServerView** old_parent) const = 0; + + // Returns the view to supply to the client when focus changes to |focused|. + virtual const ServerView* GetViewForFocusChange( + const ServerView* focused) = 0; }; } // namespace view_manager diff --git a/components/view_manager/connection_manager.cc b/components/view_manager/connection_manager.cc index a7e1f5f..685d1c5 100644 --- a/components/view_manager/connection_manager.cc +++ b/components/view_manager/connection_manager.cc @@ -9,6 +9,7 @@ #include "components/view_manager/client_connection.h" #include "components/view_manager/connection_manager_delegate.h" #include "components/view_manager/display_manager.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_manager_service_impl.h" @@ -120,15 +121,26 @@ ConnectionManager::ConnectionManager(ConnectionManagerDelegate* delegate, wm_internal_(wm_internal), current_change_(nullptr), in_destructor_(false), - animation_runner_(base::TimeTicks::Now()) { + animation_runner_(base::TimeTicks::Now()), + event_dispatcher_(this), + event_dispatcher_binding_(&event_dispatcher_), + focus_controller_(new FocusController(this, root_.get())) { root_->SetBounds(gfx::Rect(800, 600)); root_->SetVisible(true); - display_manager_->Init(this); + + mojo::NativeViewportEventDispatcherPtr event_dispatcher_ptr; + event_dispatcher_binding_.Bind(GetProxy(&event_dispatcher_ptr)); + display_manager_->Init(this, event_dispatcher_ptr.Pass()); } 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 |root_|. + focus_controller_.reset(); + STLDeleteValues(&connection_map_); // All the connections should have been destroyed. DCHECK(connection_map_.empty()); @@ -159,6 +171,9 @@ 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()->OnWillDestroyViewManagerServiceImpl( @@ -220,6 +235,18 @@ ServerView* ConnectionManager::GetView(const ViewId& id) { return service ? service->GetView(id) : nullptr; } +void ConnectionManager::SetFocusedView(ServerView* view) { + ServerView* old_focused = GetFocusedView(); + if (old_focused == view) + return; + focus_controller_->SetFocusedView(view); + OnFocusChanged(old_focused, view); +} + +ServerView* ConnectionManager::GetFocusedView() { + return focus_controller_->GetFocusedView(); +} + void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) { if (current_change_) current_change_->MarkConnectionAsMessaged(id); @@ -269,6 +296,22 @@ bool ConnectionManager::CloneAndAnimate(const ViewId& view_id) { return true; } +void ConnectionManager::ProcessEvent(mojo::EventPtr event) { + event_dispatcher_.OnEvent(event.Pass(), EventDispatcher::OnEventCallback()); +} + +void ConnectionManager::DispatchInputEventToView(const ServerView* view, + mojo::EventPtr event) { + // If the view is an embed root, forward to the embedded view, not the owner. + ViewManagerServiceImpl* connection = GetConnectionWithRoot(view->id()); + if (!connection) + connection = GetConnection(view->id().connection_id); + CHECK(connection); + connection->client()->OnViewInputEvent(ViewIdToTransportId(view->id()), + event.Pass(), + base::Bind(&base::DoNothing)); +} + void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { @@ -482,8 +525,13 @@ void ConnectionManager::OnViewSharedPropertyChanged( } } -void ConnectionManager::DispatchInputEventToView(mojo::Id transport_view_id, - mojo::EventPtr event) { +void ConnectionManager::SetViewportSize(mojo::SizePtr size) { + display_manager_->SetViewportSize(size.To<gfx::Size>()); +} + +void ConnectionManager::DispatchInputEventToViewDEPRECATED( + mojo::Id transport_view_id, + mojo::EventPtr event) { const ViewId view_id(ViewIdFromTransportId(transport_view_id)); ViewManagerServiceImpl* connection = GetConnectionWithRoot(view_id); @@ -495,13 +543,74 @@ void ConnectionManager::DispatchInputEventToView(mojo::Id transport_view_id, } } -void ConnectionManager::SetViewportSize(mojo::SizePtr size) { - gfx::Size new_size = size.To<gfx::Size>(); - display_manager_->SetViewportSize(new_size); -} - void ConnectionManager::CloneAndAnimate(mojo::Id transport_view_id) { CloneAndAnimate(ViewIdFromTransportId(transport_view_id)); } +void ConnectionManager::AddAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + event_dispatcher_.AddAccelerator(keyboard_code, flags); +} + +void ConnectionManager::RemoveAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + event_dispatcher_.RemoveAccelerator(keyboard_code, flags); +} + +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. + ViewManagerServiceImpl* owning_connection_old = nullptr; + ViewManagerServiceImpl* 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); + } + } + ViewManagerServiceImpl* owning_connection_new = nullptr; + ViewManagerServiceImpl* 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); + } + } + + // Window manager should always be notified of focus change. + ViewManagerServiceImpl* wm_connection = + window_manager_client_connection_->service(); + if (wm_connection != owning_connection_old && + wm_connection != embedded_connection_old && + wm_connection != owning_connection_new && + wm_connection != embedded_connection_new) { + wm_connection->ProcessFocusChanged(old_focused_view, new_focused_view); + } +} + } // namespace view_manager diff --git a/components/view_manager/connection_manager.h b/components/view_manager/connection_manager.h index c7e79be..ae5cf06 100644 --- a/components/view_manager/connection_manager.h +++ b/components/view_manager/connection_manager.h @@ -11,19 +11,24 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/timer/timer.h" +#include "components/native_viewport/public/interfaces/native_viewport.mojom.h" #include "components/view_manager/animation_runner.h" +#include "components/view_manager/event_dispatcher.h" +#include "components/view_manager/focus_controller_delegate.h" #include "components/view_manager/ids.h" #include "components/view_manager/public/interfaces/view_manager.mojom.h" #include "components/view_manager/server_view_delegate.h" #include "components/view_manager/server_view_observer.h" #include "components/window_manager/public/interfaces/window_manager_internal.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" namespace view_manager { class ClientConnection; class ConnectionManagerDelegate; class DisplayManager; +class FocusController; class ServerView; class ViewManagerServiceImpl; @@ -31,7 +36,8 @@ class ViewManagerServiceImpl; // ViewManagerServiceImpls) as well as providing the root of the hierarchy. class ConnectionManager : public ServerViewDelegate, public ServerViewObserver, - public mojo::WindowManagerInternalClient { + public mojo::WindowManagerInternalClient, + public FocusControllerDelegate { public: // Create when a ViewManagerServiceImpl is about to make a change. Ensures // clients are notified correctly. @@ -99,6 +105,9 @@ class ConnectionManager : public ServerViewDelegate, // Returns the View identified by |id|. ServerView* GetView(const ViewId& id); + void SetFocusedView(ServerView* view); + ServerView* GetFocusedView(); + ServerView* root() { return root_.get(); } DisplayManager* display_manager() { return display_manager_.get(); } @@ -135,6 +144,12 @@ class ConnectionManager : public ServerViewDelegate, // WindowManagerInternalClient implementation helper; see mojom for details. bool CloneAndAnimate(const ViewId& view_id); + // Processes an event, potentially changing focus. + void ProcessEvent(mojo::EventPtr event); + + // Dispatches |event| directly to the appropriate connection for |view|. + void DispatchInputEventToView(const ServerView* view, mojo::EventPtr event); + // These functions trivially delegate to all ViewManagerServiceImpls, which in // term notify their clients. void ProcessViewDestroyed(ServerView* view); @@ -209,10 +224,18 @@ class ConnectionManager : public ServerViewDelegate, const std::vector<uint8_t>* new_data) override; // WindowManagerInternalClient: - void DispatchInputEventToView(mojo::Id transport_view_id, - mojo::EventPtr event) override; + void DispatchInputEventToViewDEPRECATED(mojo::Id transport_view_id, + mojo::EventPtr event) override; void SetViewportSize(mojo::SizePtr size) override; void CloneAndAnimate(mojo::Id transport_view_id) override; + void AddAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) override; + void RemoveAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) override; + + // FocusControllerDelegate: + void OnFocusChanged(ServerView* old_focused_view, + ServerView* new_focused_view) override; ConnectionManagerDelegate* delegate_; @@ -244,6 +267,12 @@ class ConnectionManager : public ServerViewDelegate, AnimationRunner animation_runner_; + EventDispatcher event_dispatcher_; + + mojo::Binding<mojo::NativeViewportEventDispatcher> event_dispatcher_binding_; + + scoped_ptr<FocusController> focus_controller_; + DISALLOW_COPY_AND_ASSIGN(ConnectionManager); }; diff --git a/components/view_manager/default_access_policy.cc b/components/view_manager/default_access_policy.cc index ed0a6b6..4127e14 100644 --- a/components/view_manager/default_access_policy.cc +++ b/components/view_manager/default_access_policy.cc @@ -85,6 +85,11 @@ bool DefaultAccessPolicy::CanSetViewProperties(const ServerView* view) const { return WasCreatedByThisConnection(view); } +bool DefaultAccessPolicy::CanSetFocus(const ServerView* view) const { + return WasCreatedByThisConnection(view) || + delegate_->IsRootForAccessPolicy(view->id()); +} + bool DefaultAccessPolicy::ShouldNotifyOnHierarchyChange( const ServerView* view, const ServerView** new_parent, @@ -104,6 +109,14 @@ bool DefaultAccessPolicy::ShouldNotifyOnHierarchyChange( return true; } +const ServerView* DefaultAccessPolicy::GetViewForFocusChange( + const ServerView* focused) { + if (WasCreatedByThisConnection(focused) || + delegate_->IsRootForAccessPolicy(focused->id())) + return focused; + return nullptr; +} + bool DefaultAccessPolicy::WasCreatedByThisConnection( const ServerView* view) const { return view->id().connection_id == connection_id_; diff --git a/components/view_manager/default_access_policy.h b/components/view_manager/default_access_policy.h index 5c23118..b9e782b 100644 --- a/components/view_manager/default_access_policy.h +++ b/components/view_manager/default_access_policy.h @@ -34,10 +34,12 @@ class DefaultAccessPolicy : public AccessPolicy { bool CanSetViewSurfaceId(const ServerView* view) const override; bool CanSetViewBounds(const ServerView* view) const override; bool CanSetViewProperties(const ServerView* view) const override; + bool CanSetFocus(const ServerView* view) const override; bool ShouldNotifyOnHierarchyChange( const ServerView* view, const ServerView** new_parent, const ServerView** old_parent) const override; + const ServerView* GetViewForFocusChange(const ServerView* focused) override; private: bool WasCreatedByThisConnection(const ServerView* view) const; diff --git a/components/view_manager/display_manager.cc b/components/view_manager/display_manager.cc index e596618..716bb82 100644 --- a/components/view_manager/display_manager.cc +++ b/components/view_manager/display_manager.cc @@ -74,10 +74,8 @@ void DrawViewTree(mojo::Pass* pass, DefaultDisplayManager::DefaultDisplayManager( mojo::ApplicationImpl* app_impl, - mojo::ApplicationConnection* app_connection, const mojo::Callback<void()>& native_viewport_closed_callback) : app_impl_(app_impl), - app_connection_(app_connection), connection_manager_(nullptr), draw_timer_(false, false), frame_pending_(false), @@ -88,7 +86,9 @@ DefaultDisplayManager::DefaultDisplayManager( metrics_.size->height = 600; } -void DefaultDisplayManager::Init(ConnectionManager* connection_manager) { +void DefaultDisplayManager::Init( + ConnectionManager* connection_manager, + mojo::NativeViewportEventDispatcherPtr event_dispatcher) { connection_manager_ = connection_manager; app_impl_->ConnectToService("mojo:native_viewport_service", &native_viewport_); @@ -106,8 +106,6 @@ void DefaultDisplayManager::Init(ConnectionManager* connection_manager) { nullptr, // returner - we never submit resources. GetProxy(&display_)); - mojo::NativeViewportEventDispatcherPtr event_dispatcher; - app_connection_->ConnectToService(&event_dispatcher); native_viewport_->SetEventDispatcher(event_dispatcher.Pass()); } diff --git a/components/view_manager/display_manager.h b/components/view_manager/display_manager.h index 8ab8977..f82591d 100644 --- a/components/view_manager/display_manager.h +++ b/components/view_manager/display_manager.h @@ -22,7 +22,6 @@ class SurfaceIdAllocator; } namespace mojo { -class ApplicationConnection; class ApplicationImpl; } @@ -36,7 +35,9 @@ class DisplayManager { public: virtual ~DisplayManager() {} - virtual void Init(ConnectionManager* connection_manager) = 0; + virtual void Init( + ConnectionManager* connection_manager, + mojo::NativeViewportEventDispatcherPtr event_dispatcher) = 0; // Schedules a paint for the specified region in the coordinates of |view|. virtual void SchedulePaint(const ServerView* view, @@ -54,12 +55,12 @@ class DefaultDisplayManager : public DisplayManager, public: DefaultDisplayManager( mojo::ApplicationImpl* app_impl, - mojo::ApplicationConnection* app_connection, const mojo::Callback<void()>& native_viewport_closed_callback); ~DefaultDisplayManager() override; // DisplayManager: - void Init(ConnectionManager* connection_manager) override; + void Init(ConnectionManager* connection_manager, + mojo::NativeViewportEventDispatcherPtr event_dispatcher) override; void SchedulePaint(const ServerView* view, const gfx::Rect& bounds) override; void SetViewportSize(const gfx::Size& size) override; const mojo::ViewportMetrics& GetViewportMetrics() override; @@ -75,7 +76,6 @@ class DefaultDisplayManager : public DisplayManager, void OnConnectionError() override; mojo::ApplicationImpl* app_impl_; - mojo::ApplicationConnection* app_connection_; ConnectionManager* connection_manager_; mojo::ViewportMetrics metrics_; diff --git a/components/view_manager/event_dispatcher.cc b/components/view_manager/event_dispatcher.cc new file mode 100644 index 0000000..6cc8b85 --- /dev/null +++ b/components/view_manager/event_dispatcher.cc @@ -0,0 +1,64 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/view_manager/event_dispatcher.h" + +#include "components/view_manager/connection_manager.h" +#include "components/view_manager/server_view.h" +#include "components/view_manager/view_coordinate_conversions.h" +#include "components/view_manager/view_locator.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_f.h" + +namespace view_manager { + +EventDispatcher::EventDispatcher(ConnectionManager* connection_manager) + : connection_manager_(connection_manager) { +} + +EventDispatcher::~EventDispatcher() { +} + +void EventDispatcher::AddAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + accelerators_.insert(Accelerator(keyboard_code, flags)); +} + +void EventDispatcher::RemoveAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + accelerators_.erase(Accelerator(keyboard_code, flags)); +} + +void EventDispatcher::OnEvent(mojo::EventPtr event, + const OnEventCallback& callback) { + callback.Run(); + + 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(); + ; + if (event->action == mojo::EVENT_TYPE_POINTER_DOWN || !target) { + target = FindDeepestVisibleView(connection_manager_->root(), root_point); + CHECK(target); + connection_manager_->SetFocusedView(target); + } + const gfx::PointF local_point(ConvertPointFBetweenViews( + connection_manager_->root(), target, + gfx::PointF(event->pointer_data->x, event->pointer_data->y))); + event->pointer_data->x = local_point.x(); + event->pointer_data->y = local_point.y(); + connection_manager_->DispatchInputEventToView(target, event.Pass()); + } else if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && + accelerators_.count(Accelerator(event->key_data->windows_key_code, + event->flags))) { + connection_manager_->wm_internal()->OnAccelerator(event.Pass()); + } else { + ServerView* focused_view = connection_manager_->GetFocusedView(); + if (focused_view) + connection_manager_->DispatchInputEventToView(focused_view, event.Pass()); + } +} + +} // namespace view_manager diff --git a/components/view_manager/event_dispatcher.h b/components/view_manager/event_dispatcher.h new file mode 100644 index 0000000..006edc0 --- /dev/null +++ b/components/view_manager/event_dispatcher.h @@ -0,0 +1,56 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIEW_MANAGER_EVENT_DISPATCHER_H_ +#define COMPONENTS_VIEW_MANAGER_EVENT_DISPATCHER_H_ + +#include <set> + +#include "base/basictypes.h" +#include "components/native_viewport/public/interfaces/native_viewport.mojom.h" +#include "components/window_manager/public/interfaces/window_manager_internal.mojom.h" + +namespace view_manager { + +class ConnectionManager; + +// Handles dispatching events to the right location as well as updating focus. +class EventDispatcher : public mojo::NativeViewportEventDispatcher { + public: + explicit EventDispatcher(ConnectionManager* connection_manager); + ~EventDispatcher() override; + + void AddAccelerator(mojo::KeyboardCode keyboard_code, mojo::EventFlags flags); + void RemoveAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags); + + // NativeViewportEventDispatcher: + void OnEvent(mojo::EventPtr event, const OnEventCallback& callback) override; + + private: + struct Accelerator { + Accelerator(mojo::KeyboardCode keyboard_code, mojo::EventFlags flags) + : keyboard_code(keyboard_code), flags(flags) {} + + // So we can use this in a set. + bool operator<(const Accelerator& other) const { + if (keyboard_code == other.keyboard_code) + return flags < other.flags; + return keyboard_code < other.keyboard_code; + } + + mojo::KeyboardCode keyboard_code; + mojo::EventFlags flags; + }; + + ConnectionManager* connection_manager_; + + std::set<Accelerator> accelerators_; + + DISALLOW_COPY_AND_ASSIGN(EventDispatcher); +}; + +} // namespace view_manager + +#endif // COMPONENTS_VIEW_MANAGER_EVENT_DISPATCHER_H_ diff --git a/components/view_manager/public/cpp/BUILD.gn b/components/view_manager/public/cpp/BUILD.gn index 52b7cdd..e1bd479 100644 --- a/components/view_manager/public/cpp/BUILD.gn +++ b/components/view_manager/public/cpp/BUILD.gn @@ -20,7 +20,6 @@ mojo_sdk_source_set("cpp") { "view_manager.h", "view_manager_client_factory.h", "view_manager_context.h", - "view_manager_delegate.cc", "view_manager_delegate.h", "view_observer.h", "view_property.h", @@ -55,5 +54,6 @@ source_set("common") { "keys.cc", "keys.h", "types.h", + "util.h", ] } diff --git a/components/view_manager/public/cpp/lib/view_manager_client_impl.cc b/components/view_manager/public/cpp/lib/view_manager_client_impl.cc index 63a4366..e22b4d7 100644 --- a/components/view_manager/public/cpp/lib/view_manager_client_impl.cc +++ b/components/view_manager/public/cpp/lib/view_manager_client_impl.cc @@ -102,7 +102,6 @@ ViewManagerClientImpl::ViewManagerClientImpl( capture_view_(nullptr), focused_view_(nullptr), activated_view_(nullptr), - wm_observer_binding_(this), binding_(this, request.Pass()), delete_on_error_(delete_on_error) { } @@ -173,7 +172,7 @@ void ViewManagerClientImpl::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(service_); - service_->PerformAction(view_id, "focus", ActionCompletedCallback()); + service_->SetFocus(view_id, ActionCompletedCallback()); } void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) { @@ -217,11 +216,7 @@ void ViewManagerClientImpl::AddView(View* view) { void ViewManagerClientImpl::RemoveView(Id view_id) { if (focused_view_ && focused_view_->id() == view_id) - OnFocusChanged(0); - if (capture_view_ && capture_view_->id() == view_id) - OnCaptureChanged(0); - if (activated_view_ && activated_view_->id() == view_id) - OnActiveWindowChanged(0); + OnViewFocused(0); IdToViewMap::iterator it = views_.find(view_id); if (it != views_.end()) @@ -272,14 +267,13 @@ View* ViewManagerClientImpl::CreateView() { //////////////////////////////////////////////////////////////////////////////// // ViewManagerClientImpl, ViewManagerClient implementation: -void ViewManagerClientImpl::OnEmbed( - ConnectionSpecificId connection_id, - const String& creator_url, - ViewDataPtr root_data, - ViewManagerServicePtr view_manager_service, - InterfaceRequest<ServiceProvider> services, - ServiceProviderPtr exposed_services, - ScopedMessagePipeHandle window_manager_pipe) { +void ViewManagerClientImpl::OnEmbed(ConnectionSpecificId connection_id, + const String& creator_url, + ViewDataPtr root_data, + ViewManagerServicePtr view_manager_service, + InterfaceRequest<ServiceProvider> services, + ServiceProviderPtr exposed_services, + Id focused_view_id) { if (view_manager_service) { DCHECK(!service_); service_ = view_manager_service.Pass(); @@ -291,22 +285,7 @@ void ViewManagerClientImpl::OnEmbed( root_ = AddViewToViewManager(this, nullptr, root_data); root_->AddObserver(new RootObserver(root_)); - window_manager_.Bind(window_manager_pipe.Pass()); - WindowManagerObserverPtr observer; - wm_observer_binding_.Bind(GetProxy(&observer)); - // binding to |this| is safe here as |window_manager_| is bound to our - // lifetime. - window_manager_->GetFocusedAndActiveViews( - observer.Pass(), - [this](uint32_t capture_view_id, uint32_t focused_view_id, - uint32_t active_view_id) { - if (GetViewById(capture_view_id) != capture_view_) - OnCaptureChanged(capture_view_id); - if (GetViewById(focused_view_id) != focused_view_) - OnFocusChanged(focused_view_id); - if (GetViewById(active_view_id) != activated_view_) - OnActiveWindowChanged(active_view_id); - }); + focused_view_ = GetViewById(focused_view_id); delegate_->OnEmbed(root_, services.Pass(), exposed_services.Pass()); } @@ -425,65 +404,20 @@ void ViewManagerClientImpl::OnViewInputEvent( ack_callback.Run(); } -void ViewManagerClientImpl::OnPerformAction( - Id view_id, - const String& name, - const Callback<void(bool)>& callback) { - View* view = GetViewById(view_id); - callback.Run(delegate_->OnPerformAction(view, name)); -} - -//////////////////////////////////////////////////////////////////////////////// -// ViewManagerClientImpl, WindowManagerObserver implementation: - -void ViewManagerClientImpl::OnCaptureChanged(Id capture_view_id) { - View* gained_capture = GetViewById(capture_view_id); - View* lost_capture = capture_view_; - if (lost_capture) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(lost_capture).observers(), - OnViewFocusChanged(gained_capture, lost_capture)); - } - capture_view_ = gained_capture; - if (gained_capture) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(gained_capture).observers(), - OnViewFocusChanged(gained_capture, lost_capture)); - } -} - -void ViewManagerClientImpl::OnFocusChanged(Id focused_view_id) { +void ViewManagerClientImpl::OnViewFocused(Id focused_view_id) { View* focused = GetViewById(focused_view_id); View* blurred = focused_view_; if (blurred) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(blurred).observers(), + FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(blurred).observers(), OnViewFocusChanged(focused, blurred)); } focused_view_ = focused; if (focused) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(focused).observers(), + FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(focused).observers(), OnViewFocusChanged(focused, blurred)); } } -void ViewManagerClientImpl::OnActiveWindowChanged(Id active_view_id) { - View* activated = GetViewById(active_view_id); - View* deactivated = activated_view_; - if (deactivated) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(deactivated).observers(), - OnViewActivationChanged(activated, deactivated)); - } - activated_view_ = activated; - if (activated) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(activated).observers(), - OnViewActivationChanged(activated, deactivated)); - } -} - //////////////////////////////////////////////////////////////////////////////// // OnConnectionError, private: void ViewManagerClientImpl::OnConnectionError() { diff --git a/components/view_manager/public/cpp/lib/view_manager_client_impl.h b/components/view_manager/public/cpp/lib/view_manager_client_impl.h index e53785a..04bc121 100644 --- a/components/view_manager/public/cpp/lib/view_manager_client_impl.h +++ b/components/view_manager/public/cpp/lib/view_manager_client_impl.h @@ -9,7 +9,6 @@ #include "components/view_manager/public/cpp/view.h" #include "components/view_manager/public/cpp/view_manager.h" #include "components/view_manager/public/interfaces/view_manager.mojom.h" -#include "components/window_manager/public/interfaces/window_manager.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" namespace mojo { @@ -21,7 +20,6 @@ class ViewManagerTransaction; // Manages the connection with the View Manager service. class ViewManagerClientImpl : public ViewManager, public ViewManagerClient, - public WindowManagerObserver, public ErrorHandler { public: ViewManagerClientImpl(ViewManagerDelegate* delegate, @@ -96,7 +94,7 @@ class ViewManagerClientImpl : public ViewManager, ViewManagerServicePtr view_manager_service, InterfaceRequest<ServiceProvider> services, ServiceProviderPtr exposed_services, - ScopedMessagePipeHandle window_manager_pipe) override; + Id focused_view_id) override; void OnEmbeddedAppDisconnected(Id view_id) override; void OnViewBoundsChanged(Id view_id, RectPtr old_bounds, @@ -119,14 +117,7 @@ class ViewManagerClientImpl : public ViewManager, void OnViewInputEvent(Id view_id, EventPtr event, const Callback<void()>& callback) override; - void OnPerformAction(Id view_id, - const String& name, - const Callback<void(bool)>& callback) override; - - // Overridden from WindowManagerObserver: - void OnCaptureChanged(Id capture_view_id) override; - void OnFocusChanged(Id focused_view_id) override; - void OnActiveWindowChanged(Id focused_view_id) override; + void OnViewFocused(Id focused_view_id) override; // ErrorHandler implementation. void OnConnectionError() override; @@ -154,9 +145,6 @@ class ViewManagerClientImpl : public ViewManager, View* focused_view_; View* activated_view_; - WindowManagerPtr window_manager_; - Binding<WindowManagerObserver> wm_observer_binding_; - Binding<ViewManagerClient> binding_; ViewManagerServicePtr service_; const bool delete_on_error_; diff --git a/components/view_manager/public/cpp/view_manager_delegate.cc b/components/view_manager/public/cpp/view_manager_delegate.cc deleted file mode 100644 index 4ea921e..0000000 --- a/components/view_manager/public/cpp/view_manager_delegate.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/view_manager/public/cpp/view_manager_delegate.h" - -namespace mojo { - -bool ViewManagerDelegate::OnPerformAction(View* view, - const std::string& action) { - return false; -} - -} // namespace mojo diff --git a/components/view_manager/public/cpp/view_manager_delegate.h b/components/view_manager/public/cpp/view_manager_delegate.h index fa6f49d..738502f 100644 --- a/components/view_manager/public/cpp/view_manager_delegate.h +++ b/components/view_manager/public/cpp/view_manager_delegate.h @@ -39,10 +39,6 @@ class ViewManagerDelegate { // |view_manager| is not valid after this function returns. virtual void OnViewManagerDisconnected(ViewManager* view_manager) = 0; - // Asks the delegate to perform the specified action. - // TODO(sky): nuke! See comments in view_manager.mojom for details. - virtual bool OnPerformAction(View* view, const std::string& action); - protected: virtual ~ViewManagerDelegate() {} }; diff --git a/components/view_manager/public/cpp/view_observer.h b/components/view_manager/public/cpp/view_observer.h index a89b449..997a9aa 100644 --- a/components/view_manager/public/cpp/view_observer.h +++ b/components/view_manager/public/cpp/view_observer.h @@ -59,10 +59,7 @@ class ViewObserver { const ViewportMetrics& new_bounds) { } - virtual void OnViewCaptureChanged(View* gained_capture, View* lost_capture) {} virtual void OnViewFocusChanged(View* gained_focus, View* lost_focus) {} - virtual void OnViewActivationChanged(View* gained_active, View* lost_active) { - } virtual void OnViewInputEvent(View* view, const EventPtr& event) {} diff --git a/components/view_manager/public/interfaces/view_manager.mojom b/components/view_manager/public/interfaces/view_manager.mojom index 7cf83240..cb02ea6 100644 --- a/components/view_manager/public/interfaces/view_manager.mojom +++ b/components/view_manager/public/interfaces/view_manager.mojom @@ -143,13 +143,7 @@ interface ViewManagerService { ServiceProvider? exposed_services) => (bool success); Embed(uint32 view_id, ViewManagerClient client) => (bool success); - // Requests the WindowManager to perform an action on the specified view. - // It's up to the WindowManager to decide what |action| is. - // - // TODO(sky): nuke this. This is here to guarantee the state of the - // WindowManager matches that of the ViewManager at the time the client - // invokes the function. When we can enforce ordering this won't be necessary. - PerformAction(uint32 view_id, string action) => (bool success); + SetFocus(uint32 view_id) => (bool success); }; // Changes to views are not sent to the connection that originated the @@ -160,14 +154,13 @@ interface ViewManagerClient { // See Embed() on ViewManagerService for more details. |view_manager_service| // will be a handle back to the view manager service, unless the connection is // to the WindowManager in which case it will be null. - // |window_manager_pipe| is a pipe to the WindowManager. OnEmbed(uint16 connection_id, string embedder_url, ViewData root, ViewManagerService? view_manager_service, ServiceProvider&? services, ServiceProvider? exposed_services, - handle<message_pipe> window_manager_pipe); + uint32 focused_view); // Invoked when the application embedded at |view| is disconnected. OnEmbeddedAppDisconnected(uint32 view); @@ -223,8 +216,5 @@ interface ViewManagerClient { // Invoked when an event is targeted at the specified view. OnViewInputEvent(uint32 view, mojo.Event event) => (); - // Invoked solely on the WindowManager. See comments in PerformAction() above - // for details. - // TODO(sky): nuke this. - OnPerformAction(uint32 view_id, string action) => (bool success); + OnViewFocused(uint32 focused_view_id); }; diff --git a/components/view_manager/test_change_tracker.cc b/components/view_manager/test_change_tracker.cc index 7022708..f061b9d 100644 --- a/components/view_manager/test_change_tracker.cc +++ b/components/view_manager/test_change_tracker.cc @@ -94,6 +94,10 @@ std::string ChangeToDescription1(const Change& change) { case CHANGE_TYPE_DELEGATE_EMBED: return base::StringPrintf("DelegateEmbed url=%s", change.embed_url.data()); + + case CHANGE_TYPE_FOCUSED: + return base::StringPrintf("Focused id=%s", + ViewIdToString(change.view_id).c_str()); } return std::string(); } @@ -280,6 +284,13 @@ void TestChangeTracker::OnViewSharedPropertyChanged(Id view_id, AddChange(change); } +void TestChangeTracker::OnViewFocused(mojo::Id view_id) { + Change change; + change.type = CHANGE_TYPE_FOCUSED; + change.view_id = view_id; + AddChange(change); +} + void TestChangeTracker::DelegateEmbed(const String& url) { Change change; change.type = CHANGE_TYPE_DELEGATE_EMBED; diff --git a/components/view_manager/test_change_tracker.h b/components/view_manager/test_change_tracker.h index 9a2a5f3..2312828 100644 --- a/components/view_manager/test_change_tracker.h +++ b/components/view_manager/test_change_tracker.h @@ -19,7 +19,7 @@ namespace view_manager { enum ChangeType { CHANGE_TYPE_EMBED, CHANGE_TYPE_EMBEDDED_APP_DISCONNECTED, - // TODO(sky): NODE->VIEW. + // TODO(sky): nuke NODE. CHANGE_TYPE_NODE_BOUNDS_CHANGED, CHANGE_TYPE_NODE_VIEWPORT_METRICS_CHANGED, CHANGE_TYPE_NODE_HIERARCHY_CHANGED, @@ -30,6 +30,7 @@ enum ChangeType { CHANGE_TYPE_INPUT_EVENT, CHANGE_TYPE_PROPERTY_CHANGED, CHANGE_TYPE_DELEGATE_EMBED, + CHANGE_TYPE_FOCUSED, }; // TODO(sky): consider nuking and converting directly to ViewData. @@ -141,6 +142,7 @@ class TestChangeTracker { void OnViewSharedPropertyChanged(mojo::Id view_id, mojo::String name, mojo::Array<uint8_t> data); + void OnViewFocused(mojo::Id view_id); void DelegateEmbed(const mojo::String& url); private: diff --git a/components/view_manager/view_manager_app.cc b/components/view_manager/view_manager_app.cc index a37119c..a068d2a 100644 --- a/components/view_manager/view_manager_app.cc +++ b/components/view_manager/view_manager_app.cc @@ -51,9 +51,8 @@ bool ViewManagerApp::ConfigureIncomingConnection( wm_internal_.set_error_handler(this); scoped_ptr<DefaultDisplayManager> display_manager(new DefaultDisplayManager( - app_impl_, connection, - base::Bind(&ViewManagerApp::OnLostConnectionToWindowManager, - base::Unretained(this)))); + app_impl_, base::Bind(&ViewManagerApp::OnLostConnectionToWindowManager, + base::Unretained(this)))); connection_manager_.reset( new ConnectionManager(this, display_manager.Pass(), wm_internal_.get())); return true; diff --git a/components/view_manager/view_manager_service_apptest.cc b/components/view_manager/view_manager_service_apptest.cc index 43e08e0..bb533c7 100644 --- a/components/view_manager/view_manager_service_apptest.cc +++ b/components/view_manager/view_manager_service_apptest.cc @@ -290,7 +290,8 @@ class ViewManagerClientImpl : public mojo::ViewManagerClient, mojo::ViewManagerServicePtr view_manager_service, InterfaceRequest<ServiceProvider> services, ServiceProviderPtr exposed_services, - mojo::ScopedMessagePipeHandle window_manager_pipe) override { + mojo::Id focused_view_id) override { + // TODO(sky): add coverage of |focused_view_id|. service_ = view_manager_service.Pass(); tracker()->OnEmbed(connection_id, creator_url, root.Pass()); if (embed_run_loop_) @@ -340,9 +341,8 @@ class ViewManagerClientImpl : public mojo::ViewManagerClient, Array<uint8_t> new_data) override { tracker_.OnViewSharedPropertyChanged(view, name, new_data.Pass()); } - void OnPerformAction(uint32_t view, - const String& name, - const Callback<void(bool)>& callback) override {} + // TODO(sky): add testing coverage. + void OnViewFocused(uint32_t focused_view_id) override {} TestChangeTracker tracker_; @@ -502,9 +502,6 @@ class ViewManagerServiceAppTest } // mojo::WindowManagerInternal implementation. - void CreateWindowManagerForViewManagerClient( - uint16_t connection_id, - mojo::ScopedMessagePipeHandle window_manager_pipe) override {} void SetViewManagerClient( mojo::ScopedMessagePipeHandle view_manager_client_request) override { auto typed_request = mojo::MakeRequest<mojo::ViewManagerClient>( @@ -512,6 +509,7 @@ class ViewManagerServiceAppTest vm_client1_.Bind(typed_request.Pass()); view_manager_setup_run_loop_->Quit(); } + void OnAccelerator(mojo::EventPtr event) override {} mojo::Binding<mojo::WindowManagerInternal> wm_internal_binding_; mojo::WindowManagerInternalClientPtr wm_internal_client_; @@ -1099,22 +1097,6 @@ TEST_F(ViewManagerServiceAppTest, CantGetViewTreeOfOtherRoots) { EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); } -TEST_F(ViewManagerServiceAppTest, OnViewInputEvent) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - changes2()->clear(); - - // Dispatch an event to the view and verify it's received. - { - EventPtr event(mojo::Event::New()); - event->action = static_cast<mojo::EventType>(1); - wm_internal_client_->DispatchInputEventToView(BuildViewId(1, 1), - event.Pass()); - vm_client2_->WaitForChangeCount(1); - EXPECT_EQ("InputEvent view=1,1 event_action=1", - SingleChangeToDescription(*changes2())); - } -} - TEST_F(ViewManagerServiceAppTest, EmbedWithSameViewId) { ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); changes2()->clear(); diff --git a/components/view_manager/view_manager_service_impl.cc b/components/view_manager/view_manager_service_impl.cc index 95c66eb..823a2e9 100644 --- a/components/view_manager/view_manager_service_impl.cc +++ b/components/view_manager/view_manager_service_impl.cc @@ -63,12 +63,15 @@ void ViewManagerServiceImpl::Init(mojo::ViewManagerClient* client, if (root_.get()) GetUnknownViewsFrom(GetView(*root_), &to_send); - mojo::MessagePipe pipe; - connection_manager_->wm_internal()->CreateWindowManagerForViewManagerClient( - id_, pipe.handle1.Pass()); + const ServerView* focused_view = connection_manager_->GetFocusedView(); + if (focused_view) + focused_view = access_policy_->GetViewForFocusChange(focused_view); + const mojo::Id focused_view_transport_id( + ViewIdToTransportId(focused_view ? focused_view->id() : ViewId())); + client->OnEmbed(id_, creator_url_, ViewToViewData(to_send.front()), service_ptr.Pass(), services.Pass(), exposed_services.Pass(), - pipe.handle0.Pass()); + focused_view_transport_id); } const ServerView* ViewManagerServiceImpl::GetView(const ViewId& id) const { @@ -302,6 +305,16 @@ void ViewManagerServiceImpl::ProcessWillChangeViewVisibility( NotifyDrawnStateChanged(view, view_target_drawn_state); } +void ViewManagerServiceImpl::ProcessFocusChanged( + const ServerView* old_focused_view, + const ServerView* new_focused_view) { + const ServerView* view = + new_focused_view ? access_policy_->GetViewForFocusChange(new_focused_view) + : nullptr; + client()->OnViewFocused(view ? ViewIdToTransportId(view->id()) + : ViewIdToTransportId(ViewId())); +} + bool ViewManagerServiceImpl::IsViewKnown(const ServerView* view) const { return known_views_.count(ViewIdToTransportId(view->id())) > 0; } @@ -627,12 +640,16 @@ void ViewManagerServiceImpl::Embed(mojo::Id transport_view_id, callback.Run(Embed(ViewIdFromTransportId(transport_view_id), client.Pass())); } -void ViewManagerServiceImpl::PerformAction( - mojo::Id transport_view_id, - const mojo::String& action, - const mojo::Callback<void(bool)>& callback) { - connection_manager_->GetWindowManagerViewManagerClient()->OnPerformAction( - transport_view_id, action, callback); +void ViewManagerServiceImpl::SetFocus(uint32_t view_id, + const SetFocusCallback& callback) { + ServerView* view = GetView(ViewIdFromTransportId(view_id)); + bool success = view && view->IsDrawn(connection_manager_->root()) && + access_policy_->CanSetFocus(view); + if (success) { + ConnectionManager::ScopedChange change(this, connection_manager_, false); + connection_manager_->SetFocusedView(view); + } + callback.Run(success); } bool ViewManagerServiceImpl::IsRootForAccessPolicy(const ViewId& id) const { diff --git a/components/view_manager/view_manager_service_impl.h b/components/view_manager/view_manager_service_impl.h index 501d5af..63e7e3a 100644 --- a/components/view_manager/view_manager_service_impl.h +++ b/components/view_manager/view_manager_service_impl.h @@ -115,8 +115,8 @@ class ViewManagerServiceImpl : public mojo::ViewManagerService, void ProcessViewDeleted(const ViewId& view, bool originated_change); void ProcessWillChangeViewVisibility(const ServerView* view, bool originated_change); - void ProcessViewPropertiesChanged(const ServerView* view, - bool originated_change); + void ProcessFocusChanged(const ServerView* old_focused_view, + const ServerView* new_focused_view); private: typedef std::map<mojo::ConnectionSpecificId, ServerView*> ViewMap; @@ -210,9 +210,7 @@ class ViewManagerServiceImpl : public mojo::ViewManagerService, void Embed(mojo::Id transport_view_id, mojo::ViewManagerClientPtr client, const mojo::Callback<void(bool)>& callback) override; - void PerformAction(mojo::Id transport_view_id, - const mojo::String& action, - const mojo::Callback<void(bool)>& callback) override; + void SetFocus(uint32_t view_id, const SetFocusCallback& callback) override; // AccessPolicyDelegate: bool IsRootForAccessPolicy(const ViewId& id) const override; diff --git a/components/view_manager/view_manager_service_unittest.cc b/components/view_manager/view_manager_service_unittest.cc index 895a81d..43274be 100644 --- a/components/view_manager/view_manager_service_unittest.cc +++ b/components/view_manager/view_manager_service_unittest.cc @@ -54,7 +54,8 @@ class TestViewManagerClient : public mojo::ViewManagerClient { mojo::ViewManagerServicePtr view_manager_service, InterfaceRequest<ServiceProvider> services, ServiceProviderPtr exposed_services, - mojo::ScopedMessagePipeHandle window_manager_pipe) override { + mojo::Id focused_view_id) override { + // TODO(sky): add test coverage of |focused_view_id|. tracker_.OnEmbed(connection_id, embedder_url, root.Pass()); } void OnEmbeddedAppDisconnected(uint32_t view) override { @@ -99,9 +100,9 @@ class TestViewManagerClient : public mojo::ViewManagerClient { const mojo::Callback<void()>& callback) override { tracker_.OnViewInputEvent(view, event.Pass()); } - void OnPerformAction(uint32_t view_id, - const String& name, - const mojo::Callback<void(bool)>& callback) override {} + void OnViewFocused(uint32_t focused_view_id) override { + tracker_.OnViewFocused(focused_view_id); + } TestChangeTracker tracker_; @@ -180,7 +181,8 @@ class TestDisplayManager : public DisplayManager { ~TestDisplayManager() override {} // DisplayManager: - void Init(ConnectionManager* connection_manager) override {} + void Init(ConnectionManager* connection_manager, + mojo::NativeViewportEventDispatcherPtr event_dispatcher) override {} void SchedulePaint(const ServerView* view, const gfx::Rect& bounds) override { } void SetViewportSize(const gfx::Size& size) override {} @@ -203,15 +205,33 @@ class TestWindowManagerInternal : public mojo::WindowManagerInternal { ~TestWindowManagerInternal() override {} // WindowManagerInternal: - void CreateWindowManagerForViewManagerClient( - uint16_t connection_id, - mojo::ScopedMessagePipeHandle window_manager_pipe) override {} void SetViewManagerClient(mojo::ScopedMessagePipeHandle) override {} + void OnAccelerator(mojo::EventPtr event) override {} private: DISALLOW_COPY_AND_ASSIGN(TestWindowManagerInternal); }; +mojo::EventPtr CreatePointerDownEvent(int x, int y) { + mojo::EventPtr event(mojo::Event::New()); + event->action = mojo::EVENT_TYPE_POINTER_DOWN; + event->pointer_data = mojo::PointerData::New(); + event->pointer_data->pointer_id = 1u; + event->pointer_data->x = x; + event->pointer_data->y = y; + return event.Pass(); +} + +mojo::EventPtr CreatePointerUpEvent(int x, int y) { + mojo::EventPtr event(mojo::Event::New()); + event->action = mojo::EVENT_TYPE_POINTER_UP; + event->pointer_data = mojo::PointerData::New(); + event->pointer_data->pointer_id = 1u; + event->pointer_data->x = x; + event->pointer_data->y = y; + return event.Pass(); +} + } // namespace // ----------------------------------------------------------------------------- @@ -468,4 +488,79 @@ TEST_F(ViewManagerServiceTest, CloneAndAnimateLargerDepth) { EXPECT_TRUE(cloned_view_child->id() == ClonedViewId()); } +// Verifies focus correctly changes on pointer events. +TEST_F(ViewManagerServiceTest, FocusOnPointer) { + const ViewId embed_view_id(wm_connection()->id(), 1); + EXPECT_EQ(ERROR_CODE_NONE, wm_connection()->CreateView(embed_view_id)); + EXPECT_TRUE(wm_connection()->SetViewVisibility(embed_view_id, true)); + EXPECT_TRUE( + wm_connection()->AddView(*(wm_connection()->root()), embed_view_id)); + connection_manager()->root()->SetBounds(gfx::Rect(0, 0, 100, 100)); + wm_connection()->EmbedUrl(std::string(), embed_view_id, nullptr, nullptr); + ViewManagerServiceImpl* connection1 = + connection_manager()->GetConnectionWithRoot(embed_view_id); + ASSERT_TRUE(connection1 != nullptr); + ASSERT_NE(connection1, wm_connection()); + + connection_manager() + ->GetView(embed_view_id) + ->SetBounds(gfx::Rect(0, 0, 50, 50)); + + const ViewId child1(connection1->id(), 1); + EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child1)); + EXPECT_TRUE(connection1->AddView(embed_view_id, child1)); + ServerView* v1 = connection1->GetView(child1); + v1->SetVisible(true); + v1->SetBounds(gfx::Rect(20, 20, 20, 20)); + + TestViewManagerClient* connection1_client = last_view_manager_client(); + connection1_client->tracker()->changes()->clear(); + wm_client()->tracker()->changes()->clear(); + + connection_manager()->ProcessEvent(CreatePointerDownEvent(21, 22)); + // Focus should go to child1. This results in notifying both the window + // manager and client connection being notified. + EXPECT_EQ(v1, connection_manager()->GetFocusedView()); + ASSERT_GE(wm_client()->tracker()->changes()->size(), 1u); + EXPECT_EQ("Focused id=2,1", + ChangesToDescription1(*wm_client()->tracker()->changes())[0]); + ASSERT_GE(connection1_client->tracker()->changes()->size(), 1u); + EXPECT_EQ( + "Focused id=2,1", + ChangesToDescription1(*connection1_client->tracker()->changes())[0]); + + connection_manager()->ProcessEvent(CreatePointerUpEvent(21, 22)); + wm_client()->tracker()->changes()->clear(); + connection1_client->tracker()->changes()->clear(); + + // Press outside of the embedded view. Focus should go to the root. Notice + // the client1 doesn't see who has focus as the focused view (root) isn't + // visible to it. + connection_manager()->ProcessEvent(CreatePointerDownEvent(61, 22)); + EXPECT_EQ(connection_manager()->root(), + connection_manager()->GetFocusedView()); + ASSERT_GE(wm_client()->tracker()->changes()->size(), 1u); + EXPECT_EQ("Focused id=0,1", + ChangesToDescription1(*wm_client()->tracker()->changes())[0]); + ASSERT_GE(connection1_client->tracker()->changes()->size(), 1u); + EXPECT_EQ( + "Focused id=null", + ChangesToDescription1(*connection1_client->tracker()->changes())[0]); + + connection_manager()->ProcessEvent(CreatePointerUpEvent(21, 22)); + wm_client()->tracker()->changes()->clear(); + connection1_client->tracker()->changes()->clear(); + + // Press in the same location. Should not get a focus change event (only input + // event). + connection_manager()->ProcessEvent(CreatePointerDownEvent(61, 22)); + EXPECT_EQ(connection_manager()->root(), + connection_manager()->GetFocusedView()); + ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u); + EXPECT_EQ("InputEvent view=0,1 event_action=4", + ChangesToDescription1(*wm_client()->tracker()->changes())[0]); + EXPECT_TRUE(connection1_client->tracker()->changes()->empty()); + ; +} + } // namespace view_manager diff --git a/components/view_manager/window_manager_access_policy.cc b/components/view_manager/window_manager_access_policy.cc index 600a4f6..280a73c 100644 --- a/components/view_manager/window_manager_access_policy.cc +++ b/components/view_manager/window_manager_access_policy.cc @@ -77,6 +77,10 @@ bool WindowManagerAccessPolicy::CanSetViewProperties( return view->id().connection_id == connection_id_; } +bool WindowManagerAccessPolicy::CanSetFocus(const ServerView* view) const { + return true; +} + bool WindowManagerAccessPolicy::ShouldNotifyOnHierarchyChange( const ServerView* view, const ServerView** new_parent, @@ -90,6 +94,11 @@ bool WindowManagerAccessPolicy::ShouldNotifyOnHierarchyChange( return IsViewKnown(view) || (*new_parent && IsViewKnown(*new_parent)); } +const ServerView* WindowManagerAccessPolicy::GetViewForFocusChange( + const ServerView* focused) { + return focused; +} + bool WindowManagerAccessPolicy::IsViewKnown(const ServerView* view) const { return delegate_->IsViewKnownForAccessPolicy(view); } diff --git a/components/view_manager/window_manager_access_policy.h b/components/view_manager/window_manager_access_policy.h index 94cda10..9e09409 100644 --- a/components/view_manager/window_manager_access_policy.h +++ b/components/view_manager/window_manager_access_policy.h @@ -33,10 +33,12 @@ class WindowManagerAccessPolicy : public AccessPolicy { bool CanSetViewSurfaceId(const ServerView* view) const override; bool CanSetViewBounds(const ServerView* view) const override; bool CanSetViewProperties(const ServerView* view) const override; + bool CanSetFocus(const ServerView* view) const override; bool ShouldNotifyOnHierarchyChange( const ServerView* view, const ServerView** new_parent, const ServerView** old_parent) const override; + const ServerView* GetViewForFocusChange(const ServerView* focused) override; private: bool IsViewKnown(const ServerView* view) const; diff --git a/components/window_manager/BUILD.gn b/components/window_manager/BUILD.gn index 504b4b7..d30da10 100644 --- a/components/window_manager/BUILD.gn +++ b/components/window_manager/BUILD.gn @@ -8,28 +8,8 @@ import("//testing/test.gni") source_set("lib") { sources = [ - "basic_focus_rules.cc", - "basic_focus_rules.h", - "capture_controller.cc", - "capture_controller.h", - "capture_controller_observer.h", - "focus_controller.cc", - "focus_controller.h", - "focus_controller_observer.h", - "focus_rules.h", - "native_viewport_event_dispatcher_impl.cc", - "native_viewport_event_dispatcher_impl.h", - "view_event_dispatcher.cc", - "view_event_dispatcher.h", - "view_target.cc", - "view_target.h", - "view_targeter.cc", - "view_targeter.h", "window_manager_app.cc", "window_manager_app.h", - "window_manager_app_android.cc", - "window_manager_app_linux.cc", - "window_manager_app_win.cc", "window_manager_delegate.h", "window_manager_impl.cc", "window_manager_impl.h", @@ -37,57 +17,18 @@ source_set("lib") { deps = [ "//base", - "//components/native_viewport/public/interfaces", "//components/view_manager/public/cpp", "//components/window_manager/public/interfaces", "//mojo/application", "//mojo/common", "//mojo/converters/geometry", - "//mojo/converters/input_events", "//third_party/mojo/src/mojo/public/cpp/bindings:bindings", "//third_party/mojo/src/mojo/public/interfaces/application", - "//ui/base", - "//ui/events", - "//ui/gfx", "//ui/gfx/geometry", + "//ui/mojo/events:interfaces", ] } -test("window_manager_unittests") { - sources = [ - "focus_controller_unittest.cc", - "run_all_unittests.cc", - "view_target_unittest.cc", - "view_targeter_unittest.cc", - "window_manager_test_util.cc", - "window_manager_test_util.h", - ] - - public_deps = [ - ":lib", - ] - - deps = [ - "//base/test:test_support", - "//components/view_manager/public/cpp", - "//components/view_manager/public/interfaces", - "//components/window_manager/public/interfaces", - "//mojo/converters/geometry", - "//mojo/environment:chromium", - "//third_party/mojo/src/mojo/edk/system", - "//third_party/mojo/src/mojo/public/cpp/application", - "//testing/gtest", - "//ui/events:test_support", - "//ui/gfx", - "//ui/gfx:test_support", - "//ui/gl", - ] - - if (use_x11) { - deps += [ "//ui/gfx/x" ] - } -} - # A basic window manager with a default delegate used for testing. mojo_native_application("test_window_manager") { sources = [ diff --git a/components/window_manager/basic_focus_rules.cc b/components/window_manager/basic_focus_rules.cc deleted file mode 100644 index 9056a9e..0000000 --- a/components/window_manager/basic_focus_rules.cc +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/basic_focus_rules.h" - -#include "base/macros.h" -#include "components/view_manager/public/cpp/view.h" - -using mojo::View; - -namespace window_manager { - -BasicFocusRules::BasicFocusRules(View* window_container) - : window_container_(window_container) { -} - -BasicFocusRules::~BasicFocusRules() {} - -bool BasicFocusRules::SupportsChildActivation(View* view) const { - return true; -} - -bool BasicFocusRules::IsToplevelView(View* view) const { - if (!IsViewParentedToWindowContainer(view)) - return false; - - // The window must exist within a container that supports activation. - // The window cannot be blocked by a modal transient. - return SupportsChildActivation(view->parent()); -} - -bool BasicFocusRules::CanActivateView(View* view) const { - if (!view) - return true; - - // Only toplevel windows can be activated - if (!IsToplevelView(view)) - return false; - - // The view must be visible. - if (!view->visible()) - return false; - - // TODO(erg): The aura version of this class asks the aura::Window's - // ActivationDelegate whether the window is activatable. - - // A window must be focusable to be activatable. We don't call - // CanFocusWindow() from here because it will call back to us via - // GetActivatableWindow(). - if (!CanFocusViewImpl(view)) - return false; - - // TODO(erg): In the aura version, we also check whether the window is - // blocked by a modal transient window. - - return true; -} - -bool BasicFocusRules::CanFocusView(View* view) const { - // It is possible to focus a NULL window, it is equivalent to clearing focus. - if (!view) - return true; - - // The focused view is always inside the active view, so views that aren't - // activatable can't contain the focused view. - View* activatable = GetActivatableView(view); - if (!activatable || !activatable->Contains(view)) - return false; - return CanFocusViewImpl(view); -} - -View* BasicFocusRules::GetToplevelView(View* view) const { - View* parent = view->parent(); - View* child = view; - while (parent) { - if (IsToplevelView(child)) - return child; - - parent = parent->parent(); - child = child->parent(); - } - - return nullptr; -} - -View* BasicFocusRules::GetActivatableView(View* view) const { - View* parent = view->parent(); - View* child = view; - while (parent) { - if (CanActivateView(child)) - return child; - - // TODO(erg): In the aura version of this class, we have a whole bunch of - // checks to support modal transient windows, and transient parents. - - parent = parent->parent(); - child = child->parent(); - } - - return nullptr; -} - -View* BasicFocusRules::GetFocusableView(View* view) const { - if (CanFocusView(view)) - return view; - - // |view| may be in a hierarchy that is non-activatable, in which case we - // need to cut over to the activatable hierarchy. - View* activatable = GetActivatableView(view); - if (!activatable) { - // There may not be a related activatable hierarchy to cut over to, in which - // case we try an unrelated one. - View* toplevel = GetToplevelView(view); - if (toplevel) - activatable = GetNextActivatableView(toplevel); - if (!activatable) - return nullptr; - } - - if (!activatable->Contains(view)) { - // If there's already a child window focused in the activatable hierarchy, - // just use that (i.e. don't shift focus), otherwise we need to at least cut - // over to the activatable hierarchy. - View* focused = GetFocusableView(activatable); - return activatable->Contains(focused) ? focused : activatable; - } - - while (view && !CanFocusView(view)) - view = view->parent(); - return view; -} - -View* BasicFocusRules::GetNextActivatableView(View* activatable) const { - DCHECK(activatable); - - // In the basic scenarios handled by BasicFocusRules, the pool of activatable - // windows is limited to the |ignore|'s siblings. - const View::Children& siblings = activatable->parent()->children(); - DCHECK(!siblings.empty()); - - for (auto rit = siblings.rbegin(); rit != siblings.rend(); ++rit) { - View* cur = *rit; - if (cur == activatable) - continue; - if (CanActivateView(cur)) - return cur; - } - return nullptr; -} - -// TODO(erg): aura::Window::CanFocus() exists. View::CanFocus() does -// not. This is a hack that does everything that Window::CanFocus() currently -// does that doesn't require a delegate or an EventClient. -bool BasicFocusRules::CanFocusViewImpl(View* view) const { - // TODO(erg): In unit tests, views will never be drawn, so we can't rely on - // IsDrawn() here. - if (IsViewParentedToWindowContainer(view)) - return view->visible(); - - // TODO(erg): Add the intermediary delegate and event client checks once we - // have those. - - return CanFocusViewImpl(view->parent()); -} - -bool BasicFocusRules::IsViewParentedToWindowContainer(View* view) const { - return view->parent() == window_container_; -} - -} // namespace mojo diff --git a/components/window_manager/basic_focus_rules.h b/components/window_manager/basic_focus_rules.h deleted file mode 100644 index 6f31b4c..0000000 --- a/components/window_manager/basic_focus_rules.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_BASIC_FOCUS_RULES_H_ -#define COMPONENTS_WINDOW_MANAGER_BASIC_FOCUS_RULES_H_ - -#include "components/window_manager/focus_rules.h" - -namespace mojo { -class View; -} - -namespace window_manager { - -// The focusing rules used inside a window manager. -// -// This is intended to be a user supplyable, subclassable component passed to -// WindowManagerApp, allowing for the creation of other window managers. -class BasicFocusRules : public FocusRules { - public: - BasicFocusRules(mojo::View* window_container); - ~BasicFocusRules() override; - - protected: - // Overridden from mojo::FocusRules: - bool SupportsChildActivation(mojo::View* view) const override; - bool IsToplevelView(mojo::View* view) const override; - bool CanActivateView(mojo::View* view) const override; - bool CanFocusView(mojo::View* view) const override; - mojo::View* GetToplevelView(mojo::View* view) const override; - mojo::View* GetActivatableView(mojo::View* view) const override; - mojo::View* GetFocusableView(mojo::View* view) const override; - mojo::View* GetNextActivatableView(mojo::View* activatable) const override; - - private: - bool CanFocusViewImpl(mojo::View* view) const; - - // Tests to see if |view| is in |window_container_|. - bool IsViewParentedToWindowContainer(mojo::View* view) const; - - mojo::View* window_container_; - - DISALLOW_COPY_AND_ASSIGN(BasicFocusRules); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_BASIC_FOCUS_RULES_H_ diff --git a/components/window_manager/capture_controller.cc b/components/window_manager/capture_controller.cc deleted file mode 100644 index c678d48..0000000 --- a/components/window_manager/capture_controller.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/capture_controller.h" - -#include "components/view_manager/public/cpp/view_property.h" -#include "components/view_manager/public/cpp/view_tracker.h" -#include "components/window_manager/capture_controller_observer.h" - -DECLARE_VIEW_PROPERTY_TYPE(window_manager::CaptureController*); - -namespace window_manager { - -namespace { -DEFINE_VIEW_PROPERTY_KEY(CaptureController*, - kRootViewCaptureController, - nullptr); -} // namespace - -CaptureController::CaptureController() - : capture_view_(nullptr) {} - -CaptureController::~CaptureController() {} - -void CaptureController::AddObserver(CaptureControllerObserver* observer) { - capture_controller_observers_.AddObserver(observer); -} - -void CaptureController::RemoveObserver(CaptureControllerObserver* observer) { - capture_controller_observers_.RemoveObserver(observer); -} - -void CaptureController::SetCapture(mojo::View* view) { - if (capture_view_ == view) - return; - - if (capture_view_) - capture_view_->RemoveObserver(this); - - mojo::View* old_capture_view = capture_view_; - capture_view_ = view; - - if (capture_view_) - capture_view_->AddObserver(this); - - NotifyCaptureChange(capture_view_, old_capture_view); -} - -void CaptureController::ReleaseCapture(mojo::View* view) { - if (capture_view_ != view) - return; - SetCapture(nullptr); -} - -mojo::View* CaptureController::GetCapture() { - return capture_view_; -} - -void CaptureController::NotifyCaptureChange(mojo::View* new_capture, - mojo::View* old_capture) { - mojo::ViewTracker view_tracker; - if (new_capture) - view_tracker.Add(new_capture); - if (old_capture) - view_tracker.Add(old_capture); - - FOR_EACH_OBSERVER( - CaptureControllerObserver, capture_controller_observers_, - OnCaptureChanged(view_tracker.Contains(new_capture) ? new_capture - : nullptr)); -} - -void CaptureController::OnViewDestroying(mojo::View* view) { - if (view == capture_view_) { - view->RemoveObserver(this); - NotifyCaptureChange(nullptr, view); - capture_view_ = nullptr; - } -} - -void SetCaptureController(mojo::View* root_view, - CaptureController* capture_controller) { - DCHECK_EQ(root_view->GetRoot(), root_view); - root_view->SetLocalProperty(kRootViewCaptureController, capture_controller); -} - -CaptureController* GetCaptureController(mojo::View* root_view) { - if (root_view) - DCHECK_EQ(root_view->GetRoot(), root_view); - return root_view ? - root_view->GetLocalProperty(kRootViewCaptureController) : nullptr; -} - -mojo::View* GetCaptureView(mojo::View* view) { - mojo::View* root = view->GetRoot(); - if (!root) - return nullptr; - CaptureController* controller = GetCaptureController(root); - return controller ? controller->GetCapture() : nullptr; -} - -} // namespace window_manager diff --git a/components/window_manager/capture_controller.h b/components/window_manager/capture_controller.h deleted file mode 100644 index 3621e3d..0000000 --- a/components/window_manager/capture_controller.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_ -#define COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_ - -#include "base/observer_list.h" -#include "components/view_manager/public/cpp/view_observer.h" - -namespace window_manager { - -class CaptureControllerObserver; - -// Manages input capture. A view which has capture will take all input events. -class CaptureController : public mojo::ViewObserver { - public: - CaptureController(); - ~CaptureController() override; - - void AddObserver(CaptureControllerObserver* observer); - void RemoveObserver(CaptureControllerObserver* observer); - - void SetCapture(mojo::View* view); - void ReleaseCapture(mojo::View* view); - mojo::View* GetCapture(); - - private: - void NotifyCaptureChange(mojo::View* new_capture, mojo::View* old_capture); - - // Overridden from ViewObserver: - void OnViewDestroying(mojo::View* view) override; - - // The current capture view. Null if there is no capture view. - mojo::View* capture_view_; - - ObserverList<CaptureControllerObserver> capture_controller_observers_; - - DISALLOW_COPY_AND_ASSIGN(CaptureController); -}; - -void SetCaptureController(mojo::View* view, - CaptureController* capture_controller); -CaptureController* GetCaptureController(mojo::View* view); -mojo::View* GetCaptureView(mojo::View* view); - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_ diff --git a/components/window_manager/capture_controller_observer.h b/components/window_manager/capture_controller_observer.h deleted file mode 100644 index 6072622..0000000 --- a/components/window_manager/capture_controller_observer.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_ -#define COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_ - -namespace mojo { -class View; -} - -namespace window_manager { - -class CaptureControllerObserver { - public: - virtual void OnCaptureChanged(mojo::View* gained_capture) = 0; - - protected: - virtual ~CaptureControllerObserver() {} -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_ diff --git a/components/window_manager/focus_controller.cc b/components/window_manager/focus_controller.cc deleted file mode 100644 index 865d28c..0000000 --- a/components/window_manager/focus_controller.cc +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/focus_controller.h" - -#include "base/auto_reset.h" -#include "components/view_manager/public/cpp/view_property.h" -#include "components/view_manager/public/cpp/view_tracker.h" -#include "components/window_manager/focus_controller_observer.h" -#include "components/window_manager/focus_rules.h" -#include "components/window_manager/view_target.h" -#include "components/window_manager/window_manager_app.h" -#include "ui/events/event.h" - -DECLARE_VIEW_PROPERTY_TYPE(window_manager::FocusController*); - -using mojo::View; - -namespace window_manager { - -namespace { -DEFINE_VIEW_PROPERTY_KEY(FocusController*, kRootViewFocusController, nullptr); -} // namespace - -FocusController::FocusController(scoped_ptr<FocusRules> rules) - : active_view_(nullptr), - focused_view_(nullptr), - updating_focus_(false), - updating_activation_(false), - rules_(rules.Pass()), - observer_manager_(this) { - DCHECK(rules_); -} - -FocusController::~FocusController() {} - -void FocusController::AddObserver(FocusControllerObserver* observer) { - focus_controller_observers_.AddObserver(observer); -} - -void FocusController::RemoveObserver(FocusControllerObserver* observer) { - focus_controller_observers_.RemoveObserver(observer); -} - -void FocusController::ActivateView(View* view) { - FocusView(view); -} - -void FocusController::DeactivateView(View* view) { - if (view) - FocusView(rules_->GetNextActivatableView(view)); -} - -View* FocusController::GetActiveView() { - return active_view_; -} - -View* FocusController::GetActivatableView(View* view) { - return rules_->GetActivatableView(view); -} - -View* FocusController::GetToplevelView(View* view) { - return rules_->GetToplevelView(view); -} - -bool FocusController::CanActivateView(View* view) const { - return rules_->CanActivateView(view); -} - -void FocusController::FocusView(View* view) { - if (view && - (view->Contains(focused_view_) || view->Contains(active_view_))) { - return; - } - - // Focusing a window also activates its containing activatable window. Note - // that the rules could redirect activation activation and/or focus. - View* focusable = rules_->GetFocusableView(view); - View* activatable = - focusable ? rules_->GetActivatableView(focusable) : nullptr; - - // We need valid focusable/activatable windows in the event we're not clearing - // focus. "Clearing focus" is inferred by whether or not |window| passed to - // this function is non-null. - if (view && (!focusable || !activatable)) - return; - DCHECK((focusable && activatable) || !view); - - // Activation change observers may change the focused window. If this happens - // we must not adjust the focus below since this will clobber that change. - View* last_focused_view = focused_view_; - if (!updating_activation_) - SetActiveView(view, activatable); - - // If the window's ActivationChangeObserver shifted focus to a valid window, - // we don't want to focus the window we thought would be focused by default. - bool activation_changed_focus = last_focused_view != focused_view_; - if (!updating_focus_ && (!activation_changed_focus || !focused_view_)) { - if (active_view_ && focusable) - DCHECK(active_view_->Contains(focusable)); - SetFocusedView(focusable); - } -} - -void FocusController::ResetFocusWithinActiveView(View* view) { - DCHECK(view); - if (!active_view_) - return; - if (!active_view_->Contains(view)) - return; - SetFocusedView(view); -} - -View* FocusController::GetFocusedView() { - return focused_view_; -} - -//////////////////////////////////////////////////////////////////////////////// -// FocusController, ui::EventHandler implementation: - -void FocusController::OnKeyEvent(ui::KeyEvent* event) { -} - -void FocusController::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() == ui::ET_MOUSE_PRESSED && !event->handled()) { - View* view = static_cast<ViewTarget*>(event->target())->view(); - ViewFocusedFromInputEvent(view); - } -} - -void FocusController::OnScrollEvent(ui::ScrollEvent* event) { -} - -void FocusController::OnTouchEvent(ui::TouchEvent* event) { - if (event->type() == ui::ET_TOUCH_PRESSED && !event->handled()) { - View* view = static_cast<ViewTarget*>(event->target())->view(); - ViewFocusedFromInputEvent(view); - } -} - -void FocusController::OnGestureEvent(ui::GestureEvent* event) { - if (event->type() == ui::ET_GESTURE_BEGIN && - event->details().touch_points() == 1 && - !event->handled()) { - View* view = static_cast<ViewTarget*>(event->target())->view(); - ViewFocusedFromInputEvent(view); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// FocusController, mojo::ViewObserver implementation: - -void FocusController::OnViewVisibilityChanged(View* view) { - bool visible = view->visible(); - if (!visible) - ViewLostFocusFromDispositionChange(view, view->parent()); -} - -void FocusController::OnViewDestroying(View* view) { - ViewLostFocusFromDispositionChange(view, view->parent()); -} - -void FocusController::OnTreeChanging(const TreeChangeParams& params) { - // TODO(erg): In the aura version, you could get into a situation where you - // have different focus clients, so you had to check for that. Does that - // happen here? Could we get away with not checking if it does? - if (params.receiver == active_view_ && - params.target->Contains(params.receiver) && - (!params.new_parent || - /* different_focus_clients */ false)) { - ViewLostFocusFromDispositionChange(params.receiver, params.old_parent); - } -} - -void FocusController::OnTreeChanged(const TreeChangeParams& params) { - // TODO(erg): Same as Changing version. - if (params.receiver == focused_view_ && - params.target->Contains(params.receiver) && - (!params.new_parent || - /* different_focus_clients */ false)) { - ViewLostFocusFromDispositionChange(params.receiver, params.old_parent); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// FocusController, private: - -void FocusController::SetFocusedView(View* view) { - if (updating_focus_ || view == focused_view_) - return; - DCHECK(rules_->CanFocusView(view)); - if (view) - DCHECK_EQ(view, rules_->GetFocusableView(view)); - - base::AutoReset<bool> updating_focus(&updating_focus_, true); - View* lost_focus = focused_view_; - - // TODO(erg): In the aura version, we reset the text input client here. Do - // that if we bring in something like the TextInputClient. - - // Allow for the window losing focus to be deleted during dispatch. If it is - // deleted pass null to observers instead of a deleted window. - mojo::ViewTracker view_tracker; - if (lost_focus) - view_tracker.Add(lost_focus); - if (focused_view_ && observer_manager_.IsObserving(focused_view_) && - focused_view_ != active_view_) { - observer_manager_.Remove(focused_view_); - } - focused_view_ = view; - if (focused_view_ && !observer_manager_.IsObserving(focused_view_)) - observer_manager_.Add(focused_view_); - - FOR_EACH_OBSERVER(FocusControllerObserver, focus_controller_observers_, - OnFocused(focused_view_)); - - // TODO(erg): In aura, there's a concept of a single FocusChangeObserver that - // is attached to an aura::Window. We don't currently have this in - // mojo::View, but if we add it later, we should make something analogous - // here. - - // TODO(erg): In the aura version, we reset the TextInputClient here, too. -} - -void FocusController::SetActiveView(View* requested_view, View* view) { - if (updating_activation_) - return; - - if (view == active_view_) { - if (requested_view) { - FOR_EACH_OBSERVER(FocusControllerObserver, - focus_controller_observers_, - OnAttemptToReactivateView(requested_view, - active_view_)); - } - return; - } - - DCHECK(rules_->CanActivateView(view)); - if (view) - DCHECK_EQ(view, rules_->GetActivatableView(view)); - - base::AutoReset<bool> updating_activation(&updating_activation_, true); - View* lost_activation = active_view_; - // Allow for the window losing activation to be deleted during dispatch. If - // it is deleted pass null to observers instead of a deleted window. - mojo::ViewTracker view_tracker; - if (lost_activation) - view_tracker.Add(lost_activation); - if (active_view_ && observer_manager_.IsObserving(active_view_) && - focused_view_ != active_view_) { - observer_manager_.Remove(active_view_); - } - active_view_ = view; - if (active_view_ && !observer_manager_.IsObserving(active_view_)) - observer_manager_.Add(active_view_); - - if (active_view_) { - // TODO(erg): Reenable this when we have modal windows. - // StackTransientParentsBelowModalWindow(active_view_); - - active_view_->MoveToFront(); - } - - // TODO(erg): Individual windows can have a single ActivationChangeObserver - // set on them. In the aura version of this code, it sends an - // OnWindowActivated message to both the window that lost activation, and the - // window that gained it. - - FOR_EACH_OBSERVER(FocusControllerObserver, focus_controller_observers_, - OnActivated(active_view_)); -} - -void FocusController::ViewLostFocusFromDispositionChange( - View* view, - View* next) { - // TODO(erg): We clear the modality state here in the aura::Window version of - // this class, and should probably do the same once we have modal windows. - - // TODO(beng): See if this function can be replaced by a call to - // FocusWindow(). - // Activation adjustments are handled first in the event of a disposition - // changed. If an activation change is necessary, focus is reset as part of - // that process so there's no point in updating focus independently. - if (view == active_view_) { - View* next_activatable = rules_->GetNextActivatableView(view); - SetActiveView(nullptr, next_activatable); - if (!(active_view_ && active_view_->Contains(focused_view_))) - SetFocusedView(next_activatable); - } else if (view->Contains(focused_view_)) { - // Active window isn't changing, but focused window might be. - SetFocusedView(rules_->GetFocusableView(next)); - } -} - -void FocusController::ViewFocusedFromInputEvent(View* view) { - // Only focus |window| if it or any of its parents can be focused. Otherwise - // FocusWindow() will focus the topmost window, which may not be the - // currently focused one. - if (rules_->CanFocusView(GetToplevelView(view))) - FocusView(view); -} - -void SetFocusController(View* root_view, FocusController* focus_controller) { - DCHECK_EQ(root_view->GetRoot(), root_view); - root_view->SetLocalProperty(kRootViewFocusController, focus_controller); -} - -FocusController* GetFocusController(View* root_view) { - if (root_view) - DCHECK_EQ(root_view->GetRoot(), root_view); - return root_view ? - root_view->GetLocalProperty(kRootViewFocusController) : nullptr; -} - -} // namespace window_manager diff --git a/components/window_manager/focus_controller.h b/components/window_manager/focus_controller.h deleted file mode 100644 index fa56efb..0000000 --- a/components/window_manager/focus_controller.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_H_ -#define COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_H_ - -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "base/observer_list.h" -#include "base/scoped_observer.h" -#include "components/view_manager/public/cpp/view_observer.h" -#include "ui/events/event_handler.h" - -namespace window_manager { - -class FocusControllerObserver; -class FocusRules; - -// FocusController handles focus and activation changes in a mojo window -// manager. Within the window manager, there can only be one focused and one -// active window at a time. When focus or activation changes, notifications are -// sent using the FocusControllerObserver interface. -class FocusController : public ui::EventHandler, public mojo::ViewObserver { - public: - // |rules| cannot be null. - explicit FocusController(scoped_ptr<FocusRules> rules); - ~FocusController() override; - - void AddObserver(FocusControllerObserver* observer); - void RemoveObserver(FocusControllerObserver* observer); - - void ActivateView(mojo::View* view); - void DeactivateView(mojo::View* view); - mojo::View* GetActiveView(); - mojo::View* GetActivatableView(mojo::View* view); - mojo::View* GetToplevelView(mojo::View* view); - bool CanActivateView(mojo::View* view) const; - - void FocusView(mojo::View* view); - - void ResetFocusWithinActiveView(mojo::View* view); - mojo::View* GetFocusedView(); - - // Overridden from ui::EventHandler: - void OnKeyEvent(ui::KeyEvent* event) override; - void OnMouseEvent(ui::MouseEvent* event) override; - void OnScrollEvent(ui::ScrollEvent* event) override; - void OnTouchEvent(ui::TouchEvent* event) override; - void OnGestureEvent(ui::GestureEvent* event) override; - - // Overridden from ViewObserver: - void OnTreeChanging(const TreeChangeParams& params) override; - void OnTreeChanged(const TreeChangeParams& params) override; - void OnViewVisibilityChanged(mojo::View* view) override; - void OnViewDestroying(mojo::View* view) override; - - private: - // Internal implementation that sets the focused view, fires events etc. - // This function must be called with a valid focusable view. - void SetFocusedView(mojo::View* view); - - // Internal implementation that sets the active window, fires events etc. - // This function must be called with a valid |activatable_window|. - // |requested window| refers to the window that was passed in to an external - // request (e.g. FocusWindow or ActivateWindow). It may be null, e.g. if - // SetActiveWindow was not called by an external request. |activatable_window| - // refers to the actual window to be activated, which may be different. - void SetActiveView(mojo::View* requested_view, mojo::View* activatable_view); - - // Called when a window's disposition changed such that it and its hierarchy - // are no longer focusable/activatable. |next| is a valid window that is used - // as a starting point for finding a window to focus next based on rules. - void ViewLostFocusFromDispositionChange(mojo::View* view, mojo::View* next); - - // Called when an attempt is made to focus or activate a window via an input - // event targeted at that window. Rules determine the best focusable window - // for the input window. - void ViewFocusedFromInputEvent(mojo::View* view); - - mojo::View* active_view_; - mojo::View* focused_view_; - - bool updating_focus_; - bool updating_activation_; - - scoped_ptr<FocusRules> rules_; - - ObserverList<FocusControllerObserver> focus_controller_observers_; - - ScopedObserver<mojo::View, ViewObserver> observer_manager_; - - DISALLOW_COPY_AND_ASSIGN(FocusController); -}; - -// Sets/Gets the focus controller for a view. -void SetFocusController(mojo::View* view, FocusController* focus_controller); -FocusController* GetFocusController(mojo::View* view); - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_H_ diff --git a/components/window_manager/focus_controller_observer.h b/components/window_manager/focus_controller_observer.h deleted file mode 100644 index 7f37f8c..0000000 --- a/components/window_manager/focus_controller_observer.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_OBSERVER_H_ -#define COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_OBSERVER_H_ - -namespace mojo { -class View; -} - -namespace window_manager { - -class FocusControllerObserver { - public: - // Called when |active| gains focus, or there is no active view - // (|active| is null in this case.). - virtual void OnActivated(mojo::View* gained_active) = 0; - - // Called when focus moves to |gained_focus|. - virtual void OnFocused(mojo::View* gained_focus) = 0; - - // Called when during view activation the currently active view is - // selected for activation. This can happen when a view requested for - // activation cannot be activated because a system modal view is active. - virtual void OnAttemptToReactivateView(mojo::View* request_active, - mojo::View* actual_active) {} - - protected: - virtual ~FocusControllerObserver() {} -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_FOCUS_CONTROLLER_OBSERVER_H_ diff --git a/components/window_manager/focus_controller_unittest.cc b/components/window_manager/focus_controller_unittest.cc deleted file mode 100644 index 9c88814..0000000 --- a/components/window_manager/focus_controller_unittest.cc +++ /dev/null @@ -1,1197 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/focus_controller.h" - -#include "components/window_manager/basic_focus_rules.h" -#include "components/window_manager/capture_controller.h" -#include "components/window_manager/focus_controller_observer.h" -#include "components/window_manager/view_event_dispatcher.h" -#include "components/window_manager/view_targeter.h" -#include "components/window_manager/window_manager_test_util.h" -#include "mojo/converters/geometry/geometry_type_converters.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/event_utils.h" -#include "ui/gfx/geometry/rect.h" - -using mojo::View; - -namespace window_manager { - -// Counts the number of events that occur. -class FocusNotificationObserver : public FocusControllerObserver { - public: - FocusNotificationObserver() - : activation_changed_count_(0), - focus_changed_count_(0), - reactivation_count_(0), - reactivation_requested_view_(NULL), - reactivation_actual_view_(NULL) {} - ~FocusNotificationObserver() override {} - - void ExpectCounts(int activation_changed_count, int focus_changed_count) { - EXPECT_EQ(activation_changed_count, activation_changed_count_); - EXPECT_EQ(focus_changed_count, focus_changed_count_); - } - int reactivation_count() const { return reactivation_count_; } - View* reactivation_requested_view() const { - return reactivation_requested_view_; - } - View* reactivation_actual_view() const { - return reactivation_actual_view_; - } - - protected: - // Overridden from FocusControllerObserver: - void OnActivated(View* gained_active) override { - ++activation_changed_count_; - } - - void OnFocused(View* gained_focus) override { ++focus_changed_count_; } - - void OnAttemptToReactivateView(View* request_active, - View* actual_active) override { - ++reactivation_count_; - reactivation_requested_view_ = request_active; - reactivation_actual_view_ = actual_active; - } - - private: - int activation_changed_count_; - int focus_changed_count_; - int reactivation_count_; - View* reactivation_requested_view_; - View* reactivation_actual_view_; - - DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver); -}; - -class ViewDestroyer { - public: - virtual View* GetDestroyedView() = 0; - - protected: - virtual ~ViewDestroyer() {} -}; - -// FocusNotificationObserver that keeps track of whether it was notified about -// activation changes or focus changes with a destroyed view. -class RecordingFocusNotificationObserver : public FocusNotificationObserver { - public: - RecordingFocusNotificationObserver(FocusController* focus_controller, - ViewDestroyer* destroyer) - : focus_controller_(focus_controller), - destroyer_(destroyer), - active_(nullptr), - focus_(nullptr), - was_notified_with_destroyed_view_(false) { - focus_controller_->AddObserver(this); - } - ~RecordingFocusNotificationObserver() override { - focus_controller_->RemoveObserver(this); - } - - bool was_notified_with_destroyed_view() const { - return was_notified_with_destroyed_view_; - } - - // Overridden from FocusNotificationObserver: - void OnActivated(View* gained_active) override { - if (active_ && active_ == destroyer_->GetDestroyedView()) - was_notified_with_destroyed_view_ = true; - active_ = gained_active; - } - - void OnFocused(View* gained_focus) override { - if (focus_ && focus_ == destroyer_->GetDestroyedView()) - was_notified_with_destroyed_view_ = true; - focus_ = gained_focus; - } - - private: - FocusController* focus_controller_; - - // Not owned. - ViewDestroyer* destroyer_; - View* active_; - View* focus_; - - // Whether the observer was notified about the loss of activation or the - // loss of focus with a view already destroyed by |destroyer_| as the - // |lost_active| or |lost_focus| parameter. - bool was_notified_with_destroyed_view_; - - DISALLOW_COPY_AND_ASSIGN(RecordingFocusNotificationObserver); -}; - -class DestroyOnLoseActivationFocusNotificationObserver - : public FocusNotificationObserver, - public ViewDestroyer { - public: - DestroyOnLoseActivationFocusNotificationObserver( - FocusController* focus_controller, - View* view_to_destroy, - View* initial_active) - : focus_controller_(focus_controller), - view_to_destroy_(view_to_destroy), - active_(initial_active), - did_destroy_(false) { - focus_controller_->AddObserver(this); - } - ~DestroyOnLoseActivationFocusNotificationObserver() override { - focus_controller_->RemoveObserver(this); - } - - // Overridden from FocusNotificationObserver: - void OnActivated(View* gained_active) override { - if (view_to_destroy_ && active_ == view_to_destroy_) { - view_to_destroy_->Destroy(); - did_destroy_ = true; - } - active_ = gained_active; - } - - // Overridden from ViewDestroyer: - View* GetDestroyedView() override { - return did_destroy_ ? view_to_destroy_ : nullptr; - } - - private: - FocusController* focus_controller_; - View* view_to_destroy_; - View* active_; - bool did_destroy_; - - DISALLOW_COPY_AND_ASSIGN(DestroyOnLoseActivationFocusNotificationObserver); -}; - -class ScopedFocusNotificationObserver : public FocusNotificationObserver { - public: - ScopedFocusNotificationObserver(FocusController* focus_controller) - : focus_controller_(focus_controller) { - focus_controller_->AddObserver(this); - } - ~ScopedFocusNotificationObserver() override { - focus_controller_->RemoveObserver(this); - } - - private: - FocusController* focus_controller_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver); -}; - -// Only responds to events if a message contains |target| as a parameter. -class ScopedFilteringFocusNotificationObserver - : public FocusNotificationObserver { - public: - ScopedFilteringFocusNotificationObserver(FocusController* focus_controller, - View* target, - View* initial_active, - View* initial_focus) - : focus_controller_(focus_controller), - target_(target), - active_(initial_active), - focus_(initial_focus) { - focus_controller_->AddObserver(this); - } - ~ScopedFilteringFocusNotificationObserver() override { - focus_controller_->RemoveObserver(this); - } - - private: - // Overridden from FocusControllerObserver: - void OnActivated(View* gained_active) override { - if (gained_active == target_ || active_ == target_) - FocusNotificationObserver::OnActivated(gained_active); - active_ = gained_active; - } - - void OnFocused(View* gained_focus) override { - if (gained_focus == target_ || focus_ == target_) - FocusNotificationObserver::OnFocused(gained_focus); - focus_ = gained_focus; - } - - void OnAttemptToReactivateView(View* request_active, - View* actual_active) override { - if (request_active == target_ || actual_active == target_) { - FocusNotificationObserver::OnAttemptToReactivateView(request_active, - actual_active); - } - } - - FocusController* focus_controller_; - View* target_; - View* active_; - View* focus_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFilteringFocusNotificationObserver); -}; - -// Used to fake the handling of events in the pre-target phase. -class SimpleEventHandler : public ui::EventHandler { - public: - SimpleEventHandler() {} - ~SimpleEventHandler() override {} - - // Overridden from ui::EventHandler: - void OnMouseEvent(ui::MouseEvent* event) override { - event->SetHandled(); - } - void OnGestureEvent(ui::GestureEvent* event) override { - event->SetHandled(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(SimpleEventHandler); -}; - -class FocusShiftingActivationObserver - : public FocusControllerObserver { - public: - explicit FocusShiftingActivationObserver(FocusController* focus_controller, - View* activated_view) - : focus_controller_(focus_controller), - activated_view_(activated_view), - shift_focus_to_(NULL) {} - ~FocusShiftingActivationObserver() override {} - - void set_shift_focus_to(View* shift_focus_to) { - shift_focus_to_ = shift_focus_to; - } - - private: - // Overridden from FocusControllerObserver: - void OnActivated(View* gained_active) override { - // Shift focus to a child. This should prevent the default focusing from - // occurring in FocusController::FocusView(). - if (gained_active == activated_view_) - focus_controller_->FocusView(shift_focus_to_); - } - - void OnFocused(View* gained_focus) override {} - - FocusController* focus_controller_; - View* activated_view_; - View* shift_focus_to_; - - DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver); -}; - -// BasicFocusRules subclass that allows basic overrides of focus/activation to -// be tested. This is intended more as a test that the override system works at -// all, rather than as an exhaustive set of use cases, those should be covered -// in tests for those FocusRules implementations. -class TestFocusRules : public BasicFocusRules { - public: - TestFocusRules(View* root) - : BasicFocusRules(root), focus_restriction_(NULL) {} - - // Restricts focus and activation to this view and its child hierarchy. - void set_focus_restriction(View* focus_restriction) { - focus_restriction_ = focus_restriction; - } - - // Overridden from BasicFocusRules: - bool SupportsChildActivation(View* view) const override { - // In FocusControllerTests, only the Root has activatable children. - return view->GetRoot() == view; - } - bool CanActivateView(View* view) const override { - // Restricting focus to a non-activatable child view means the activatable - // parent outside the focus restriction is activatable. - bool can_activate = - CanFocusOrActivate(view) || view->Contains(focus_restriction_); - return can_activate ? BasicFocusRules::CanActivateView(view) : false; - } - bool CanFocusView(View* view) const override { - return CanFocusOrActivate(view) ? BasicFocusRules::CanFocusView(view) - : false; - } - View* GetActivatableView(View* view) const override { - return BasicFocusRules::GetActivatableView( - CanFocusOrActivate(view) ? view : focus_restriction_); - } - View* GetFocusableView(View* view) const override { - return BasicFocusRules::GetFocusableView( - CanFocusOrActivate(view) ? view : focus_restriction_); - } - View* GetNextActivatableView(View* ignore) const override { - View* next_activatable = BasicFocusRules::GetNextActivatableView(ignore); - return CanFocusOrActivate(next_activatable) - ? next_activatable - : GetActivatableView(focus_restriction_); - } - - private: - bool CanFocusOrActivate(View* view) const { - return !focus_restriction_ || focus_restriction_->Contains(view); - } - - View* focus_restriction_; - - DISALLOW_COPY_AND_ASSIGN(TestFocusRules); -}; - -// Common infrastructure shared by all FocusController test types. -class FocusControllerTestBase : public testing::Test { - protected: - // Hierarchy used by all tests: - // root_view - // +-- w1 - // | +-- w11 - // | +-- w12 - // +-- w2 - // | +-- w21 - // | +-- w211 - // +-- w3 - FocusControllerTestBase() - : root_view_(TestView::Build(0, gfx::Rect(0, 0, 800, 600))), - v1(TestView::Build(1, gfx::Rect(0, 0, 50, 50), root_view())), - v11(TestView::Build(11, gfx::Rect(5, 5, 10, 10), v1)), - v12(TestView::Build(12, gfx::Rect(15, 15, 10, 10), v1)), - v2(TestView::Build(2, gfx::Rect(75, 75, 50, 50), root_view())), - v21(TestView::Build(21, gfx::Rect(5, 5, 10, 10), v2)), - v211(TestView::Build(211, gfx::Rect(1, 1, 5, 5), v21)), - v3(TestView::Build(3, gfx::Rect(125, 125, 50, 50), root_view())) {} - - // Overridden from testing::Test: - void SetUp() override { - testing::Test::SetUp(); - - test_focus_rules_ = new TestFocusRules(root_view()); - focus_controller_.reset( - new FocusController(scoped_ptr<FocusRules>(test_focus_rules_))); - SetFocusController(root_view(), focus_controller_.get()); - - capture_controller_.reset(new CaptureController); - SetCaptureController(root_view(), capture_controller_.get()); - - ViewTarget* root_target = root_view_->target(); - root_target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); - view_event_dispatcher_.reset(new ViewEventDispatcher()); - view_event_dispatcher_->SetRootViewTarget(root_target); - - GetRootViewTarget()->AddPreTargetHandler(focus_controller_.get()); - } - - void TearDown() override { - GetRootViewTarget()->RemovePreTargetHandler(focus_controller_.get()); - view_event_dispatcher_.reset(); - - root_view_->Destroy(); - - capture_controller_.reset(); - test_focus_rules_ = nullptr; // Owned by FocusController. - focus_controller_.reset(); - - testing::Test::TearDown(); - } - - void FocusView(View* view) { focus_controller_->FocusView(view); } - View* GetFocusedView() { return focus_controller_->GetFocusedView(); } - int GetFocusedViewId() { - View* focused_view = GetFocusedView(); - return focused_view ? focused_view->id() : -1; - } - void ActivateView(View* view) { focus_controller_->ActivateView(view); } - void DeactivateView(View* view) { focus_controller_->DeactivateView(view); } - View* GetActiveView() { return focus_controller_->GetActiveView(); } - int GetActiveViewId() { - View* active_view = GetActiveView(); - return active_view ? active_view->id() : -1; - } - - View* GetViewById(int id) { return root_view_->GetChildById(id); } - - void ClickLeftButton(View* view) { - // Get the center bounds of |target| in |root_view_| coordinate space. - gfx::Point center = - gfx::Rect(view->bounds().To<gfx::Rect>().size()).CenterPoint(); - ViewTarget::ConvertPointToTarget(ViewTarget::TargetFromView(view), - root_view_->target(), ¢er); - - ui::MouseEvent button_down(ui::ET_MOUSE_PRESSED, center, center, - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_NONE); - ui::EventDispatchDetails details = - view_event_dispatcher_->OnEventFromSource(&button_down); - CHECK(!details.dispatcher_destroyed); - - ui::MouseEvent button_up(ui::ET_MOUSE_RELEASED, center, center, - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_NONE); - details = view_event_dispatcher_->OnEventFromSource(&button_up); - CHECK(!details.dispatcher_destroyed); - } - - ViewTarget* GetRootViewTarget() { - return ViewTarget::TargetFromView(root_view()); - } - - View* root_view() { return root_view_; } - TestFocusRules* test_focus_rules() { return test_focus_rules_; } - FocusController* focus_controller() { return focus_controller_.get(); } - CaptureController* capture_controller() { return capture_controller_.get(); } - - // Test functions. - virtual void BasicFocus() = 0; - virtual void BasicActivation() = 0; - virtual void FocusEvents() = 0; - virtual void DuplicateFocusEvents() {} - virtual void ActivationEvents() = 0; - virtual void ReactivationEvents() {} - virtual void DuplicateActivationEvents() {} - virtual void ShiftFocusWithinActiveView() {} - virtual void ShiftFocusToChildOfInactiveView() {} - virtual void ShiftFocusToParentOfFocusedView() {} - virtual void FocusRulesOverride() = 0; - virtual void ActivationRulesOverride() = 0; - virtual void ShiftFocusOnActivation() {} - virtual void ShiftFocusOnActivationDueToHide() {} - virtual void NoShiftActiveOnActivation() {} - virtual void ChangeFocusWhenNothingFocusedAndCaptured() {} - virtual void DontPassDestroyedView() {} - // TODO(erg): Also, void FocusedTextInputClient() once we build the IME. - - private: - TestView* root_view_; - scoped_ptr<FocusController> focus_controller_; - TestFocusRules* test_focus_rules_; - scoped_ptr<CaptureController> capture_controller_; - // TODO(erg): The aura version of this class also keeps track of WMState. Do - // we need something analogous here? - - scoped_ptr<ViewEventDispatcher> view_event_dispatcher_; - - TestView* v1; - TestView* v11; - TestView* v12; - TestView* v2; - TestView* v21; - TestView* v211; - TestView* v3; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase); -}; - -// Test base for tests where focus is directly set to a target view. -class FocusControllerDirectTestBase : public FocusControllerTestBase { - protected: - FocusControllerDirectTestBase() {} - - // Different test types shift focus in different ways. - virtual void FocusViewDirect(View* view) = 0; - virtual void ActivateViewDirect(View* view) = 0; - virtual void DeactivateViewDirect(View* view) = 0; - - // Input events do not change focus if the view can not be focused. - virtual bool IsInputEvent() = 0; - - void FocusViewById(int id) { - View* view = root_view()->GetChildById(id); - DCHECK(view); - FocusViewDirect(view); - } - void ActivateViewById(int id) { - View* view = root_view()->GetChildById(id); - DCHECK(view); - ActivateViewDirect(view); - } - - // Overridden from FocusControllerTestBase: - void BasicFocus() override { - EXPECT_EQ(nullptr, GetFocusedView()); - FocusViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - FocusViewById(2); - EXPECT_EQ(2, GetFocusedViewId()); - } - void BasicActivation() override { - EXPECT_EQ(nullptr, GetActiveView()); - ActivateViewById(1); - EXPECT_EQ(1, GetActiveViewId()); - ActivateViewById(2); - EXPECT_EQ(2, GetActiveViewId()); - // Verify that attempting to deactivate NULL does not crash and does not - // change activation. - DeactivateView(nullptr); - EXPECT_EQ(2, GetActiveViewId()); - DeactivateView(GetActiveView()); - EXPECT_EQ(1, GetActiveViewId()); - } - void FocusEvents() override { - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer1( - focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); - ScopedFilteringFocusNotificationObserver observer2( - focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); - - { - SCOPED_TRACE("initial state"); - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - } - - FocusViewById(1); - { - SCOPED_TRACE("FocusViewById(1)"); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(0, 0); - } - - FocusViewById(2); - { - SCOPED_TRACE("FocusViewById(2)"); - root_observer.ExpectCounts(2, 2); - observer1.ExpectCounts(2, 2); - observer2.ExpectCounts(1, 1); - } - } - void DuplicateFocusEvents() override { - // Focusing an existing focused view should not resend focus events. - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer1( - focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - - FocusViewById(1); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - - FocusViewById(1); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - } - void ActivationEvents() override { - ActivateViewById(1); - - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer1( - focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); - ScopedFilteringFocusNotificationObserver observer2( - focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - - ActivateViewById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - } - void ReactivationEvents() override { - ActivateViewById(1); - ScopedFocusNotificationObserver root_observer(focus_controller()); - EXPECT_EQ(0, root_observer.reactivation_count()); - GetViewById(2)->SetVisible(false); - // When we attempt to activate "2", which cannot be activated because it - // is not visible, "1" will be reactivated. - ActivateViewById(2); - EXPECT_EQ(1, root_observer.reactivation_count()); - EXPECT_EQ(GetViewById(2), - root_observer.reactivation_requested_view()); - EXPECT_EQ(GetViewById(1), - root_observer.reactivation_actual_view()); - } - void DuplicateActivationEvents() override { - ActivateViewById(1); - - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer1( - focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); - ScopedFilteringFocusNotificationObserver observer2( - focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - - ActivateViewById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - - // Activating an existing active view should not resend activation events. - ActivateViewById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - } - void ShiftFocusWithinActiveView() override { - ActivateViewById(1); - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(1, GetFocusedViewId()); - FocusViewById(11); - EXPECT_EQ(11, GetFocusedViewId()); - FocusViewById(12); - EXPECT_EQ(12, GetFocusedViewId()); - } - void ShiftFocusToChildOfInactiveView() override { - ActivateViewById(2); - EXPECT_EQ(2, GetActiveViewId()); - EXPECT_EQ(2, GetFocusedViewId()); - FocusViewById(11); - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(11, GetFocusedViewId()); - } - void ShiftFocusToParentOfFocusedView() override { - ActivateViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - FocusViewById(11); - EXPECT_EQ(11, GetFocusedViewId()); - FocusViewById(1); - // Focus should _not_ shift to the parent of the already-focused view. - EXPECT_EQ(11, GetFocusedViewId()); - } - void FocusRulesOverride() override { - EXPECT_EQ(NULL, GetFocusedView()); - FocusViewById(11); - EXPECT_EQ(11, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(GetViewById(211)); - FocusViewById(12); - // Input events leave focus unchanged; direct API calls will change focus - // to the restricted view. - int focused_view = IsInputEvent() ? 11 : 211; - EXPECT_EQ(focused_view, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(NULL); - FocusViewById(12); - EXPECT_EQ(12, GetFocusedViewId()); - } - void ActivationRulesOverride() override { - ActivateViewById(1); - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(1, GetFocusedViewId()); - - View* v3 = GetViewById(3); - test_focus_rules()->set_focus_restriction(v3); - - ActivateViewById(2); - // Input events leave activation unchanged; direct API calls will activate - // the restricted view. - int active_view = IsInputEvent() ? 1 : 3; - EXPECT_EQ(active_view, GetActiveViewId()); - EXPECT_EQ(active_view, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(NULL); - ActivateViewById(2); - EXPECT_EQ(2, GetActiveViewId()); - EXPECT_EQ(2, GetFocusedViewId()); - } - void ShiftFocusOnActivation() override { - // When a view is activated, by default that view is also focused. - // An ActivationChangeObserver may shift focus to another view within the - // same activatable view. - ActivateViewById(2); - EXPECT_EQ(2, GetFocusedViewId()); - ActivateViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - - ActivateViewById(2); - - View* target = GetViewById(1); - - scoped_ptr<FocusShiftingActivationObserver> observer( - new FocusShiftingActivationObserver(focus_controller(), target)); - observer->set_shift_focus_to(target->GetChildById(11)); - focus_controller()->AddObserver(observer.get()); - - ActivateViewById(1); - - // w1's ActivationChangeObserver shifted focus to this child, pre-empting - // FocusController's default setting. - EXPECT_EQ(11, GetFocusedViewId()); - - ActivateViewById(2); - EXPECT_EQ(2, GetFocusedViewId()); - - // Simulate a focus reset by the ActivationChangeObserver. This should - // trigger the default setting in FocusController. - observer->set_shift_focus_to(nullptr); - ActivateViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - - focus_controller()->RemoveObserver(observer.get()); - - ActivateViewById(2); - EXPECT_EQ(2, GetFocusedViewId()); - ActivateViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - } - void ShiftFocusOnActivationDueToHide() override { - // Similar to ShiftFocusOnActivation except the activation change is - // triggered by hiding the active view. - ActivateViewById(1); - EXPECT_EQ(1, GetFocusedViewId()); - - // Removes view 3 as candidate for next activatable view. - root_view()->GetChildById(3)->SetVisible(false); - EXPECT_EQ(1, GetFocusedViewId()); - - View* target = root_view()->GetChildById(2); - - scoped_ptr<FocusShiftingActivationObserver> observer( - new FocusShiftingActivationObserver(focus_controller(), target)); - observer->set_shift_focus_to(target->GetChildById(21)); - focus_controller()->AddObserver(observer.get()); - - // Hide the active view. - root_view()->GetChildById(1)->SetVisible(false); - - EXPECT_EQ(21, GetFocusedViewId()); - - focus_controller()->RemoveObserver(observer.get()); - } - void NoShiftActiveOnActivation() override { - // When a view is activated, we need to prevent any change to activation - // from being made in response to an activation change notification. - } - - // Verifies focus change is honored while capture held. - void ChangeFocusWhenNothingFocusedAndCaptured() override { - View* v1 = root_view()->GetChildById(1); - capture_controller()->SetCapture(v1); - - EXPECT_EQ(-1, GetActiveViewId()); - EXPECT_EQ(-1, GetFocusedViewId()); - - FocusViewById(1); - - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(1, GetFocusedViewId()); - - capture_controller()->ReleaseCapture(v1); - } - - // Verifies if a view that loses activation or focus is destroyed during - // observer notification we don't pass the destroyed view to other observers. - void DontPassDestroyedView() override { - FocusViewById(1); - - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(1, GetFocusedViewId()); - - { - View* to_destroy = root_view()->GetChildById(1); - DestroyOnLoseActivationFocusNotificationObserver observer1( - focus_controller(), to_destroy, GetActiveView()); - RecordingFocusNotificationObserver observer2(focus_controller(), - &observer1); - - FocusViewById(2); - - EXPECT_EQ(2, GetActiveViewId()); - EXPECT_EQ(2, GetFocusedViewId()); - - EXPECT_EQ(to_destroy, observer1.GetDestroyedView()); - EXPECT_FALSE(observer2.was_notified_with_destroyed_view()); - } - - { - View* to_destroy = root_view()->GetChildById(2); - DestroyOnLoseActivationFocusNotificationObserver observer1( - focus_controller(), to_destroy, GetActiveView()); - RecordingFocusNotificationObserver observer2(focus_controller(), - &observer1); - - FocusViewById(3); - - EXPECT_EQ(3, GetActiveViewId()); - EXPECT_EQ(3, GetFocusedViewId()); - - EXPECT_EQ(to_destroy, observer1.GetDestroyedView()); - EXPECT_FALSE(observer2.was_notified_with_destroyed_view()); - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase); -}; - -// Focus and Activation changes via the FocusController API. -class FocusControllerApiTest : public FocusControllerDirectTestBase { - public: - FocusControllerApiTest() {} - - private: - // Overridden from FocusControllerTestBase: - void FocusViewDirect(View* view) override { FocusView(view); } - void ActivateViewDirect(View* view) override { ActivateView(view); } - void DeactivateViewDirect(View* view) override { DeactivateView(view); } - bool IsInputEvent() override { return false; } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest); -}; - -// Focus and Activation changes via input events. -class FocusControllerMouseEventTest : public FocusControllerDirectTestBase { - public: - FocusControllerMouseEventTest() {} - - // Tests that a handled mouse event does not trigger a view activation. - void IgnoreHandledEvent() { - EXPECT_EQ(NULL, GetActiveView()); - View* v1 = root_view()->GetChildById(1); - SimpleEventHandler handler; - GetRootViewTarget()->PrependPreTargetHandler(&handler); - ClickLeftButton(v1); - EXPECT_EQ(NULL, GetActiveView()); - // TODO(erg): Add gesture testing when we get gestures working. - GetRootViewTarget()->RemovePreTargetHandler(&handler); - ClickLeftButton(v1); - EXPECT_EQ(1, GetActiveViewId()); - } - - private: - // Overridden from FocusControllerTestBase: - void FocusViewDirect(View* view) override { ClickLeftButton(view); } - void ActivateViewDirect(View* view) override { ClickLeftButton(view); } - void DeactivateViewDirect(View* view) override { - View* next_activatable = test_focus_rules()->GetNextActivatableView(view); - ClickLeftButton(next_activatable); - } - bool IsInputEvent() override { return true; } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest); -}; - -// TODO(erg): Add a FocusControllerGestureEventTest once we have working -// gesture forwarding and handling. - -// Test base for tests where focus is implicitly set to a window as the result -// of a disposition change to the focused window or the hierarchy that contains -// it. -class FocusControllerImplicitTestBase : public FocusControllerTestBase { - protected: - explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {} - - View* GetDispositionView(View* view) { - return parent_ ? view->parent() : view; - } - - // Change the disposition of |view| in such a way as it will lose focus. - virtual void ChangeViewDisposition(View* view) = 0; - - // Allow each disposition change test to add additional post-disposition - // change expectations. - virtual void PostDispostionChangeExpectations() {} - - // Overridden from FocusControllerTestBase: - void BasicFocus() override { - EXPECT_EQ(NULL, GetFocusedView()); - - View* w211 = root_view()->GetChildById(211); - FocusView(w211); - EXPECT_EQ(211, GetFocusedViewId()); - - ChangeViewDisposition(w211); - // BasicFocusRules passes focus to the parent. - EXPECT_EQ(parent_ ? 2 : 21, GetFocusedViewId()); - } - - void BasicActivation() override { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - EXPECT_EQ(NULL, GetActiveView()); - - View* w2 = root_view()->GetChildById(2); - ActivateView(w2); - EXPECT_EQ(2, GetActiveViewId()); - - ChangeViewDisposition(w2); - EXPECT_EQ(3, GetActiveViewId()); - PostDispostionChangeExpectations(); - } - - void FocusEvents() override { - View* w211 = root_view()->GetChildById(211); - FocusView(w211); - - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer211( - focus_controller(), GetViewById(211), GetActiveView(), - GetFocusedView()); - - { - SCOPED_TRACE("first"); - root_observer.ExpectCounts(0, 0); - observer211.ExpectCounts(0, 0); - } - - ChangeViewDisposition(w211); - { - SCOPED_TRACE("second"); - { - SCOPED_TRACE("root_observer"); - root_observer.ExpectCounts(0, 1); - } - { - SCOPED_TRACE("observer211"); - observer211.ExpectCounts(0, 1); - } - } - } - - void ActivationEvents() override { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - View* w2 = root_view()->GetChildById(2); - ActivateView(w2); - - ScopedFocusNotificationObserver root_observer(focus_controller()); - ScopedFilteringFocusNotificationObserver observer2( - focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); - ScopedFilteringFocusNotificationObserver observer3( - focus_controller(), GetViewById(3), GetActiveView(), GetFocusedView()); - root_observer.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - observer3.ExpectCounts(0, 0); - - ChangeViewDisposition(w2); - root_observer.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - observer3.ExpectCounts(1, 1); - } - - void FocusRulesOverride() override { - EXPECT_EQ(NULL, GetFocusedView()); - View* w211 = root_view()->GetChildById(211); - FocusView(w211); - EXPECT_EQ(211, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(root_view()->GetChildById(11)); - ChangeViewDisposition(w211); - // Normally, focus would shift to the parent (w21) but the override shifts - // it to 11. - EXPECT_EQ(11, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(NULL); - } - - void ActivationRulesOverride() override { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - View* w1 = root_view()->GetChildById(1); - ActivateView(w1); - - EXPECT_EQ(1, GetActiveViewId()); - EXPECT_EQ(1, GetFocusedViewId()); - - View* w3 = root_view()->GetChildById(3); - test_focus_rules()->set_focus_restriction(w3); - - // Normally, activation/focus would move to w2, but since we have a focus - // restriction, it should move to w3 instead. - ChangeViewDisposition(w1); - EXPECT_EQ(3, GetActiveViewId()); - EXPECT_EQ(3, GetFocusedViewId()); - - test_focus_rules()->set_focus_restriction(NULL); - ActivateView(root_view()->GetChildById(2)); - EXPECT_EQ(2, GetActiveViewId()); - EXPECT_EQ(2, GetFocusedViewId()); - } - - private: - // When true, the disposition change occurs to the parent of the window - // instead of to the window. This verifies that changes occurring in the - // hierarchy that contains the window affect the window's focus. - bool parent_; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase); -}; - -// Focus and Activation changes in response to window visibility changes. -class FocusControllerHideTest : public FocusControllerImplicitTestBase { - public: - FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {} - - protected: - FocusControllerHideTest(bool parent) - : FocusControllerImplicitTestBase(parent) {} - - // Overridden from FocusControllerImplicitTestBase: - void ChangeViewDisposition(View* view) override { - GetDispositionView(view)->SetVisible(false); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest); -}; - -// Focus and Activation changes in response to window parent visibility -// changes. -class FocusControllerParentHideTest : public FocusControllerHideTest { - public: - FocusControllerParentHideTest() : FocusControllerHideTest(true) {} - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest); -}; - -// Focus and Activation changes in response to window destruction. -class FocusControllerDestructionTest : public FocusControllerImplicitTestBase { - public: - FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {} - - protected: - FocusControllerDestructionTest(bool parent) - : FocusControllerImplicitTestBase(parent) {} - - // Overridden from FocusControllerImplicitTestBase: - void ChangeViewDisposition(View* view) override { - GetDispositionView(view)->Destroy(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest); -}; - -// Focus and Activation changes in response to window removal. -class FocusControllerRemovalTest : public FocusControllerImplicitTestBase { - public: - FocusControllerRemovalTest() - : FocusControllerImplicitTestBase(false), - window_to_destroy_(nullptr) {} - - protected: - FocusControllerRemovalTest(bool parent) - : FocusControllerImplicitTestBase(parent), - window_to_destroy_(nullptr) {} - - // Overridden from FocusControllerImplicitTestBase: - void ChangeViewDisposition(View* view) override { - View* disposition_view = GetDispositionView(view); - disposition_view->parent()->RemoveChild(disposition_view); - window_to_destroy_ = disposition_view; - } - void TearDown() override { - if (window_to_destroy_) - window_to_destroy_->Destroy(); - - FocusControllerImplicitTestBase::TearDown(); - } - - private: - View* window_to_destroy_; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest); -}; - -// Focus and Activation changes in response to window parent removal. -class FocusControllerParentRemovalTest : public FocusControllerRemovalTest { - public: - FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {} - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest); -}; - -#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \ - TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); } - -// Runs direct focus change tests (input events and API calls). -// -// TODO(erg): Enable gesture events in the future. -#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) - -// Runs implicit focus change tests for disposition changes to target. -#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME) - -// Runs implicit focus change tests for disposition changes to target's parent -// hierarchy. -#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME) -// TODO(erg): FocusControllerParentDestructionTest were commented out in the -// aura version of this file, and don't work when I tried porting things over. - -// Runs all implicit focus change tests (changes to the target and target's -// parent hierarchy) -#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) - -// Runs all possible focus change tests. -#define ALL_FOCUS_TESTS(TESTNAME) \ - DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) - -// Runs focus change tests that apply only to the target. For example, -// implicit activation changes caused by window disposition changes do not -// occur when changes to the containing hierarchy happen. -#define TARGET_FOCUS_TESTS(TESTNAME) \ - DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) - -// - Focuses a window, verifies that focus changed. -ALL_FOCUS_TESTS(BasicFocus); - -// - Activates a window, verifies that activation changed. -TARGET_FOCUS_TESTS(BasicActivation); - -// - Focuses a window, verifies that focus events were dispatched. -ALL_FOCUS_TESTS(FocusEvents); - -// - Focuses or activates a window multiple times, verifies that events are only -// dispatched when focus/activation actually changes. -DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents); -DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents); - -// - Activates a window, verifies that activation events were dispatched. -TARGET_FOCUS_TESTS(ActivationEvents); - -// - Attempts to active a hidden view, verifies that current view is -// attempted to be reactivated and the appropriate event dispatched. -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents); - -// - Input events/API calls shift focus between focusable views within the -// active view. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveView); - -// - Input events/API calls to a child view of an inactive view shifts -// activation to the activatable parent and focuses the child. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveView); - -// - Input events/API calls to focus the parent of the focused view do not -// shift focus away from the child. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedView); - -// - Verifies that FocusRules determine what can be focused. -ALL_FOCUS_TESTS(FocusRulesOverride); - -// - Verifies that FocusRules determine what can be activated. -TARGET_FOCUS_TESTS(ActivationRulesOverride); - -// - Verifies that attempts to change focus or activation from a focus or -// activation change observer are ignored. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation); -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide); -DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation); - -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, - ChangeFocusWhenNothingFocusedAndCaptured); - -// See description above DontPassDestroyedView() for details. -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDestroyedView); - -// TODO(erg): Add the TextInputClient tests here. - -// If a mouse event was handled, it should not activate a view. -FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent); - -} // namespace window_manager diff --git a/components/window_manager/focus_rules.h b/components/window_manager/focus_rules.h deleted file mode 100644 index d36f933..0000000 --- a/components/window_manager/focus_rules.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_FOCUS_RULES_H_ -#define COMPONENTS_WINDOW_MANAGER_FOCUS_RULES_H_ - -#include "components/view_manager/public/cpp/types.h" -#include "components/view_manager/public/cpp/view.h" - -namespace window_manager { - -// Implemented by an object that establishes the rules about what can be -// focused or activated. -class FocusRules { - public: - virtual ~FocusRules() {} - - // Returns true if the children of |window| can be activated. - virtual bool SupportsChildActivation(mojo::View* window) const = 0; - - // Returns true if |view| is a toplevel view. Whether or not a view - // is considered toplevel is determined by a similar set of rules that - // govern activation and focus. Not all toplevel views are activatable, - // call CanActivateView() to determine if a view can be activated. - virtual bool IsToplevelView(mojo::View* view) const = 0; - // Returns true if |view| can be activated or focused. - virtual bool CanActivateView(mojo::View* view) const = 0; - // For CanFocusView(), null is supported, because null is a valid focusable - // view (in the case of clearing focus). - virtual bool CanFocusView(mojo::View* view) const = 0; - - // Returns the toplevel view containing |view|. Not all toplevel views - // are activatable, call GetActivatableView() instead to return the - // activatable view, which might be in a different hierarchy. - // Will return null if |view| is not contained by a view considered to be - // a toplevel view. - virtual mojo::View* GetToplevelView(mojo::View* view) const = 0; - // Returns the activatable or focusable view given an attempt to activate or - // focus |view|. Some possible scenarios (not intended to be exhaustive): - // - |view| is a child of a non-focusable view and so focus must be set - // according to rules defined by the delegate, e.g. to a parent. - // - |view| is an activatable view that is the transient parent of a modal - // view, so attempts to activate |view| should result in the modal - // transient being activated instead. - // These methods may return null if they are unable to find an activatable - // or focusable view given |view|. - virtual mojo::View* GetActivatableView(mojo::View* view) const = 0; - virtual mojo::View* GetFocusableView(mojo::View* view) const = 0; - - // Returns the next view to activate in the event that |ignore| is no longer - // activatable. This function is called when something is happening to - // |ignore| that means it can no longer have focus or activation, including - // but not limited to: - // - it or its parent hierarchy is being hidden, or removed from the - // RootView. - // - it is being destroyed. - // - it is being explicitly deactivated. - // |ignore| cannot be null. - virtual mojo::View* GetNextActivatableView(mojo::View* ignore) const = 0; -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_FOCUS_RULES_H_ diff --git a/components/window_manager/hit_test.h b/components/window_manager/hit_test.h deleted file mode 100644 index 37a7ea5..0000000 --- a/components/window_manager/hit_test.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_HIT_TEST_H_ -#define COMPONENTS_WINDOW_MANAGER_HIT_TEST_H_ - -#if !defined(OS_WIN) - -// Defines the same symbolic names used by the WM_NCHITTEST Notification under -// win32 (the integer values are not guaranteed to be equivalent). We do this -// because we have a whole bunch of code that deals with window resizing and -// such that requires these values. -enum HitTestCompat { - HTNOWHERE = 0, - HTBORDER, - HTBOTTOM, - HTBOTTOMLEFT, - HTBOTTOMRIGHT, - HTCAPTION, - HTCLIENT, - HTCLOSE, - HTERROR, - HTGROWBOX, - HTHELP, - HTHSCROLL, - HTLEFT, - HTMENU, - HTMAXBUTTON, - HTMINBUTTON, - HTREDUCE, - HTRIGHT, - HTSIZE, - HTSYSMENU, - HTTOP, - HTTOPLEFT, - HTTOPRIGHT, - HTTRANSPARENT, - HTVSCROLL, - HTZOOM -}; - -#endif // !defined(OS_WIN) - -#endif // COMPONENTS_WINDOW_MANAGER_HIT_TEST_H_ diff --git a/components/window_manager/main.cc b/components/window_manager/main.cc index 5fbda31..5f50026 100644 --- a/components/window_manager/main.cc +++ b/components/window_manager/main.cc @@ -5,7 +5,6 @@ #include "base/memory/scoped_ptr.h" #include "components/view_manager/public/cpp/view_manager.h" #include "components/view_manager/public/cpp/view_manager_delegate.h" -#include "components/window_manager/basic_focus_rules.h" #include "components/window_manager/window_manager_app.h" #include "components/window_manager/window_manager_delegate.h" #include "mojo/application/application_runner_chromium.h" @@ -51,8 +50,6 @@ class DefaultWindowManager : public mojo::ApplicationDelegate, mojo::InterfaceRequest<mojo::ServiceProvider> services, mojo::ServiceProviderPtr exposed_services) override { root_ = root; - window_manager_app_->InitFocus( - make_scoped_ptr(new window_manager::BasicFocusRules(root_))); } void OnViewManagerDisconnected(ViewManager* view_manager) override {} diff --git a/components/window_manager/native_viewport_event_dispatcher_impl.cc b/components/window_manager/native_viewport_event_dispatcher_impl.cc deleted file mode 100644 index 4c77e96..0000000 --- a/components/window_manager/native_viewport_event_dispatcher_impl.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/native_viewport_event_dispatcher_impl.h" - -#include "components/window_manager/view_event_dispatcher.h" -#include "components/window_manager/window_manager_app.h" -#include "mojo/converters/input_events/input_events_type_converters.h" - -namespace window_manager { - -NativeViewportEventDispatcherImpl::NativeViewportEventDispatcherImpl( - WindowManagerApp* app, - mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> request) - : app_(app), binding_(this, request.Pass()) { -} -NativeViewportEventDispatcherImpl::~NativeViewportEventDispatcherImpl() { -} - -ui::EventProcessor* NativeViewportEventDispatcherImpl::GetEventProcessor() { - return app_->event_dispatcher(); -} - -void NativeViewportEventDispatcherImpl::OnEvent( - mojo::EventPtr event, - const mojo::Callback<void()>& callback) { - scoped_ptr<ui::Event> ui_event = event.To<scoped_ptr<ui::Event>>(); - - if (ui_event) - SendEventToProcessor(ui_event.get()); - - callback.Run(); -} - -} // namespace window_manager diff --git a/components/window_manager/native_viewport_event_dispatcher_impl.h b/components/window_manager/native_viewport_event_dispatcher_impl.h deleted file mode 100644 index 5fc4dcd..0000000 --- a/components/window_manager/native_viewport_event_dispatcher_impl.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_ -#define COMPONENTS_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_ - -#include "base/basictypes.h" -#include "components/native_viewport/public/interfaces/native_viewport.mojom.h" -#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" -#include "ui/events/event_source.h" - -namespace window_manager { - -class WindowManagerApp; - -class NativeViewportEventDispatcherImpl - : public ui::EventSource, - public mojo::NativeViewportEventDispatcher { - public: - NativeViewportEventDispatcherImpl( - WindowManagerApp* app, - mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> request); - ~NativeViewportEventDispatcherImpl() override; - - private: - // ui::EventSource: - ui::EventProcessor* GetEventProcessor() override; - - // NativeViewportEventDispatcher: - void OnEvent(mojo::EventPtr event, - const mojo::Callback<void()>& callback) override; - - WindowManagerApp* app_; - - mojo::StrongBinding<mojo::NativeViewportEventDispatcher> binding_; - DISALLOW_COPY_AND_ASSIGN(NativeViewportEventDispatcherImpl); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_ diff --git a/components/window_manager/public/interfaces/window_manager.mojom b/components/window_manager/public/interfaces/window_manager.mojom index b11b5ff..0ff82fe 100644 --- a/components/window_manager/public/interfaces/window_manager.mojom +++ b/components/window_manager/public/interfaces/window_manager.mojom @@ -5,7 +5,6 @@ module mojo; import "mojo/public/interfaces/application/service_provider.mojom"; -import "ui/mojo/events/input_events.mojom"; interface WindowManager { // Requests the WindowManager to embed the app for |url| at an appropriate @@ -14,23 +13,4 @@ interface WindowManager { Embed(string url, ServiceProvider&? services, ServiceProvider? exposed_services); - - SetCapture(uint32 view_id) => (bool success); - FocusWindow(uint32 view_id) => (bool success); - ActivateWindow(uint32 view_id) => (bool success); - - // Requests the current focus and activation state and an interface to observe - // future changes. - // If |observer| is not null capture, focus and activation updates will be - // sent to it. - GetFocusedAndActiveViews(WindowManagerObserver? observer) - => (uint32 capture_view_id, - uint32 focused_view_id, - uint32 active_view_id); -}; - -interface WindowManagerObserver { - OnCaptureChanged(uint32 capture_view_id); - OnFocusChanged(uint32 focused_view_id); - OnActiveWindowChanged(uint32 focused_view_id); }; diff --git a/components/window_manager/public/interfaces/window_manager_internal.mojom b/components/window_manager/public/interfaces/window_manager_internal.mojom index f0955c8..e987189 100644 --- a/components/window_manager/public/interfaces/window_manager_internal.mojom +++ b/components/window_manager/public/interfaces/window_manager_internal.mojom @@ -4,28 +4,27 @@ module mojo; +import "ui/mojo/events/input_event_constants.mojom"; import "ui/mojo/events/input_events.mojom"; +import "ui/mojo/events/input_key_codes.mojom"; import "ui/mojo/geometry/geometry.mojom"; // WindowManagerInternal is an interface provided by the WindowManager // exclusively to the ViewManager. interface WindowManagerInternal { - // Creates a connection to the WindowManager specifically for a connection to - // the ViewManager. |connection_id| is the id of the connection to the - // ViewManager. See view_manager.mojom for details on the id. - CreateWindowManagerForViewManagerClient( - uint16 connection_id, - handle<message_pipe> window_manager_pipe); - SetViewManagerClient(handle<message_pipe> view_manager_client_request); + + // An accelerator registered via AddAccelerator() has been triggered. + OnAccelerator(mojo.Event event); }; // WindowManagerInternalClient is an interface provide by the ViewManager // exclusively to the WindowManager. It provides functionality only available // to the WindowManager. interface WindowManagerInternalClient { - // Dispatches the specified input event to the specified view. - DispatchInputEventToView(uint32 view_id, mojo.Event event); + // TODO(sky): this is only used by sky's testing harness. It should be + // removed. + DispatchInputEventToViewDEPRECATED(uint32 view_id, mojo.Event event); // Sets the native viewport size. SetViewportSize(mojo.Size size); @@ -36,4 +35,11 @@ interface WindowManagerInternalClient { // TODO(sky): I think this only makes sense when destroying (view is // already visible), should it be named to indicate this? CloneAndAnimate(uint32 view_id); + + // Adds or removes an accelerators. When the ViewManager receives a key event + // it checks if an accelerator has been registered. If it has, the event is + // sent to the window manager (OnAccelerator()), if not, the event is sent to + // the focused view. + AddAccelerator(mojo.KeyboardCode keyboard_code, mojo.EventFlags flags); + RemoveAccelerator(mojo.KeyboardCode keyboard_code, mojo.EventFlags flags); }; diff --git a/components/window_manager/run_all_unittests.cc b/components/window_manager/run_all_unittests.cc deleted file mode 100644 index 51fd967..0000000 --- a/components/window_manager/run_all_unittests.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/test/launcher/unit_test_launcher.h" -#include "base/test/test_suite.h" -#include "ui/gl/gl_surface.h" - -#if defined(USE_X11) -#include "ui/gfx/x/x11_connection.h" -#endif - -namespace window_manager { - -class WindowManagerTestSuite : public base::TestSuite { - public: - WindowManagerTestSuite(int argc, char** argv) : TestSuite(argc, argv) {} - ~WindowManagerTestSuite() override {} - - protected: - void Initialize() override { -#if defined(USE_X11) - // Each test ends up creating a new thread for the native viewport service. - // In other words we'll use X on different threads, so tell it that. - gfx::InitializeThreadedX11(); -#endif - base::TestSuite::Initialize(); - gfx::GLSurface::InitializeOneOffForTests(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(WindowManagerTestSuite); -}; - -} // namespace window_manager - -int main(int argc, char** argv) { - window_manager::WindowManagerTestSuite test_suite(argc, argv); - - return base::LaunchUnitTests( - argc, argv, base::Bind(&TestSuite::Run, base::Unretained(&test_suite))); -} diff --git a/components/window_manager/view_event_dispatcher.cc b/components/window_manager/view_event_dispatcher.cc deleted file mode 100644 index 45566e3..0000000 --- a/components/window_manager/view_event_dispatcher.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/view_event_dispatcher.h" - -#include "components/view_manager/public/cpp/view.h" -#include "components/window_manager/view_target.h" - -namespace window_manager { - -ViewEventDispatcher::ViewEventDispatcher() - : event_dispatch_target_(nullptr), - old_dispatch_target_(nullptr) { -} - -ViewEventDispatcher::~ViewEventDispatcher() {} - -void ViewEventDispatcher::SetRootViewTarget(ViewTarget* root_view_target) { - root_view_target_ = root_view_target; -} - -ui::EventTarget* ViewEventDispatcher::GetRootTarget() { - return root_view_target_; -} - -void ViewEventDispatcher::OnEventProcessingStarted(ui::Event* event) { -} - -bool ViewEventDispatcher::CanDispatchToTarget(ui::EventTarget* target) { - return event_dispatch_target_ == target; -} - -ui::EventDispatchDetails ViewEventDispatcher::PreDispatchEvent( - ui::EventTarget* target, - ui::Event* event) { - // TODO(erg): PreDispatch in aura::WindowEventDispatcher does many, many - // things. It, and the functions split off for different event types, are - // most of the file. - old_dispatch_target_ = event_dispatch_target_; - event_dispatch_target_ = static_cast<ViewTarget*>(target); - return ui::EventDispatchDetails(); -} - -ui::EventDispatchDetails ViewEventDispatcher::PostDispatchEvent( - ui::EventTarget* target, - const ui::Event& event) { - // TODO(erg): Not at all as long as PreDispatchEvent, but still missing core - // details. - event_dispatch_target_ = old_dispatch_target_; - old_dispatch_target_ = nullptr; - return ui::EventDispatchDetails(); -} - -} // namespace window_manager diff --git a/components/window_manager/view_event_dispatcher.h b/components/window_manager/view_event_dispatcher.h deleted file mode 100644 index 8757e63..0000000 --- a/components/window_manager/view_event_dispatcher.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_VIEW_EVENT_DISPATCHER_H_ -#define COMPONENTS_WINDOW_MANAGER_VIEW_EVENT_DISPATCHER_H_ - -#include "base/memory/scoped_ptr.h" -#include "ui/events/event_processor.h" -#include "ui/events/event_target.h" - -namespace window_manager { - -class ViewTarget; - -class ViewEventDispatcher : public ui::EventProcessor { - public: - ViewEventDispatcher(); - ~ViewEventDispatcher() override; - - void SetRootViewTarget(ViewTarget* root_view_target); - - private: - // Overridden from ui::EventProcessor: - ui::EventTarget* GetRootTarget() override; - void OnEventProcessingStarted(ui::Event* event) override; - - // Overridden from ui::EventDispatcherDelegate. - bool CanDispatchToTarget(ui::EventTarget* target) override; - ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target, - ui::Event* event) override; - ui::EventDispatchDetails PostDispatchEvent( - ui::EventTarget* target, const ui::Event& event) override; - - // We keep a weak reference to ViewTarget*, which corresponds to the root of - // the mojo::View tree. - ViewTarget* root_view_target_; - - ViewTarget* event_dispatch_target_; - ViewTarget* old_dispatch_target_; - - DISALLOW_COPY_AND_ASSIGN(ViewEventDispatcher); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_VIEW_EVENT_DISPATCHER_H_ diff --git a/components/window_manager/view_target.cc b/components/window_manager/view_target.cc deleted file mode 100644 index fe61bf0..0000000 --- a/components/window_manager/view_target.cc +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/view_target.h" - -#include "components/view_manager/public/cpp/view.h" -#include "components/view_manager/public/cpp/view_property.h" -#include "components/window_manager/view_targeter.h" -#include "components/window_manager/window_manager_app.h" -#include "mojo/converters/geometry/geometry_type_converters.h" -#include "ui/events/event.h" -#include "ui/events/event_target_iterator.h" -#include "ui/events/event_targeter.h" -#include "ui/gfx/geometry/point3_f.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/transform.h" - -namespace window_manager { - -namespace { - -DEFINE_OWNED_VIEW_PROPERTY_KEY(ViewTarget, kViewTargetKey, nullptr); - -// Provides a version which keeps a copy of the data (for when it has to be -// derived instead of pointed at). -template <typename T> -class CopyingEventTargetIteratorImpl : public ui::EventTargetIterator { - public: - explicit CopyingEventTargetIteratorImpl(const std::vector<T*>& children) - : children_(children), - begin_(children_.rbegin()), - end_(children_.rend()) {} - ~CopyingEventTargetIteratorImpl() override {} - - ui::EventTarget* GetNextTarget() override { - if (begin_ == end_) - return nullptr; - ui::EventTarget* target = *(begin_); - ++begin_; - return target; - } - - private: - typename std::vector<T*> children_; - typename std::vector<T*>::const_reverse_iterator begin_; - typename std::vector<T*>::const_reverse_iterator end_; -}; - -} // namespace - -ViewTarget::~ViewTarget() { -} - -// static -ViewTarget* ViewTarget::TargetFromView(mojo::View* view) { - if (!view) - return nullptr; - - ViewTarget* target = view->GetLocalProperty(kViewTargetKey); - if (target) - return target; - - return new ViewTarget(view); -} - -void ViewTarget::ConvertPointToTarget(const ViewTarget* source, - const ViewTarget* target, - gfx::Point* point) { - // TODO(erg): Do we need to deal with |source| and |target| being in - // different trees? - DCHECK_EQ(source->GetRoot(), target->GetRoot()); - if (source == target) - return; - - const ViewTarget* root_target = source->GetRoot(); - CHECK_EQ(root_target, target->GetRoot()); - - if (source != root_target) - source->ConvertPointForAncestor(root_target, point); - if (target != root_target) - target->ConvertPointFromAncestor(root_target, point); -} - -std::vector<ViewTarget*> ViewTarget::GetChildren() const { - std::vector<ViewTarget*> targets; - for (mojo::View* child : view_->children()) - targets.push_back(TargetFromView(child)); - return targets; -} - -const ViewTarget* ViewTarget::GetParent() const { - return TargetFromView(view_->parent()); -} - -gfx::Rect ViewTarget::GetBounds() const { - return view_->bounds().To<gfx::Rect>(); -} - -bool ViewTarget::HasParent() const { - return !!view_->parent(); -} - -bool ViewTarget::IsVisible() const { - return view_->visible(); -} - -const ViewTarget* ViewTarget::GetRoot() const { - const ViewTarget* root = this; - for (const ViewTarget* parent = this; parent; parent = parent->GetParent()) - root = parent; - return root; -} - -scoped_ptr<ViewTargeter> ViewTarget::SetEventTargeter( - scoped_ptr<ViewTargeter> targeter) { - scoped_ptr<ViewTargeter> old_targeter = targeter_.Pass(); - targeter_ = targeter.Pass(); - return old_targeter.Pass(); -} - -bool ViewTarget::CanAcceptEvent(const ui::Event& event) { - // We need to make sure that a touch cancel event and any gesture events it - // creates can always reach the window. This ensures that we receive a valid - // touch / gesture stream. - if (event.IsEndingEvent()) - return true; - - if (!view_->visible()) - return false; - - // The top-most window can always process an event. - if (!view_->parent()) - return true; - - // In aura, we only accept events if this is a key event or if the user - // supplied a TargetHandler, usually the aura::WindowDelegate. Here, we're - // just forwarding events to other Views which may be in other processes, so - // always accept. - return true; -} - -ui::EventTarget* ViewTarget::GetParentTarget() { - return TargetFromView(view_->parent()); -} - -scoped_ptr<ui::EventTargetIterator> ViewTarget::GetChildIterator() const { - return scoped_ptr<ui::EventTargetIterator>( - new CopyingEventTargetIteratorImpl<ViewTarget>(GetChildren())); -} - -ui::EventTargeter* ViewTarget::GetEventTargeter() { - return targeter_.get(); -} - -void ViewTarget::ConvertEventToTarget(ui::EventTarget* target, - ui::LocatedEvent* event) { - event->ConvertLocationToTarget(this, static_cast<ViewTarget*>(target)); -} - -ViewTarget::ViewTarget(mojo::View* view_to_wrap) : view_(view_to_wrap) { - DCHECK(view_->GetLocalProperty(kViewTargetKey) == nullptr); - view_->SetLocalProperty(kViewTargetKey, this); -} - -bool ViewTarget::ConvertPointForAncestor(const ViewTarget* ancestor, - gfx::Point* point) const { - gfx::Vector2d offset; - bool result = GetTargetOffsetRelativeTo(ancestor, &offset); - *point += offset; - return result; -} - -bool ViewTarget::ConvertPointFromAncestor(const ViewTarget* ancestor, - gfx::Point* point) const { - gfx::Vector2d offset; - bool result = GetTargetOffsetRelativeTo(ancestor, &offset); - *point -= offset; - return result; -} - -bool ViewTarget::GetTargetOffsetRelativeTo(const ViewTarget* ancestor, - gfx::Vector2d* offset) const { - const ViewTarget* v = this; - for (; v && v != ancestor; v = v->GetParent()) { - gfx::Rect bounds = v->GetBounds(); - *offset += gfx::Vector2d(bounds.x(), bounds.y()); - } - return v == ancestor; -} - -} // namespace window_manager diff --git a/components/window_manager/view_target.h b/components/window_manager/view_target.h deleted file mode 100644 index 5bfa4da..0000000 --- a/components/window_manager/view_target.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_VIEW_TARGET_H_ -#define COMPONENTS_WINDOW_MANAGER_VIEW_TARGET_H_ - -#include "ui/events/event_target.h" - -namespace gfx { -class Point; -class Rect; -class Vector2d; -} - -namespace ui { -class EventTargeter; -} - -namespace mojo { -class View; -} - -namespace window_manager { - -class TestView; -class ViewTargeter; -class WindowManagerApp; - -// A wrapper class around mojo::View; we can't subclass View to implement the -// event targeting interfaces, so we create a separate object which observes -// the View and ties its lifetime to it. -// -// We set ourselves as a property of the view passed in, and we are owned by -// said View. -class ViewTarget : public ui::EventTarget { - public: - ~ViewTarget() override; - - // Returns the ViewTarget for a View. ViewTargets are owned by the |view| - // passed in, and are created on demand. - static ViewTarget* TargetFromView(mojo::View* view); - - // Converts |point| from |source|'s coordinates to |target|'s. If |source| is - // NULL, the function returns without modifying |point|. |target| cannot be - // NULL. - static void ConvertPointToTarget(const ViewTarget* source, - const ViewTarget* target, - gfx::Point* point); - - mojo::View* view() { return view_; } - - // TODO(erg): Make this const once we've removed aura from the tree and it's - // feasible to change all callers of the EventTargeter interface to pass and - // accept const objects. (When that gets done, re-const the - // EventTargetIterator::GetNextTarget and EventTarget::GetChildIterator - // interfaces.) - std::vector<ViewTarget*> GetChildren() const; - - const ViewTarget* GetParent() const; - gfx::Rect GetBounds() const; - bool HasParent() const; - bool IsVisible() const; - - const ViewTarget* GetRoot() const; - - // Sets a new ViewTargeter for the view, and returns the previous - // ViewTargeter. - scoped_ptr<ViewTargeter> SetEventTargeter(scoped_ptr<ViewTargeter> targeter); - - // Overridden from ui::EventTarget: - bool CanAcceptEvent(const ui::Event& event) override; - EventTarget* GetParentTarget() override; - scoped_ptr<ui::EventTargetIterator> GetChildIterator() const override; - ui::EventTargeter* GetEventTargeter() override; - void ConvertEventToTarget(ui::EventTarget* target, - ui::LocatedEvent* event) override; - - private: - friend class TestView; - explicit ViewTarget(mojo::View* view_to_wrap); - - bool ConvertPointForAncestor(const ViewTarget* ancestor, - gfx::Point* point) const; - bool ConvertPointFromAncestor(const ViewTarget* ancestor, - gfx::Point* point) const; - bool GetTargetOffsetRelativeTo(const ViewTarget* ancestor, - gfx::Vector2d* offset) const; - - // The mojo::View that we dispatch to. - mojo::View* view_; - - scoped_ptr<ViewTargeter> targeter_; - - DISALLOW_COPY_AND_ASSIGN(ViewTarget); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_VIEW_TARGET_H_ diff --git a/components/window_manager/view_target_unittest.cc b/components/window_manager/view_target_unittest.cc deleted file mode 100644 index 7e3f5bf..0000000 --- a/components/window_manager/view_target_unittest.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/view_target.h" - -#include <set> - -#include "components/view_manager/public/cpp/view.h" -#include "components/window_manager/window_manager_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/rect.h" - -namespace window_manager { - -using ViewTargetTest = testing::Test; - -// V1 -// +-- V2 -// +-- V3 -TEST_F(ViewTargetTest, GetRoot) { - TestView v1(1, gfx::Rect(20, 20, 400, 400)); - TestView v2(2, gfx::Rect(10, 10, 350, 350)); - TestView v3(3, gfx::Rect(10, 10, 100, 100)); - v1.AddChild(&v2); - v2.AddChild(&v3); - - EXPECT_EQ(ViewTarget::TargetFromView(&v1), - ViewTarget::TargetFromView(&v1)->GetRoot()); - EXPECT_EQ(ViewTarget::TargetFromView(&v1), - ViewTarget::TargetFromView(&v2)->GetRoot()); - EXPECT_EQ(ViewTarget::TargetFromView(&v1), - ViewTarget::TargetFromView(&v3)->GetRoot()); -} - -// V1 -// +-- V2 -TEST_F(ViewTargetTest, ConvertPointToTarget_Simple) { - TestView v1(1, gfx::Rect(20, 20, 400, 400)); - TestView v2(2, gfx::Rect(10, 10, 350, 350)); - v1.AddChild(&v2); - - ViewTarget* t1 = v1.target(); - ViewTarget* t2 = v2.target(); - - gfx::Point point1_in_t2_coords(5, 5); - ViewTarget::ConvertPointToTarget(t2, t1, &point1_in_t2_coords); - gfx::Point point1_in_t1_coords(15, 15); - EXPECT_EQ(point1_in_t1_coords, point1_in_t2_coords); - - gfx::Point point2_in_t1_coords(5, 5); - ViewTarget::ConvertPointToTarget(t1, t2, &point2_in_t1_coords); - gfx::Point point2_in_t2_coords(-5, -5); - EXPECT_EQ(point2_in_t2_coords, point2_in_t1_coords); -} - -// V1 -// +-- V2 -// +-- V3 -TEST_F(ViewTargetTest, ConvertPointToTarget_Medium) { - TestView v1(1, gfx::Rect(20, 20, 400, 400)); - TestView v2(2, gfx::Rect(10, 10, 350, 350)); - TestView v3(3, gfx::Rect(10, 10, 100, 100)); - v1.AddChild(&v2); - v2.AddChild(&v3); - - ViewTarget* t1 = v1.target(); - ViewTarget* t3 = v3.target(); - - gfx::Point point1_in_t3_coords(5, 5); - ViewTarget::ConvertPointToTarget(t3, t1, &point1_in_t3_coords); - gfx::Point point1_in_t1_coords(25, 25); - EXPECT_EQ(point1_in_t1_coords, point1_in_t3_coords); - - gfx::Point point2_in_t1_coords(5, 5); - ViewTarget::ConvertPointToTarget(t1, t3, &point2_in_t1_coords); - gfx::Point point2_in_t3_coords(-15, -15); - EXPECT_EQ(point2_in_t3_coords, point2_in_t1_coords); -} - -} // namespace window_manager diff --git a/components/window_manager/view_targeter.cc b/components/window_manager/view_targeter.cc deleted file mode 100644 index 96c8fb9..0000000 --- a/components/window_manager/view_targeter.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/view_targeter.h" - -#include "components/window_manager/capture_controller.h" -#include "components/window_manager/focus_controller.h" -#include "components/window_manager/view_target.h" - -namespace window_manager { - -ViewTargeter::ViewTargeter() {} - -ViewTargeter::~ViewTargeter() {} - -ui::EventTarget* ViewTargeter::FindTargetForEvent(ui::EventTarget* root, - ui::Event* event) { - ViewTarget* view = static_cast<ViewTarget*>(root); - ViewTarget* target = - event->IsKeyEvent() - ? FindTargetForKeyEvent(view, *static_cast<ui::KeyEvent*>(event)) - : static_cast<ViewTarget*>( - EventTargeter::FindTargetForEvent(root, event)); - - // TODO(erg): The aura version of this method does a lot of work to handle - // dispatching to a target that isn't a child of |view|. For now, punt on - // this. - DCHECK_EQ(view->GetRoot(), target->GetRoot()); - - return target; -} - -ui::EventTarget* ViewTargeter::FindTargetForLocatedEvent( - ui::EventTarget* root, - ui::LocatedEvent* event) { - ViewTarget* view = static_cast<ViewTarget*>(root); - if (!view->HasParent()) { - ViewTarget* target = FindTargetInRootView(view, *event); - if (target) { - view->ConvertEventToTarget(target, event); - return target; - } - } - return EventTargeter::FindTargetForLocatedEvent(view, event); -} - -bool ViewTargeter::SubtreeCanAcceptEvent(ui::EventTarget* target, - const ui::LocatedEvent& event) const { - ViewTarget* view = static_cast<ViewTarget*>(target); - - if (!view->IsVisible()) - return false; - - // TODO(erg): We may need to keep track of the parent on ViewTarget, because - // we have a check here about - // WindowDelegate::ShouldDescendIntoChildForEventHandling(). - - // TODO(sky): decide if we really want this. If we do, it should be a public - // constant and documented. - if (view->view()->shared_properties().count("deliver-events-to-parent")) - return false; - - return true; -} - -bool ViewTargeter::EventLocationInsideBounds( - ui::EventTarget* target, - const ui::LocatedEvent& event) const { - ViewTarget* view = static_cast<ViewTarget*>(target); - gfx::Point point = event.location(); - const ViewTarget* parent = view->GetParent(); - if (parent) - ViewTarget::ConvertPointToTarget(parent, view, &point); - return gfx::Rect(view->GetBounds().size()).Contains(point); -} - -ViewTarget* ViewTargeter::FindTargetForKeyEvent(ViewTarget* view_target, - const ui::KeyEvent& key) { - FocusController* focus_controller = GetFocusController(view_target->view()); - if (focus_controller) { - mojo::View* focused_view = focus_controller->GetFocusedView(); - if (focused_view) - return ViewTarget::TargetFromView(focused_view); - } - return view_target; -} - -ViewTarget* ViewTargeter::FindTargetInRootView(ViewTarget* root_view, - const ui::LocatedEvent& event) { - // TODO(erg): This here is important because it resolves - // mouse_pressed_handler() in the aura version. This is what makes sure - // that a view gets both the mouse down and up. - - CaptureController* capture_controller = - GetCaptureController(root_view->view()); - if (capture_controller) { - mojo::View* capture_view = capture_controller->GetCapture(); - if (capture_view) - return ViewTarget::TargetFromView(capture_view); - } - - // TODO(erg): There's a whole bunch of junk about handling touch events - // here. Handle later. - - return nullptr; -} - -} // namespace window_manager diff --git a/components/window_manager/view_targeter.h b/components/window_manager/view_targeter.h deleted file mode 100644 index 75ca1de..0000000 --- a/components/window_manager/view_targeter.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_VIEW_TARGETER_H_ -#define COMPONENTS_WINDOW_MANAGER_VIEW_TARGETER_H_ - -#include "ui/events/event_targeter.h" - -namespace window_manager { - -class ViewTarget; - -class ViewTargeter : public ui::EventTargeter { - public: - ViewTargeter(); - ~ViewTargeter() override; - - protected: - // ui::EventTargeter: - ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, - ui::Event* event) override; - ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root, - ui::LocatedEvent* event) override; - bool SubtreeCanAcceptEvent(ui::EventTarget* target, - const ui::LocatedEvent& event) const override; - bool EventLocationInsideBounds(ui::EventTarget* target, - const ui::LocatedEvent& event) const override; - - private: - // Targets either the root View or the currently focused view. - ViewTarget* FindTargetForKeyEvent(ViewTarget* view, const ui::KeyEvent& key); - - // Deals with cases where the |root_view| needs to change how things are - // dispatched. (For example, in the case of capture.) - ViewTarget* FindTargetInRootView(ViewTarget* root_view, - const ui::LocatedEvent& event); - - DISALLOW_COPY_AND_ASSIGN(ViewTargeter); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_VIEW_TARGETER_H_ diff --git a/components/window_manager/view_targeter_unittest.cc b/components/window_manager/view_targeter_unittest.cc deleted file mode 100644 index 12a36d0..0000000 --- a/components/window_manager/view_targeter_unittest.cc +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/view_targeter.h" - -#include "components/window_manager/basic_focus_rules.h" -#include "components/window_manager/capture_controller.h" -#include "components/window_manager/focus_controller.h" -#include "components/window_manager/view_event_dispatcher.h" -#include "components/window_manager/window_manager_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/event_utils.h" -#include "ui/events/test/test_event_handler.h" - -namespace window_manager { - -class ViewTargeterTest : public testing::Test { - public: - ViewTargeterTest() {} - ~ViewTargeterTest() override {} - - void SetUp() override { - view_event_dispatcher_.reset(new ViewEventDispatcher()); - } - - void TearDown() override { - view_event_dispatcher_.reset(); - testing::Test::TearDown(); - } - - protected: - scoped_ptr<ViewEventDispatcher> view_event_dispatcher_; - - private: - DISALLOW_COPY_AND_ASSIGN(ViewTargeterTest); -}; - -TEST_F(ViewTargeterTest, Basic) { - // The dispatcher will take ownership of the tree root. - TestView root(1, gfx::Rect(0, 0, 100, 100)); - ViewTarget* root_target = root.target(); - root_target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); - view_event_dispatcher_->SetRootViewTarget(root_target); - - CaptureController capture_controller; - SetCaptureController(&root, &capture_controller); - - TestView one(2, gfx::Rect(0, 0, 500, 100)); - TestView two(3, gfx::Rect(501, 0, 500, 1000)); - - root.AddChild(&one); - root.AddChild(&two); - - ui::test::TestEventHandler handler; - one.target()->AddPreTargetHandler(&handler); - - ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(20, 20), - gfx::Point(20, 20), ui::EventTimeForNow(), ui::EF_NONE, - ui::EF_NONE); - ui::EventDispatchDetails details = - view_event_dispatcher_->OnEventFromSource(&press); - ASSERT_FALSE(details.dispatcher_destroyed); - - EXPECT_EQ(1, handler.num_mouse_events()); - - one.target()->RemovePreTargetHandler(&handler); -} - -TEST_F(ViewTargeterTest, KeyTest) { - // The dispatcher will take ownership of the tree root. - TestView root(1, gfx::Rect(0, 0, 100, 100)); - ViewTarget* root_target = root.target(); - root_target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); - view_event_dispatcher_->SetRootViewTarget(root_target); - - CaptureController capture_controller; - SetCaptureController(&root, &capture_controller); - - TestView one(2, gfx::Rect(0, 0, 500, 100)); - TestView two(3, gfx::Rect(501, 0, 500, 1000)); - - root.AddChild(&one); - root.AddChild(&two); - - ui::test::TestEventHandler one_handler; - one.target()->AddPreTargetHandler(&one_handler); - - ui::test::TestEventHandler two_handler; - two.target()->AddPreTargetHandler(&two_handler); - - FocusController focus_controller(make_scoped_ptr(new BasicFocusRules(&root))); - SetFocusController(&root, &focus_controller); - - // Focus |one|. Then test that it receives a key event. - focus_controller.FocusView(&one); - ui::KeyEvent key_event_one(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); - ui::EventDispatchDetails details = - view_event_dispatcher_->OnEventFromSource(&key_event_one); - ASSERT_FALSE(details.dispatcher_destroyed); - EXPECT_EQ(1, one_handler.num_key_events()); - - // Focus |two|. Then test that it receives a key event. - focus_controller.FocusView(&two); - ui::KeyEvent key_event_two(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); - details = view_event_dispatcher_->OnEventFromSource(&key_event_two); - ASSERT_FALSE(details.dispatcher_destroyed); - EXPECT_EQ(1, two_handler.num_key_events()); - - two.target()->RemovePreTargetHandler(&two_handler); - one.target()->RemovePreTargetHandler(&one_handler); -} - -} // namespace window_manager diff --git a/components/window_manager/window_manager_app.cc b/components/window_manager/window_manager_app.cc index ffc0d68..da40ef7 100644 --- a/components/window_manager/window_manager_app.cc +++ b/components/window_manager/window_manager_app.cc @@ -8,16 +8,8 @@ #include "base/stl_util.h" #include "components/view_manager/public/cpp/view.h" #include "components/view_manager/public/cpp/view_manager.h" -#include "components/window_manager/capture_controller.h" -#include "components/window_manager/focus_controller.h" -#include "components/window_manager/focus_rules.h" -#include "components/window_manager/hit_test.h" -#include "components/window_manager/view_event_dispatcher.h" -#include "components/window_manager/view_target.h" -#include "components/window_manager/view_targeter.h" #include "components/window_manager/window_manager_delegate.h" #include "mojo/converters/geometry/geometry_type_converters.h" -#include "mojo/converters/input_events/input_events_type_converters.h" #include "third_party/mojo/src/mojo/public/cpp/application/application_connection.h" #include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h" #include "third_party/mojo/src/mojo/public/interfaces/application/shell.mojom.h" @@ -30,14 +22,6 @@ using mojo::WindowManager; namespace window_manager { -namespace { - -Id GetIdForView(View* view) { - return view ? view->id() : 0; -} - -} // namespace - // Used for calls to Embed() that occur before we've connected to the // ViewManager. struct WindowManagerApp::PendingEmbed { @@ -60,17 +44,8 @@ WindowManagerApp::WindowManagerApp( WindowManagerApp::~WindowManagerApp() { // TODO(msw|sky): Should this destructor explicitly delete the ViewManager? - mojo::ViewManager* cached_view_manager = view_manager(); - for (RegisteredViewIdSet::const_iterator it = registered_view_id_set_.begin(); - cached_view_manager && it != registered_view_id_set_.end(); ++it) { - View* view = cached_view_manager->GetViewById(*it); - if (view && view == root_) - root_ = nullptr; - if (view) - view->RemoveObserver(this); - } - registered_view_id_set_.clear(); - DCHECK(!root_); + if (root_) + root_->RemoveObserver(this); STLDeleteElements(&connections_); } @@ -85,35 +60,13 @@ void WindowManagerApp::RemoveConnection(WindowManagerImpl* connection) { connections_.erase(connection); } -bool WindowManagerApp::SetCapture(Id view_id) { - View* view = view_manager()->GetViewById(view_id); - return view && SetCaptureImpl(view); -} - -bool WindowManagerApp::FocusWindow(Id view_id) { - View* view = view_manager()->GetViewById(view_id); - return view && FocusWindowImpl(view); -} - -bool WindowManagerApp::ActivateWindow(Id view_id) { - View* view = view_manager()->GetViewById(view_id); - return view && ActivateWindowImpl(view); -} - bool WindowManagerApp::IsReady() const { return !!root_; } -void WindowManagerApp::InitFocus(scoped_ptr<FocusRules> rules) { - DCHECK(root_); - - focus_controller_.reset(new FocusController(rules.Pass())); - focus_controller_->AddObserver(this); - SetFocusController(root_, focus_controller_.get()); - - capture_controller_.reset(new CaptureController); - capture_controller_->AddObserver(this); - SetCaptureController(root_, capture_controller_.get()); +void WindowManagerApp::AddAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) { + window_manager_client_->AddAccelerator(keyboard_code, flags); } void WindowManagerApp::Embed( @@ -156,9 +109,7 @@ void WindowManagerApp::OnEmbed( DCHECK(!root_); root_ = root; - view_event_dispatcher_.reset(new ViewEventDispatcher); - - RegisterSubtree(root_); + root_->AddObserver(this); if (wrapped_view_manager_delegate_) { wrapped_view_manager_delegate_->OnEmbed(root, services.Pass(), @@ -182,172 +133,23 @@ void WindowManagerApp::OnViewManagerDisconnected( message_loop->Quit(); } -bool WindowManagerApp::OnPerformAction(mojo::View* view, - const std::string& action) { - if (!view) - return false; - if (action == "capture") - return SetCaptureImpl(view); - if (action == "focus") - return FocusWindowImpl(view); - else if (action == "activate") - return ActivateWindowImpl(view); - return false; -} - //////////////////////////////////////////////////////////////////////////////// // WindowManagerApp, ViewObserver implementation: -void WindowManagerApp::OnTreeChanged( - const ViewObserver::TreeChangeParams& params) { - if (params.receiver != root_) - return; - DCHECK(params.old_parent || params.new_parent); - if (!params.target) - return; - - if (params.new_parent) { - if (registered_view_id_set_.find(params.target->id()) == - registered_view_id_set_.end()) { - RegisteredViewIdSet::const_iterator it = - registered_view_id_set_.find(params.new_parent->id()); - DCHECK(it != registered_view_id_set_.end()); - RegisterSubtree(params.target); - } - } else if (params.old_parent) { - UnregisterSubtree(params.target); - } -} - void WindowManagerApp::OnViewDestroying(View* view) { - Unregister(view); - if (view == root_) { - root_ = nullptr; - if (focus_controller_) - focus_controller_->RemoveObserver(this); - if (capture_controller_) - capture_controller_->RemoveObserver(this); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowManagerApp, ui::EventHandler implementation: - -void WindowManagerApp::OnEvent(ui::Event* event) { - if (!window_manager_client_) - return; - - View* view = static_cast<ViewTarget*>(event->target())->view(); - if (!view) - return; - - if (event->IsKeyEvent()) { - const ui::KeyEvent* key_event = static_cast<const ui::KeyEvent*>(event); - if (key_event->type() == ui::ET_KEY_PRESSED) { - ui::Accelerator accelerator = ConvertEventToAccelerator(key_event); - if (accelerator_manager_.Process(accelerator)) - return; - } - } - - if (focus_controller_) - focus_controller_->OnEvent(event); - - window_manager_client_->DispatchInputEventToView(view->id(), - mojo::Event::From(*event)); -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowManagerApp, mojo::FocusControllerObserver implementation: - -void WindowManagerApp::OnFocused(View* gained_focus) { - for (Connections::const_iterator it = connections_.begin(); - it != connections_.end(); ++it) { - (*it)->NotifyViewFocused(GetIdForView(gained_focus)); - } -} - -void WindowManagerApp::OnActivated(View* gained_active) { - for (Connections::const_iterator it = connections_.begin(); - it != connections_.end(); ++it) { - (*it)->NotifyWindowActivated(GetIdForView(gained_active)); - } - if (gained_active) - gained_active->MoveToFront(); -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowManagerApp, mojo::CaptureControllerObserver implementation: - -void WindowManagerApp::OnCaptureChanged(View* gained_capture) { - for (Connections::const_iterator it = connections_.begin(); - it != connections_.end(); ++it) { - (*it)->NotifyCaptureChanged(GetIdForView(gained_capture)); - } - if (gained_capture) - gained_capture->MoveToFront(); + DCHECK_EQ(root_, view); + root_->RemoveObserver(this); + root_ = nullptr; } //////////////////////////////////////////////////////////////////////////////// // WindowManagerApp, private: -bool WindowManagerApp::SetCaptureImpl(View* view) { - CHECK(view); - capture_controller_->SetCapture(view); - return capture_controller_->GetCapture() == view; -} - -bool WindowManagerApp::FocusWindowImpl(View* view) { - CHECK(view); - focus_controller_->FocusView(view); - return focus_controller_->GetFocusedView() == view; -} - -bool WindowManagerApp::ActivateWindowImpl(View* view) { - CHECK(view); - focus_controller_->ActivateView(view); - return focus_controller_->GetActiveView() == view; -} - -void WindowManagerApp::RegisterSubtree(View* view) { - view->AddObserver(this); - DCHECK(registered_view_id_set_.find(view->id()) == - registered_view_id_set_.end()); - // All events pass through the root during dispatch, so we only need a handler - // installed there. - if (view == root_) { - ViewTarget* target = ViewTarget::TargetFromView(view); - target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); - target->AddPreTargetHandler(this); - view_event_dispatcher_->SetRootViewTarget(target); - } - registered_view_id_set_.insert(view->id()); - View::Children::const_iterator it = view->children().begin(); - for (; it != view->children().end(); ++it) - RegisterSubtree(*it); -} - -void WindowManagerApp::UnregisterSubtree(View* view) { - for (View* child : view->children()) - UnregisterSubtree(child); - Unregister(view); -} - -void WindowManagerApp::Unregister(View* view) { - RegisteredViewIdSet::iterator it = registered_view_id_set_.find(view->id()); - if (it == registered_view_id_set_.end()) { - // Because we unregister in OnViewDestroying() we can still get a subsequent - // OnTreeChanged for the same view. Ignore this one. - return; - } - view->RemoveObserver(this); - DCHECK(it != registered_view_id_set_.end()); - registered_view_id_set_.erase(it); -} - -void WindowManagerApp::DispatchInputEventToView(View* view, - mojo::EventPtr event) { - window_manager_client_->DispatchInputEventToView(view->id(), event.Pass()); +void WindowManagerApp::DispatchInputEventToViewDEPRECATED( + View* view, + mojo::EventPtr event) { + window_manager_client_->DispatchInputEventToViewDEPRECATED(view->id(), + event.Pass()); } void WindowManagerApp::SetViewportSize(const gfx::Size& size) { @@ -364,7 +166,6 @@ void WindowManagerApp::LaunchViewManager(mojo::ApplicationImpl* app) { view_manager_app->ConnectToService(&view_manager_service_); view_manager_app->AddService<WindowManagerInternal>(this); - view_manager_app->AddService<mojo::NativeViewportEventDispatcher>(this); view_manager_app->ConnectToService(&window_manager_client_); } @@ -389,22 +190,6 @@ void WindowManagerApp::Create(ApplicationConnection* connection, // destructor. } -void WindowManagerApp::Create( - mojo::ApplicationConnection* connection, - mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> request) { - new NativeViewportEventDispatcherImpl(this, request.Pass()); -} - -void WindowManagerApp::CreateWindowManagerForViewManagerClient( - uint16_t connection_id, - mojo::ScopedMessagePipeHandle window_manager_pipe) { - // TODO(sky): pass in |connection_id| for validation. - WindowManagerImpl* wm = new WindowManagerImpl(this, true); - wm->Bind(window_manager_pipe.Pass()); - // WindowManagerImpl is deleted when the connection has an error, or from our - // destructor. -} - void WindowManagerApp::SetViewManagerClient( mojo::ScopedMessagePipeHandle view_manager_client_request) { view_manager_client_.reset( @@ -414,4 +199,10 @@ void WindowManagerApp::SetViewManagerClient( view_manager_service_.Pass(), shell_, this)); } +void WindowManagerApp::OnAccelerator(mojo::EventPtr event) { + window_manager_delegate_->OnAcceleratorPressed( + root_->view_manager()->GetFocusedView(), + event->key_data->windows_key_code, event->flags); +} + } // namespace window_manager diff --git a/components/window_manager/window_manager_app.h b/components/window_manager/window_manager_app.h index 73c9c90..81a2e46 100644 --- a/components/window_manager/window_manager_app.h +++ b/components/window_manager/window_manager_app.h @@ -13,18 +13,14 @@ #include "components/view_manager/public/cpp/view_manager_client_factory.h" #include "components/view_manager/public/cpp/view_manager_delegate.h" #include "components/view_manager/public/cpp/view_observer.h" -#include "components/window_manager/capture_controller_observer.h" -#include "components/window_manager/focus_controller_observer.h" -#include "components/window_manager/native_viewport_event_dispatcher_impl.h" #include "components/window_manager/public/interfaces/window_manager_internal.mojom.h" -#include "components/window_manager/view_target.h" #include "components/window_manager/window_manager_impl.h" #include "third_party/mojo/src/mojo/public/cpp/application/application_delegate.h" #include "third_party/mojo/src/mojo/public/cpp/application/interface_factory_impl.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/string.h" -#include "ui/base/accelerators/accelerator_manager.h" -#include "ui/events/event_handler.h" +#include "ui/mojo/events/input_events.mojom.h" +#include "ui/mojo/events/input_key_codes.mojom.h" namespace gfx { class Size; @@ -32,10 +28,6 @@ class Size; namespace window_manager { -class CaptureController; -class FocusController; -class FocusRules; -class ViewEventDispatcher; class WindowManagerDelegate; class WindowManagerImpl; @@ -51,44 +43,27 @@ class WindowManagerApp : public mojo::ApplicationDelegate, public mojo::ViewManagerDelegate, public mojo::ViewObserver, - public ui::EventHandler, - public FocusControllerObserver, - public CaptureControllerObserver, public mojo::InterfaceFactory<mojo::WindowManager>, public mojo::InterfaceFactory<mojo::WindowManagerInternal>, - public mojo::InterfaceFactory<mojo::NativeViewportEventDispatcher>, public mojo::WindowManagerInternal { public: WindowManagerApp(ViewManagerDelegate* view_manager_delegate, WindowManagerDelegate* window_manager_delegate); ~WindowManagerApp() override; - ViewEventDispatcher* event_dispatcher() { - return view_event_dispatcher_.get(); - } - // Register/deregister new connections to the window manager service. void AddConnection(WindowManagerImpl* connection); void RemoveConnection(WindowManagerImpl* connection); - // These are canonical implementations of the window manager API methods. - bool SetCapture(mojo::Id view); - bool FocusWindow(mojo::Id view); - bool ActivateWindow(mojo::Id view); - - void DispatchInputEventToView(mojo::View* view, mojo::EventPtr event); + void DispatchInputEventToViewDEPRECATED(mojo::View* view, + mojo::EventPtr event); void SetViewportSize(const gfx::Size& size); bool IsReady() const; - FocusController* focus_controller() { return focus_controller_.get(); } - CaptureController* capture_controller() { return capture_controller_.get(); } - - void InitFocus(scoped_ptr<FocusRules> rules); - - ui::AcceleratorManager* accelerator_manager() { - return &accelerator_manager_; - } + void AddAccelerator(mojo::KeyboardCode keyboard_code, mojo::EventFlags flags); + void RemoveAccelerator(mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags); // WindowManagerImpl::Embed() forwards to this. If connected to ViewManager // then forwards to delegate, otherwise waits for connection to establish then @@ -105,55 +80,22 @@ class WindowManagerApp private: // TODO(sky): rename this. Connections is ambiguous. typedef std::set<WindowManagerImpl*> Connections; - typedef std::set<mojo::Id> RegisteredViewIdSet; struct PendingEmbed; - class WindowManagerInternalImpl; mojo::ViewManager* view_manager() { return root_ ? root_->view_manager() : nullptr; } - bool SetCaptureImpl(mojo::View* view); - bool FocusWindowImpl(mojo::View* view); - bool ActivateWindowImpl(mojo::View* view); - - ui::Accelerator ConvertEventToAccelerator(const ui::KeyEvent* event); - - // Creates an ViewTarget for every view in the hierarchy beneath |view|, - // and adds to the registry so that it can be retrieved later via - // GetViewTargetForViewId(). - // TODO(beng): perhaps View should have a property bag. - void RegisterSubtree(mojo::View* view); - - // Recursively invokes Unregister() for |view| and all its descendants. - void UnregisterSubtree(mojo::View* view); - - // Deletes the ViewTarget associated with the hierarchy beneath |id|, - // and removes from the registry. - void Unregister(mojo::View* view); - // Overridden from ViewManagerDelegate: void OnEmbed(mojo::View* root, mojo::InterfaceRequest<mojo::ServiceProvider> services, mojo::ServiceProviderPtr exposed_services) override; void OnViewManagerDisconnected(mojo::ViewManager* view_manager) override; - bool OnPerformAction(mojo::View* view, const std::string& action) override; // Overridden from ViewObserver: - void OnTreeChanged(const ViewObserver::TreeChangeParams& params) override; void OnViewDestroying(mojo::View* view) override; - // Overridden from ui::EventHandler: - void OnEvent(ui::Event* event) override; - - // Overridden from mojo::FocusControllerObserver: - void OnFocused(mojo::View* gained_focus) override; - void OnActivated(mojo::View* gained_active) override; - - // Overridden from mojo::CaptureControllerObserver: - void OnCaptureChanged(mojo::View* gained_capture) override; - // Creates the connection to the ViewManager. void LaunchViewManager(mojo::ApplicationImpl* app); @@ -166,17 +108,10 @@ class WindowManagerApp void Create(mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::WindowManager> request) override; - // InterfaceFactory<NativeViewportEventDispatcher>: - void Create(mojo::ApplicationConnection* connection, - mojo::InterfaceRequest<mojo::NativeViewportEventDispatcher> - request) override; - // WindowManagerInternal: - void CreateWindowManagerForViewManagerClient( - uint16_t connection_id, - mojo::ScopedMessagePipeHandle window_manager_pipe) override; void SetViewManagerClient( mojo::ScopedMessagePipeHandle view_manager_client_request) override; + void OnAccelerator(mojo::EventPtr event) override; mojo::Shell* shell_; @@ -185,15 +120,10 @@ class WindowManagerApp mojo::ViewManagerServicePtr view_manager_service_; scoped_ptr<mojo::ViewManagerClientFactory> view_manager_client_factory_; - mojo::View* root_; - - scoped_ptr<FocusController> focus_controller_; - scoped_ptr<CaptureController> capture_controller_; - ui::AcceleratorManager accelerator_manager_; + mojo::View* root_; Connections connections_; - RegisteredViewIdSet registered_view_id_set_; mojo::WindowManagerInternalClientPtr window_manager_client_; @@ -201,8 +131,6 @@ class WindowManagerApp scoped_ptr<mojo::ViewManagerClient> view_manager_client_; - scoped_ptr<ViewEventDispatcher> view_event_dispatcher_; - scoped_ptr<mojo::Binding<WindowManagerInternal>> wm_internal_binding_; DISALLOW_COPY_AND_ASSIGN(WindowManagerApp); diff --git a/components/window_manager/window_manager_app_android.cc b/components/window_manager/window_manager_app_android.cc deleted file mode 100644 index 3ec92c3..0000000 --- a/components/window_manager/window_manager_app_android.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/window_manager_app.h" - -#include <android/keycodes.h> - -#include "ui/events/keycodes/keyboard_codes_posix.h" - -namespace window_manager { - -ui::Accelerator WindowManagerApp::ConvertEventToAccelerator( - const ui::KeyEvent* event) { - if (event->platform_keycode() == AKEYCODE_BACK) - return ui::Accelerator(ui::VKEY_BROWSER_BACK, 0); - return ui::Accelerator(event->key_code(), event->flags()); -} - -} // namespace window_manager diff --git a/components/window_manager/window_manager_app_linux.cc b/components/window_manager/window_manager_app_linux.cc deleted file mode 100644 index effb54c..0000000 --- a/components/window_manager/window_manager_app_linux.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/window_manager_app.h" - -namespace window_manager { - -ui::Accelerator WindowManagerApp::ConvertEventToAccelerator( - const ui::KeyEvent* event) { - return ui::Accelerator(event->key_code(), event->flags()); -} - -} // namespace window_manager diff --git a/components/window_manager/window_manager_app_win.cc b/components/window_manager/window_manager_app_win.cc deleted file mode 100644 index effb54c..0000000 --- a/components/window_manager/window_manager_app_win.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/window_manager_app.h" - -namespace window_manager { - -ui::Accelerator WindowManagerApp::ConvertEventToAccelerator( - const ui::KeyEvent* event) { - return ui::Accelerator(event->key_code(), event->flags()); -} - -} // namespace window_manager diff --git a/components/window_manager/window_manager_apptest.cc b/components/window_manager/window_manager_apptest.cc index e32899b..f7915fd 100644 --- a/components/window_manager/window_manager_apptest.cc +++ b/components/window_manager/window_manager_apptest.cc @@ -57,24 +57,6 @@ class TestApplication : public ApplicationDelegate, public ViewManagerDelegate { MOJO_DISALLOW_COPY_AND_ASSIGN(TestApplication); }; -class TestWindowManagerObserver : public WindowManagerObserver { - public: - explicit TestWindowManagerObserver( - InterfaceRequest<WindowManagerObserver> observer_request) - : binding_(this, observer_request.Pass()) {} - ~TestWindowManagerObserver() override {} - - private: - // Overridden from WindowManagerClient: - void OnCaptureChanged(Id new_capture_node_id) override {} - void OnFocusChanged(Id focused_node_id) override {} - void OnActiveWindowChanged(Id active_window) override {} - - Binding<WindowManagerObserver> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestWindowManagerObserver); -}; - class WindowManagerApplicationTest : public test::ApplicationTestBase { public: WindowManagerApplicationTest() {} @@ -112,101 +94,5 @@ TEST_F(WindowManagerApplicationTest, Embed) { EXPECT_NE(nullptr, test_application_.root()); } -struct BoolCallback { - BoolCallback(bool* bool_value, base::RunLoop* run_loop) - : bool_value(bool_value), run_loop(run_loop) {} - - void Run(bool value) const { - *bool_value = value; - run_loop->Quit(); - } - - bool* bool_value; - base::RunLoop* run_loop; -}; - -TEST_F(WindowManagerApplicationTest, SetCaptureFailsFromNonVM) { - EmbedApplicationWithURL(application_impl()->url()); - bool callback_value = true; - base::RunLoop run_loop; - window_manager_->SetCapture(test_application_.root()->id(), - BoolCallback(&callback_value, &run_loop)); - run_loop.Run(); - // This call only succeeds for WindowManager connections from the ViewManager. - EXPECT_FALSE(callback_value); -} - -TEST_F(WindowManagerApplicationTest, FocusWindowFailsFromNonVM) { - EmbedApplicationWithURL(application_impl()->url()); - bool callback_value = true; - base::RunLoop run_loop; - window_manager_->FocusWindow(test_application_.root()->id(), - BoolCallback(&callback_value, &run_loop)); - run_loop.Run(); - // This call only succeeds for WindowManager connections from the ViewManager. - EXPECT_FALSE(callback_value); -} - -TEST_F(WindowManagerApplicationTest, ActivateWindowFailsFromNonVM) { - EmbedApplicationWithURL(application_impl()->url()); - bool callback_value = true; - base::RunLoop run_loop; - window_manager_->ActivateWindow(test_application_.root()->id(), - BoolCallback(&callback_value, &run_loop)); - run_loop.Run(); - // This call only succeeds for WindowManager connections from the ViewManager. - EXPECT_FALSE(callback_value); -} - -struct FocusedAndActiveViewsCallback { - FocusedAndActiveViewsCallback(uint32* capture_view_id, - uint32* focused_view_id, - uint32* active_view_id, - base::RunLoop* run_loop) - : capture_view_id(capture_view_id), - focused_view_id(focused_view_id), - active_view_id(active_view_id), - run_loop(run_loop) { - } - - void Run(uint32 capture, uint32 focused, uint32 active) const { - *capture_view_id = capture; - *focused_view_id = focused; - *active_view_id = active; - run_loop->Quit(); - } - - uint32* capture_view_id; - uint32* focused_view_id; - uint32* active_view_id; - base::RunLoop* run_loop; -}; - -TEST_F(WindowManagerApplicationTest, GetFocusedAndActiveViewsFailsWithoutFC) { - EmbedApplicationWithURL(application_impl()->url()); - uint32 capture_view_id = static_cast<uint32>(-1); - uint32 focused_view_id = static_cast<uint32>(-1); - uint32 active_view_id = static_cast<uint32>(-1); - base::RunLoop run_loop; - - WindowManagerObserverPtr observer; - scoped_ptr<TestWindowManagerObserver> window_manager_observer( - new TestWindowManagerObserver(GetProxy(&observer))); - - window_manager_->GetFocusedAndActiveViews( - observer.Pass(), - FocusedAndActiveViewsCallback(&capture_view_id, - &focused_view_id, - &active_view_id, - &run_loop)); - run_loop.Run(); - // This call fails if the WindowManager does not have a FocusController. - EXPECT_EQ(0u, capture_view_id); - EXPECT_EQ(0u, focused_view_id); - EXPECT_EQ(0u, active_view_id); -} - -// TODO(msw): Write tests exercising other WindowManager functionality. - } // namespace } // namespace mojo diff --git a/components/window_manager/window_manager_delegate.h b/components/window_manager/window_manager_delegate.h index bbfeefe..71e154c 100644 --- a/components/window_manager/window_manager_delegate.h +++ b/components/window_manager/window_manager_delegate.h @@ -7,6 +7,8 @@ #include "third_party/mojo/src/mojo/public/cpp/bindings/string.h" #include "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom.h" +#include "ui/mojo/events/input_events.mojom.h" +#include "ui/mojo/events/input_key_codes.mojom.h" namespace window_manager { @@ -17,6 +19,10 @@ class WindowManagerDelegate { mojo::InterfaceRequest<mojo::ServiceProvider> services, mojo::ServiceProviderPtr exposed_services) = 0; + virtual void OnAcceleratorPressed(mojo::View* view, + mojo::KeyboardCode keyboard_code, + mojo::EventFlags flags) {} + protected: virtual ~WindowManagerDelegate() {} }; diff --git a/components/window_manager/window_manager_impl.cc b/components/window_manager/window_manager_impl.cc index 11e4658..9e0a165 100644 --- a/components/window_manager/window_manager_impl.cc +++ b/components/window_manager/window_manager_impl.cc @@ -4,14 +4,8 @@ #include "components/window_manager/window_manager_impl.h" -#include "components/view_manager/public/cpp/view.h" -#include "components/window_manager/capture_controller.h" -#include "components/window_manager/focus_controller.h" #include "components/window_manager/window_manager_app.h" -using mojo::Callback; -using mojo::Id; - namespace window_manager { WindowManagerImpl::WindowManagerImpl(WindowManagerApp* window_manager, @@ -30,21 +24,6 @@ void WindowManagerImpl::Bind( binding_.Bind(window_manager_pipe.Pass()); } -void WindowManagerImpl::NotifyViewFocused(Id focused_id) { - if (from_vm_ && observer_) - observer_->OnFocusChanged(focused_id); -} - -void WindowManagerImpl::NotifyWindowActivated(Id active_id) { - if (from_vm_ && observer_) - observer_->OnActiveWindowChanged(active_id); -} - -void WindowManagerImpl::NotifyCaptureChanged(Id capture_id) { - if (from_vm_ && observer_) - observer_->OnCaptureChanged(capture_id); -} - void WindowManagerImpl::Embed( const mojo::String& url, mojo::InterfaceRequest<mojo::ServiceProvider> services, @@ -52,45 +31,6 @@ void WindowManagerImpl::Embed( window_manager_->Embed(url, services.Pass(), exposed_services.Pass()); } -void WindowManagerImpl::SetCapture(Id view, - const Callback<void(bool)>& callback) { - callback.Run(from_vm_ && window_manager_->IsReady() && - window_manager_->SetCapture(view)); -} - -void WindowManagerImpl::FocusWindow(Id view, - const Callback<void(bool)>& callback) { - callback.Run(from_vm_ && window_manager_->IsReady() && - window_manager_->FocusWindow(view)); -} - -void WindowManagerImpl::ActivateWindow(Id view, - const Callback<void(bool)>& callback) { - callback.Run(from_vm_ && window_manager_->IsReady() && - window_manager_->ActivateWindow(view)); -} - -void WindowManagerImpl::GetFocusedAndActiveViews( - mojo::WindowManagerObserverPtr observer, - const mojo::WindowManager::GetFocusedAndActiveViewsCallback& callback) { - observer_ = observer.Pass(); - if (!window_manager_->focus_controller()) { - // TODO(sky): add typedef for 0. - callback.Run(0, 0, 0); - return; - } - mojo::View* capture_view = - window_manager_->capture_controller()->GetCapture(); - mojo::View* active_view = - window_manager_->focus_controller()->GetActiveView(); - mojo::View* focused_view = - window_manager_->focus_controller()->GetFocusedView(); - // TODO(sky): sanitize ids for client. - callback.Run(capture_view ? capture_view->id() : 0, - focused_view ? focused_view->id() : 0, - active_view ? active_view->id() : 0); -} - void WindowManagerImpl::OnConnectionError() { delete this; } diff --git a/components/window_manager/window_manager_impl.h b/components/window_manager/window_manager_impl.h index 826831f..0ee6f88 100644 --- a/components/window_manager/window_manager_impl.h +++ b/components/window_manager/window_manager_impl.h @@ -27,25 +27,11 @@ class WindowManagerImpl : public mojo::WindowManager, void Bind(mojo::ScopedMessagePipeHandle window_manager_pipe); - void NotifyViewFocused(mojo::Id focused_id); - void NotifyWindowActivated(mojo::Id active_id); - void NotifyCaptureChanged(mojo::Id capture_id); - private: // mojo::WindowManager: void Embed(const mojo::String& url, mojo::InterfaceRequest<mojo::ServiceProvider> services, mojo::ServiceProviderPtr exposed_services) override; - void SetCapture(uint32_t view_id, - const mojo::Callback<void(bool)>& callback) override; - void FocusWindow(uint32_t view_id, - const mojo::Callback<void(bool)>& callback) override; - void ActivateWindow(uint32_t view_id, - const mojo::Callback<void(bool)>& callback) override; - void GetFocusedAndActiveViews( - mojo::WindowManagerObserverPtr observer, - const mojo::WindowManager::GetFocusedAndActiveViewsCallback& callback) - override; // mojo::ErrorHandler: void OnConnectionError() override; @@ -58,7 +44,6 @@ class WindowManagerImpl : public mojo::WindowManager, const bool from_vm_; mojo::Binding<mojo::WindowManager> binding_; - mojo::WindowManagerObserverPtr observer_; DISALLOW_COPY_AND_ASSIGN(WindowManagerImpl); }; diff --git a/components/window_manager/window_manager_test_util.cc b/components/window_manager/window_manager_test_util.cc deleted file mode 100644 index e1b6ca0..0000000 --- a/components/window_manager/window_manager_test_util.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/window_manager/window_manager_test_util.h" - -#include "base/stl_util.h" -#include "mojo/converters/geometry/geometry_type_converters.h" -#include "ui/gfx/geometry/rect.h" - -namespace window_manager { - -TestView::TestView(int id, const gfx::Rect& rect) - : target_(new ViewTarget(this)) { - mojo::ViewPrivate(this).set_id(id); - - mojo::Rect mojo_rect = *mojo::Rect::From(rect); - SetBounds(mojo_rect); -} - -TestView::TestView(int id, const gfx::Rect& rect, View* parent) - : TestView(id, rect) { - parent->AddChild(this); -} - -TestView::~TestView() { -} - -// static -TestView* TestView::Build(int id, const gfx::Rect& rect) { - return new TestView(id, rect); -} - -// static -TestView* TestView::Build(int id, const gfx::Rect& rect, mojo::View* parent) { - return new TestView(id, rect, parent); -} - -} // namespace window_manager diff --git a/components/window_manager/window_manager_test_util.h b/components/window_manager/window_manager_test_util.h deleted file mode 100644 index 579cc4f..0000000 --- a/components/window_manager/window_manager_test_util.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_WINDOW_MANAGER_WINDOW_MANAGER_TEST_UTIL_H_ -#define COMPONENTS_WINDOW_MANAGER_WINDOW_MANAGER_TEST_UTIL_H_ - -#include <set> - -#include "components/view_manager/public/cpp/lib/view_private.h" -#include "components/view_manager/public/cpp/view.h" -#include "components/window_manager/view_target.h" - -namespace gfx { -class Rect; -} - -namespace window_manager { - -// A wrapper around View so we can instantiate these directly without a -// ViewManager. -class TestView : public mojo::View { - public: - TestView(int id, const gfx::Rect& rect); - TestView(int id, const gfx::Rect& rect, mojo::View* parent); - ~TestView(); - - // Builds a child view as a pointer. The caller is responsible for making - // sure that the root of any tree allocated this way is Destroy()ed. - static TestView* Build(int id, const gfx::Rect& rect); - static TestView* Build(int id, const gfx::Rect& rect, View* parent); - - ViewTarget* target() { return target_; } - - private: - ViewTarget* target_; - - DISALLOW_COPY_AND_ASSIGN(TestView); -}; - -} // namespace window_manager - -#endif // COMPONENTS_WINDOW_MANAGER_WINDOW_MANAGER_TEST_UTIL_H_ |