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