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 3 // found in the LICENSE file. 4 5 #include "ui/aura/window.h" 6 7 #include <algorithm> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/callback.h" 12 #include "base/logging.h" 13 #include "base/stl_util.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_util.h" 16 #include "base/strings/stringprintf.h" 17 #include "ui/aura/client/capture_client.h" 18 #include "ui/aura/client/cursor_client.h" 19 #include "ui/aura/client/event_client.h" 20 #include "ui/aura/client/focus_client.h" 21 #include "ui/aura/client/screen_position_client.h" 22 #include "ui/aura/client/visibility_client.h" 23 #include "ui/aura/client/window_stacking_client.h" 24 #include "ui/aura/env.h" 25 #include "ui/aura/layout_manager.h" 26 #include "ui/aura/root_window.h" 27 #include "ui/aura/window_delegate.h" 28 #include "ui/aura/window_observer.h" 29 #include "ui/aura/window_tracker.h" 30 #include "ui/aura/window_tree_host.h" 31 #include "ui/compositor/compositor.h" 32 #include "ui/compositor/layer.h" 33 #include "ui/events/event_target_iterator.h" 34 #include "ui/gfx/animation/multi_animation.h" 35 #include "ui/gfx/canvas.h" 36 #include "ui/gfx/path.h" 37 #include "ui/gfx/scoped_canvas.h" 38 #include "ui/gfx/screen.h" 39 40 namespace aura { 41 42 namespace { 43 44 WindowLayerType UILayerTypeToWindowLayerType(ui::LayerType layer_type) { 45 switch (layer_type) { 46 case ui::LAYER_NOT_DRAWN: 47 return WINDOW_LAYER_NOT_DRAWN; 48 case ui::LAYER_TEXTURED: 49 return WINDOW_LAYER_TEXTURED; 50 case ui::LAYER_SOLID_COLOR: 51 return WINDOW_LAYER_SOLID_COLOR; 52 } 53 NOTREACHED(); 54 return WINDOW_LAYER_NOT_DRAWN; 55 } 56 57 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) { 58 switch (window_layer_type) { 59 case WINDOW_LAYER_NONE: 60 break; 61 case WINDOW_LAYER_NOT_DRAWN: 62 return ui::LAYER_NOT_DRAWN; 63 case WINDOW_LAYER_TEXTURED: 64 return ui::LAYER_TEXTURED; 65 case WINDOW_LAYER_SOLID_COLOR: 66 return ui::LAYER_SOLID_COLOR; 67 } 68 NOTREACHED(); 69 return ui::LAYER_NOT_DRAWN; 70 } 71 72 // Used when searching for a Window to stack relative to. 73 template <class T> 74 T IteratorForDirectionBegin(aura::Window* window); 75 76 template <> 77 Window::Windows::const_iterator IteratorForDirectionBegin( 78 aura::Window* window) { 79 return window->children().begin(); 80 } 81 82 template <> 83 Window::Windows::const_reverse_iterator IteratorForDirectionBegin( 84 aura::Window* window) { 85 return window->children().rbegin(); 86 } 87 88 template <class T> 89 T IteratorForDirectionEnd(aura::Window* window); 90 91 template <> 92 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) { 93 return window->children().end(); 94 } 95 96 template <> 97 Window::Windows::const_reverse_iterator IteratorForDirectionEnd( 98 aura::Window* window) { 99 return window->children().rend(); 100 } 101 102 // Depth first search for the first Window with a layer to stack relative 103 // to. Starts at target. Does not descend into |ignore|. 104 template <class T> 105 ui::Layer* FindStackingTargetLayerDown(aura::Window* target, 106 aura::Window* ignore) { 107 if (target == ignore) 108 return NULL; 109 110 if (target->layer()) 111 return target->layer(); 112 113 for (T i = IteratorForDirectionBegin<T>(target); 114 i != IteratorForDirectionEnd<T>(target); ++i) { 115 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore); 116 if (layer) 117 return layer; 118 } 119 return NULL; 120 } 121 122 // Depth first search through the siblings of |target||. This does not search 123 // all the siblings, only those before/after |target| (depening upon the 124 // template type) and ignoring |ignore|. Returns the Layer of the first Window 125 // encountered with a Layer. 126 template <class T> 127 ui::Layer* FindStackingLayerInSiblings(aura::Window* target, 128 aura::Window* ignore) { 129 aura::Window* parent = target->parent(); 130 for (T i = std::find(IteratorForDirectionBegin<T>(parent), 131 IteratorForDirectionEnd<T>(parent), target); 132 i != IteratorForDirectionEnd<T>(parent); ++i) { 133 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore); 134 if (layer) 135 return layer; 136 } 137 return NULL; 138 } 139 140 // Returns the first Window that has a Layer. This does a depth first search 141 // through the descendants of |target| first, then ascends up doing a depth 142 // first search through siblings of all ancestors until a Layer is found or an 143 // ancestor with a layer is found. This is intended to locate a layer to stack 144 // other layers relative to. 145 template <class T> 146 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) { 147 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore); 148 if (result) 149 return result; 150 while (target->parent()) { 151 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore); 152 if (result) 153 return result; 154 target = target->parent(); 155 if (target->layer()) 156 return NULL; 157 } 158 return NULL; 159 } 160 161 // Does a depth first search for all descendants of |child| that have layers. 162 // This stops at any descendants that have layers (and adds them to |layers|). 163 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) { 164 if (child->layer()) { 165 layers->push_back(child->layer()); 166 return; 167 } 168 for (size_t i = 0; i < child->children().size(); ++i) 169 GetLayersToStack(child->children()[i], layers); 170 } 171 172 } // namespace 173 174 class ScopedCursorHider { 175 public: 176 explicit ScopedCursorHider(Window* window) 177 : window_(window), 178 hid_cursor_(false) { 179 if (!window_->HasDispatcher()) 180 return; 181 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains( 182 Env::GetInstance()->last_mouse_location()); 183 client::CursorClient* cursor_client = client::GetCursorClient(window_); 184 if (cursor_is_in_bounds && cursor_client && 185 cursor_client->IsCursorVisible()) { 186 cursor_client->HideCursor(); 187 hid_cursor_ = true; 188 } 189 } 190 ~ScopedCursorHider() { 191 if (!window_->HasDispatcher()) 192 return; 193 194 // Update the device scale factor of the cursor client only when the last 195 // mouse location is on this root window. 196 if (hid_cursor_) { 197 client::CursorClient* cursor_client = client::GetCursorClient(window_); 198 if (cursor_client) { 199 const gfx::Display& display = 200 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow( 201 window_); 202 cursor_client->SetDisplay(display); 203 cursor_client->ShowCursor(); 204 } 205 } 206 } 207 208 private: 209 Window* window_; 210 bool hid_cursor_; 211 212 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider); 213 }; 214 215 Window::Window(WindowDelegate* delegate) 216 : dispatcher_(NULL), 217 type_(client::WINDOW_TYPE_UNKNOWN), 218 owned_by_parent_(true), 219 delegate_(delegate), 220 parent_(NULL), 221 transient_parent_(NULL), 222 visible_(false), 223 id_(-1), 224 transparent_(false), 225 user_data_(NULL), 226 ignore_events_(false), 227 // Don't notify newly added observers during notification. This causes 228 // problems for code that adds an observer as part of an observer 229 // notification (such as the workspace code). 230 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) { 231 set_target_handler(delegate_); 232 } 233 234 Window::~Window() { 235 // |layer_| can be NULL during tests, or if this Window is layerless. 236 if (layer_) 237 layer_->SuppressPaint(); 238 239 // Let the delegate know we're in the processing of destroying. 240 if (delegate_) 241 delegate_->OnWindowDestroying(); 242 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); 243 244 // Let the root know so that it can remove any references to us. 245 WindowEventDispatcher* dispatcher = GetDispatcher(); 246 if (dispatcher) 247 dispatcher->OnWindowDestroying(this); 248 249 // Then destroy the children. 250 RemoveOrDestroyChildren(); 251 252 // Removes ourselves from our transient parent (if it hasn't been done by the 253 // RootWindow). 254 if (transient_parent_) 255 transient_parent_->RemoveTransientChild(this); 256 257 // The window needs to be removed from the parent before calling the 258 // WindowDestroyed callbacks of delegate and the observers. 259 if (parent_) 260 parent_->RemoveChild(this); 261 262 // Destroy transient children, only after we've removed ourselves from our 263 // parent, as destroying an active transient child may otherwise attempt to 264 // refocus us. 265 Windows transient_children(transient_children_); 266 STLDeleteElements(&transient_children); 267 DCHECK(transient_children_.empty()); 268 269 // Delegate and observers need to be notified after transients are deleted. 270 if (delegate_) 271 delegate_->OnWindowDestroyed(); 272 ObserverListBase<WindowObserver>::Iterator iter(observers_); 273 WindowObserver* observer; 274 while ((observer = iter.GetNext())) { 275 RemoveObserver(observer); 276 observer->OnWindowDestroyed(this); 277 } 278 279 // Clear properties. 280 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin(); 281 iter != prop_map_.end(); 282 ++iter) { 283 if (iter->second.deallocator) 284 (*iter->second.deallocator)(iter->second.value); 285 } 286 prop_map_.clear(); 287 288 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or 289 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or 290 // we are layerless. 291 if (layer_) { 292 layer_->set_delegate(NULL); 293 layer_ = NULL; 294 } 295 } 296 297 void Window::Init(ui::LayerType layer_type) { 298 InitWithWindowLayerType(UILayerTypeToWindowLayerType(layer_type)); 299 } 300 301 void Window::InitWithWindowLayerType(WindowLayerType window_layer_type) { 302 if (window_layer_type != WINDOW_LAYER_NONE) { 303 layer_ = new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type)); 304 layer_owner_.reset(layer_); 305 layer_->SetVisible(false); 306 layer_->set_delegate(this); 307 UpdateLayerName(name_); 308 layer_->SetFillsBoundsOpaquely(!transparent_); 309 } 310 311 Env::GetInstance()->NotifyWindowInitialized(this); 312 } 313 314 ui::Layer* Window::RecreateLayer() { 315 // Disconnect the old layer, but don't delete it. 316 ui::Layer* old_layer = AcquireLayer(); 317 if (!old_layer) 318 return NULL; 319 320 old_layer->set_delegate(NULL); 321 322 layer_ = new ui::Layer(old_layer->type()); 323 layer_owner_.reset(layer_); 324 layer_->SetVisible(old_layer->visible()); 325 layer_->set_scale_content(old_layer->scale_content()); 326 layer_->set_delegate(this); 327 layer_->SetMasksToBounds(old_layer->GetMasksToBounds()); 328 329 if (delegate_) 330 delegate_->DidRecreateLayer(old_layer, layer_); 331 332 UpdateLayerName(name_); 333 layer_->SetFillsBoundsOpaquely(!transparent_); 334 // Install new layer as a sibling of the old layer, stacked below it. 335 if (old_layer->parent()) { 336 old_layer->parent()->Add(layer_); 337 old_layer->parent()->StackBelow(layer_, old_layer); 338 } 339 // Migrate all the child layers over to the new layer. Copy the list because 340 // the items are removed during iteration. 341 std::vector<ui::Layer*> children_copy = old_layer->children(); 342 for (std::vector<ui::Layer*>::const_iterator it = children_copy.begin(); 343 it != children_copy.end(); 344 ++it) { 345 ui::Layer* child = *it; 346 layer_->Add(child); 347 } 348 return old_layer; 349 } 350 351 void Window::SetType(client::WindowType type) { 352 // Cannot change type after the window is initialized. 353 DCHECK(!layer_); 354 type_ = type; 355 } 356 357 void Window::SetName(const std::string& name) { 358 name_ = name; 359 360 if (layer_) 361 UpdateLayerName(name_); 362 } 363 364 void Window::SetTransparent(bool transparent) { 365 transparent_ = transparent; 366 if (layer_) 367 layer_->SetFillsBoundsOpaquely(!transparent_); 368 } 369 370 Window* Window::GetRootWindow() { 371 return const_cast<Window*>( 372 static_cast<const Window*>(this)->GetRootWindow()); 373 } 374 375 const Window* Window::GetRootWindow() const { 376 return dispatcher_ ? this : parent_ ? parent_->GetRootWindow() : NULL; 377 } 378 379 WindowEventDispatcher* Window::GetDispatcher() { 380 return const_cast<WindowEventDispatcher*>(const_cast<const Window*>(this)-> 381 GetDispatcher()); 382 } 383 384 const WindowEventDispatcher* Window::GetDispatcher() const { 385 const Window* root_window = GetRootWindow(); 386 return root_window ? root_window->dispatcher_ : NULL; 387 } 388 389 void Window::Show() { 390 SetVisible(true); 391 } 392 393 void Window::Hide() { 394 for (Windows::iterator it = transient_children_.begin(); 395 it != transient_children_.end(); ++it) { 396 (*it)->Hide(); 397 } 398 SetVisible(false); 399 ReleaseCapture(); 400 } 401 402 bool Window::IsVisible() const { 403 // Layer visibility can be inconsistent with window visibility, for example 404 // when a Window is hidden, we want this function to return false immediately 405 // after, even though the client may decide to animate the hide effect (and 406 // so the layer will be visible for some time after Hide() is called). 407 for (const Window* window = this; window; window = window->parent()) { 408 if (!window->visible_) 409 return false; 410 if (window->layer_) 411 return window->layer_->IsDrawn(); 412 } 413 return false; 414 } 415 416 gfx::Rect Window::GetBoundsInRootWindow() const { 417 // TODO(beng): There may be a better way to handle this, and the existing code 418 // is likely wrong anyway in a multi-display world, but this will 419 // do for now. 420 if (!GetRootWindow()) 421 return bounds(); 422 gfx::Point origin = bounds().origin(); 423 ConvertPointToTarget(parent_, GetRootWindow(), &origin); 424 return gfx::Rect(origin, bounds().size()); 425 } 426 427 gfx::Rect Window::GetBoundsInScreen() const { 428 gfx::Rect bounds(GetBoundsInRootWindow()); 429 const Window* root = GetRootWindow(); 430 if (root) { 431 aura::client::ScreenPositionClient* screen_position_client = 432 aura::client::GetScreenPositionClient(root); 433 if (screen_position_client) { 434 gfx::Point origin = bounds.origin(); 435 screen_position_client->ConvertPointToScreen(root, &origin); 436 bounds.set_origin(origin); 437 } 438 } 439 return bounds; 440 } 441 442 void Window::SetTransform(const gfx::Transform& transform) { 443 if (!layer_) { 444 // Transforms aren't supported on layerless windows. 445 NOTREACHED(); 446 return; 447 } 448 WindowEventDispatcher* dispatcher = GetDispatcher(); 449 bool contained_mouse = IsVisible() && dispatcher && 450 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); 451 layer_->SetTransform(transform); 452 if (dispatcher) 453 dispatcher->OnWindowTransformed(this, contained_mouse); 454 } 455 456 void Window::SetLayoutManager(LayoutManager* layout_manager) { 457 if (layout_manager == layout_manager_) 458 return; 459 layout_manager_.reset(layout_manager); 460 if (!layout_manager) 461 return; 462 // If we're changing to a new layout manager, ensure it is aware of all the 463 // existing child windows. 464 for (Windows::const_iterator it = children_.begin(); 465 it != children_.end(); 466 ++it) 467 layout_manager_->OnWindowAddedToLayout(*it); 468 } 469 470 void Window::SetBounds(const gfx::Rect& new_bounds) { 471 if (parent_ && parent_->layout_manager()) 472 parent_->layout_manager()->SetChildBounds(this, new_bounds); 473 else 474 SetBoundsInternal(new_bounds); 475 } 476 477 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen, 478 const gfx::Display& dst_display) { 479 Window* root = GetRootWindow(); 480 if (root) { 481 gfx::Point origin = new_bounds_in_screen.origin(); 482 aura::client::ScreenPositionClient* screen_position_client = 483 aura::client::GetScreenPositionClient(root); 484 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display); 485 return; 486 } 487 SetBounds(new_bounds_in_screen); 488 } 489 490 gfx::Rect Window::GetTargetBounds() const { 491 if (!layer_) 492 return bounds(); 493 494 if (!parent_ || parent_->layer_) 495 return layer_->GetTargetBounds(); 496 497 // We have a layer but our parent (who is valid) doesn't. This means the 498 // coordinates of the layer are relative to the first ancestor with a layer; 499 // convert to be relative to parent. 500 gfx::Vector2d offset; 501 const aura::Window* ancestor_with_layer = 502 parent_->GetAncestorWithLayer(&offset); 503 if (!ancestor_with_layer) 504 return layer_->GetTargetBounds(); 505 506 gfx::Rect layer_target_bounds = layer_->GetTargetBounds(); 507 layer_target_bounds -= offset; 508 return layer_target_bounds; 509 } 510 511 void Window::SchedulePaintInRect(const gfx::Rect& rect) { 512 if (!layer_ && parent_) { 513 // Notification of paint scheduled happens for the window with a layer. 514 gfx::Rect parent_rect(bounds().size()); 515 parent_rect.Intersect(rect); 516 if (!parent_rect.IsEmpty()) { 517 parent_rect.Offset(bounds().origin().OffsetFromOrigin()); 518 parent_->SchedulePaintInRect(parent_rect); 519 } 520 } else if (layer_ && layer_->SchedulePaint(rect)) { 521 FOR_EACH_OBSERVER( 522 WindowObserver, observers_, OnWindowPaintScheduled(this, rect)); 523 } 524 } 525 526 void Window::StackChildAtTop(Window* child) { 527 if (children_.size() <= 1 || child == children_.back()) 528 return; // In the front already. 529 StackChildAbove(child, children_.back()); 530 } 531 532 void Window::StackChildAbove(Window* child, Window* target) { 533 StackChildRelativeTo(child, target, STACK_ABOVE); 534 } 535 536 void Window::StackChildAtBottom(Window* child) { 537 if (children_.size() <= 1 || child == children_.front()) 538 return; // At the bottom already. 539 StackChildBelow(child, children_.front()); 540 } 541 542 void Window::StackChildBelow(Window* child, Window* target) { 543 StackChildRelativeTo(child, target, STACK_BELOW); 544 } 545 546 void Window::AddChild(Window* child) { 547 WindowObserver::HierarchyChangeParams params; 548 params.target = child; 549 params.new_parent = this; 550 params.old_parent = child->parent(); 551 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; 552 NotifyWindowHierarchyChange(params); 553 554 Window* old_root = child->GetRootWindow(); 555 556 DCHECK(std::find(children_.begin(), children_.end(), child) == 557 children_.end()); 558 if (child->parent()) 559 child->parent()->RemoveChildImpl(child, this); 560 561 gfx::Vector2d offset; 562 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset); 563 if (ancestor_with_layer) { 564 offset += child->bounds().OffsetFromOrigin(); 565 child->ReparentLayers(ancestor_with_layer->layer(), offset); 566 } 567 568 child->parent_ = this; 569 570 children_.push_back(child); 571 if (layout_manager_) 572 layout_manager_->OnWindowAddedToLayout(child); 573 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); 574 child->OnParentChanged(); 575 576 Window* root_window = GetRootWindow(); 577 if (root_window && old_root != root_window) { 578 root_window->GetDispatcher()->OnWindowAddedToRootWindow(child); 579 child->NotifyAddedToRootWindow(); 580 } 581 582 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED; 583 NotifyWindowHierarchyChange(params); 584 } 585 586 void Window::RemoveChild(Window* child) { 587 WindowObserver::HierarchyChangeParams params; 588 params.target = child; 589 params.new_parent = NULL; 590 params.old_parent = this; 591 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING; 592 NotifyWindowHierarchyChange(params); 593 594 RemoveChildImpl(child, NULL); 595 596 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED; 597 NotifyWindowHierarchyChange(params); 598 } 599 600 bool Window::Contains(const Window* other) const { 601 for (const Window* parent = other; parent; parent = parent->parent_) { 602 if (parent == this) 603 return true; 604 } 605 return false; 606 } 607 608 void Window::AddTransientChild(Window* child) { 609 if (child->transient_parent_) 610 child->transient_parent_->RemoveTransientChild(child); 611 DCHECK(std::find(transient_children_.begin(), transient_children_.end(), 612 child) == transient_children_.end()); 613 transient_children_.push_back(child); 614 child->transient_parent_ = this; 615 FOR_EACH_OBSERVER(WindowObserver, observers_, 616 OnAddTransientChild(this, child)); 617 } 618 619 void Window::RemoveTransientChild(Window* child) { 620 Windows::iterator i = 621 std::find(transient_children_.begin(), transient_children_.end(), child); 622 DCHECK(i != transient_children_.end()); 623 transient_children_.erase(i); 624 if (child->transient_parent_ == this) 625 child->transient_parent_ = NULL; 626 FOR_EACH_OBSERVER(WindowObserver, observers_, 627 OnRemoveTransientChild(this, child)); 628 } 629 630 Window* Window::GetChildById(int id) { 631 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id)); 632 } 633 634 const Window* Window::GetChildById(int id) const { 635 Windows::const_iterator i; 636 for (i = children_.begin(); i != children_.end(); ++i) { 637 if ((*i)->id() == id) 638 return *i; 639 const Window* result = (*i)->GetChildById(id); 640 if (result) 641 return result; 642 } 643 return NULL; 644 } 645 646 // static 647 void Window::ConvertPointToTarget(const Window* source, 648 const Window* target, 649 gfx::Point* point) { 650 if (!source) 651 return; 652 if (source->GetRootWindow() != target->GetRootWindow()) { 653 client::ScreenPositionClient* source_client = 654 client::GetScreenPositionClient(source->GetRootWindow()); 655 source_client->ConvertPointToScreen(source, point); 656 657 client::ScreenPositionClient* target_client = 658 client::GetScreenPositionClient(target->GetRootWindow()); 659 target_client->ConvertPointFromScreen(target, point); 660 } else if ((source != target) && (!source->layer_ || !target->layer_)) { 661 if (!source->layer_) { 662 gfx::Vector2d offset_to_layer; 663 source = source->GetAncestorWithLayer(&offset_to_layer); 664 *point += offset_to_layer; 665 } 666 if (!target->layer_) { 667 gfx::Vector2d offset_to_layer; 668 target = target->GetAncestorWithLayer(&offset_to_layer); 669 *point -= offset_to_layer; 670 } 671 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point); 672 } else { 673 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point); 674 } 675 } 676 677 void Window::MoveCursorTo(const gfx::Point& point_in_window) { 678 Window* root_window = GetRootWindow(); 679 DCHECK(root_window); 680 gfx::Point point_in_root(point_in_window); 681 ConvertPointToTarget(this, root_window, &point_in_root); 682 root_window->GetDispatcher()->MoveCursorTo(point_in_root); 683 } 684 685 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const { 686 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor; 687 } 688 689 void Window::SetEventFilter(ui::EventHandler* event_filter) { 690 if (event_filter_) 691 RemovePreTargetHandler(event_filter_.get()); 692 event_filter_.reset(event_filter); 693 if (event_filter) 694 AddPreTargetHandler(event_filter); 695 } 696 697 void Window::AddObserver(WindowObserver* observer) { 698 observers_.AddObserver(observer); 699 } 700 701 void Window::RemoveObserver(WindowObserver* observer) { 702 observers_.RemoveObserver(observer); 703 } 704 705 bool Window::HasObserver(WindowObserver* observer) { 706 return observers_.HasObserver(observer); 707 } 708 709 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const { 710 const Window* root_window = GetRootWindow(); 711 if (!root_window) 712 return false; 713 gfx::Point local_point(point_in_root); 714 ConvertPointToTarget(root_window, this, &local_point); 715 return gfx::Rect(GetTargetBounds().size()).Contains(local_point); 716 } 717 718 bool Window::ContainsPoint(const gfx::Point& local_point) const { 719 return gfx::Rect(bounds().size()).Contains(local_point); 720 } 721 722 bool Window::HitTest(const gfx::Point& local_point) { 723 // Expand my bounds for hit testing (override is usually zero but it's 724 // probably cheaper to do the math every time than to branch). 725 gfx::Rect local_bounds(gfx::Point(), bounds().size()); 726 local_bounds.Inset(aura::Env::GetInstance()->is_touch_down() ? 727 hit_test_bounds_override_outer_touch_ : 728 hit_test_bounds_override_outer_mouse_); 729 730 if (!delegate_ || !delegate_->HasHitTestMask()) 731 return local_bounds.Contains(local_point); 732 733 gfx::Path mask; 734 delegate_->GetHitTestMask(&mask); 735 736 SkRegion clip_region; 737 clip_region.setRect(local_bounds.x(), local_bounds.y(), 738 local_bounds.width(), local_bounds.height()); 739 SkRegion mask_region; 740 return mask_region.setPath(mask, clip_region) && 741 mask_region.contains(local_point.x(), local_point.y()); 742 } 743 744 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) { 745 return GetWindowForPoint(local_point, true, true); 746 } 747 748 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) { 749 return GetWindowForPoint(local_point, false, false); 750 } 751 752 Window* Window::GetToplevelWindow() { 753 Window* topmost_window_with_delegate = NULL; 754 for (aura::Window* window = this; window != NULL; window = window->parent()) { 755 if (window->delegate()) 756 topmost_window_with_delegate = window; 757 } 758 return topmost_window_with_delegate; 759 } 760 761 void Window::Focus() { 762 client::FocusClient* client = client::GetFocusClient(this); 763 DCHECK(client); 764 client->FocusWindow(this); 765 } 766 767 void Window::Blur() { 768 client::FocusClient* client = client::GetFocusClient(this); 769 DCHECK(client); 770 client->FocusWindow(NULL); 771 } 772 773 bool Window::HasFocus() const { 774 client::FocusClient* client = client::GetFocusClient(this); 775 return client && client->GetFocusedWindow() == this; 776 } 777 778 bool Window::CanFocus() const { 779 if (dispatcher_) 780 return IsVisible(); 781 782 // NOTE: as part of focusing the window the ActivationClient may make the 783 // window visible (by way of making a hidden ancestor visible). For this 784 // reason we can't check visibility here and assume the client is doing it. 785 if (!parent_ || (delegate_ && !delegate_->CanFocus())) 786 return false; 787 788 // The client may forbid certain windows from receiving focus at a given point 789 // in time. 790 client::EventClient* client = client::GetEventClient(GetRootWindow()); 791 if (client && !client->CanProcessEventsWithinSubtree(this)) 792 return false; 793 794 return parent_->CanFocus(); 795 } 796 797 bool Window::CanReceiveEvents() const { 798 if (dispatcher_) 799 return IsVisible(); 800 801 // The client may forbid certain windows from receiving events at a given 802 // point in time. 803 client::EventClient* client = client::GetEventClient(GetRootWindow()); 804 if (client && !client->CanProcessEventsWithinSubtree(this)) 805 return false; 806 807 return parent_ && IsVisible() && parent_->CanReceiveEvents(); 808 } 809 810 void Window::SetCapture() { 811 if (!IsVisible()) 812 return; 813 814 Window* root_window = GetRootWindow(); 815 if (!root_window) 816 return; 817 client::GetCaptureClient(root_window)->SetCapture(this); 818 } 819 820 void Window::ReleaseCapture() { 821 Window* root_window = GetRootWindow(); 822 if (!root_window) 823 return; 824 client::GetCaptureClient(root_window)->ReleaseCapture(this); 825 } 826 827 bool Window::HasCapture() { 828 Window* root_window = GetRootWindow(); 829 if (!root_window) 830 return false; 831 client::CaptureClient* capture_client = client::GetCaptureClient(root_window); 832 return capture_client && capture_client->GetCaptureWindow() == this; 833 } 834 835 void Window::SuppressPaint() { 836 if (layer_) 837 layer_->SuppressPaint(); 838 } 839 840 // {Set,Get,Clear}Property are implemented in window_property.h. 841 842 void Window::SetNativeWindowProperty(const char* key, void* value) { 843 SetPropertyInternal( 844 key, key, NULL, reinterpret_cast<int64>(value), 0); 845 } 846 847 void* Window::GetNativeWindowProperty(const char* key) const { 848 return reinterpret_cast<void*>(GetPropertyInternal(key, 0)); 849 } 850 851 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) { 852 ScopedCursorHider hider(this); 853 if (dispatcher_) 854 dispatcher_->host()->OnDeviceScaleFactorChanged(device_scale_factor); 855 if (delegate_) 856 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 857 } 858 859 #if !defined(NDEBUG) 860 std::string Window::GetDebugInfo() const { 861 return base::StringPrintf( 862 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f", 863 name().empty() ? "Unknown" : name().c_str(), id(), 864 bounds().x(), bounds().y(), bounds().width(), bounds().height(), 865 visible_ ? "WindowVisible" : "WindowHidden", 866 layer_ ? 867 (layer_->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") : 868 "NoLayer", 869 layer_ ? layer_->opacity() : 1.0f); 870 } 871 872 void Window::PrintWindowHierarchy(int depth) const { 873 VLOG(0) << base::StringPrintf( 874 "%*s%s", depth * 2, "", GetDebugInfo().c_str()); 875 for (Windows::const_iterator it = children_.begin(); 876 it != children_.end(); ++it) { 877 Window* child = *it; 878 child->PrintWindowHierarchy(depth + 1); 879 } 880 } 881 #endif 882 883 void Window::RemoveOrDestroyChildren() { 884 while (!children_.empty()) { 885 Window* child = children_[0]; 886 if (child->owned_by_parent_) { 887 delete child; 888 // Deleting the child so remove it from out children_ list. 889 DCHECK(std::find(children_.begin(), children_.end(), child) == 890 children_.end()); 891 } else { 892 // Even if we can't delete the child, we still need to remove it from the 893 // parent so that relevant bookkeeping (parent_ back-pointers etc) are 894 // updated. 895 RemoveChild(child); 896 } 897 } 898 } 899 900 /////////////////////////////////////////////////////////////////////////////// 901 // Window, private: 902 903 int64 Window::SetPropertyInternal(const void* key, 904 const char* name, 905 PropertyDeallocator deallocator, 906 int64 value, 907 int64 default_value) { 908 int64 old = GetPropertyInternal(key, default_value); 909 if (value == default_value) { 910 prop_map_.erase(key); 911 } else { 912 Value prop_value; 913 prop_value.name = name; 914 prop_value.value = value; 915 prop_value.deallocator = deallocator; 916 prop_map_[key] = prop_value; 917 } 918 FOR_EACH_OBSERVER(WindowObserver, observers_, 919 OnWindowPropertyChanged(this, key, old)); 920 return old; 921 } 922 923 int64 Window::GetPropertyInternal(const void* key, 924 int64 default_value) const { 925 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); 926 if (iter == prop_map_.end()) 927 return default_value; 928 return iter->second.value; 929 } 930 931 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) { 932 gfx::Rect actual_new_bounds(new_bounds); 933 934 // Ensure we don't go smaller than our minimum bounds. 935 if (delegate_) { 936 const gfx::Size& min_size = delegate_->GetMinimumSize(); 937 actual_new_bounds.set_width( 938 std::max(min_size.width(), actual_new_bounds.width())); 939 actual_new_bounds.set_height( 940 std::max(min_size.height(), actual_new_bounds.height())); 941 } 942 943 gfx::Rect old_bounds = GetTargetBounds(); 944 945 // Always need to set the layer's bounds -- even if it is to the same thing. 946 // This may cause important side effects such as stopping animation. 947 if (!layer_) { 948 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() - 949 bounds_.OffsetFromOrigin(); 950 bounds_ = new_bounds; 951 OffsetLayerBounds(origin_delta); 952 } else { 953 if (parent_ && !parent_->layer_) { 954 gfx::Vector2d offset; 955 const aura::Window* ancestor_with_layer = 956 parent_->GetAncestorWithLayer(&offset); 957 if (ancestor_with_layer) 958 actual_new_bounds.Offset(offset); 959 } 960 layer_->SetBounds(actual_new_bounds); 961 } 962 963 // If we are currently not the layer's delegate, we will not get bounds 964 // changed notification from the layer (this typically happens after animating 965 // hidden). We must notify ourselves. 966 if (!layer_ || layer_->delegate() != this) 967 OnWindowBoundsChanged(old_bounds, ContainsMouse()); 968 } 969 970 void Window::SetVisible(bool visible) { 971 if ((layer_ && visible == layer_->GetTargetVisibility()) || 972 (!layer_ && visible == visible_)) 973 return; // No change. 974 975 FOR_EACH_OBSERVER(WindowObserver, observers_, 976 OnWindowVisibilityChanging(this, visible)); 977 978 WindowEventDispatcher* dispatcher = GetDispatcher(); 979 if (dispatcher) 980 dispatcher->DispatchMouseExitToHidingWindow(this); 981 982 client::VisibilityClient* visibility_client = 983 client::GetVisibilityClient(this); 984 if (visibility_client) 985 visibility_client->UpdateLayerVisibility(this, visible); 986 else if (layer_) 987 layer_->SetVisible(visible); 988 visible_ = visible; 989 SchedulePaint(); 990 if (parent_ && parent_->layout_manager_) 991 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); 992 993 if (delegate_) 994 delegate_->OnWindowTargetVisibilityChanged(visible); 995 996 NotifyWindowVisibilityChanged(this, visible); 997 998 if (dispatcher) 999 dispatcher->OnWindowVisibilityChanged(this, visible); 1000 } 1001 1002 void Window::SchedulePaint() { 1003 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); 1004 } 1005 1006 void Window::Paint(gfx::Canvas* canvas) { 1007 if (delegate_) 1008 delegate_->OnPaint(canvas); 1009 PaintLayerlessChildren(canvas); 1010 } 1011 1012 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) { 1013 for (size_t i = 0, count = children_.size(); i < count; ++i) { 1014 Window* child = children_[i]; 1015 if (!child->layer_ && child->visible_) { 1016 gfx::ScopedCanvas scoped_canvas(canvas); 1017 if (canvas->ClipRect(child->bounds())) { 1018 canvas->Translate(child->bounds().OffsetFromOrigin()); 1019 child->Paint(canvas); 1020 } 1021 } 1022 } 1023 } 1024 1025 Window* Window::GetWindowForPoint(const gfx::Point& local_point, 1026 bool return_tightest, 1027 bool for_event_handling) { 1028 if (!IsVisible()) 1029 return NULL; 1030 1031 if ((for_event_handling && !HitTest(local_point)) || 1032 (!for_event_handling && !ContainsPoint(local_point))) 1033 return NULL; 1034 1035 // Check if I should claim this event and not pass it to my children because 1036 // the location is inside my hit test override area. For details, see 1037 // set_hit_test_bounds_override_inner(). 1038 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) { 1039 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size()); 1040 inset_local_bounds.Inset(hit_test_bounds_override_inner_); 1041 // We know we're inside the normal local bounds, so if we're outside the 1042 // inset bounds we must be in the special hit test override area. 1043 DCHECK(HitTest(local_point)); 1044 if (!inset_local_bounds.Contains(local_point)) 1045 return delegate_ ? this : NULL; 1046 } 1047 1048 if (!return_tightest && delegate_) 1049 return this; 1050 1051 for (Windows::const_reverse_iterator it = children_.rbegin(), 1052 rend = children_.rend(); 1053 it != rend; ++it) { 1054 Window* child = *it; 1055 1056 if (for_event_handling) { 1057 if (child->ignore_events_) 1058 continue; 1059 // The client may not allow events to be processed by certain subtrees. 1060 client::EventClient* client = client::GetEventClient(GetRootWindow()); 1061 if (client && !client->CanProcessEventsWithinSubtree(child)) 1062 continue; 1063 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling( 1064 child, local_point)) 1065 continue; 1066 } 1067 1068 gfx::Point point_in_child_coords(local_point); 1069 ConvertPointToTarget(this, child, &point_in_child_coords); 1070 Window* match = child->GetWindowForPoint(point_in_child_coords, 1071 return_tightest, 1072 for_event_handling); 1073 if (match) 1074 return match; 1075 } 1076 1077 return delegate_ ? this : NULL; 1078 } 1079 1080 void Window::RemoveChildImpl(Window* child, Window* new_parent) { 1081 if (layout_manager_) 1082 layout_manager_->OnWillRemoveWindowFromLayout(child); 1083 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); 1084 Window* root_window = child->GetRootWindow(); 1085 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL; 1086 if (root_window && root_window != new_root_window) { 1087 root_window->GetDispatcher()->OnWindowRemovedFromRootWindow( 1088 child, new_root_window); 1089 child->NotifyRemovingFromRootWindow(); 1090 } 1091 1092 gfx::Vector2d offset; 1093 GetAncestorWithLayer(&offset); 1094 child->UnparentLayers(!layer_, offset); 1095 child->parent_ = NULL; 1096 Windows::iterator i = std::find(children_.begin(), children_.end(), child); 1097 DCHECK(i != children_.end()); 1098 children_.erase(i); 1099 child->OnParentChanged(); 1100 if (layout_manager_) 1101 layout_manager_->OnWindowRemovedFromLayout(child); 1102 } 1103 1104 void Window::UnparentLayers(bool has_layerless_ancestor, 1105 const gfx::Vector2d& offset) { 1106 if (!layer_) { 1107 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin(); 1108 for (size_t i = 0; i < children_.size(); ++i) { 1109 children_[i]->UnparentLayers(true, new_offset); 1110 } 1111 } else { 1112 // Only remove the layer if we still own it. Someone else may have acquired 1113 // ownership of it via AcquireLayer() and may expect the hierarchy to go 1114 // unchanged as the Window is destroyed. 1115 if (layer_owner_) { 1116 if (layer_->parent()) 1117 layer_->parent()->Remove(layer_); 1118 if (has_layerless_ancestor) { 1119 const gfx::Rect real_bounds(bounds_); 1120 gfx::Rect layer_bounds(layer_->bounds()); 1121 layer_bounds.Offset(-offset); 1122 layer_->SetBounds(layer_bounds); 1123 bounds_ = real_bounds; 1124 } 1125 } 1126 } 1127 } 1128 1129 void Window::ReparentLayers(ui::Layer* parent_layer, 1130 const gfx::Vector2d& offset) { 1131 if (!layer_) { 1132 for (size_t i = 0; i < children_.size(); ++i) { 1133 children_[i]->ReparentLayers( 1134 parent_layer, 1135 offset + children_[i]->bounds().OffsetFromOrigin()); 1136 } 1137 } else { 1138 const gfx::Rect real_bounds(bounds()); 1139 parent_layer->Add(layer_); 1140 gfx::Rect layer_bounds(layer_->bounds().size()); 1141 layer_bounds += offset; 1142 layer_->SetBounds(layer_bounds); 1143 bounds_ = real_bounds; 1144 } 1145 } 1146 1147 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) { 1148 if (!layer_) { 1149 for (size_t i = 0; i < children_.size(); ++i) 1150 children_[i]->OffsetLayerBounds(offset); 1151 } else { 1152 gfx::Rect layer_bounds(layer_->bounds()); 1153 layer_bounds += offset; 1154 layer_->SetBounds(layer_bounds); 1155 } 1156 } 1157 1158 void Window::OnParentChanged() { 1159 FOR_EACH_OBSERVER( 1160 WindowObserver, observers_, OnWindowParentChanged(this, parent_)); 1161 } 1162 1163 bool Window::HasTransientAncestor(const Window* ancestor) const { 1164 if (transient_parent_ == ancestor) 1165 return true; 1166 return transient_parent_ ? 1167 transient_parent_->HasTransientAncestor(ancestor) : false; 1168 } 1169 1170 void Window::SkipNullDelegatesForStacking(StackDirection direction, 1171 Window** target) const { 1172 DCHECK_EQ(this, (*target)->parent()); 1173 size_t target_i = 1174 std::find(children_.begin(), children_.end(), *target) - 1175 children_.begin(); 1176 1177 // By convention we don't stack on top of windows with layers with NULL 1178 // delegates. Walk backward to find a valid target window. 1179 // See tests WindowTest.StackingMadrigal and StackOverClosingTransient 1180 // for an explanation of this. 1181 while (target_i > 0) { 1182 const size_t index = direction == STACK_ABOVE ? target_i : target_i - 1; 1183 if (!children_[index]->layer_ || 1184 children_[index]->layer_->delegate() != NULL) 1185 break; 1186 --target_i; 1187 } 1188 *target = children_[target_i]; 1189 } 1190 1191 void Window::StackChildRelativeTo(Window* child, 1192 Window* target, 1193 StackDirection direction) { 1194 DCHECK_NE(child, target); 1195 DCHECK(child); 1196 DCHECK(target); 1197 DCHECK_EQ(this, child->parent()); 1198 DCHECK_EQ(this, target->parent()); 1199 1200 client::WindowStackingClient* stacking_client = 1201 client::GetWindowStackingClient(); 1202 if (stacking_client) 1203 stacking_client->AdjustStacking(&child, &target, &direction); 1204 1205 SkipNullDelegatesForStacking(direction, &target); 1206 1207 // If we couldn't find a valid target position, don't move anything. 1208 if (direction == STACK_ABOVE && 1209 (target->layer_ && target->layer_->delegate() == NULL)) 1210 return; 1211 1212 // Don't try to stack a child above itself. 1213 if (child == target) 1214 return; 1215 1216 // Move the child. 1217 StackChildRelativeToImpl(child, target, direction); 1218 1219 // Stack any transient children that share the same parent to be in front of 1220 // 'child'. Preserve the existing stacking order by iterating in the order 1221 // those children appear in children_ array. 1222 Window* last_transient = child; 1223 Windows children(children_); 1224 for (Windows::iterator it = children.begin(); it != children.end(); ++it) { 1225 Window* transient_child = *it; 1226 if (transient_child != last_transient && 1227 transient_child->HasTransientAncestor(child)) { 1228 StackChildRelativeToImpl(transient_child, last_transient, STACK_ABOVE); 1229 last_transient = transient_child; 1230 } 1231 } 1232 } 1233 1234 void Window::StackChildRelativeToImpl(Window* child, 1235 Window* target, 1236 StackDirection direction) { 1237 DCHECK_NE(child, target); 1238 DCHECK(child); 1239 DCHECK(target); 1240 DCHECK_EQ(this, child->parent()); 1241 DCHECK_EQ(this, target->parent()); 1242 1243 const size_t child_i = 1244 std::find(children_.begin(), children_.end(), child) - children_.begin(); 1245 const size_t target_i = 1246 std::find(children_.begin(), children_.end(), target) - children_.begin(); 1247 1248 // Don't move the child if it is already in the right place. 1249 if ((direction == STACK_ABOVE && child_i == target_i + 1) || 1250 (direction == STACK_BELOW && child_i + 1 == target_i)) 1251 return; 1252 1253 const size_t dest_i = 1254 direction == STACK_ABOVE ? 1255 (child_i < target_i ? target_i : target_i + 1) : 1256 (child_i < target_i ? target_i - 1 : target_i); 1257 children_.erase(children_.begin() + child_i); 1258 children_.insert(children_.begin() + dest_i, child); 1259 1260 StackChildLayerRelativeTo(child, target, direction); 1261 1262 child->OnStackingChanged(); 1263 } 1264 1265 void Window::StackChildLayerRelativeTo(Window* child, 1266 Window* target, 1267 StackDirection direction) { 1268 Window* ancestor_with_layer = GetAncestorWithLayer(NULL); 1269 ui::Layer* ancestor_layer = 1270 ancestor_with_layer ? ancestor_with_layer->layer() : NULL; 1271 if (!ancestor_layer) 1272 return; 1273 1274 if (child->layer_ && target->layer_) { 1275 if (direction == STACK_ABOVE) 1276 ancestor_layer->StackAbove(child->layer_, target->layer_); 1277 else 1278 ancestor_layer->StackBelow(child->layer_, target->layer_); 1279 return; 1280 } 1281 typedef std::vector<ui::Layer*> Layers; 1282 Layers layers; 1283 GetLayersToStack(child, &layers); 1284 if (layers.empty()) 1285 return; 1286 1287 ui::Layer* target_layer; 1288 if (direction == STACK_ABOVE) { 1289 target_layer = 1290 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child); 1291 } else { 1292 target_layer = 1293 FindStackingTargetLayer<Windows::const_iterator>(target, child); 1294 } 1295 1296 if (!target_layer) { 1297 if (direction == STACK_ABOVE) { 1298 for (Layers::const_reverse_iterator i = layers.rbegin(); 1299 i != layers.rend(); ++i) { 1300 ancestor_layer->StackAtBottom(*i); 1301 } 1302 } else { 1303 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i) 1304 ancestor_layer->StackAtTop(*i); 1305 } 1306 return; 1307 } 1308 1309 if (direction == STACK_ABOVE) { 1310 for (Layers::const_reverse_iterator i = layers.rbegin(); 1311 i != layers.rend(); ++i) { 1312 ancestor_layer->StackAbove(*i, target_layer); 1313 } 1314 } else { 1315 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i) 1316 ancestor_layer->StackBelow(*i, target_layer); 1317 } 1318 } 1319 1320 void Window::OnStackingChanged() { 1321 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this)); 1322 } 1323 1324 void Window::NotifyRemovingFromRootWindow() { 1325 FOR_EACH_OBSERVER(WindowObserver, observers_, 1326 OnWindowRemovingFromRootWindow(this)); 1327 for (Window::Windows::const_iterator it = children_.begin(); 1328 it != children_.end(); ++it) { 1329 (*it)->NotifyRemovingFromRootWindow(); 1330 } 1331 } 1332 1333 void Window::NotifyAddedToRootWindow() { 1334 FOR_EACH_OBSERVER(WindowObserver, observers_, 1335 OnWindowAddedToRootWindow(this)); 1336 for (Window::Windows::const_iterator it = children_.begin(); 1337 it != children_.end(); ++it) { 1338 (*it)->NotifyAddedToRootWindow(); 1339 } 1340 } 1341 1342 void Window::NotifyWindowHierarchyChange( 1343 const WindowObserver::HierarchyChangeParams& params) { 1344 params.target->NotifyWindowHierarchyChangeDown(params); 1345 switch (params.phase) { 1346 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING: 1347 if (params.old_parent) 1348 params.old_parent->NotifyWindowHierarchyChangeUp(params); 1349 break; 1350 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED: 1351 if (params.new_parent) 1352 params.new_parent->NotifyWindowHierarchyChangeUp(params); 1353 break; 1354 default: 1355 NOTREACHED(); 1356 break; 1357 } 1358 } 1359 1360 void Window::NotifyWindowHierarchyChangeDown( 1361 const WindowObserver::HierarchyChangeParams& params) { 1362 NotifyWindowHierarchyChangeAtReceiver(params); 1363 for (Window::Windows::const_iterator it = children_.begin(); 1364 it != children_.end(); ++it) { 1365 (*it)->NotifyWindowHierarchyChangeDown(params); 1366 } 1367 } 1368 1369 void Window::NotifyWindowHierarchyChangeUp( 1370 const WindowObserver::HierarchyChangeParams& params) { 1371 for (Window* window = this; window; window = window->parent()) 1372 window->NotifyWindowHierarchyChangeAtReceiver(params); 1373 } 1374 1375 void Window::NotifyWindowHierarchyChangeAtReceiver( 1376 const WindowObserver::HierarchyChangeParams& params) { 1377 WindowObserver::HierarchyChangeParams local_params = params; 1378 local_params.receiver = this; 1379 1380 switch (params.phase) { 1381 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING: 1382 FOR_EACH_OBSERVER(WindowObserver, observers_, 1383 OnWindowHierarchyChanging(local_params)); 1384 break; 1385 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED: 1386 FOR_EACH_OBSERVER(WindowObserver, observers_, 1387 OnWindowHierarchyChanged(local_params)); 1388 break; 1389 default: 1390 NOTREACHED(); 1391 break; 1392 } 1393 } 1394 1395 void Window::NotifyWindowVisibilityChanged(aura::Window* target, 1396 bool visible) { 1397 if (!NotifyWindowVisibilityChangedDown(target, visible)) { 1398 return; // |this| has been deleted. 1399 } 1400 NotifyWindowVisibilityChangedUp(target, visible); 1401 } 1402 1403 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target, 1404 bool visible) { 1405 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one 1406 // of the observers. We create an local observer for that. In that case we 1407 // exit without further access to any members. 1408 WindowTracker tracker; 1409 tracker.Add(this); 1410 FOR_EACH_OBSERVER(WindowObserver, observers_, 1411 OnWindowVisibilityChanged(target, visible)); 1412 return tracker.Contains(this); 1413 } 1414 1415 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target, 1416 bool visible) { 1417 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible)) 1418 return false; // |this| was deleted. 1419 std::set<const Window*> child_already_processed; 1420 bool child_destroyed = false; 1421 do { 1422 child_destroyed = false; 1423 for (Window::Windows::const_iterator it = children_.begin(); 1424 it != children_.end(); ++it) { 1425 if (!child_already_processed.insert(*it).second) 1426 continue; 1427 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) { 1428 // |*it| was deleted, |it| is invalid and |children_| has changed. 1429 // We exit the current for-loop and enter a new one. 1430 child_destroyed = true; 1431 break; 1432 } 1433 } 1434 } while (child_destroyed); 1435 return true; 1436 } 1437 1438 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target, 1439 bool visible) { 1440 for (Window* window = this; window; window = window->parent()) { 1441 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible); 1442 DCHECK(ret); 1443 } 1444 } 1445 1446 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds, 1447 bool contained_mouse) { 1448 if (layer_) { 1449 bounds_ = layer_->bounds(); 1450 if (parent_ && !parent_->layer_) { 1451 gfx::Vector2d offset; 1452 aura::Window* ancestor_with_layer = 1453 parent_->GetAncestorWithLayer(&offset); 1454 if (ancestor_with_layer) 1455 bounds_.Offset(-offset); 1456 } 1457 } 1458 1459 if (layout_manager_) 1460 layout_manager_->OnWindowResized(); 1461 if (delegate_) 1462 delegate_->OnBoundsChanged(old_bounds, bounds()); 1463 FOR_EACH_OBSERVER(WindowObserver, 1464 observers_, 1465 OnWindowBoundsChanged(this, old_bounds, bounds())); 1466 WindowEventDispatcher* dispatcher = GetDispatcher(); 1467 if (dispatcher) 1468 dispatcher->OnWindowBoundsChanged(this, contained_mouse); 1469 } 1470 1471 void Window::OnPaintLayer(gfx::Canvas* canvas) { 1472 Paint(canvas); 1473 } 1474 1475 base::Closure Window::PrepareForLayerBoundsChange() { 1476 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this), 1477 bounds(), ContainsMouse()); 1478 } 1479 1480 bool Window::CanAcceptEvent(const ui::Event& event) { 1481 // The client may forbid certain windows from receiving events at a given 1482 // point in time. 1483 client::EventClient* client = client::GetEventClient(GetRootWindow()); 1484 if (client && !client->CanProcessEventsWithinSubtree(this)) 1485 return false; 1486 1487 // We need to make sure that a touch cancel event and any gesture events it 1488 // creates can always reach the window. This ensures that we receive a valid 1489 // touch / gesture stream. 1490 if (event.IsEndingEvent()) 1491 return true; 1492 1493 if (!IsVisible()) 1494 return false; 1495 1496 // The top-most window can always process an event. 1497 if (!parent_) 1498 return true; 1499 1500 // For located events (i.e. mouse, touch etc.), an assumption is made that 1501 // windows that don't have a delegate cannot process the event (see more in 1502 // GetWindowForPoint()). This assumption is not made for key events. 1503 return event.IsKeyEvent() || delegate_; 1504 } 1505 1506 ui::EventTarget* Window::GetParentTarget() { 1507 if (dispatcher_) { 1508 return client::GetEventClient(this) ? 1509 client::GetEventClient(this)->GetToplevelEventTarget() : 1510 Env::GetInstance(); 1511 } 1512 return parent_; 1513 } 1514 1515 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const { 1516 return scoped_ptr<ui::EventTargetIterator>( 1517 new ui::EventTargetIteratorImpl<Window>(children())); 1518 } 1519 1520 ui::EventTargeter* Window::GetEventTargeter() { 1521 return targeter_.get(); 1522 } 1523 1524 void Window::ConvertEventToTarget(ui::EventTarget* target, 1525 ui::LocatedEvent* event) { 1526 event->ConvertLocationToTarget(this, 1527 static_cast<Window*>(target)); 1528 } 1529 1530 void Window::UpdateLayerName(const std::string& name) { 1531 #if !defined(NDEBUG) 1532 DCHECK(layer_); 1533 1534 std::string layer_name(name_); 1535 if (layer_name.empty()) 1536 layer_name = "Unnamed Window"; 1537 1538 if (id_ != -1) 1539 layer_name += " " + base::IntToString(id_); 1540 1541 layer_->set_name(layer_name); 1542 #endif 1543 } 1544 1545 bool Window::ContainsMouse() { 1546 bool contains_mouse = false; 1547 if (IsVisible()) { 1548 WindowEventDispatcher* dispatcher = GetDispatcher(); 1549 contains_mouse = dispatcher && 1550 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot()); 1551 } 1552 return contains_mouse; 1553 } 1554 1555 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const { 1556 for (const aura::Window* window = this; window; window = window->parent()) { 1557 if (window->layer_) 1558 return window; 1559 if (offset) 1560 *offset += window->bounds().OffsetFromOrigin(); 1561 } 1562 if (offset) 1563 *offset = gfx::Vector2d(); 1564 return NULL; 1565 } 1566 1567 } // namespace aura 1568