OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/frame_painter.h" | 5 #include "ash/wm/frame_painter.h" |
6 | 6 |
7 #include "ash/ash_constants.h" | 7 #include "ash/ash_constants.h" |
8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
9 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
10 #include "ash/wm/property_util.h" | 10 #include "ash/wm/property_util.h" |
11 #include "ash/wm/window_properties.h" | 11 #include "ash/wm/window_properties.h" |
12 #include "ash/wm/window_util.h" | 12 #include "ash/wm/window_util.h" |
13 #include "ash/wm/workspace_controller.h" | |
14 #include "base/logging.h" // DCHECK | 13 #include "base/logging.h" // DCHECK |
15 #include "grit/ash_resources.h" | 14 #include "grit/ash_resources.h" |
16 #include "third_party/skia/include/core/SkCanvas.h" | 15 #include "third_party/skia/include/core/SkCanvas.h" |
17 #include "third_party/skia/include/core/SkColor.h" | 16 #include "third_party/skia/include/core/SkColor.h" |
18 #include "third_party/skia/include/core/SkPaint.h" | 17 #include "third_party/skia/include/core/SkPaint.h" |
19 #include "third_party/skia/include/core/SkPath.h" | 18 #include "third_party/skia/include/core/SkPath.h" |
20 #include "ui/aura/client/aura_constants.h" | 19 #include "ui/aura/client/aura_constants.h" |
21 #include "ui/aura/env.h" | 20 #include "ui/aura/env.h" |
22 #include "ui/aura/root_window.h" | 21 #include "ui/aura/root_window.h" |
23 #include "ui/aura/window.h" | 22 #include "ui/aura/window.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 FramePainter::~FramePainter() { | 159 FramePainter::~FramePainter() { |
161 // Sometimes we are destroyed before the window closes, so ensure we clean up. | 160 // Sometimes we are destroyed before the window closes, so ensure we clean up. |
162 if (window_) { | 161 if (window_) { |
163 aura::RootWindow* root = window_->GetRootWindow(); | 162 aura::RootWindow* root = window_->GetRootWindow(); |
164 if (root && | 163 if (root && |
165 root->GetProperty(internal::kSoloWindowFramePainterKey) == this) { | 164 root->GetProperty(internal::kSoloWindowFramePainterKey) == this) { |
166 root->SetProperty(internal::kSoloWindowFramePainterKey, | 165 root->SetProperty(internal::kSoloWindowFramePainterKey, |
167 static_cast<FramePainter*>(NULL)); | 166 static_cast<FramePainter*>(NULL)); |
168 } | 167 } |
169 window_->RemoveObserver(this); | 168 window_->RemoveObserver(this); |
169 if (root) | |
170 root->RemoveObserver(this); | |
170 } | 171 } |
171 instances_->erase(this); | 172 instances_->erase(this); |
172 } | 173 } |
173 | 174 |
174 void FramePainter::Init(views::Widget* frame, | 175 void FramePainter::Init(views::Widget* frame, |
175 views::View* window_icon, | 176 views::View* window_icon, |
176 views::ImageButton* size_button, | 177 views::ImageButton* size_button, |
177 views::ImageButton* close_button, | 178 views::ImageButton* close_button, |
178 SizeButtonBehavior behavior) { | 179 SizeButtonBehavior behavior) { |
179 DCHECK(frame); | 180 DCHECK(frame); |
(...skipping 29 matching lines...) Expand all Loading... | |
209 kResizeOutsideBoundsScaleForTouch); | 210 kResizeOutsideBoundsScaleForTouch); |
210 // Ensure we get resize cursors just inside our bounds as well. | 211 // Ensure we get resize cursors just inside our bounds as well. |
211 window_->set_hit_test_bounds_override_inner( | 212 window_->set_hit_test_bounds_override_inner( |
212 gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, | 213 gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, |
213 kResizeInsideBoundsSize, kResizeInsideBoundsSize)); | 214 kResizeInsideBoundsSize, kResizeInsideBoundsSize)); |
214 | 215 |
215 // Watch for maximize/restore/fullscreen state changes. Observer removes | 216 // Watch for maximize/restore/fullscreen state changes. Observer removes |
216 // itself in OnWindowDestroying() below, or in the destructor if we go away | 217 // itself in OnWindowDestroying() below, or in the destructor if we go away |
217 // before the window. | 218 // before the window. |
218 window_->AddObserver(this); | 219 window_->AddObserver(this); |
220 aura::Window* root = window_->GetRootWindow(); | |
221 if (root) | |
222 root->AddObserver(this); | |
219 | 223 |
220 // If there is already a solo window in the same root, this initialization | 224 // If there is already a solo window in the same root, this initialization |
221 // should turn off its solo-mode. | 225 // should turn off its solo-mode. |
222 UpdateSoloWindowFramePainter(NULL); | 226 UpdateSoloWindowFramePainter(NULL); |
223 } | 227 } |
224 | 228 |
225 // static | 229 // static |
226 void FramePainter::UpdateSoloWindowHeader(RootWindow* root_window) { | 230 void FramePainter::UpdateSoloWindowHeader(RootWindow* root_window) { |
227 // Use a separate function here so callers outside of FramePainter don't need | 231 // Use a separate function here so callers outside of FramePainter don't need |
228 // to know about "ignorable_window". | 232 // to know about "ignorable_window". |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 frame_->non_client_view()->SchedulePaintInRect( | 580 frame_->non_client_view()->SchedulePaintInRect( |
577 GetTitleBounds(view, title_font)); | 581 GetTitleBounds(view, title_font)); |
578 } | 582 } |
579 | 583 |
580 /////////////////////////////////////////////////////////////////////////////// | 584 /////////////////////////////////////////////////////////////////////////////// |
581 // aura::WindowObserver overrides: | 585 // aura::WindowObserver overrides: |
582 | 586 |
583 void FramePainter::OnWindowPropertyChanged(aura::Window* window, | 587 void FramePainter::OnWindowPropertyChanged(aura::Window* window, |
584 const void* key, | 588 const void* key, |
585 intptr_t old) { | 589 intptr_t old) { |
590 // When either 'kWindowTrackedByWorkspaceKey' changes or | |
591 // 'kCyclingThroughWorkspacesKey' changes, we are going to paint the header | |
592 // differently. Schedule a paint to ensure everything is updated correctly. | |
586 if (key == internal::kWindowTrackedByWorkspaceKey && | 593 if (key == internal::kWindowTrackedByWorkspaceKey && |
587 GetTrackedByWorkspace(window)) { | 594 GetTrackedByWorkspace(window)) { |
588 // When 'kWindowTrackedByWorkspaceKey' changes we're going to paint the | 595 frame_->non_client_view()->SchedulePaint(); |
589 // header differently. Schedule a paint to ensure everything is updated | 596 } else if (key == internal::kCyclingThroughWorkspacesKey) { |
590 // correctly. | |
591 frame_->non_client_view()->SchedulePaint(); | 597 frame_->non_client_view()->SchedulePaint(); |
592 } | 598 } |
599 | |
593 if (key != aura::client::kShowStateKey) | 600 if (key != aura::client::kShowStateKey) |
594 return; | 601 return; |
595 | 602 |
596 // Maximized and fullscreen windows don't want resize handles overlapping the | 603 // Maximized and fullscreen windows don't want resize handles overlapping the |
597 // content area, because when the user moves the cursor to the right screen | 604 // content area, because when the user moves the cursor to the right screen |
598 // edge we want them to be able to hit the scroll bar. | 605 // edge we want them to be able to hit the scroll bar. |
599 if (ash::wm::IsWindowMaximized(window) || | 606 if (ash::wm::IsWindowMaximized(window) || |
600 ash::wm::IsWindowFullscreen(window)) { | 607 ash::wm::IsWindowFullscreen(window)) { |
601 window->set_hit_test_bounds_override_inner(gfx::Insets()); | 608 window->set_hit_test_bounds_override_inner(gfx::Insets()); |
602 } else { | 609 } else { |
603 window->set_hit_test_bounds_override_inner( | 610 window->set_hit_test_bounds_override_inner( |
604 gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, | 611 gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, |
605 kResizeInsideBoundsSize, kResizeInsideBoundsSize)); | 612 kResizeInsideBoundsSize, kResizeInsideBoundsSize)); |
606 } | 613 } |
607 } | 614 } |
608 | 615 |
609 void FramePainter::OnWindowVisibilityChanged(aura::Window* window, | 616 void FramePainter::OnWindowVisibilityChanged(aura::Window* window, |
610 bool visible) { | 617 bool visible) { |
618 // Ignore updates from the root window. | |
619 if (window != window_) | |
620 return; | |
621 | |
611 // Window visibility change may trigger the change of window solo-ness in a | 622 // Window visibility change may trigger the change of window solo-ness in a |
612 // different window. | 623 // different window. |
613 UpdateSoloWindowFramePainter(visible ? NULL : window_); | 624 UpdateSoloWindowFramePainter(visible ? NULL : window_); |
614 } | 625 } |
615 | 626 |
616 void FramePainter::OnWindowDestroying(aura::Window* destroying) { | 627 void FramePainter::OnWindowDestroying(aura::Window* destroying) { |
617 DCHECK_EQ(window_, destroying); | 628 aura::Window* root = window_->GetRootWindow(); |
629 DCHECK(destroying == window_ || destroying == root); | |
630 | |
618 // Must be removed here and not in the destructor, as the aura::Window is | 631 // Must be removed here and not in the destructor, as the aura::Window is |
619 // already destroyed when our destructor runs. | 632 // already destroyed when our destructor runs. |
620 window_->RemoveObserver(this); | 633 window_->RemoveObserver(this); |
634 if (root) | |
635 root->RemoveObserver(this); | |
621 | 636 |
622 // For purposes of painting and solo window computation, we're done. | 637 // For purposes of painting and solo window computation, we're done. |
623 instances_->erase(this); | 638 instances_->erase(this); |
624 | 639 |
625 // If we have two or more windows open and we close this one, we might trigger | 640 // If we have two or more windows open and we close this one, we might trigger |
626 // the solo window appearance for another window. | 641 // the solo window appearance for another window. |
627 UpdateSoloWindowFramePainter(window_); | 642 UpdateSoloWindowFramePainter(window_); |
628 | 643 |
629 window_ = NULL; | 644 window_ = NULL; |
630 } | 645 } |
631 | 646 |
632 void FramePainter::OnWindowBoundsChanged(aura::Window* window, | 647 void FramePainter::OnWindowBoundsChanged(aura::Window* window, |
633 const gfx::Rect& old_bounds, | 648 const gfx::Rect& old_bounds, |
634 const gfx::Rect& new_bounds) { | 649 const gfx::Rect& new_bounds) { |
650 // Ignore updates from the root window. | |
651 if (window != window_) | |
652 return; | |
653 | |
635 // TODO(sky): this isn't quite right. What we really want is a method that | 654 // TODO(sky): this isn't quite right. What we really want is a method that |
636 // returns bounds ignoring transforms on certain windows (such as workspaces). | 655 // returns bounds ignoring transforms on certain windows (such as workspaces). |
637 if (!frame_->IsMaximized() && | 656 if (!frame_->IsMaximized() && |
638 ((old_bounds.y() == 0 && new_bounds.y() != 0) || | 657 ((old_bounds.y() == 0 && new_bounds.y() != 0) || |
639 (old_bounds.y() != 0 && new_bounds.y() == 0))) { | 658 (old_bounds.y() != 0 && new_bounds.y() == 0))) { |
640 SchedulePaintForHeader(); | 659 SchedulePaintForHeader(); |
641 } | 660 } |
642 } | 661 } |
643 | 662 |
644 void FramePainter::OnWindowAddedToRootWindow(aura::Window* window) { | 663 void FramePainter::OnWindowAddedToRootWindow(aura::Window* window) { |
664 DCHECK_EQ(window_, window); | |
665 window->GetRootWindow()->AddObserver(this); | |
James Cook
2013/03/06 23:45:39
Comment why this is necessary? I presume it's for
pkotwicz
2013/03/07 00:47:19
Yes, we reparent windows if they move across monit
| |
666 | |
645 // Needs to trigger the window appearance change if the window moves across | 667 // Needs to trigger the window appearance change if the window moves across |
646 // root windows and a solo window is already in the new root. | 668 // root windows and a solo window is already in the new root. |
647 UpdateSoloWindowFramePainter(NULL); | 669 UpdateSoloWindowFramePainter(NULL); |
648 } | 670 } |
649 | 671 |
650 void FramePainter::OnWindowRemovingFromRootWindow(aura::Window* window) { | 672 void FramePainter::OnWindowRemovingFromRootWindow(aura::Window* window) { |
673 DCHECK_EQ(window_, window); | |
674 window->GetRootWindow()->RemoveObserver(this); | |
675 | |
651 // Needs to trigger the window appearance change if the window moves across | 676 // Needs to trigger the window appearance change if the window moves across |
652 // root windows and only one window is left in the previous root. Because | 677 // root windows and only one window is left in the previous root. Because |
653 // |window| is not yet moved, |window| has to be ignored. | 678 // |window| is not yet moved, |window| has to be ignored. |
654 UpdateSoloWindowFramePainter(window); | 679 UpdateSoloWindowFramePainter(window); |
655 } | 680 } |
656 | 681 |
657 /////////////////////////////////////////////////////////////////////////////// | 682 /////////////////////////////////////////////////////////////////////////////// |
658 // ui::AnimationDelegate overrides: | 683 // ui::AnimationDelegate overrides: |
659 | 684 |
660 void FramePainter::AnimationProgressed(const ui::Animation* animation) { | 685 void FramePainter::AnimationProgressed(const ui::Animation* animation) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
698 | 723 |
699 int FramePainter::GetHeaderOpacity(HeaderMode header_mode, | 724 int FramePainter::GetHeaderOpacity(HeaderMode header_mode, |
700 int theme_frame_id, | 725 int theme_frame_id, |
701 const gfx::ImageSkia* theme_frame_overlay) { | 726 const gfx::ImageSkia* theme_frame_overlay) { |
702 // User-provided themes are painted fully opaque. | 727 // User-provided themes are painted fully opaque. |
703 if (frame_->GetThemeProvider()->HasCustomImage(theme_frame_id)) | 728 if (frame_->GetThemeProvider()->HasCustomImage(theme_frame_id)) |
704 return kFullyOpaque; | 729 return kFullyOpaque; |
705 if (theme_frame_overlay) | 730 if (theme_frame_overlay) |
706 return kFullyOpaque; | 731 return kFullyOpaque; |
707 | 732 |
708 // Maximized windows with workspace2 are totally transparent, except those not | 733 // Maximized windows with workspaces are totally transparent, except: |
709 // tracked by workspace code (which are used for tab dragging). | 734 // - For windows whose workspace is not tracked by the workspace code (which |
710 if (frame_->IsMaximized() && GetTrackedByWorkspace(frame_->GetNativeWindow())) | 735 // are used for tab dragging). |
736 // - When the user is cycling through workspaces. | |
737 if (frame_->IsMaximized() && | |
738 GetTrackedByWorkspace(frame_->GetNativeWindow()) && | |
739 !IsCyclingThroughWorkspaces()) | |
711 return 0; | 740 return 0; |
712 | 741 |
713 // Single browser window is very transparent. | 742 // Single browser window is very transparent. |
714 if (UseSoloWindowHeader()) | 743 if (UseSoloWindowHeader()) |
715 return kSoloWindowOpacity; | 744 return kSoloWindowOpacity; |
716 | 745 |
717 // Otherwise, change transparency based on window activation status. | 746 // Otherwise, change transparency based on window activation status. |
718 if (header_mode == ACTIVE) | 747 if (header_mode == ACTIVE) |
719 return kActiveWindowOpacity; | 748 return kActiveWindowOpacity; |
720 return kInactiveWindowOpacity; | 749 return kInactiveWindowOpacity; |
(...skipping 29 matching lines...) Expand all Loading... | |
750 hit_code == HTTOPLEFT) | 779 hit_code == HTTOPLEFT) |
751 return HTTOP; | 780 return HTTOP; |
752 return (hit_code == HTBOTTOMRIGHT || | 781 return (hit_code == HTBOTTOMRIGHT || |
753 hit_code == HTBOTTOM || | 782 hit_code == HTBOTTOM || |
754 hit_code == HTBOTTOMLEFT) ? HTBOTTOM : HTNOWHERE; | 783 hit_code == HTBOTTOMLEFT) ? HTBOTTOM : HTNOWHERE; |
755 } | 784 } |
756 } | 785 } |
757 return hit_code; | 786 return hit_code; |
758 } | 787 } |
759 | 788 |
789 bool FramePainter::IsCyclingThroughWorkspaces() const { | |
790 aura::RootWindow* root = window_->GetRootWindow(); | |
791 return root && root->GetProperty(internal::kCyclingThroughWorkspacesKey); | |
792 } | |
793 | |
760 bool FramePainter::UseSoloWindowHeader() { | 794 bool FramePainter::UseSoloWindowHeader() { |
761 aura::RootWindow* root = window_->GetRootWindow(); | 795 aura::RootWindow* root = window_->GetRootWindow(); |
762 if (!root || root->GetProperty(internal::kIgnoreSoloWindowFramePainterPolicy)) | 796 if (!root || root->GetProperty(internal::kIgnoreSoloWindowFramePainterPolicy)) |
763 return false; | 797 return false; |
764 return (root->GetProperty(internal::kSoloWindowFramePainterKey) == this); | 798 return (root->GetProperty(internal::kSoloWindowFramePainterKey) == this); |
765 } | 799 } |
766 | 800 |
767 // static | 801 // static |
768 FramePainter* FramePainter::GetSoloPainterInRoot(RootWindow* root_window, | 802 FramePainter* FramePainter::GetSoloPainterInRoot(RootWindow* root_window, |
769 Window* ignorable_window) { | 803 Window* ignorable_window) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
841 int title_y = | 875 int title_y = |
842 (view->GetBoundsForClientView().y() - title_font.GetHeight()) / 2; | 876 (view->GetBoundsForClientView().y() - title_font.GetHeight()) / 2; |
843 return gfx::Rect( | 877 return gfx::Rect( |
844 title_x, | 878 title_x, |
845 std::max(0, title_y), | 879 std::max(0, title_y), |
846 std::max(0, size_button_->x() - kTitleLogoSpacing - title_x), | 880 std::max(0, size_button_->x() - kTitleLogoSpacing - title_x), |
847 title_font.GetHeight()); | 881 title_font.GetHeight()); |
848 } | 882 } |
849 | 883 |
850 } // namespace ash | 884 } // namespace ash |
OLD | NEW |