OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/aura/window.h" | 5 #include "ui/aura/window.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 #include "ui/aura/window_tree_host.h" | 28 #include "ui/aura/window_tree_host.h" |
29 #include "ui/compositor/compositor.h" | 29 #include "ui/compositor/compositor.h" |
30 #include "ui/compositor/layer.h" | 30 #include "ui/compositor/layer.h" |
31 #include "ui/gfx/animation/multi_animation.h" | 31 #include "ui/gfx/animation/multi_animation.h" |
32 #include "ui/gfx/canvas.h" | 32 #include "ui/gfx/canvas.h" |
33 #include "ui/gfx/path.h" | 33 #include "ui/gfx/path.h" |
34 #include "ui/gfx/screen.h" | 34 #include "ui/gfx/screen.h" |
35 | 35 |
36 namespace aura { | 36 namespace aura { |
37 | 37 |
38 namespace { | |
39 | |
40 WindowLayerType UILayerTypeToWindowLayerType(ui::LayerType layer_type) { | |
41 switch (layer_type) { | |
42 case ui::LAYER_NOT_DRAWN: | |
43 return WINDOW_LAYER_NOT_DRAWN; | |
44 case ui::LAYER_TEXTURED: | |
45 return WINDOW_LAYER_TEXTURED; | |
46 case ui::LAYER_SOLID_COLOR: | |
47 return WINDOW_LAYER_SOLID_COLOR; | |
48 } | |
49 NOTREACHED(); | |
50 return WINDOW_LAYER_NOT_DRAWN; | |
51 } | |
52 | |
53 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) { | |
54 switch (window_layer_type) { | |
55 case WINDOW_LAYER_NONE: | |
56 break; | |
57 case WINDOW_LAYER_NOT_DRAWN: | |
58 return ui::LAYER_NOT_DRAWN; | |
59 case WINDOW_LAYER_TEXTURED: | |
60 return ui::LAYER_TEXTURED; | |
61 case WINDOW_LAYER_SOLID_COLOR: | |
62 return ui::LAYER_SOLID_COLOR; | |
63 } | |
64 NOTREACHED(); | |
65 return ui::LAYER_NOT_DRAWN; | |
66 } | |
67 | |
68 } // namespace | |
69 | |
38 class ScopedCursorHider { | 70 class ScopedCursorHider { |
39 public: | 71 public: |
40 explicit ScopedCursorHider(Window* window) | 72 explicit ScopedCursorHider(Window* window) |
41 : window_(window), | 73 : window_(window), |
42 hid_cursor_(false) { | 74 hid_cursor_(false) { |
43 if (!window_->HasDispatcher()) | 75 if (!window_->HasDispatcher()) |
44 return; | 76 return; |
45 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains( | 77 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains( |
46 Env::GetInstance()->last_mouse_location()); | 78 Env::GetInstance()->last_mouse_location()); |
47 client::CursorClient* cursor_client = client::GetCursorClient(window_); | 79 client::CursorClient* cursor_client = client::GetCursorClient(window_); |
(...skipping 22 matching lines...) Expand all Loading... | |
70 } | 102 } |
71 | 103 |
72 private: | 104 private: |
73 Window* window_; | 105 Window* window_; |
74 bool hid_cursor_; | 106 bool hid_cursor_; |
75 | 107 |
76 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider); | 108 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider); |
77 }; | 109 }; |
78 | 110 |
79 Window::Window(WindowDelegate* delegate) | 111 Window::Window(WindowDelegate* delegate) |
80 : dispatcher_(NULL), | 112 : window_layer_type_(WINDOW_LAYER_NOT_DRAWN), |
113 dispatcher_(NULL), | |
81 type_(client::WINDOW_TYPE_UNKNOWN), | 114 type_(client::WINDOW_TYPE_UNKNOWN), |
82 owned_by_parent_(true), | 115 owned_by_parent_(true), |
83 delegate_(delegate), | 116 delegate_(delegate), |
84 parent_(NULL), | 117 parent_(NULL), |
85 transient_parent_(NULL), | 118 transient_parent_(NULL), |
86 visible_(false), | 119 visible_(false), |
87 id_(-1), | 120 id_(-1), |
88 transparent_(false), | 121 transparent_(false), |
89 user_data_(NULL), | 122 user_data_(NULL), |
90 ignore_events_(false), | 123 ignore_events_(false), |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 | 180 |
148 // If we have layer it will either be destroyed by layer_owner_'s dtor, or by | 181 // If we have layer it will either be destroyed by layer_owner_'s dtor, or by |
149 // whoever acquired it. We don't have a layer if Init() wasn't invoked, which | 182 // whoever acquired it. We don't have a layer if Init() wasn't invoked, which |
150 // can happen in tests. | 183 // can happen in tests. |
151 if (layer_) | 184 if (layer_) |
152 layer_->set_delegate(NULL); | 185 layer_->set_delegate(NULL); |
153 layer_ = NULL; | 186 layer_ = NULL; |
154 } | 187 } |
155 | 188 |
156 void Window::Init(ui::LayerType layer_type) { | 189 void Window::Init(ui::LayerType layer_type) { |
157 layer_ = new ui::Layer(layer_type); | 190 InitWithWindowLayerType(UILayerTypeToWindowLayerType(layer_type)); |
158 layer_owner_.reset(layer_); | 191 } |
159 layer_->SetVisible(false); | 192 |
160 layer_->set_delegate(this); | 193 void Window::InitWithWindowLayerType(WindowLayerType window_layer_type) { |
161 UpdateLayerName(name_); | 194 window_layer_type_ = window_layer_type; |
162 layer_->SetFillsBoundsOpaquely(!transparent_); | 195 |
196 if (window_layer_type != WINDOW_LAYER_NONE) { | |
197 layer_ = new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type)); | |
198 layer_owner_.reset(layer_); | |
199 layer_->SetVisible(false); | |
200 layer_->set_delegate(this); | |
201 UpdateLayerName(name_); | |
202 layer_->SetFillsBoundsOpaquely(!transparent_); | |
203 } | |
163 | 204 |
164 Env::GetInstance()->NotifyWindowInitialized(this); | 205 Env::GetInstance()->NotifyWindowInitialized(this); |
165 } | 206 } |
166 | 207 |
167 ui::Layer* Window::RecreateLayer() { | 208 ui::Layer* Window::RecreateLayer() { |
168 // Disconnect the old layer, but don't delete it. | 209 // Disconnect the old layer, but don't delete it. |
169 ui::Layer* old_layer = AcquireLayer(); | 210 ui::Layer* old_layer = AcquireLayer(); |
170 if (!old_layer) | 211 if (!old_layer) |
171 return NULL; | 212 return NULL; |
172 | 213 |
(...skipping 23 matching lines...) Expand all Loading... | |
196 it != children_copy.end(); | 237 it != children_copy.end(); |
197 ++it) { | 238 ++it) { |
198 ui::Layer* child = *it; | 239 ui::Layer* child = *it; |
199 layer_->Add(child); | 240 layer_->Add(child); |
200 } | 241 } |
201 return old_layer; | 242 return old_layer; |
202 } | 243 } |
203 | 244 |
204 void Window::SetType(client::WindowType type) { | 245 void Window::SetType(client::WindowType type) { |
205 // Cannot change type after the window is initialized. | 246 // Cannot change type after the window is initialized. |
206 DCHECK(!layer()); | 247 DCHECK(!layer_); |
207 type_ = type; | 248 type_ = type; |
208 } | 249 } |
209 | 250 |
210 void Window::SetName(const std::string& name) { | 251 void Window::SetName(const std::string& name) { |
211 name_ = name; | 252 name_ = name; |
212 | 253 |
213 if (layer()) | 254 if (layer_) |
214 UpdateLayerName(name_); | 255 UpdateLayerName(name_); |
215 } | 256 } |
216 | 257 |
217 void Window::SetTransparent(bool transparent) { | 258 void Window::SetTransparent(bool transparent) { |
218 transparent_ = transparent; | 259 transparent_ = transparent; |
219 if (layer()) | 260 if (layer_) |
220 layer_->SetFillsBoundsOpaquely(!transparent_); | 261 layer_->SetFillsBoundsOpaquely(!transparent_); |
221 } | 262 } |
222 | 263 |
223 Window* Window::GetRootWindow() { | 264 Window* Window::GetRootWindow() { |
224 return const_cast<Window*>( | 265 return const_cast<Window*>( |
225 static_cast<const Window*>(this)->GetRootWindow()); | 266 static_cast<const Window*>(this)->GetRootWindow()); |
226 } | 267 } |
227 | 268 |
228 const Window* Window::GetRootWindow() const { | 269 const Window* Window::GetRootWindow() const { |
229 return dispatcher_ ? this : parent_ ? parent_->GetRootWindow() : NULL; | 270 return dispatcher_ ? this : parent_ ? parent_->GetRootWindow() : NULL; |
(...skipping 20 matching lines...) Expand all Loading... | |
250 } | 291 } |
251 SetVisible(false); | 292 SetVisible(false); |
252 ReleaseCapture(); | 293 ReleaseCapture(); |
253 } | 294 } |
254 | 295 |
255 bool Window::IsVisible() const { | 296 bool Window::IsVisible() const { |
256 // Layer visibility can be inconsistent with window visibility, for example | 297 // Layer visibility can be inconsistent with window visibility, for example |
257 // when a Window is hidden, we want this function to return false immediately | 298 // when a Window is hidden, we want this function to return false immediately |
258 // after, even though the client may decide to animate the hide effect (and | 299 // after, even though the client may decide to animate the hide effect (and |
259 // so the layer will be visible for some time after Hide() is called). | 300 // so the layer will be visible for some time after Hide() is called). |
260 return visible_ && layer_ && layer_->IsDrawn(); | 301 for (const Window* window = this; window; window = window->parent()) { |
302 if (!window->visible_) | |
303 return false; | |
304 if (window->layer_) | |
305 return window->layer_->IsDrawn(); | |
306 } | |
307 return false; | |
261 } | 308 } |
262 | 309 |
263 gfx::Rect Window::GetBoundsInRootWindow() const { | 310 gfx::Rect Window::GetBoundsInRootWindow() const { |
264 // TODO(beng): There may be a better way to handle this, and the existing code | 311 // TODO(beng): There may be a better way to handle this, and the existing code |
265 // is likely wrong anyway in a multi-display world, but this will | 312 // is likely wrong anyway in a multi-display world, but this will |
266 // do for now. | 313 // do for now. |
267 if (!GetRootWindow()) | 314 if (!GetRootWindow()) |
268 return bounds(); | 315 return bounds(); |
269 gfx::Point origin = bounds().origin(); | 316 gfx::Point origin = bounds().origin(); |
270 ConvertPointToTarget(parent_, GetRootWindow(), &origin); | 317 ConvertPointToTarget(parent_, GetRootWindow(), &origin); |
271 return gfx::Rect(origin, bounds().size()); | 318 return gfx::Rect(origin, bounds().size()); |
272 } | 319 } |
273 | 320 |
274 gfx::Rect Window::GetBoundsInScreen() const { | 321 gfx::Rect Window::GetBoundsInScreen() const { |
275 gfx::Rect bounds(GetBoundsInRootWindow()); | 322 gfx::Rect bounds(GetBoundsInRootWindow()); |
276 const Window* root = GetRootWindow(); | 323 const Window* root = GetRootWindow(); |
277 if (root) { | 324 if (root) { |
278 aura::client::ScreenPositionClient* screen_position_client = | 325 aura::client::ScreenPositionClient* screen_position_client = |
279 aura::client::GetScreenPositionClient(root); | 326 aura::client::GetScreenPositionClient(root); |
280 if (screen_position_client) { | 327 if (screen_position_client) { |
281 gfx::Point origin = bounds.origin(); | 328 gfx::Point origin = bounds.origin(); |
282 screen_position_client->ConvertPointToScreen(root, &origin); | 329 screen_position_client->ConvertPointToScreen(root, &origin); |
283 bounds.set_origin(origin); | 330 bounds.set_origin(origin); |
284 } | 331 } |
285 } | 332 } |
286 return bounds; | 333 return bounds; |
287 } | 334 } |
288 | 335 |
289 void Window::SetTransform(const gfx::Transform& transform) { | 336 void Window::SetTransform(const gfx::Transform& transform) { |
337 if (is_layerless()) { | |
338 // Transforms aren't supported on layerless windows. | |
339 NOTREACHED(); | |
340 return; | |
341 } | |
290 WindowEventDispatcher* dispatcher = GetDispatcher(); | 342 WindowEventDispatcher* dispatcher = GetDispatcher(); |
291 bool contained_mouse = IsVisible() && dispatcher && | 343 bool contained_mouse = IsVisible() && dispatcher && |
292 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); | 344 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); |
293 layer()->SetTransform(transform); | 345 layer_->SetTransform(transform); |
294 if (dispatcher) | 346 if (dispatcher) |
295 dispatcher->OnWindowTransformed(this, contained_mouse); | 347 dispatcher->OnWindowTransformed(this, contained_mouse); |
296 } | 348 } |
297 | 349 |
298 void Window::SetLayoutManager(LayoutManager* layout_manager) { | 350 void Window::SetLayoutManager(LayoutManager* layout_manager) { |
299 if (layout_manager == layout_manager_) | 351 if (layout_manager == layout_manager_) |
300 return; | 352 return; |
301 layout_manager_.reset(layout_manager); | 353 layout_manager_.reset(layout_manager); |
302 if (!layout_manager) | 354 if (!layout_manager) |
303 return; | 355 return; |
(...skipping 19 matching lines...) Expand all Loading... | |
323 gfx::Point origin = new_bounds_in_screen.origin(); | 375 gfx::Point origin = new_bounds_in_screen.origin(); |
324 aura::client::ScreenPositionClient* screen_position_client = | 376 aura::client::ScreenPositionClient* screen_position_client = |
325 aura::client::GetScreenPositionClient(root); | 377 aura::client::GetScreenPositionClient(root); |
326 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display); | 378 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display); |
327 return; | 379 return; |
328 } | 380 } |
329 SetBounds(new_bounds_in_screen); | 381 SetBounds(new_bounds_in_screen); |
330 } | 382 } |
331 | 383 |
332 gfx::Rect Window::GetTargetBounds() const { | 384 gfx::Rect Window::GetTargetBounds() const { |
333 return layer_->GetTargetBounds(); | 385 // TODO(sky): this needs to be updated when there is a layerless ancestor. |
334 } | 386 return is_layerless() ? bounds() : layer_->GetTargetBounds(); |
335 | |
336 const gfx::Rect& Window::bounds() const { | |
337 return layer_->bounds(); | |
338 } | 387 } |
339 | 388 |
340 void Window::SchedulePaintInRect(const gfx::Rect& rect) { | 389 void Window::SchedulePaintInRect(const gfx::Rect& rect) { |
341 if (layer_->SchedulePaint(rect)) { | 390 if (is_layerless() && parent_) { |
391 // Notification of paint scheduled happens for the window with a layer. | |
392 gfx::Rect parent_rect(bounds().size()); | |
393 parent_rect.Intersect(rect); | |
394 if (!parent_rect.IsEmpty()) { | |
395 parent_rect.Offset(bounds().origin().OffsetFromOrigin()); | |
396 parent_->SchedulePaintInRect(parent_rect); | |
397 } | |
398 } else if (layer_ && layer_->SchedulePaint(rect)) { | |
342 FOR_EACH_OBSERVER( | 399 FOR_EACH_OBSERVER( |
343 WindowObserver, observers_, OnWindowPaintScheduled(this, rect)); | 400 WindowObserver, observers_, OnWindowPaintScheduled(this, rect)); |
344 } | 401 } |
345 } | 402 } |
346 | 403 |
347 void Window::StackChildAtTop(Window* child) { | 404 void Window::StackChildAtTop(Window* child) { |
348 if (children_.size() <= 1 || child == children_.back()) | 405 if (children_.size() <= 1 || child == children_.back()) |
349 return; // In the front already. | 406 return; // In the front already. |
350 StackChildAbove(child, children_.back()); | 407 StackChildAbove(child, children_.back()); |
351 } | 408 } |
(...skipping 19 matching lines...) Expand all Loading... | |
371 params.old_parent = child->parent(); | 428 params.old_parent = child->parent(); |
372 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; | 429 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; |
373 NotifyWindowHierarchyChange(params); | 430 NotifyWindowHierarchyChange(params); |
374 | 431 |
375 Window* old_root = child->GetRootWindow(); | 432 Window* old_root = child->GetRootWindow(); |
376 | 433 |
377 DCHECK(std::find(children_.begin(), children_.end(), child) == | 434 DCHECK(std::find(children_.begin(), children_.end(), child) == |
378 children_.end()); | 435 children_.end()); |
379 if (child->parent()) | 436 if (child->parent()) |
380 child->parent()->RemoveChildImpl(child, this); | 437 child->parent()->RemoveChildImpl(child, this); |
438 | |
439 gfx::Vector2d offset; | |
440 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset); | |
441 if (ancestor_with_layer) { | |
442 offset += child->bounds().OffsetFromOrigin(); | |
443 child->ReparentLayers(ancestor_with_layer->layer(), offset); | |
444 } | |
445 | |
381 child->parent_ = this; | 446 child->parent_ = this; |
382 | 447 |
383 layer_->Add(child->layer_); | |
384 | |
385 children_.push_back(child); | 448 children_.push_back(child); |
386 if (layout_manager_) | 449 if (layout_manager_) |
387 layout_manager_->OnWindowAddedToLayout(child); | 450 layout_manager_->OnWindowAddedToLayout(child); |
388 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); | 451 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); |
389 child->OnParentChanged(); | 452 child->OnParentChanged(); |
390 | 453 |
391 Window* root_window = GetRootWindow(); | 454 Window* root_window = GetRootWindow(); |
392 if (root_window && old_root != root_window) { | 455 if (root_window && old_root != root_window) { |
393 root_window->GetDispatcher()->OnWindowAddedToRootWindow(child); | 456 root_window->GetDispatcher()->OnWindowAddedToRootWindow(child); |
394 child->NotifyAddedToRootWindow(); | 457 child->NotifyAddedToRootWindow(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 return; | 529 return; |
467 if (source->GetRootWindow() != target->GetRootWindow()) { | 530 if (source->GetRootWindow() != target->GetRootWindow()) { |
468 client::ScreenPositionClient* source_client = | 531 client::ScreenPositionClient* source_client = |
469 client::GetScreenPositionClient(source->GetRootWindow()); | 532 client::GetScreenPositionClient(source->GetRootWindow()); |
470 source_client->ConvertPointToScreen(source, point); | 533 source_client->ConvertPointToScreen(source, point); |
471 | 534 |
472 client::ScreenPositionClient* target_client = | 535 client::ScreenPositionClient* target_client = |
473 client::GetScreenPositionClient(target->GetRootWindow()); | 536 client::GetScreenPositionClient(target->GetRootWindow()); |
474 target_client->ConvertPointFromScreen(target, point); | 537 target_client->ConvertPointFromScreen(target, point); |
475 } else { | 538 } else { |
476 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point); | 539 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point); |
477 } | 540 } |
478 } | 541 } |
479 | 542 |
480 void Window::MoveCursorTo(const gfx::Point& point_in_window) { | 543 void Window::MoveCursorTo(const gfx::Point& point_in_window) { |
481 Window* root_window = GetRootWindow(); | 544 Window* root_window = GetRootWindow(); |
482 DCHECK(root_window); | 545 DCHECK(root_window); |
483 gfx::Point point_in_root(point_in_window); | 546 gfx::Point point_in_root(point_in_window); |
484 ConvertPointToTarget(this, root_window, &point_in_root); | 547 ConvertPointToTarget(this, root_window, &point_in_root); |
485 root_window->GetDispatcher()->MoveCursorTo(point_in_root); | 548 root_window->GetDispatcher()->MoveCursorTo(point_in_root); |
486 } | 549 } |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 actual_new_bounds.set_width( | 799 actual_new_bounds.set_width( |
737 std::max(min_size.width(), actual_new_bounds.width())); | 800 std::max(min_size.width(), actual_new_bounds.width())); |
738 actual_new_bounds.set_height( | 801 actual_new_bounds.set_height( |
739 std::max(min_size.height(), actual_new_bounds.height())); | 802 std::max(min_size.height(), actual_new_bounds.height())); |
740 } | 803 } |
741 | 804 |
742 gfx::Rect old_bounds = GetTargetBounds(); | 805 gfx::Rect old_bounds = GetTargetBounds(); |
743 | 806 |
744 // Always need to set the layer's bounds -- even if it is to the same thing. | 807 // Always need to set the layer's bounds -- even if it is to the same thing. |
745 // This may cause important side effects such as stopping animation. | 808 // This may cause important side effects such as stopping animation. |
746 layer_->SetBounds(actual_new_bounds); | 809 if (is_layerless()) { |
810 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() - | |
811 bounds_.OffsetFromOrigin(); | |
812 bounds_ = new_bounds; | |
813 OffsetLayerBounds(origin_delta); | |
814 } else { | |
815 if (parent_ && parent_->is_layerless()) { | |
816 gfx::Vector2d offset; | |
817 const aura::Window* ancestor_with_layer = | |
818 parent_->GetAncestorWithLayer(&offset); | |
819 if (ancestor_with_layer) | |
820 actual_new_bounds.Offset(offset); | |
821 } | |
822 layer_->SetBounds(actual_new_bounds); | |
823 } | |
747 | 824 |
748 // If we are currently not the layer's delegate, we will not get bounds | 825 // If we are currently not the layer's delegate, we will not get bounds |
749 // changed notification from the layer (this typically happens after animating | 826 // changed notification from the layer (this typically happens after animating |
750 // hidden). We must notify ourselves. | 827 // hidden). We must notify ourselves. |
751 if (layer_->delegate() != this) | 828 if (is_layerless() || layer_->delegate() != this) |
752 OnLayerBoundsChanged(old_bounds, ContainsMouse()); | 829 OnWindowBoundsChanged(old_bounds, ContainsMouse()); |
753 } | 830 } |
754 | 831 |
755 void Window::SetVisible(bool visible) { | 832 void Window::SetVisible(bool visible) { |
756 if (visible == layer_->GetTargetVisibility()) | 833 if (visible == layer_->GetTargetVisibility()) |
757 return; // No change. | 834 return; // No change. |
758 | 835 |
759 FOR_EACH_OBSERVER(WindowObserver, observers_, | 836 FOR_EACH_OBSERVER(WindowObserver, observers_, |
760 OnWindowVisibilityChanging(this, visible)); | 837 OnWindowVisibilityChanging(this, visible)); |
761 | 838 |
762 WindowEventDispatcher* dispatcher = GetDispatcher(); | 839 WindowEventDispatcher* dispatcher = GetDispatcher(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 if (layout_manager_) | 924 if (layout_manager_) |
848 layout_manager_->OnWillRemoveWindowFromLayout(child); | 925 layout_manager_->OnWillRemoveWindowFromLayout(child); |
849 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); | 926 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); |
850 Window* root_window = child->GetRootWindow(); | 927 Window* root_window = child->GetRootWindow(); |
851 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL; | 928 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL; |
852 if (root_window && root_window != new_root_window) { | 929 if (root_window && root_window != new_root_window) { |
853 root_window->GetDispatcher()->OnWindowRemovedFromRootWindow( | 930 root_window->GetDispatcher()->OnWindowRemovedFromRootWindow( |
854 child, new_root_window); | 931 child, new_root_window); |
855 child->NotifyRemovingFromRootWindow(); | 932 child->NotifyRemovingFromRootWindow(); |
856 } | 933 } |
934 | |
935 gfx::Vector2d offset; | |
936 GetAncestorWithLayer(&offset); | |
937 child->UnparentLayers(is_layerless(), offset); | |
857 child->parent_ = NULL; | 938 child->parent_ = NULL; |
858 // We should only remove the child's layer if the child still owns that layer. | |
859 // Someone else may have acquired ownership of it via AcquireLayer() and may | |
860 // expect the hierarchy to go unchanged as the Window is destroyed. | |
861 if (child->layer_owner_) | |
862 layer_->Remove(child->layer_); | |
863 Windows::iterator i = std::find(children_.begin(), children_.end(), child); | 939 Windows::iterator i = std::find(children_.begin(), children_.end(), child); |
864 DCHECK(i != children_.end()); | 940 DCHECK(i != children_.end()); |
865 children_.erase(i); | 941 children_.erase(i); |
866 child->OnParentChanged(); | 942 child->OnParentChanged(); |
867 if (layout_manager_) | 943 if (layout_manager_) |
868 layout_manager_->OnWindowRemovedFromLayout(child); | 944 layout_manager_->OnWindowRemovedFromLayout(child); |
869 } | 945 } |
870 | 946 |
947 void Window::UnparentLayers(bool has_layerless_ancestor, | |
948 const gfx::Vector2d& offset) { | |
949 if (is_layerless()) { | |
950 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin(); | |
951 for (size_t i = 0; i < children_.size(); ++i) { | |
952 children_[i]->UnparentLayers(true, new_offset); | |
953 } | |
954 } else { | |
955 // We should only remove the child's layer if the child still owns that | |
Ben Goodger (Google)
2013/11/22 05:49:24
use of the term "child" here is confusing.
// We
sky
2013/11/22 20:20:12
Ya, sorry, I copied this comment from 858 old wher
| |
956 // layer. Someone else may have acquired ownership of it via AcquireLayer() | |
957 // and may expect the hierarchy to go unchanged as the Window is destroyed. | |
958 if (layer_owner_) { | |
959 if (layer_->parent()) | |
960 layer_->parent()->Remove(layer_); | |
961 if (has_layerless_ancestor) { | |
962 const gfx::Rect real_bounds(bounds_); | |
963 gfx::Rect layer_bounds(layer_->bounds()); | |
964 layer_bounds.Offset(-offset); | |
965 layer_->SetBounds(layer_bounds); | |
966 bounds_ = real_bounds; | |
967 } | |
968 } | |
969 } | |
970 } | |
971 | |
972 void Window::ReparentLayers(ui::Layer* parent_layer, | |
973 const gfx::Vector2d& offset) { | |
974 if (is_layerless()) { | |
975 for (size_t i = 0; i < children_.size(); ++i) { | |
976 children_[i]->ReparentLayers( | |
977 parent_layer, | |
978 offset + children_[i]->bounds().OffsetFromOrigin()); | |
979 } | |
980 } else { | |
981 const gfx::Rect real_bounds(bounds()); | |
982 parent_layer->Add(layer_); | |
983 gfx::Rect layer_bounds(layer_->bounds().size()); | |
984 layer_bounds += offset; | |
985 layer_->SetBounds(layer_bounds); | |
986 bounds_ = real_bounds; | |
987 } | |
988 } | |
989 | |
990 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) { | |
991 if (is_layerless()) { | |
992 for (size_t i = 0; i < children_.size(); ++i) | |
993 children_[i]->OffsetLayerBounds(offset); | |
994 } else { | |
995 gfx::Rect layer_bounds(layer_->bounds()); | |
996 layer_bounds += offset; | |
997 layer_->SetBounds(layer_bounds); | |
998 } | |
999 } | |
1000 | |
871 void Window::OnParentChanged() { | 1001 void Window::OnParentChanged() { |
872 FOR_EACH_OBSERVER( | 1002 FOR_EACH_OBSERVER( |
873 WindowObserver, observers_, OnWindowParentChanged(this, parent_)); | 1003 WindowObserver, observers_, OnWindowParentChanged(this, parent_)); |
874 } | 1004 } |
875 | 1005 |
876 bool Window::GetAllTransientAncestors(Window* window, | 1006 bool Window::GetAllTransientAncestors(Window* window, |
877 Windows* ancestors) const { | 1007 Windows* ancestors) const { |
878 for (; window; window = window->transient_parent()) { | 1008 for (; window; window = window->transient_parent()) { |
879 if (window->parent() == this) | 1009 if (window->parent() == this) |
880 ancestors->push_back(window); | 1010 ancestors->push_back(window); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
939 ++final_target_i; | 1069 ++final_target_i; |
940 } | 1070 } |
941 } | 1071 } |
942 | 1072 |
943 // By convention we don't stack on top of windows with layers with NULL | 1073 // By convention we don't stack on top of windows with layers with NULL |
944 // delegates. Walk backward to find a valid target window. | 1074 // delegates. Walk backward to find a valid target window. |
945 // See tests WindowTest.StackingMadrigal and StackOverClosingTransient | 1075 // See tests WindowTest.StackingMadrigal and StackOverClosingTransient |
946 // for an explanation of this. | 1076 // for an explanation of this. |
947 while (final_target_i > 0 && | 1077 while (final_target_i > 0 && |
948 children_[direction == STACK_ABOVE ? final_target_i : | 1078 children_[direction == STACK_ABOVE ? final_target_i : |
949 final_target_i - 1]->layer() | 1079 final_target_i - 1]->layer_ |
950 ->delegate() == NULL) { | 1080 ->delegate() == NULL) { |
951 --final_target_i; | 1081 --final_target_i; |
952 } | 1082 } |
953 | 1083 |
954 Window* final_target = children_[final_target_i]; | 1084 Window* final_target = children_[final_target_i]; |
955 | 1085 |
956 // If we couldn't find a valid target position, don't move anything. | 1086 // If we couldn't find a valid target position, don't move anything. |
957 if (direction == STACK_ABOVE && final_target->layer()->delegate() == NULL) | 1087 if (direction == STACK_ABOVE && final_target->layer_->delegate() == NULL) |
958 return; | 1088 return; |
959 | 1089 |
960 // Don't try to stack a child above itself. | 1090 // Don't try to stack a child above itself. |
961 if (child == final_target) | 1091 if (child == final_target) |
962 return; | 1092 return; |
963 | 1093 |
964 // Move the child. | 1094 // Move the child. |
965 StackChildRelativeToImpl(child, final_target, direction); | 1095 StackChildRelativeToImpl(child, final_target, direction); |
966 | 1096 |
967 // Stack any transient children that share the same parent to be in front of | 1097 // Stack any transient children that share the same parent to be in front of |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
999 return; | 1129 return; |
1000 | 1130 |
1001 const size_t dest_i = | 1131 const size_t dest_i = |
1002 direction == STACK_ABOVE ? | 1132 direction == STACK_ABOVE ? |
1003 (child_i < target_i ? target_i : target_i + 1) : | 1133 (child_i < target_i ? target_i : target_i + 1) : |
1004 (child_i < target_i ? target_i - 1 : target_i); | 1134 (child_i < target_i ? target_i - 1 : target_i); |
1005 children_.erase(children_.begin() + child_i); | 1135 children_.erase(children_.begin() + child_i); |
1006 children_.insert(children_.begin() + dest_i, child); | 1136 children_.insert(children_.begin() + dest_i, child); |
1007 | 1137 |
1008 if (direction == STACK_ABOVE) | 1138 if (direction == STACK_ABOVE) |
1009 layer()->StackAbove(child->layer(), target->layer()); | 1139 layer_->StackAbove(child->layer_, target->layer_); |
1010 else | 1140 else |
1011 layer()->StackBelow(child->layer(), target->layer()); | 1141 layer_->StackBelow(child->layer_, target->layer_); |
1012 | 1142 |
1013 child->OnStackingChanged(); | 1143 child->OnStackingChanged(); |
1014 } | 1144 } |
1015 | 1145 |
1016 void Window::OnStackingChanged() { | 1146 void Window::OnStackingChanged() { |
1017 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this)); | 1147 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this)); |
1018 } | 1148 } |
1019 | 1149 |
1020 void Window::NotifyRemovingFromRootWindow() { | 1150 void Window::NotifyRemovingFromRootWindow() { |
1021 FOR_EACH_OBSERVER(WindowObserver, observers_, | 1151 FOR_EACH_OBSERVER(WindowObserver, observers_, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 } | 1262 } |
1133 | 1263 |
1134 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target, | 1264 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target, |
1135 bool visible) { | 1265 bool visible) { |
1136 for (Window* window = this; window; window = window->parent()) { | 1266 for (Window* window = this; window; window = window->parent()) { |
1137 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible); | 1267 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible); |
1138 DCHECK(ret); | 1268 DCHECK(ret); |
1139 } | 1269 } |
1140 } | 1270 } |
1141 | 1271 |
1142 void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds, | 1272 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds, |
1143 bool contained_mouse) { | 1273 bool contained_mouse) { |
1274 if (layer_) { | |
1275 bounds_ = layer_->bounds(); | |
1276 if (parent_ && parent_->is_layerless()) { | |
1277 gfx::Vector2d offset; | |
1278 aura::Window* ancestor_with_layer = | |
1279 parent_->GetAncestorWithLayer(&offset); | |
1280 if (ancestor_with_layer) | |
1281 bounds_.Offset(-offset); | |
1282 } | |
1283 } | |
1284 | |
1144 if (layout_manager_) | 1285 if (layout_manager_) |
1145 layout_manager_->OnWindowResized(); | 1286 layout_manager_->OnWindowResized(); |
1146 if (delegate_) | 1287 if (delegate_) |
1147 delegate_->OnBoundsChanged(old_bounds, bounds()); | 1288 delegate_->OnBoundsChanged(old_bounds, bounds()); |
1148 FOR_EACH_OBSERVER(WindowObserver, | 1289 FOR_EACH_OBSERVER(WindowObserver, |
1149 observers_, | 1290 observers_, |
1150 OnWindowBoundsChanged(this, old_bounds, bounds())); | 1291 OnWindowBoundsChanged(this, old_bounds, bounds())); |
1151 WindowEventDispatcher* dispatcher = GetDispatcher(); | 1292 WindowEventDispatcher* dispatcher = GetDispatcher(); |
1152 if (dispatcher) | 1293 if (dispatcher) |
1153 dispatcher->OnWindowBoundsChanged(this, contained_mouse); | 1294 dispatcher->OnWindowBoundsChanged(this, contained_mouse); |
1154 } | 1295 } |
1155 | 1296 |
1156 void Window::OnPaintLayer(gfx::Canvas* canvas) { | 1297 void Window::OnPaintLayer(gfx::Canvas* canvas) { |
1157 if (delegate_) | 1298 if (delegate_) |
1158 delegate_->OnPaint(canvas); | 1299 delegate_->OnPaint(canvas); |
1159 } | 1300 } |
1160 | 1301 |
1161 base::Closure Window::PrepareForLayerBoundsChange() { | 1302 base::Closure Window::PrepareForLayerBoundsChange() { |
1162 return base::Bind(&Window::OnLayerBoundsChanged, base::Unretained(this), | 1303 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this), |
1163 bounds(), ContainsMouse()); | 1304 bounds(), ContainsMouse()); |
1164 } | 1305 } |
1165 | 1306 |
1166 bool Window::CanAcceptEvent(const ui::Event& event) { | 1307 bool Window::CanAcceptEvent(const ui::Event& event) { |
1167 if (!IsVisible()) | 1308 if (!IsVisible()) |
1168 return false; | 1309 return false; |
1169 | 1310 |
1170 // The client may forbid certain windows from receiving events at a given | 1311 // The client may forbid certain windows from receiving events at a given |
1171 // point in time. | 1312 // point in time. |
1172 client::EventClient* client = client::GetEventClient(GetRootWindow()); | 1313 client::EventClient* client = client::GetEventClient(GetRootWindow()); |
(...skipping 14 matching lines...) Expand all Loading... | |
1187 if (dispatcher_) { | 1328 if (dispatcher_) { |
1188 return client::GetEventClient(this) ? | 1329 return client::GetEventClient(this) ? |
1189 client::GetEventClient(this)->GetToplevelEventTarget() : | 1330 client::GetEventClient(this)->GetToplevelEventTarget() : |
1190 Env::GetInstance(); | 1331 Env::GetInstance(); |
1191 } | 1332 } |
1192 return parent_; | 1333 return parent_; |
1193 } | 1334 } |
1194 | 1335 |
1195 void Window::UpdateLayerName(const std::string& name) { | 1336 void Window::UpdateLayerName(const std::string& name) { |
1196 #if !defined(NDEBUG) | 1337 #if !defined(NDEBUG) |
1197 DCHECK(layer()); | 1338 DCHECK(layer_); |
1198 | 1339 |
1199 std::string layer_name(name_); | 1340 std::string layer_name(name_); |
1200 if (layer_name.empty()) | 1341 if (layer_name.empty()) |
1201 layer_name.append("Unnamed Window"); | 1342 layer_name.append("Unnamed Window"); |
1202 | 1343 |
1203 if (id_ != -1) { | 1344 if (id_ != -1) { |
1204 char id_buf[10]; | 1345 char id_buf[10]; |
1205 base::snprintf(id_buf, sizeof(id_buf), " %d", id_); | 1346 base::snprintf(id_buf, sizeof(id_buf), " %d", id_); |
1206 layer_name.append(id_buf); | 1347 layer_name.append(id_buf); |
1207 } | 1348 } |
1208 layer()->set_name(layer_name); | 1349 layer_->set_name(layer_name); |
1209 #endif | 1350 #endif |
1210 } | 1351 } |
1211 | 1352 |
1212 bool Window::ContainsMouse() { | 1353 bool Window::ContainsMouse() { |
1213 bool contains_mouse = false; | 1354 bool contains_mouse = false; |
1214 if (IsVisible()) { | 1355 if (IsVisible()) { |
1215 WindowEventDispatcher* dispatcher = GetDispatcher(); | 1356 WindowEventDispatcher* dispatcher = GetDispatcher(); |
1216 contains_mouse = dispatcher && | 1357 contains_mouse = dispatcher && |
1217 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); | 1358 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); |
1218 } | 1359 } |
1219 return contains_mouse; | 1360 return contains_mouse; |
1220 } | 1361 } |
1221 | 1362 |
1363 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const { | |
1364 for (const aura::Window* window = this; window; window = window->parent()) { | |
1365 if (!window->is_layerless()) | |
1366 return window; | |
1367 *offset += window->bounds().OffsetFromOrigin(); | |
1368 } | |
1369 *offset = gfx::Vector2d(); | |
1370 return NULL; | |
1371 } | |
1372 | |
1222 } // namespace aura | 1373 } // namespace aura |
OLD | NEW |