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