diff options
-rw-r--r-- | ash/ash.gyp | 1 | ||||
-rw-r--r-- | ash/wm/panels/panel_layout_manager.cc | 6 | ||||
-rw-r--r-- | ash/wm/root_window_layout_manager.cc | 14 | ||||
-rw-r--r-- | ash/wm/root_window_layout_manager_unittest.cc | 46 | ||||
-rw-r--r-- | ui/aura/test/test_windows.cc | 2 | ||||
-rw-r--r-- | ui/aura/window_tracker.cc | 30 | ||||
-rw-r--r-- | ui/aura/window_tracker.h | 16 | ||||
-rw-r--r-- | ui/wm/core/transient_window_manager.cc | 12 |
8 files changed, 95 insertions, 32 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 6686402..1dd7430 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -908,6 +908,7 @@ 'wm/panels/panel_layout_manager_unittest.cc', 'wm/panels/panel_window_resizer_unittest.cc', 'wm/resize_shadow_and_cursor_unittest.cc', + 'wm/root_window_layout_manager_unittest.cc', 'wm/screen_dimmer_unittest.cc', 'wm/session_state_animator_impl_unittest.cc', 'wm/stacking_controller_unittest.cc', diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc index 8e59a7f..412a8d1 100644 --- a/ash/wm/panels/panel_layout_manager.cc +++ b/ash/wm/panels/panel_layout_manager.cc @@ -545,9 +545,9 @@ void PanelLayoutManager::WillChangeVisibilityState( if (restore_windows_on_shelf_visible_) { scoped_ptr<aura::WindowTracker> restore_windows( restore_windows_on_shelf_visible_.Pass()); - for (aura::WindowTracker::Windows::const_iterator iter = - restore_windows->windows().begin(); iter != - restore_windows->windows().end(); ++iter) { + for (aura::Window::Windows::const_iterator iter = + restore_windows->windows().begin(); + iter != restore_windows->windows().end(); ++iter) { RestorePanel(*iter); } } diff --git a/ash/wm/root_window_layout_manager.cc b/ash/wm/root_window_layout_manager.cc index 65b71f4..542bbec 100644 --- a/ash/wm/root_window_layout_manager.cc +++ b/ash/wm/root_window_layout_manager.cc @@ -7,6 +7,7 @@ #include "ash/desktop_background/desktop_background_widget_controller.h" #include "ash/root_window_controller.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/aura/window_tracker.h" #include "ui/compositor/layer.h" #include "ui/views/widget/widget.h" @@ -32,12 +33,13 @@ void RootWindowLayoutManager::OnWindowResized() { // Resize both our immediate children (the containers-of-containers animated // by PowerButtonController) and their children (the actual containers). - aura::Window::Windows::const_iterator i; - for (i = owner_->children().begin(); i != owner_->children().end(); ++i) { - (*i)->SetBounds(fullscreen_bounds); - aura::Window::Windows::const_iterator j; - for (j = (*i)->children().begin(); j != (*i)->children().end(); ++j) - (*j)->SetBounds(fullscreen_bounds); + aura::WindowTracker children_tracker(owner_->children()); + while (children_tracker.has_windows()) { + aura::Window* child = children_tracker.Pop(); + child->SetBounds(fullscreen_bounds); + aura::WindowTracker grandchildren_tracker(child->children()); + while (grandchildren_tracker.has_windows()) + grandchildren_tracker.Pop()->SetBounds(fullscreen_bounds); } RootWindowController* root_window_controller = GetRootWindowController(owner_); diff --git a/ash/wm/root_window_layout_manager_unittest.cc b/ash/wm/root_window_layout_manager_unittest.cc new file mode 100644 index 0000000..5769301 --- /dev/null +++ b/ash/wm/root_window_layout_manager_unittest.cc @@ -0,0 +1,46 @@ +// 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 "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "ash/test/ash_test_base.h" +#include "ui/aura/test/test_windows.h" +#include "ui/aura/window_observer.h" + +namespace ash { +namespace { + +class WindowDeleter : public aura::WindowObserver { + public: + explicit WindowDeleter(aura::Window* window) : target_(window) {} + + // aura::WindowObserver:: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) override { + delete target_; + } + + private: + aura::Window* target_; + + DISALLOW_COPY_AND_ASSIGN(WindowDeleter); +}; + +} // namespace + +using RootWindowLayoutManagerTest = test::AshTestBase; + +TEST_F(RootWindowLayoutManagerTest, DeleteChildDuringResize) { + aura::Window* parent = Shell::GetPrimaryRootWindow()->GetChildById( + kShellWindowId_DesktopBackgroundContainer); + aura::Window* w1 = aura::test::CreateTestWindowWithId(1, parent); + aura::Window* w2 = aura::test::CreateTestWindowWithId(2, parent); + WindowDeleter deleter(w1); + w2->AddObserver(&deleter); + UpdateDisplay("600x500"); + w2->RemoveObserver(&deleter); +} + +} // namespace ash diff --git a/ui/aura/test/test_windows.cc b/ui/aura/test/test_windows.cc index 50f8315..141510a 100644 --- a/ui/aura/test/test_windows.cc +++ b/ui/aura/test/test_windows.cc @@ -46,11 +46,11 @@ Window* CreateTestWindowWithDelegateAndType(WindowDelegate* delegate, window->set_id(id); window->SetType(type); window->Init(ui::LAYER_TEXTURED); + window->SetProperty(aura::client::kCanMaximizeKey, true); window->SetBounds(bounds); window->Show(); if (parent) parent->AddChild(window); - window->SetProperty(aura::client::kCanMaximizeKey, true); return window; } diff --git a/ui/aura/window_tracker.cc b/ui/aura/window_tracker.cc index 9653e5f..522a1fc 100644 --- a/ui/aura/window_tracker.cc +++ b/ui/aura/window_tracker.cc @@ -11,32 +11,46 @@ namespace aura { WindowTracker::WindowTracker() { } +WindowTracker::WindowTracker(const WindowList& windows) { + // |windows| may contain dups, so call Add() instead of insert(). + for (auto iter = windows.begin(); iter != windows.end(); iter++) + Add(*iter); +} + WindowTracker::~WindowTracker() { - for (Windows::iterator i = windows_.begin(); i != windows_.end(); ++i) - (*i)->RemoveObserver(this); + while (has_windows()) + Pop()->RemoveObserver(this); } void WindowTracker::Add(Window* window) { - if (windows_.count(window)) + if (Contains(window)) return; window->AddObserver(this); - windows_.insert(window); + windows_.push_back(window); } void WindowTracker::Remove(Window* window) { - if (windows_.count(window)) { - windows_.erase(window); + auto iter = std::find(windows_.begin(), windows_.end(), window); + if (iter != windows_.end()) { + windows_.erase(iter); window->RemoveObserver(this); } } bool WindowTracker::Contains(Window* window) { - return windows_.count(window) > 0; + return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); +} + +aura::Window* WindowTracker::Pop() { + DCHECK(!windows_.empty()); + aura::Window* window = *windows_.begin(); + Remove(window); + return window; } void WindowTracker::OnWindowDestroying(Window* window) { - DCHECK_GT(windows_.count(window), 0u); + DCHECK(Contains(window)); Remove(window); } diff --git a/ui/aura/window_tracker.h b/ui/aura/window_tracker.h index cd83969..005dde3 100644 --- a/ui/aura/window_tracker.h +++ b/ui/aura/window_tracker.h @@ -5,7 +5,7 @@ #ifndef UI_AURA_WINDOW_TRACKER_H_ #define UI_AURA_WINDOW_TRACKER_H_ -#include <set> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -15,16 +15,19 @@ namespace aura { // This class keeps track of a set of windows. A Window is removed either -// explicitly by Remove(), or implicitly when the window is destroyed. +// explicitly by Remove() or Pop(), or implicitly when the window is destroyed. class AURA_EXPORT WindowTracker : public WindowObserver { public: - typedef std::set<Window*> Windows; + using WindowList = std::vector<Window*>; WindowTracker(); + explicit WindowTracker(const WindowList& windows); ~WindowTracker() override; + bool has_windows() const { return !windows_.empty(); } + // Returns the set of windows being observed. - const std::set<Window*>& windows() const { return windows_; } + const std::vector<Window*>& windows() const { return windows_; } // Adds |window| to the set of Windows being tracked. void Add(Window* window); @@ -36,11 +39,14 @@ class AURA_EXPORT WindowTracker : public WindowObserver { // deleted. bool Contains(Window* window); + // Removes and returns the window object from the tracking windows. + aura::Window* Pop(); + // WindowObserver overrides: void OnWindowDestroying(Window* window) override; private: - Windows windows_; + WindowList windows_; DISALLOW_COPY_AND_ASSIGN(WindowTracker); }; diff --git a/ui/wm/core/transient_window_manager.cc b/ui/wm/core/transient_window_manager.cc index f9d723f..e5f6232 100644 --- a/ui/wm/core/transient_window_manager.cc +++ b/ui/wm/core/transient_window_manager.cc @@ -165,15 +165,9 @@ void TransientWindowManager::OnWindowVisibilityChanged(Window* window, // visiblity as well. // WindowTracker is used because child window // could be deleted inside UpdateTransientChildVisibility call. - aura::WindowTracker tracker; - for (Window* child : transient_children_) - tracker.Add(child); - - while (!tracker.windows().empty()) { - Window* window = *(tracker.windows().begin()); - Get(window)->UpdateTransientChildVisibility(visible); - tracker.Remove(window); - } + aura::WindowTracker tracker(transient_children_); + while (tracker.has_windows()) + Get(tracker.Pop())->UpdateTransientChildVisibility(visible); // Remember the show request in |show_on_parent_visible_| and hide it again // if the following conditions are met |