Index: ash/wm/frame_painter.cc |
diff --git a/ash/wm/frame_painter.cc b/ash/wm/frame_painter.cc |
index b75be062130df509a650b6638bfc0185bcefbb6e..826462049b8b7a6af5fd1e992583bc74b09dc191 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)) |