From d102d04d237761cb414e253504e8bee4a0decd36 Mon Sep 17 00:00:00 2001 From: sky Date: Tue, 30 Sep 2014 17:43:06 -0700 Subject: [PATCH] Fixes two bugs in causing demo_launcher to crash . MoveToFront/Back triggered a DCHECK. Made them early out if view already in position. . Called WindowManagerApp::InitFocus so that we don't crash when WM::SetFocus is called. BUG=none TEST=none R=ben@chromium.org Review URL: https://codereview.chromium.org/615233003 Cr-Commit-Position: refs/heads/master@{#297559} --- mojo/examples/window_manager/BUILD.gn | 1 + mojo/examples/window_manager/DEPS | 1 + .../examples/window_manager/window_manager.cc | 62 +++++++++++++++++++ mojo/mojo_examples.gypi | 1 + .../public/cpp/view_manager/lib/view.cc | 4 ++ 5 files changed, 69 insertions(+) diff --git a/mojo/examples/window_manager/BUILD.gn b/mojo/examples/window_manager/BUILD.gn index 2d55368b8c8b5..8c89c04b7bae8 100644 --- a/mojo/examples/window_manager/BUILD.gn +++ b/mojo/examples/window_manager/BUILD.gn @@ -42,6 +42,7 @@ shared_library("window_manager") { "//ui/gl", "//ui/resources", "//ui/views", + "//ui/wm", ] } diff --git a/mojo/examples/window_manager/DEPS b/mojo/examples/window_manager/DEPS index bfc0d9fa05897..372b6a82677cc 100644 --- a/mojo/examples/window_manager/DEPS +++ b/mojo/examples/window_manager/DEPS @@ -3,4 +3,5 @@ include_rules = [ "+ui/events", "+ui/gfx", "+ui/views", + "+ui/wm/core", ] diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc index 992407182f392..83c96ce33cbbf 100644 --- a/mojo/examples/window_manager/window_manager.cc +++ b/mojo/examples/window_manager/window_manager.cc @@ -29,6 +29,7 @@ #include "ui/events/event.h" #include "ui/events/event_constants.h" #include "ui/gfx/geometry/size_conversions.h" +#include "ui/wm/core/focus_rules.h" #if defined CreateWindow #undef CreateWindow @@ -45,6 +46,64 @@ const int kBorderInset = 25; const int kControlPanelWidth = 200; const int kTextfieldHeight = 25; +class WMFocusRules : public wm::FocusRules { + public: + WMFocusRules(mojo::WindowManagerApp* window_manager_app, + mojo::View* window_container) + : window_container_(window_container), + window_manager_app_(window_manager_app) {} + virtual ~WMFocusRules() {} + + private: + // Overridden from wm::FocusRules: + virtual bool IsToplevelWindow(aura::Window* window) const override { + return mojo::WindowManagerApp::GetViewForWindow(window)->parent() == + window_container_; + } + virtual bool CanActivateWindow(aura::Window* window) const override { + return mojo::WindowManagerApp::GetViewForWindow(window)->parent() == + window_container_; + } + virtual bool CanFocusWindow(aura::Window* window) const override { + return true; + } + virtual aura::Window* GetToplevelWindow(aura::Window* window) const override { + mojo::View* view = mojo::WindowManagerApp::GetViewForWindow(window); + while (view->parent() != window_container_) { + view = view->parent(); + // Unparented hierarchy, there is no "top level" window. + if (!view) + return NULL; + } + + return window_manager_app_->GetWindowForViewId(view->id()); + } + virtual aura::Window* GetActivatableWindow( + aura::Window* window) const override { + return GetToplevelWindow(window); + } + virtual aura::Window* GetFocusableWindow( + aura::Window* window) const override { + return window; + } + virtual aura::Window* GetNextActivatableWindow( + aura::Window* ignore) const override { + aura::Window* activatable = GetActivatableWindow(ignore); + const aura::Window::Windows& children = activatable->parent()->children(); + for (aura::Window::Windows::const_reverse_iterator it = children.rbegin(); + it != children.rend(); ++it) { + if (*it != ignore) + return *it; + } + return NULL; + } + + mojo::View* window_container_; + mojo::WindowManagerApp* window_manager_app_; + + DISALLOW_COPY_AND_ASSIGN(WMFocusRules); +}; + } // namespace class WindowManagerConnection : public InterfaceImpl { @@ -385,6 +444,9 @@ class WindowManager root->AddObserver(root_layout_manager_.get()); window_manager_app_->host()->window()->AddPreTargetHandler(this); + + window_manager_app_->InitFocus(new WMFocusRules(window_manager_app_.get(), + view)); } virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { DCHECK_EQ(view_manager_, view_manager); diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi index 359dfc9ec97e5..b863a39d4678f 100644 --- a/mojo/mojo_examples.gypi +++ b/mojo/mojo_examples.gypi @@ -668,6 +668,7 @@ '../ui/resources/ui_resources.gyp:ui_resources', '../ui/resources/ui_resources.gyp:ui_test_pak', '../ui/views/views.gyp:views', + '../ui/wm/wm.gyp:wm', 'mojo_base.gyp:mojo_application_chromium', 'mojo_base.gyp:mojo_cpp_bindings', 'mojo_base.gyp:mojo_utility', diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc index c3bf63a750824..82b6d11e9e981 100644 --- a/mojo/services/public/cpp/view_manager/lib/view.cc +++ b/mojo/services/public/cpp/view_manager/lib/view.cc @@ -256,10 +256,14 @@ void View::RemoveChild(View* child) { } void View::MoveToFront() { + if (!parent_ || parent_->children_.back() == this) + return; Reorder(parent_->children_.back(), ORDER_DIRECTION_ABOVE); } void View::MoveToBack() { + if (!parent_ || parent_->children_.front() == this) + return; Reorder(parent_->children_.front(), ORDER_DIRECTION_BELOW); }