summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-08 00:30:48 +0000
committerpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-08 00:30:48 +0000
commita9f94bc6fc85c5d406035402e116f1ae29b0b675 (patch)
treeeeb0f202f10d70844ec96d3271d4d6a31163c65a /ash
parent7d8549b015dd20de2c8bc52bb93bc2819ab859ea (diff)
downloadchromium_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.cc51
-rw-r--r--ash/wm/frame_painter.h3
-rw-r--r--ash/wm/frame_painter_unittest.cc56
-rw-r--r--ash/wm/window_properties.cc1
-rw-r--r--ash/wm/window_properties.h5
-rw-r--r--ash/wm/workspace/workspace_cycler_animator.cc11
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();