Chromium Code Reviews| 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 |