diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-08 00:30:48 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-08 00:30:48 +0000 |
commit | a9f94bc6fc85c5d406035402e116f1ae29b0b675 (patch) | |
tree | eeb0f202f10d70844ec96d3271d4d6a31163c65a /ash | |
parent | 7d8549b015dd20de2c8bc52bb93bc2819ab859ea (diff) | |
download | chromium_src-a9f94bc6fc85c5d406035402e116f1ae29b0b675.zip chromium_src-a9f94bc6fc85c5d406035402e116f1ae29b0b675.tar.gz chromium_src-a9f94bc6fc85c5d406035402e116f1ae29b0b675.tar.bz2 |
Set the window frames to be non transparent while the user is cycling through workspaces
Bug=176025
Test=Manual, see bug
Review URL: https://chromiumcodereview.appspot.com/12319039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186826 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/wm/frame_painter.cc | 51 | ||||
-rw-r--r-- | ash/wm/frame_painter.h | 3 | ||||
-rw-r--r-- | ash/wm/frame_painter_unittest.cc | 56 | ||||
-rw-r--r-- | ash/wm/window_properties.cc | 1 | ||||
-rw-r--r-- | ash/wm/window_properties.h | 5 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_cycler_animator.cc | 11 |
6 files changed, 119 insertions, 8 deletions
diff --git a/ash/wm/frame_painter.cc b/ash/wm/frame_painter.cc index b75be06..8264620 100644 --- a/ash/wm/frame_painter.cc +++ b/ash/wm/frame_painter.cc @@ -10,7 +10,6 @@ #include "ash/wm/property_util.h" #include "ash/wm/window_properties.h" #include "ash/wm/window_util.h" -#include "ash/wm/workspace_controller.h" #include "base/logging.h" // DCHECK #include "grit/ash_resources.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -167,6 +166,8 @@ FramePainter::~FramePainter() { static_cast<FramePainter*>(NULL)); } window_->RemoveObserver(this); + if (root) + root->RemoveObserver(this); } instances_->erase(this); } @@ -216,6 +217,9 @@ void FramePainter::Init(views::Widget* frame, // itself in OnWindowDestroying() below, or in the destructor if we go away // before the window. window_->AddObserver(this); + aura::Window* root = window_->GetRootWindow(); + if (root) + root->AddObserver(this); // If there is already a solo window in the same root, this initialization // should turn off its solo-mode. @@ -583,13 +587,16 @@ void FramePainter::SchedulePaintForTitle(views::NonClientFrameView* view, void FramePainter::OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) { + // When either 'kWindowTrackedByWorkspaceKey' changes or + // 'kCyclingThroughWorkspacesKey' changes, we are going to paint the header + // differently. Schedule a paint to ensure everything is updated correctly. if (key == internal::kWindowTrackedByWorkspaceKey && GetTrackedByWorkspace(window)) { - // When 'kWindowTrackedByWorkspaceKey' changes we're going to paint the - // header differently. Schedule a paint to ensure everything is updated - // correctly. + frame_->non_client_view()->SchedulePaint(); + } else if (key == internal::kCyclingThroughWorkspacesKey) { frame_->non_client_view()->SchedulePaint(); } + if (key != aura::client::kShowStateKey) return; @@ -608,16 +615,24 @@ void FramePainter::OnWindowPropertyChanged(aura::Window* window, void FramePainter::OnWindowVisibilityChanged(aura::Window* window, bool visible) { + // Ignore updates from the root window. + if (window != window_) + return; + // Window visibility change may trigger the change of window solo-ness in a // different window. UpdateSoloWindowFramePainter(visible ? NULL : window_); } void FramePainter::OnWindowDestroying(aura::Window* destroying) { - DCHECK_EQ(window_, destroying); + aura::Window* root = window_->GetRootWindow(); + DCHECK(destroying == window_ || destroying == root); + // Must be removed here and not in the destructor, as the aura::Window is // already destroyed when our destructor runs. window_->RemoveObserver(this); + if (root) + root->RemoveObserver(this); // For purposes of painting and solo window computation, we're done. instances_->erase(this); @@ -632,6 +647,10 @@ void FramePainter::OnWindowDestroying(aura::Window* destroying) { void FramePainter::OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { + // Ignore updates from the root window. + if (window != window_) + return; + // TODO(sky): this isn't quite right. What we really want is a method that // returns bounds ignoring transforms on certain windows (such as workspaces). if (!frame_->IsMaximized() && @@ -642,12 +661,18 @@ void FramePainter::OnWindowBoundsChanged(aura::Window* window, } void FramePainter::OnWindowAddedToRootWindow(aura::Window* window) { + DCHECK_EQ(window_, window); + window->GetRootWindow()->AddObserver(this); + // Needs to trigger the window appearance change if the window moves across // root windows and a solo window is already in the new root. UpdateSoloWindowFramePainter(NULL); } void FramePainter::OnWindowRemovingFromRootWindow(aura::Window* window) { + DCHECK_EQ(window_, window); + window->GetRootWindow()->RemoveObserver(this); + // Needs to trigger the window appearance change if the window moves across // root windows and only one window is left in the previous root. Because // |window| is not yet moved, |window| has to be ignored. @@ -705,10 +730,15 @@ int FramePainter::GetHeaderOpacity(HeaderMode header_mode, if (theme_frame_overlay) return kFullyOpaque; - // Maximized windows with workspace2 are totally transparent, except those not - // tracked by workspace code (which are used for tab dragging). - if (frame_->IsMaximized() && GetTrackedByWorkspace(frame_->GetNativeWindow())) + // Maximized windows with workspaces are totally transparent, except: + // - For windows whose workspace is not tracked by the workspace code (which + // are used for tab dragging). + // - When the user is cycling through workspaces. + if (frame_->IsMaximized() && + GetTrackedByWorkspace(frame_->GetNativeWindow()) && + !IsCyclingThroughWorkspaces()) { return 0; + } // Single browser window is very transparent. if (UseSoloWindowHeader()) @@ -757,6 +787,11 @@ int FramePainter::AdjustFrameHitCodeForMaximizedModes(int hit_code) { return hit_code; } +bool FramePainter::IsCyclingThroughWorkspaces() const { + aura::RootWindow* root = window_->GetRootWindow(); + return root && root->GetProperty(internal::kCyclingThroughWorkspacesKey); +} + bool FramePainter::UseSoloWindowHeader() { aura::RootWindow* root = window_->GetRootWindow(); if (!root || root->GetProperty(internal::kIgnoreSoloWindowFramePainterPolicy)) diff --git a/ash/wm/frame_painter.h b/ash/wm/frame_painter.h index e02ca04..547c35d 100644 --- a/ash/wm/frame_painter.h +++ b/ash/wm/frame_painter.h @@ -170,6 +170,9 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver, // Adjust frame operations for left / right maximized modes. int AdjustFrameHitCodeForMaximizedModes(int hit_code); + // Returns true if the user is cycling through workspaces. + bool IsCyclingThroughWorkspaces() const; + // Returns true if |window_| is exactly one visible, normal-type window in // |window_->GetRootWindow()|, in which case we should paint a transparent // window header. diff --git a/ash/wm/frame_painter_unittest.cc b/ash/wm/frame_painter_unittest.cc index 72754b9..6aa34e4 100644 --- a/ash/wm/frame_painter_unittest.cc +++ b/ash/wm/frame_painter_unittest.cc @@ -102,6 +102,36 @@ class WindowRepaintChecker : public aura::WindowObserver { DISALLOW_COPY_AND_ASSIGN(WindowRepaintChecker); }; +// Modifies the values of kInactiveWindowOpacity, kActiveWindowOpacity, and +// kSoloWindowOpacity for the lifetime of the class. This is useful so that +// the constants each have different values. +class ScopedOpacityConstantModifier { + public: + ScopedOpacityConstantModifier() + : initial_active_window_opacity_( + ash::FramePainter::kActiveWindowOpacity), + initial_inactive_window_opacity_( + ash::FramePainter::kInactiveWindowOpacity), + initial_solo_window_opacity_(ash::FramePainter::kSoloWindowOpacity) { + ash::FramePainter::kActiveWindowOpacity = 100; + ash::FramePainter::kInactiveWindowOpacity = 120; + ash::FramePainter::kSoloWindowOpacity = 140; + } + ~ScopedOpacityConstantModifier() { + ash::FramePainter::kActiveWindowOpacity = initial_active_window_opacity_; + ash::FramePainter::kInactiveWindowOpacity = + initial_inactive_window_opacity_; + ash::FramePainter::kSoloWindowOpacity = initial_solo_window_opacity_; + } + + private: + int initial_active_window_opacity_; + int initial_inactive_window_opacity_; + int initial_solo_window_opacity_; + + DISALLOW_COPY_AND_ASSIGN(ScopedOpacityConstantModifier); +}; + } // namespace namespace ash { @@ -443,6 +473,10 @@ TEST_F(FramePainterTest, GetHeaderOpacity) { p1.Init(w1.get(), NULL, &size1, &close1, FramePainter::SIZE_BUTTON_MAXIMIZES); w1->Show(); + // Modify the values of the opacity constants so that they each have a + // different value. + ScopedOpacityConstantModifier opacity_constant_modifier; + // Solo active window has solo window opacity. EXPECT_EQ(FramePainter::kSoloWindowOpacity, p1.GetHeaderOpacity(FramePainter::ACTIVE, @@ -475,6 +509,28 @@ TEST_F(FramePainterTest, GetHeaderOpacity) { p1.GetHeaderOpacity(FramePainter::ACTIVE, IDR_AURA_WINDOW_HEADER_BASE_ACTIVE, &custom_overlay)); + + // Regular maximized window is fully transparent. + ash::wm::MaximizeWindow(w1->GetNativeWindow()); + EXPECT_EQ(0, + p1.GetHeaderOpacity(FramePainter::ACTIVE, + IDR_AURA_WINDOW_HEADER_BASE_ACTIVE, + NULL)); + + // Windows with custom overlays are fully opaque when maximized. + EXPECT_EQ(255, + p1.GetHeaderOpacity(FramePainter::ACTIVE, + IDR_AURA_WINDOW_HEADER_BASE_ACTIVE, + &custom_overlay)); + + // The maximized window frame should take on the active/inactive opacity + // while the user is cycling through workspaces. + w1->GetNativeWindow()->GetRootWindow()->SetProperty( + ash::internal::kCyclingThroughWorkspacesKey, true); + EXPECT_EQ(FramePainter::kInactiveWindowOpacity, + p1.GetHeaderOpacity(FramePainter::INACTIVE, + IDR_AURA_WINDOW_HEADER_BASE_ACTIVE, + NULL)); } // Test the hit test function with windows which are "partially maximized". diff --git a/ash/wm/window_properties.cc b/ash/wm/window_properties.cc index 493cea7..48fc7f7 100644 --- a/ash/wm/window_properties.cc +++ b/ash/wm/window_properties.cc @@ -20,6 +20,7 @@ namespace internal { DEFINE_OWNED_WINDOW_PROPERTY_KEY(ash::internal::AlwaysOnTopController, kAlwaysOnTopControllerKey, NULL); +DEFINE_WINDOW_PROPERTY_KEY(bool, kCyclingThroughWorkspacesKey, false); DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoreSoloWindowFramePainterPolicy, false); DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoredByShelfKey, false); DEFINE_WINDOW_PROPERTY_KEY(bool, kImmersiveModeKey, false); diff --git a/ash/wm/window_properties.h b/ash/wm/window_properties.h index 41144c9..3804f76 100644 --- a/ash/wm/window_properties.h +++ b/ash/wm/window_properties.h @@ -29,6 +29,11 @@ class RootWindowController; extern const aura::WindowProperty<internal::AlwaysOnTopController*>* const kAlwaysOnTopControllerKey; +// A property key to indicate that the user is cycling through workspaces. +// The property should only be set on the root window. +ASH_EXPORT extern const aura::WindowProperty<bool>* const + kCyclingThroughWorkspacesKey; + // A property key to disable the frame painter policy for solo windows. // It is only available for root windows. ASH_EXPORT extern const aura::WindowProperty<bool>* const diff --git a/ash/wm/workspace/workspace_cycler_animator.cc b/ash/wm/workspace/workspace_cycler_animator.cc index a22375c..0575c02 100644 --- a/ash/wm/workspace/workspace_cycler_animator.cc +++ b/ash/wm/workspace/workspace_cycler_animator.cc @@ -13,10 +13,12 @@ #include "ash/shell_window_ids.h" #include "ash/wm/property_util.h" #include "ash/wm/shelf_layout_manager.h" +#include "ash/wm/window_properties.h" #include "ash/wm/workspace/colored_window_controller.h" #include "ash/wm/workspace/workspace.h" #include "ash/wm/workspace/workspace_cycler_configuration.h" #include "base/values.h" +#include "ui/aura/root_window.h" #include "ui/aura/window.h" #include "ui/base/events/event_utils.h" #include "ui/compositor/layer_animator.h" @@ -388,6 +390,11 @@ void WorkspaceCyclerAnimator::Init(const std::vector<Workspace*>& workspaces, } void WorkspaceCyclerAnimator::AnimateStartingCycler() { + // Set kCyclingThroughWorkspaces so that the window frame is painted with the + // correct style. + workspaces_[0]->window()->GetRootWindow()->SetProperty( + ash::internal::kCyclingThroughWorkspacesKey, true); + // Ensure that the workspaces are stacked with respect to their order // in |workspaces_|. aura::Window* parent = workspaces_[0]->window()->parent(); @@ -592,6 +599,10 @@ void WorkspaceCyclerAnimator::AnimateToUpdatedState(int animation_duration) { } void WorkspaceCyclerAnimator::CyclerStopped(size_t visible_workspace_index) { + aura::Window* root_window = workspaces_[0]->window()->GetRootWindow(); + root_window->SetProperty(ash::internal::kCyclingThroughWorkspacesKey, + false); + for(size_t i = 0; i < workspaces_.size(); ++i) { aura::Window* window = workspaces_[i]->window(); ui::Layer* layer = window->layer(); |