ash: Fix transparency glitches in window header

Due to a race between when window show/hide animations change IsVisible() and "solo" window counting for determining header transparency, a missed update when windows are hidden, and FramePainter::PaintHeader() being called repeatedly with different clip rects for widget updates, we could get into a state where the window header has different transparency values behind various views::View widgets.

Fix this by using Window::TargetVisibility() instead of IsVisible() and monitoring for window visibility change events.

BUG=123866
TEST=manual, see bug


Review URL: http://codereview.chromium.org/10192001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133595 0039d316-1c4b-4281-b951-d872f2087c98
parent 9b4f608a
......@@ -115,8 +115,10 @@ void TileRoundRect(gfx::Canvas* canvas,
// Returns true if |window| is a visible, normal window.
bool IsVisibleNormalWindow(aura::Window* window) {
// We must use TargetVisibility() because windows animate in and out and
// IsVisible() also tracks the layer visibility state.
return window &&
window->IsVisible() &&
window->TargetVisibility() &&
window->type() == aura::client::WINDOW_TYPE_NORMAL;
}
......@@ -514,6 +516,14 @@ void FramePainter::OnWindowPropertyChanged(aura::Window* window,
}
}
void FramePainter::OnWindowVisibilityChanged(aura::Window* window,
bool visible) {
// Hiding a window may trigger the solo window appearance in a different
// window.
if (!visible && UseSoloWindowHeader())
SchedulePaintForSoloWindow();
}
void FramePainter::OnWindowDestroying(aura::Window* destroying) {
DCHECK_EQ(window_, destroying);
// Must be removed here and not in the destructor, as the aura::Window is
......@@ -525,17 +535,9 @@ void FramePainter::OnWindowDestroying(aura::Window* destroying) {
instances_->erase(this);
// If we have two or more windows open and we close this one, we might trigger
// the solo window appearance. If so, find the window that is becoming solo
// and schedule it to paint.
if (UseSoloWindowHeader()) {
for (std::set<FramePainter*>::const_iterator it = instances_->begin();
it != instances_->end();
++it) {
FramePainter* painter = *it;
if (IsVisibleNormalWindow(painter->window_) && painter->frame_)
painter->frame_->non_client_view()->SchedulePaint();
}
}
// the solo window appearance for another window.
if (UseSoloWindowHeader())
SchedulePaintForSoloWindow();
}
///////////////////////////////////////////////////////////////////////////////
......@@ -582,4 +584,15 @@ bool FramePainter::UseSoloWindowHeader() {
return window_count == 1;
}
// static
void FramePainter::SchedulePaintForSoloWindow() {
for (std::set<FramePainter*>::const_iterator it = instances_->begin();
it != instances_->end();
++it) {
FramePainter* painter = *it;
if (IsVisibleNormalWindow(painter->window_))
painter->frame_->non_client_view()->SchedulePaint();
}
}
} // namespace ash
......@@ -110,6 +110,8 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver,
virtual void OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) OVERRIDE;
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE;
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
// Overridden from ui::AnimationDelegate
......@@ -133,6 +135,11 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver,
// window header.
static bool UseSoloWindowHeader();
// Schedules a paint for the window header of the solo window. Invoke this
// when another window is hidden or destroyed to force the transparency of
// the now-solo window to update.
static void SchedulePaintForSoloWindow();
static std::set<FramePainter*>* instances_;
// Not owned
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment