Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: ash/shelf/shelf_window_watcher.cc

Issue 108313006: [ash] Don't remove an item when associated window is dragged (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/shelf/shelf_window_watcher.h" 5 #include "ash/shelf/shelf_window_watcher.h"
6 6
7 #include "ash/ash_switches.h"
7 #include "ash/display/display_controller.h" 8 #include "ash/display/display_controller.h"
8 #include "ash/shelf/shelf_constants.h" 9 #include "ash/shelf/shelf_constants.h"
9 #include "ash/shelf/shelf_item_delegate_manager.h" 10 #include "ash/shelf/shelf_item_delegate_manager.h"
10 #include "ash/shelf/shelf_model.h" 11 #include "ash/shelf/shelf_model.h"
11 #include "ash/shelf/shelf_util.h" 12 #include "ash/shelf/shelf_util.h"
12 #include "ash/shelf/shelf_window_watcher_item_delegate.h" 13 #include "ash/shelf/shelf_window_watcher_item_delegate.h"
13 #include "ash/shell.h" 14 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h" 15 #include "ash/shell_window_ids.h"
16 #include "ash/wm/window_state.h"
15 #include "ash/wm/window_util.h" 17 #include "ash/wm/window_util.h"
16 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
17 #include "ui/aura/client/activation_client.h" 19 #include "ui/aura/client/activation_client.h"
18 #include "ui/aura/window.h" 20 #include "ui/aura/window.h"
19 #include "ui/base/resource/resource_bundle.h" 21 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/gfx/image/image_skia.h" 22 #include "ui/gfx/image/image_skia.h"
21 #include "ui/gfx/screen.h" 23 #include "ui/gfx/screen.h"
22 24
23 namespace { 25 namespace {
24 26
25 // Sets LauncherItem property by using the value of |details|. 27 // Sets LauncherItem property by using the value of |details|.
26 void SetShelfItemDetailsForLauncherItem( 28 void SetShelfItemDetailsForLauncherItem(
27 ash::LauncherItem* item, 29 ash::LauncherItem* item,
28 const ash::LauncherItemDetails& details) { 30 const ash::LauncherItemDetails& details) {
29 item->type = details.type; 31 item->type = details.type;
30 if (details.image_resource_id != ash::kInvalidImageResourceID) { 32 if (details.image_resource_id != ash::kInvalidImageResourceID) {
31 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 33 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
32 item->image = *rb.GetImageSkiaNamed(details.image_resource_id); 34 item->image = *rb.GetImageSkiaNamed(details.image_resource_id);
33 } 35 }
34 } 36 }
35 37
36 // Returns true if |window| has a LauncherItem added by ShelfWindowWatcher. 38 // Returns true if |window| has a LauncherItem added by ShelfWindowWatcher.
37 bool HasLauncherItemForWindow(aura::Window* window) { 39 bool HasLauncherItemForWindow(aura::Window* window) {
38 if (ash::GetLauncherItemDetailsForWindow(window) != NULL && 40 if (ash::GetLauncherItemDetailsForWindow(window) != NULL &&
39 ash::GetLauncherIDForWindow(window) != ash::kInvalidShelfID) 41 ash::GetLauncherIDForWindow(window) != ash::kInvalidShelfID)
40 return true; 42 return true;
41 return false; 43 return false;
42 } 44 }
43 45
46 // Returns true if |window| is in the process of being dragged.
47 bool IsDragging(aura::Window* window) {
48 return ash::wm::GetWindowState(window)->is_dragged();
49 }
50
44 } // namespace 51 } // namespace
45 52
46 namespace ash { 53 namespace ash {
47 namespace internal { 54 namespace internal {
48 55
49 ShelfWindowWatcher::RootWindowObserver::RootWindowObserver( 56 ShelfWindowWatcher::RootWindowObserver::RootWindowObserver(
50 ShelfWindowWatcher* window_watcher) 57 ShelfWindowWatcher* window_watcher)
51 : window_watcher_(window_watcher) { 58 : window_watcher_(window_watcher) {
52 } 59 }
53 60
54 ShelfWindowWatcher::RootWindowObserver::~RootWindowObserver() { 61 ShelfWindowWatcher::RootWindowObserver::~RootWindowObserver() {
55 } 62 }
56 63
57 void ShelfWindowWatcher::RootWindowObserver::OnWindowDestroying( 64 void ShelfWindowWatcher::RootWindowObserver::OnWindowDestroying(
58 aura::Window* window) { 65 aura::Window* window) {
59 window_watcher_->OnRootWindowRemoved(window); 66 window_watcher_->OnRootWindowRemoved(window);
60 } 67 }
61 68
69 ShelfWindowWatcher::RemovedWindowObserver::RemovedWindowObserver(
70 ShelfWindowWatcher* window_watcher)
71 : window_watcher_(window_watcher) {
72 }
73
74 ShelfWindowWatcher::RemovedWindowObserver::~RemovedWindowObserver() {
75 }
76
77 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowParentChanged(
78 aura::Window* window,
79 aura::Window* parent) {
80 // When |parent| is NULL, this |window| will be destroyed. In that case, its
81 // item will be removed at OnWindowDestroyed().
82 if (!parent)
83 return;
84
85 // When |parent| is changed from default container to docked container
86 // during the dragging, |window|'s item should not be removed because it will
87 // be re-parented to default container again after finishing the dragging.
88 // We don't need to check |parent| is default container because this observer
89 // is already removed from |window| when |window| is re-parented to default
90 // container.
91 if (switches::UseDockedWindows() &&
92 IsDragging(window) &&
93 parent->id() == kShellWindowId_DockedContainer)
94 return;
95
96 // When |window| is re-parented to other containers or |window| is re-parented
97 // not to |docked_container| during the dragging, its item should be removed
98 // and stop observing this |window|.
99 window_watcher_->FinishObserveRemovedWindow(window);
100 }
101
102 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowDestroyed(
103 aura::Window* window) {
104 DCHECK(HasLauncherItemForWindow(window));
105 window_watcher_->FinishObserveRemovedWindow(window);
106 }
107
62 ShelfWindowWatcher::ShelfWindowWatcher( 108 ShelfWindowWatcher::ShelfWindowWatcher(
63 ShelfModel* model, 109 ShelfModel* model,
64 ShelfItemDelegateManager* item_delegate_manager) 110 ShelfItemDelegateManager* item_delegate_manager)
65 : model_(model), 111 : model_(model),
66 item_delegate_manager_(item_delegate_manager), 112 item_delegate_manager_(item_delegate_manager),
67 root_window_observer_(this), 113 root_window_observer_(this),
114 removed_window_observer_(this),
68 observed_windows_(this), 115 observed_windows_(this),
69 observed_root_windows_(&root_window_observer_), 116 observed_root_windows_(&root_window_observer_),
117 observed_removed_windows_(&removed_window_observer_),
70 observed_activation_clients_(this) { 118 observed_activation_clients_(this) {
71 // We can't assume all RootWindows have the same ActivationClient. 119 // We can't assume all RootWindows have the same ActivationClient.
72 // Add a RootWindow and its ActivationClient to the observed list. 120 // Add a RootWindow and its ActivationClient to the observed list.
73 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 121 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
74 for (aura::Window::Windows::const_iterator it = root_windows.begin(); 122 for (aura::Window::Windows::const_iterator it = root_windows.begin();
75 it != root_windows.end(); ++it) 123 it != root_windows.end(); ++it)
76 OnRootWindowAdded(*it); 124 OnRootWindowAdded(*it);
77 125
78 Shell::GetScreen()->AddObserver(this); 126 Shell::GetScreen()->AddObserver(this);
79 } 127 }
80 128
81 ShelfWindowWatcher::~ShelfWindowWatcher() { 129 ShelfWindowWatcher::~ShelfWindowWatcher() {
82 Shell::GetScreen()->RemoveObserver(this); 130 Shell::GetScreen()->RemoveObserver(this);
83 } 131 }
84 132
85 void ShelfWindowWatcher::AddLauncherItem(aura::Window* window) { 133 void ShelfWindowWatcher::AddLauncherItem(aura::Window* window) {
86 const LauncherItemDetails* item_details = 134 const LauncherItemDetails* item_details =
87 GetLauncherItemDetailsForWindow(window); 135 GetLauncherItemDetailsForWindow(window);
88 LauncherItem item; 136 LauncherItem item;
89 LauncherID id = model_->next_id(); 137 LauncherID id = model_->next_id();
90 item.status = ash::wm::IsActiveWindow(window) ? STATUS_ACTIVE: STATUS_RUNNING; 138 item.status = wm::IsActiveWindow(window) ? STATUS_ACTIVE: STATUS_RUNNING;
91 SetShelfItemDetailsForLauncherItem(&item, *item_details); 139 SetShelfItemDetailsForLauncherItem(&item, *item_details);
92 SetLauncherIDForWindow(id, window); 140 SetLauncherIDForWindow(id, window);
93 scoped_ptr<ShelfItemDelegate> item_delegate( 141 scoped_ptr<ShelfItemDelegate> item_delegate(
94 new ShelfWindowWatcherItemDelegate(window)); 142 new ShelfWindowWatcherItemDelegate(window));
95 // |item_delegate| is owned by |item_delegate_manager_|. 143 // |item_delegate| is owned by |item_delegate_manager_|.
96 item_delegate_manager_->SetShelfItemDelegate(id, item_delegate.Pass()); 144 item_delegate_manager_->SetShelfItemDelegate(id, item_delegate.Pass());
97 model_->Add(item); 145 model_->Add(item);
98 } 146 }
99 147
100 void ShelfWindowWatcher::RemoveLauncherItem(aura::Window* window) { 148 void ShelfWindowWatcher::RemoveLauncherItem(aura::Window* window) {
(...skipping 30 matching lines...) Expand all
131 LauncherItem item = model_->items()[index]; 179 LauncherItem item = model_->items()[index];
132 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING; 180 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING;
133 model_->Set(index, item); 181 model_->Set(index, item);
134 } 182 }
135 183
136 int ShelfWindowWatcher::GetLauncherItemIndexForWindow( 184 int ShelfWindowWatcher::GetLauncherItemIndexForWindow(
137 aura::Window* window) const { 185 aura::Window* window) const {
138 return model_->ItemIndexByID(GetLauncherIDForWindow(window)); 186 return model_->ItemIndexByID(GetLauncherIDForWindow(window));
139 } 187 }
140 188
189 void ShelfWindowWatcher::StartObserveRemovedWindow(aura::Window* window) {
190 observed_removed_windows_.Add(window);
sky 2014/01/08 15:01:49 Is there a reason this doesn't remove from observe
simonhong 2014/01/09 01:00:09 |window| is removed from |observed_windows_| at On
191 }
192
193 void ShelfWindowWatcher::FinishObserveRemovedWindow(aura::Window* window) {
194 observed_removed_windows_.Remove(window);
195 RemoveLauncherItem(window);
196 }
197
141 void ShelfWindowWatcher::OnWindowActivated(aura::Window* gained_active, 198 void ShelfWindowWatcher::OnWindowActivated(aura::Window* gained_active,
142 aura::Window* lost_active) { 199 aura::Window* lost_active) {
143 if (gained_active && HasLauncherItemForWindow(gained_active)) 200 if (gained_active && HasLauncherItemForWindow(gained_active))
144 UpdateLauncherItemStatus(gained_active, true); 201 UpdateLauncherItemStatus(gained_active, true);
145 if (lost_active && HasLauncherItemForWindow(lost_active)) 202 if (lost_active && HasLauncherItemForWindow(lost_active))
146 UpdateLauncherItemStatus(lost_active, false); 203 UpdateLauncherItemStatus(lost_active, false);
147 } 204 }
148 205
149 void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) { 206 void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) {
150 observed_windows_.Add(window); 207 observed_windows_.Add(window);
208
209 if (observed_removed_windows_.IsObserving(window)) {
210 // When |window| is added and it is already observed by
211 // |dragged_window_observer_|, |window| already has its item.
212 DCHECK(HasLauncherItemForWindow(window));
213 observed_removed_windows_.Remove(window);
214 return;
215 }
216
151 // Add LauncherItem if |window| already has a LauncherItemDetails when it is 217 // Add LauncherItem if |window| already has a LauncherItemDetails when it is
152 // created. Don't make a new LauncherItem for the re-parented |window| that 218 // created. Don't make a new LauncherItem for the re-parented |window| that
153 // already has a LauncherItem. 219 // already has a LauncherItem.
154 if (GetLauncherIDForWindow(window) == ash::kInvalidShelfID && 220 if (GetLauncherIDForWindow(window) == kInvalidShelfID &&
155 GetLauncherItemDetailsForWindow(window)) 221 GetLauncherItemDetailsForWindow(window))
156 AddLauncherItem(window); 222 AddLauncherItem(window);
157 } 223 }
158 224
159 void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) { 225 void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) {
160 // Remove a child window of default container and its item if it has. 226 // Remove a child window of default container.
161 if (observed_windows_.IsObserving(window)) 227 if (observed_windows_.IsObserving(window))
162 observed_windows_.Remove(window); 228 observed_windows_.Remove(window);
163 229
230 // Don't remove |window| item immediately. Instead, defer handling of removing
231 // |window|'s item to RemovedWindowObserver because |window| could be added
232 // again to default container.
164 if (HasLauncherItemForWindow(window)) 233 if (HasLauncherItemForWindow(window))
165 RemoveLauncherItem(window); 234 StartObserveRemovedWindow(window);
166 } 235 }
167 236
168 void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) { 237 void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) {
169 // Remove the default container. 238 // Remove the default container.
170 if (observed_windows_.IsObserving(window)) 239 if (observed_windows_.IsObserving(window))
171 observed_windows_.Remove(window); 240 observed_windows_.Remove(window);
172 } 241 }
173 242
174 void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window, 243 void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window,
175 const void* key, 244 const void* key,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 285
217 void ShelfWindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) { 286 void ShelfWindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) {
218 // When this is called, RootWindow of |old_display| is already removed. 287 // When this is called, RootWindow of |old_display| is already removed.
219 // Instead, we remove an observer from RootWindow and ActivationClient in the 288 // Instead, we remove an observer from RootWindow and ActivationClient in the
220 // OnRootWindowDestroyed(). 289 // OnRootWindowDestroyed().
221 // Do nothing here. 290 // Do nothing here.
222 } 291 }
223 292
224 } // namespace internal 293 } // namespace internal
225 } // namespace ash 294 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698