Adds capture to the mojo window_manager. This adds a CaptureController which manages capture, puts a checkbox that makes a window have capture in the wm_flow demo, and ports the relevant unit tests for FocusController. BUG=442545 R=sky@chromium.org Review URL: https://codereview.chromium.org/805123003
diff --git a/examples/wm_flow/wm/frame_controller.cc b/examples/wm_flow/wm/frame_controller.cc index e391f42..acf608c 100644 --- a/examples/wm_flow/wm/frame_controller.cc +++ b/examples/wm_flow/wm/frame_controller.cc
@@ -9,8 +9,10 @@ #include "mojo/converters/geometry/geometry_type_converters.h" #include "mojo/services/view_manager/public/cpp/view.h" #include "mojo/views/native_widget_mojo.h" +#include "services/window_manager/capture_controller.h" #include "services/window_manager/window_manager_app.h" #include "ui/views/background.h" +#include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/layout/layout_manager.h" #include "ui/views/widget/widget.h" @@ -21,10 +23,14 @@ public: explicit LayoutManager(FrameController* controller) : controller_(controller), + capture_checkbox_( + new views::Checkbox(base::ASCIIToUTF16("Capture"))), close_button_( new views::LabelButton(this, base::ASCIIToUTF16("Begone"))), maximize_button_( - new views::LabelButton(this, base::ASCIIToUTF16("Embiggen"))) {} + new views::LabelButton(this, base::ASCIIToUTF16("Embiggen"))) { + capture_checkbox_->set_listener(this); + } virtual ~LayoutManager() {} private: @@ -34,11 +40,16 @@ // Overridden from views::LayoutManager: virtual void Installed(views::View* host) override { + host->AddChildView(capture_checkbox_); host->AddChildView(close_button_); host->AddChildView(maximize_button_); } virtual void Layout(views::View* host) override { - gfx::Size ps = close_button_->GetPreferredSize(); + gfx::Size ps = capture_checkbox_->GetPreferredSize(); + capture_checkbox_->SetBounds(kButtonFrameMargin, kButtonFrameMargin, + ps.width(), ps.height()); + + ps = close_button_->GetPreferredSize(); gfx::Rect bounds = host->GetLocalBounds(); close_button_->SetBounds(bounds.right() - kButtonFrameMargin - ps.width(), kButtonFrameMargin, ps.width(), ps.height()); @@ -64,9 +75,12 @@ controller_->CloseWindow(); else if (sender == maximize_button_) controller_->ToggleMaximize(); + else if (sender == capture_checkbox_) + controller_->SetCapture(capture_checkbox_->checked()); } FrameController* controller_; + views::Checkbox* capture_checkbox_; views::Button* close_button_; views::Button* maximize_button_; @@ -146,6 +160,13 @@ window_manager_app_->focus_controller()->ActivateView(view_); } +void FrameController::SetCapture(bool frame_has_capture) { + if (frame_has_capture) + window_manager_app_->capture_controller()->SetCapture(view_); + else + window_manager_app_->capture_controller()->ReleaseCapture(view_); +} + //////////////////////////////////////////////////////////////////////////////// // FrameController, mojo::ViewObserver implementation:
diff --git a/examples/wm_flow/wm/frame_controller.h b/examples/wm_flow/wm/frame_controller.h index 440761d..5d6bdf4 100644 --- a/examples/wm_flow/wm/frame_controller.h +++ b/examples/wm_flow/wm/frame_controller.h
@@ -41,6 +41,8 @@ void ActivateWindow(); + void SetCapture(bool frame_has_capture); + private: class LayoutManager; friend class LayoutManager;
diff --git a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc index 3ebb4c7..a51e234 100644 --- a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc +++ b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc
@@ -100,6 +100,7 @@ next_id_(1), delegate_(delegate), root_(nullptr), + capture_view_(nullptr), focused_view_(nullptr), activated_view_(nullptr), binding_(this, handle.Pass()), @@ -381,7 +382,21 @@ // ViewManagerClientImpl, WindowManagerClient implementation: void ViewManagerClientImpl::OnCaptureChanged(Id old_capture_view_id, - Id new_capture_view_id) {} + Id new_capture_view_id) { + View* gained_capture = GetViewById(new_capture_view_id); + View* lost_capture = GetViewById(old_capture_view_id); + 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 old_focused_view_id, Id new_focused_view_id) {
diff --git a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h index 2ed83f8..91e4358 100644 --- a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h +++ b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h
@@ -152,6 +152,7 @@ IdToViewMap views_; + View* capture_view_; View* focused_view_; View* activated_view_;
diff --git a/mojo/services/view_manager/public/cpp/view.h b/mojo/services/view_manager/public/cpp/view.h index 8569616..d3c6292 100644 --- a/mojo/services/view_manager/public/cpp/view.h +++ b/mojo/services/view_manager/public/cpp/view.h
@@ -103,6 +103,9 @@ View* parent() { return parent_; } const View* parent() const { return parent_; } const Children& children() const { return children_; } + View* GetRoot() { + return const_cast<View*>(const_cast<const View*>(this)->GetRoot()); + } const View* GetRoot() const; void AddChild(View* child);
diff --git a/mojo/services/view_manager/public/cpp/view_observer.h b/mojo/services/view_manager/public/cpp/view_observer.h index b6b1a70..4f49fbd 100644 --- a/mojo/services/view_manager/public/cpp/view_observer.h +++ b/mojo/services/view_manager/public/cpp/view_observer.h
@@ -56,6 +56,7 @@ const Rect& old_bounds, const Rect& new_bounds) {} + virtual void OnCaptureChanged(View* gained_capture, View* lost_capture) {} virtual void OnViewFocusChanged(View* gained_focus, View* lost_focus) {} virtual void OnViewActivationChanged(View* gained_active, View* lost_active) { }
diff --git a/services/window_manager/BUILD.gn b/services/window_manager/BUILD.gn index afc86f3..1affe54 100644 --- a/services/window_manager/BUILD.gn +++ b/services/window_manager/BUILD.gn
@@ -26,6 +26,9 @@ 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",
diff --git a/services/window_manager/capture_controller.cc b/services/window_manager/capture_controller.cc new file mode 100644 index 0000000..227d92f --- /dev/null +++ b/services/window_manager/capture_controller.cc
@@ -0,0 +1,105 @@ +// 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 "services/window_manager/capture_controller.h" + +#include "mojo/services/view_manager/public/cpp/view_property.h" +#include "mojo/services/view_manager/public/cpp/view_tracker.h" +#include "services/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, + view_tracker.Contains(old_capture) ? old_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/services/window_manager/capture_controller.h b/services/window_manager/capture_controller.h new file mode 100644 index 0000000..dc495f5 --- /dev/null +++ b/services/window_manager/capture_controller.h
@@ -0,0 +1,49 @@ +// 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 SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_ +#define SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_ + +#include "base/observer_list.h" +#include "mojo/services/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 // SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_H_
diff --git a/services/window_manager/capture_controller_observer.h b/services/window_manager/capture_controller_observer.h new file mode 100644 index 0000000..ba3ec3b --- /dev/null +++ b/services/window_manager/capture_controller_observer.h
@@ -0,0 +1,21 @@ +// 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 SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_ +#define SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_ + +namespace window_manager { + +class CaptureControllerObserver { + public: + virtual void OnCaptureChanged(mojo::View* gained_capture, + mojo::View* lost_capture) = 0; + + protected: + virtual ~CaptureControllerObserver() {} +}; + +} // namespace window_manager + +#endif // SERVICES_WINDOW_MANAGER_CAPTURE_CONTROLLER_OBSERVER_H_
diff --git a/services/window_manager/focus_controller.cc b/services/window_manager/focus_controller.cc index ba6454a..e58dca8 100644 --- a/services/window_manager/focus_controller.cc +++ b/services/window_manager/focus_controller.cc
@@ -74,9 +74,6 @@ return; } - // TODO(erg): We need to early abort in the of a view having - // capture. However, we currently don't have a capture client here. - // 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);
diff --git a/services/window_manager/focus_controller.h b/services/window_manager/focus_controller.h index f212123..20f966e 100644 --- a/services/window_manager/focus_controller.h +++ b/services/window_manager/focus_controller.h
@@ -93,7 +93,7 @@ DISALLOW_COPY_AND_ASSIGN(FocusController); }; -// Sets/Gets the focus controller for a root view. +// Sets/Gets the focus controller for a view. void SetFocusController(mojo::View* view, FocusController* focus_controller); FocusController* GetFocusController(mojo::View* view);
diff --git a/services/window_manager/focus_controller_unittest.cc b/services/window_manager/focus_controller_unittest.cc index 13e841d..7dacf03 100644 --- a/services/window_manager/focus_controller_unittest.cc +++ b/services/window_manager/focus_controller_unittest.cc
@@ -6,6 +6,7 @@ #include "mojo/converters/geometry/geometry_type_converters.h" #include "services/window_manager/basic_focus_rules.h" +#include "services/window_manager/capture_controller.h" #include "services/window_manager/focus_controller_observer.h" #include "services/window_manager/view_event_dispatcher.h" #include "services/window_manager/view_targeter.h" @@ -347,6 +348,10 @@ 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())); @@ -362,6 +367,7 @@ root_view_->Destroy(); + capture_controller_.reset(); test_focus_rules_ = nullptr; // Owned by FocusController. focus_controller_.reset(); @@ -410,6 +416,7 @@ 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; @@ -427,9 +434,7 @@ virtual void ShiftFocusOnActivation() {} virtual void ShiftFocusOnActivationDueToHide() {} virtual void NoShiftActiveOnActivation() {} - // TODO(erg): void NoFocusChangeOnClickOnCaptureWindow() once we have a - // system of capture. - // TODO(erg): Also, void ChangeFocusWhenNothingFocusedAndCaptured(). + virtual void ChangeFocusWhenNothingFocusedAndCaptured() {} virtual void DontPassDestroyedView() {} // TODO(erg): Also, void FocusedTextInputClient() once we build the IME. @@ -437,6 +442,7 @@ 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? @@ -723,7 +729,21 @@ // from being made in response to an activation change notification. } - // TODO(erg): Port the capture tests here, once we have a capture mechanism. + // 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. @@ -1122,7 +1142,8 @@ DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide); DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation); -// TODO(erg): Add the capture tests here. +FOCUS_CONTROLLER_TEST(FocusControllerApiTest, + ChangeFocusWhenNothingFocusedAndCaptured); // See description above DontPassDestroyedView() for details. FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDestroyedView);
diff --git a/services/window_manager/view_targeter.cc b/services/window_manager/view_targeter.cc index ab822ff..5a2de7b 100644 --- a/services/window_manager/view_targeter.cc +++ b/services/window_manager/view_targeter.cc
@@ -4,6 +4,7 @@ #include "services/window_manager/view_targeter.h" +#include "services/window_manager/capture_controller.h" #include "services/window_manager/focus_controller.h" #include "services/window_manager/view_target.h" @@ -85,8 +86,12 @@ // mouse_pressed_handler() in the aura version. This is what makes sure // that a view gets both the mouse down and up. - // TODO(erg): We redirect to a currently active capture window here. Add this - // when we have capture working. + CaptureController* capture_controller = + GetCaptureController(root_view->view()); + DCHECK(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.
diff --git a/services/window_manager/view_targeter_unittest.cc b/services/window_manager/view_targeter_unittest.cc index a55ef75..298ce27 100644 --- a/services/window_manager/view_targeter_unittest.cc +++ b/services/window_manager/view_targeter_unittest.cc
@@ -5,6 +5,7 @@ #include "services/window_manager/view_targeter.h" #include "services/window_manager/basic_focus_rules.h" +#include "services/window_manager/capture_controller.h" #include "services/window_manager/focus_controller.h" #include "services/window_manager/view_event_dispatcher.h" #include "services/window_manager/window_manager_test_util.h" @@ -41,6 +42,9 @@ 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)); @@ -68,6 +72,9 @@ 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));
diff --git a/services/window_manager/window_manager_app.cc b/services/window_manager/window_manager_app.cc index 023af5f..2c25e2b 100644 --- a/services/window_manager/window_manager_app.cc +++ b/services/window_manager/window_manager_app.cc
@@ -13,6 +13,7 @@ #include "mojo/public/interfaces/application/shell.mojom.h" #include "mojo/services/view_manager/public/cpp/view.h" #include "mojo/services/view_manager/public/cpp/view_manager.h" +#include "services/window_manager/capture_controller.h" #include "services/window_manager/focus_controller.h" #include "services/window_manager/focus_rules.h" #include "services/window_manager/view_event_dispatcher.h" @@ -72,13 +73,10 @@ connections_.erase(connection); } -void WindowManagerApp::SetCapture(Id view) { - // TODO(erg): Capture. Another pile of worms that is mixed in here. - - // capture_client_->capture_client()->SetCapture(GetWindowForViewId(view)); - - // TODO(beng): notify connected clients that capture has changed, probably - // by implementing some capture-client observer. +void WindowManagerApp::SetCapture(Id view_id) { + View* view = view_manager_->GetViewById(view_id); + DCHECK(view); + capture_controller_->SetCapture(view); } void WindowManagerApp::FocusWindow(Id view_id) { @@ -98,11 +96,15 @@ } void WindowManagerApp::InitFocus(scoped_ptr<FocusRules> rules) { + DCHECK(root_); + focus_controller_.reset(new FocusController(rules.Pass())); focus_controller_->AddObserver(this); - - DCHECK(root_); SetFocusController(root_, focus_controller_.get()); + + capture_controller_.reset(new CaptureController); + capture_controller_->AddObserver(this); + SetCaptureController(root_, capture_controller_.get()); } void WindowManagerApp::Embed( @@ -147,11 +149,6 @@ RegisterSubtree(root_); - // TODO(erg): Also move the capture client over. - // - // capture_client_.reset( - // new wm::ScopedCaptureClient(window_tree_host_->window())); - if (wrapped_view_manager_delegate_) { wrapped_view_manager_delegate_->OnEmbed( view_manager, root, exported_services, imported_services.Pass()); @@ -203,6 +200,8 @@ root_ = nullptr; if (focus_controller_) focus_controller_->RemoveObserver(this); + if (capture_controller_) + capture_controller_->RemoveObserver(this); } //////////////////////////////////////////////////////////////////////////////// @@ -247,6 +246,20 @@ } //////////////////////////////////////////////////////////////////////////////// +// WindowManagerApp, mojo::CaptureControllerObserver implementation: + +void WindowManagerApp::OnCaptureChanged(View* gained_capture, + View* lost_capture) { + for (Connections::const_iterator it = connections_.begin(); + it != connections_.end(); ++it) { + (*it)->NotifyCaptureChanged(GetIdForView(gained_capture), + GetIdForView(lost_capture)); + } + if (gained_capture) + gained_capture->MoveToFront(); +} + +//////////////////////////////////////////////////////////////////////////////// // WindowManagerApp, private: void WindowManagerApp::RegisterSubtree(View* view) {
diff --git a/services/window_manager/window_manager_app.h b/services/window_manager/window_manager_app.h index 5a97037..e866c38 100644 --- a/services/window_manager/window_manager_app.h +++ b/services/window_manager/window_manager_app.h
@@ -18,6 +18,7 @@ #include "mojo/services/view_manager/public/cpp/view_manager_delegate.h" #include "mojo/services/view_manager/public/cpp/view_observer.h" #include "mojo/services/window_manager/public/interfaces/window_manager_internal.mojom.h" +#include "services/window_manager/capture_controller_observer.h" #include "services/window_manager/focus_controller_observer.h" #include "services/window_manager/native_viewport_event_dispatcher_impl.h" #include "services/window_manager/view_target.h" @@ -30,6 +31,7 @@ namespace window_manager { +class CaptureController; class FocusController; class FocusRules; class ViewEventDispatcher; @@ -51,6 +53,7 @@ public mojo::ViewObserver, public ui::EventHandler, public FocusControllerObserver, + public CaptureControllerObserver, public mojo::InterfaceFactory<mojo::WindowManager>, public mojo::InterfaceFactory<mojo::WindowManagerInternal>, public mojo::WindowManagerInternal { @@ -78,6 +81,7 @@ bool IsReady() const; FocusController* focus_controller() { return focus_controller_.get(); } + CaptureController* capture_controller() { return capture_controller_.get(); } void InitFocus(scoped_ptr<FocusRules> rules); @@ -132,6 +136,10 @@ void OnViewActivated(mojo::View* gained_active, mojo::View* lost_active) override; + // Overridden from mojo::CaptureControllerObserver: + void OnCaptureChanged(mojo::View* gained_capture, + mojo::View* lost_capture) override; + // Creates the connection to the ViewManager. void LaunchViewManager(mojo::ApplicationImpl* app); @@ -163,6 +171,7 @@ mojo::View* root_; scoped_ptr<FocusController> focus_controller_; + scoped_ptr<CaptureController> capture_controller_; Connections connections_; RegisteredViewIdSet registered_view_id_set_;
diff --git a/services/window_manager/window_manager_impl.cc b/services/window_manager/window_manager_impl.cc index 2af9ffe..1cba820 100644 --- a/services/window_manager/window_manager_impl.cc +++ b/services/window_manager/window_manager_impl.cc
@@ -41,6 +41,12 @@ client()->OnActiveWindowChanged(old_active_id, new_active_id); } +void WindowManagerImpl::NotifyCaptureChanged(Id new_capture_id, + Id old_capture_id) { + if (from_vm_) + client()->OnCaptureChanged(old_capture_id, new_capture_id); +} + void WindowManagerImpl::Embed( const mojo::String& url, mojo::InterfaceRequest<mojo::ServiceProvider> service_provider) {
diff --git a/services/window_manager/window_manager_impl.h b/services/window_manager/window_manager_impl.h index 3b010cc..f433378 100644 --- a/services/window_manager/window_manager_impl.h +++ b/services/window_manager/window_manager_impl.h
@@ -29,6 +29,7 @@ void NotifyViewFocused(mojo::Id new_focused_id, mojo::Id old_focused_id); void NotifyWindowActivated(mojo::Id new_active_id, mojo::Id old_active_id); + void NotifyCaptureChanged(mojo::Id new_capture_id, mojo::Id old_capture_id); private: mojo::WindowManagerClient* client() {