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