Commit a46f73ff authored by nsatragno's avatar nsatragno Committed by Commit bot

Remove TransparentActivateWindowButton from Overview Mode

This change eliminates the need to have a transparent button on top of
overview mode windows by installing a static event targeter on each of
the item windows. The targeter checks for events on the item bounds and
redirects events to a label button located under each item. This way, we
greatly simplify event handling while preventing events to reach the
actual windows.

The reason why we use a label button now is that it already handles clicks
and taps, as well as accessibility stuff (touch exploration, chromevox
feedback) that were being handled in the transparent window before.

The CL only involves refactoring - no features have been added or
removed.

BUG=446548
TEST=WindowSelectorTest.*

Review URL: https://codereview.chromium.org/810033010

Cr-Commit-Position: refs/heads/master@{#312936}
parent efb5b62b
......@@ -539,6 +539,10 @@
'wm/overlay_event_filter.cc',
'wm/overlay_event_filter.h',
'wm/overview/overview_animation_type.h',
'wm/overview/overview_window_button.h',
'wm/overview/overview_window_button.cc',
'wm/overview/overview_window_targeter.h',
'wm/overview/overview_window_targeter.cc',
'wm/overview/scoped_overview_animation_settings.h',
'wm/overview/scoped_overview_animation_settings.cc',
'wm/overview/scoped_transform_overview_window.cc',
......@@ -551,11 +555,8 @@
'wm/window_cycle_controller.h',
'wm/window_cycle_list.cc',
'wm/window_cycle_list.h',
'wm/overview/transparent_activate_window_button.cc',
'wm/overview/transparent_activate_window_button.h',
'wm/overview/window_selector_controller.cc',
'wm/overview/window_selector_controller.h',
'wm/overview/window_selector_delegate.h',
'wm/overview/window_selector_item.cc',
'wm/overview/window_selector_item.h',
'wm/panels/attached_panel_window_targeter.cc',
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/overview/overview_animation_type.h"
#include "ash/wm/overview/overview_window_button.h"
#include "ash/wm/overview/overview_window_targeter.h"
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/wm/window_state.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
// Foreground label color.
static const SkColor kLabelColor = SK_ColorWHITE;
// Label shadow color.
static const SkColor kLabelShadow = 0xB0000000;
// Solid shadow length from the label
static const int kVerticalShadowOffset = 1;
// Amount of blur applied to the label shadow
static const int kShadowBlur = 10;
} // namespace
// LabelButton shown under each of the windows.
class OverviewWindowButton::OverviewButtonView : public views::LabelButton {
public:
OverviewButtonView(views::ButtonListener* listener,
const base::string16& text)
: views::LabelButton(listener, text),
selector_item_bounds_(gfx::Rect()) {}
~OverviewButtonView() override {}
// Updates the |selector_item_bounds_|, converting them to our coordinates.
void SetSelectorItemBounds(const gfx::Rect& selector_item_bounds) {
selector_item_bounds_ = ScreenUtil::ConvertRectFromScreen(
GetWidget()->GetNativeWindow()->GetRootWindow(), selector_item_bounds);
gfx::Point origin = selector_item_bounds_.origin();
gfx::Rect target_bounds = GetWidget()->GetNativeWindow()->GetTargetBounds();
origin.Offset(-target_bounds.x(), -target_bounds.y());
selector_item_bounds_.set_origin(origin);
}
// views::View:
void OnMouseReleased(const ui::MouseEvent& event) override {
if (!selector_item_bounds_.Contains(event.location()))
return;
NotifyClick(event);
}
private:
// Bounds to check if a mouse release occurred outside the window item.
gfx::Rect selector_item_bounds_;
DISALLOW_COPY_AND_ASSIGN(OverviewButtonView);
};
OverviewWindowButton::OverviewWindowButton(aura::Window* target)
: target_(target), window_label_(new views::Widget) {
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_POPUP;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.parent = Shell::GetContainer(target_->GetRootWindow(),
kShellWindowId_OverlayContainer);
params.visible_on_all_workspaces = true;
window_label_->set_focus_on_creation(false);
window_label_->Init(params);
window_label_button_view_ = new OverviewButtonView(this, target_->title());
window_label_button_view_->SetTextColor(views::LabelButton::STATE_NORMAL,
kLabelColor);
window_label_button_view_->SetTextColor(views::LabelButton::STATE_HOVERED,
kLabelColor);
window_label_button_view_->SetTextColor(views::LabelButton::STATE_PRESSED,
kLabelColor);
window_label_button_view_->set_animate_on_state_change(false);
window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
window_label_button_view_->SetBorder(views::Border::NullBorder());
window_label_button_view_->SetTextShadows(gfx::ShadowValues(
1, gfx::ShadowValue(gfx::Point(0, kVerticalShadowOffset), kShadowBlur,
kLabelShadow)));
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
window_label_button_view_->SetFontList(
bundle.GetFontList(ui::ResourceBundle::BoldFont));
window_label_->SetContentsView(window_label_button_view_);
overview_window_targeter_ =
new OverviewWindowTargeter(window_label_->GetNativeWindow());
scoped_window_targeter_.reset(new aura::ScopedWindowTargeter(
target, scoped_ptr<OverviewWindowTargeter>(overview_window_targeter_)));
}
OverviewWindowButton::~OverviewWindowButton() {
}
void OverviewWindowButton::SetBounds(
const gfx::Rect& bounds,
const OverviewAnimationType& animation_type) {
if (!window_label_->IsVisible()) {
window_label_->Show();
ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
window_label_->GetNativeWindow());
}
gfx::Rect converted_bounds =
ScreenUtil::ConvertRectFromScreen(target_->GetRootWindow(), bounds);
gfx::Rect label_bounds(converted_bounds.x(), converted_bounds.bottom(),
converted_bounds.width(), 0);
label_bounds.set_height(
window_label_->GetContentsView()->GetPreferredSize().height());
label_bounds.set_y(
label_bounds.y() -
window_label_->GetContentsView()->GetPreferredSize().height());
ScopedOverviewAnimationSettings animation_settings(
animation_type, window_label_->GetNativeWindow());
window_label_->GetNativeWindow()->SetBounds(label_bounds);
window_label_button_view_->SetSelectorItemBounds(bounds);
overview_window_targeter_->set_bounds(
ScreenUtil::ConvertRectFromScreen(target_->GetRootWindow(), bounds));
}
void OverviewWindowButton::SendFocusAlert() const {
window_label_button_view_->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
}
void OverviewWindowButton::SetLabelText(const base::string16& title) {
window_label_button_view_->SetText(title);
}
void OverviewWindowButton::SetOpacity(float opacity) {
window_label_->GetNativeWindow()->layer()->SetOpacity(opacity);
}
void OverviewWindowButton::ButtonPressed(views::Button* sender,
const ui::Event& event) {
wm::GetWindowState(target_)->Activate();
}
} // namespace ash
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_OVERVIEW_OVERVIEW_WINDOW_BUTTON_H_
#define ASH_WM_OVERVIEW_OVERVIEW_WINDOW_BUTTON_H_
#include "ash/wm/overview/scoped_transform_overview_window.h"
#include "ui/views/controls/button/button.h"
namespace aura {
class ScopedWindowTargeter;
}
namespace ash {
class OverviewWindowTargeter;
// A class that encapsulates the LabelButton and targeting logic for overview
// mode.
class OverviewWindowButton : public views::ButtonListener {
public:
// |target| is the window that should be activated when the button is pressed.
explicit OverviewWindowButton(aura::Window* target);
~OverviewWindowButton() override;
// Sets the label and targetable bounds.
void SetBounds(const gfx::Rect& bounds,
const OverviewAnimationType& animation_type);
// Sends an a11y focus alert so that, if chromevox is enabled, the window
// label is read.
void SendFocusAlert() const;
// Sets the label text.
void SetLabelText(const base::string16& title);
// Sets the label opacity.
void SetOpacity(float opacity);
// views::ButtonListener
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
private:
friend class WindowSelectorTest;
// LabelButton shown under each of the windows.
class OverviewButtonView;
// Window that the button will activate on click.
aura::Window* target_;
// Label under the window displaying its active tab name.
scoped_ptr<views::Widget> window_label_;
// View for the label button under the window.
OverviewButtonView* window_label_button_view_;
// Reference to the targeter implemented by the scoped window targeter.
OverviewWindowTargeter* overview_window_targeter_;
// Stores and restores on exit the actual window targeter.
scoped_ptr<aura::ScopedWindowTargeter> scoped_window_targeter_;
DISALLOW_COPY_AND_ASSIGN(OverviewWindowButton);
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_OVERVIEW_WINDOW_BUTTON_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/overview/overview_window_targeter.h"
#include "ui/aura/window.h"
namespace ash {
OverviewWindowTargeter::OverviewWindowTargeter(aura::Window* target)
: bounds_(gfx::Rect()), target_(target) {
}
OverviewWindowTargeter::~OverviewWindowTargeter() {
}
ui::EventTarget* OverviewWindowTargeter::FindTargetForLocatedEvent(
ui::EventTarget* target,
ui::LocatedEvent* event) {
// Manually override the location of the event to make sure it targets the
// contents view on the target window.
event->set_location(gfx::PointF(0, 0));
return target_;
}
bool OverviewWindowTargeter::EventLocationInsideBounds(
ui::EventTarget* target,
const ui::LocatedEvent& event) const {
return bounds_.Contains(event.location());
}
} // namespace ash
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_OVERVIEW_OVERVIEW_WINDOW_TARGETER_H_
#define ASH_WM_OVERVIEW_OVERVIEW_WINDOW_TARGETER_H_
#include "ui/aura/window_targeter.h"
#include "ui/gfx/geometry/rect.h"
namespace ash {
// A targeter for the windows in the overview. Avoids propagating events to
// window children and uses the WindowSelectorItem bounds to check for hits.
class OverviewWindowTargeter : public aura::WindowTargeter {
public:
explicit OverviewWindowTargeter(aura::Window* target);
~OverviewWindowTargeter() override;
// Sets the targetable bounds.
void set_bounds(const gfx::Rect& bounds) { bounds_ = bounds; }
// ui::EventTargeter:
ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* target,
ui::LocatedEvent* event) override;
protected:
// ui::EventTargeter:
bool EventLocationInsideBounds(ui::EventTarget* target,
const ui::LocatedEvent& event) const override;
private:
// Bounds used to check for event hits in the root window coordinates.
gfx::Rect bounds_;
// Target to which events are redirected.
aura::Window* target_;
DISALLOW_COPY_AND_ASSIGN(OverviewWindowTargeter);
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_OVERVIEW_WINDOW_TARGETER_H_
......@@ -73,4 +73,15 @@ ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings(
ScopedOverviewAnimationSettings::~ScopedOverviewAnimationSettings() {
}
// static:
void ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
aura::Window* window) {
ui::Layer* layer = window->layer();
layer->SetOpacity(0.0f);
ScopedOverviewAnimationSettings animation_settings(
OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
window);
layer->SetOpacity(1.0f);
}
} // namespace ash
......@@ -24,6 +24,11 @@ class ScopedOverviewAnimationSettings {
aura::Window* window);
virtual ~ScopedOverviewAnimationSettings();
// Convenvience method to fade in a Window with predefined animation settings.
// Note: The fade in animation will occur after a delay where the delay is how
// long the lay out animations take.
static void SetupFadeInAfterLayout(aura::Window* window);
private:
// The managed animation settings.
ui::ScopedLayerAnimationSettings animation_settings_;
......
......@@ -166,8 +166,6 @@ TransientDescendantIteratorRange GetTransientTreeIterator(
ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(
aura::Window* window)
: window_(window),
activate_button_(new TransparentActivateWindowButton(
window_->GetRootWindow(), this)),
minimized_(window->GetProperty(aura::client::kShowStateKey) ==
ui::SHOW_STATE_MINIMIZED),
ignored_by_shelf_(wm::GetWindowState(window)->ignored_by_shelf()),
......@@ -304,10 +302,6 @@ void ScopedTransformOverviewWindow::SetOpacity(float opacity) {
}
}
void ScopedTransformOverviewWindow::Select() {
wm::GetWindowState(window_)->Activate();
}
void ScopedTransformOverviewWindow::Close() {
aura::Window* window = GetTransientRoot(window_);
views::Widget::GetWidgetForNativeView(window)->Close();
......
......@@ -6,8 +6,6 @@
#define ASH_WM_OVERVIEW_SCOPED_TRANSFORM_OVERVIEW_WINDOW_H_
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/wm/overview/transparent_activate_window_button.h"
#include "ash/wm/overview/transparent_activate_window_button_delegate.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
......@@ -35,8 +33,7 @@ class ScopedWindowCopy;
// class allows transforming the windows with a helper to determine the best
// fit in certain bounds. The window's state is restored on destruction of this
// object.
class ScopedTransformOverviewWindow
: public TransparentActivateWindowButtonDelegate {
class ScopedTransformOverviewWindow {
public:
typedef ScopedVector<ScopedOverviewAnimationSettings> ScopedAnimationSettings;
......@@ -51,7 +48,7 @@ class ScopedTransformOverviewWindow
const gfx::Rect& dst_rect);
explicit ScopedTransformOverviewWindow(aura::Window* window);
~ScopedTransformOverviewWindow() override;
~ScopedTransformOverviewWindow();
gfx::Transform get_overview_transform() const { return overview_transform_; }
......@@ -59,10 +56,6 @@ class ScopedTransformOverviewWindow
overview_transform_ = transform;
}
TransparentActivateWindowButton* activate_button() {
return activate_button_.get();
}
// Starts an animation sequence which will use animation settings specified by
// |animation_type|. The |animation_settings| container is populated with
// scoped entities and the container should be destroyed at the end of the
......@@ -115,9 +108,6 @@ class ScopedTransformOverviewWindow
// Closes the transient root of the window managed by |this|.
void Close();
// ash::TransparentActivateWindowButtonDelegate:
void Select() override;
private:
// Shows the window if it was minimized.
void ShowWindowIfMinimized();
......@@ -125,9 +115,6 @@ class ScopedTransformOverviewWindow
// A weak pointer to the real window in the overview.
aura::Window* window_;
// The transparent overlay that captures events.
scoped_ptr<TransparentActivateWindowButton> activate_button_;
// If true, the window was minimized and should be restored if the window
// was not selected.
bool minimized_;
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/overview/transparent_activate_window_button.h"
#include <vector>
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/overview/transparent_activate_window_button_delegate.h"
#include "ui/events/event.h"
#include "ui/events/gesture_event_details.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/custom_button.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
const char kTransparentButtonName[] = "TransparentButton";
// Transparent button that handles events to activate or close windows in
// overview mode.
class TransparentButton
: public views::CustomButton,
public views::ButtonListener {
public:
explicit TransparentButton(TransparentActivateWindowButtonDelegate* delegate);
~TransparentButton() override;
TransparentActivateWindowButtonDelegate* delegate() { return delegate_; }
// views::View:
void OnGestureEvent(ui::GestureEvent* event) override;
const char* GetClassName() const override { return kTransparentButtonName; }
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
private:
TransparentActivateWindowButtonDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(TransparentButton);
};
TransparentButton::TransparentButton(
TransparentActivateWindowButtonDelegate* delegate)
: CustomButton(this),
delegate_(delegate) {
}
TransparentButton::~TransparentButton() {
}
void TransparentButton::OnGestureEvent(ui::GestureEvent* event) {
// TODO(tdanderson): Re-evaluate whether we want to set capture once
// the a fix has landed to avoid crashing when a window
// having an active gesture sequence is destroyed as a
// result of a gesture in a separate window. Consider using
// a StaticWindowTargeter instead of a transparent overlay
// widget to re-direct input events.
if (event->type() == ui::ET_GESTURE_TAP_DOWN)
GetWidget()->SetCapture(this);
if (event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_END) {
GetWidget()->ReleaseCapture();
}
CustomButton::OnGestureEvent(event);
event->StopPropagation();
}
void TransparentButton::ButtonPressed(views::Button* sender,
const ui::Event& event) {
delegate_->Select();
}
// Initializes the event handler transparent window.
views::Widget* InitEventHandler(aura::Window* root_window) {
views::Widget* widget = new views::Widget;
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_POPUP;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.accept_events = true;
params.parent = Shell::GetContainer(root_window,
kShellWindowId_OverlayContainer);
widget->set_focus_on_creation(false);
widget->Init(params);
widget->Show();
aura::Window* handler = widget->GetNativeWindow();
handler->parent()->StackChildAtBottom(handler);
return widget;
}
} // namespace
TransparentActivateWindowButton::TransparentActivateWindowButton(
aura::Window* root_window,
TransparentActivateWindowButtonDelegate* delegate)
: event_handler_widget_(InitEventHandler(root_window)),
transparent_button_(new TransparentButton(delegate)) {
event_handler_widget_->SetContentsView(transparent_button_);
}
TransparentActivateWindowButton::~TransparentActivateWindowButton() {
}
void TransparentActivateWindowButton::SetAccessibleName(
const base::string16& name) {
transparent_button_->SetAccessibleName(name);
}
void TransparentActivateWindowButton::SetBounds(const gfx::Rect& bounds) {
aura::Window* window = event_handler_widget_->GetNativeWindow();
const gfx::Display& display = gfx::Screen::GetScreenFor(
window)->GetDisplayNearestWindow(window);
// Explicitly specify the display so that the window doesn't change root
// windows and cause the z-order of the transparent overlays to be updated.
window->SetBoundsInScreen(bounds, display);
}
void TransparentActivateWindowButton::SendFocusAlert() const {
event_handler_widget_->GetContentsView()->
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
}
} // namespace ash
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_H_
#define ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_H_
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "ui/gfx/geometry/rect.h"
namespace aura {
class Window;
} // namespace aura
namespace views {
class Button;
class Widget;
} // namespace views
namespace ash {
class TransparentActivateWindowButtonDelegate;
// Transparent window that covers window selector items and handles mouse and
// gestures on overview mode for them.
class TransparentActivateWindowButton {
public:
TransparentActivateWindowButton(
aura::Window* root_window,
TransparentActivateWindowButtonDelegate* delegate);
~TransparentActivateWindowButton();
// Sets the accessibility name.
void SetAccessibleName(const base::string16& name);
// Sets the bounds of the transparent window.
void SetBounds(const gfx::Rect& bounds);
// Sends an accessibility focus alert so that if chromevox is enabled, the
// window title is read.
void SendFocusAlert() const;
private:
// The transparent window event handler widget itself.
scoped_ptr<views::Widget> event_handler_widget_;
// The transparent button view that handles user input. Not owned.
views::Button* transparent_button_;
DISALLOW_COPY_AND_ASSIGN(TransparentActivateWindowButton);
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// A delegate that
#ifndef ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_DELEGATE_H_
#define ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_DELEGATE_H_
#include "ash/ash_export.h"
namespace ash {
// A pure-virtual delegate that is used by the TransparentActivateWindowButton
// to manipulate windows while in overview mode.
class ASH_EXPORT TransparentActivateWindowButtonDelegate {
public:
// Called when the TransparentActivateWindowButton was selected.
virtual void Select() = 0;
protected:
TransparentActivateWindowButtonDelegate() {}
virtual ~TransparentActivateWindowButtonDelegate() {}
private:
DISALLOW_COPY_AND_ASSIGN(TransparentActivateWindowButtonDelegate);
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_TRANSPARENT_ACTIVATE_WINDOW_BUTTON_DELEGATE_H_
......@@ -11,10 +11,10 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/overview/overview_animation_type.h"
#include "ash/wm/overview/overview_window_button.h"
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/wm/overview/scoped_transform_overview_window.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_state.h"
#include "base/auto_reset.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
......@@ -28,7 +28,6 @@
#include "ui/gfx/transform_util.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
......@@ -42,24 +41,6 @@ namespace {
// closest distance between adjacent windows will be twice this amount.
static const int kWindowMargin = 30;
// Foreground label color.
static const SkColor kLabelColor = SK_ColorWHITE;
// Background label color.
static const SkColor kLabelBackground = SK_ColorTRANSPARENT;
// Label shadow color.
static const SkColor kLabelShadow = 0xB0000000;
// Vertical padding for the label, both over and beneath it.
static const int kVerticalLabelPadding = 20;
// Solid shadow length from the label
static const int kVerticalShadowOffset = 1;
// Amount of blur applied to the label shadow
static const int kShadowBlur = 10;
// Opacity for dimmed items.
static const float kDimmedItemOpacity = 0.5f;
......@@ -75,18 +56,6 @@ gfx::Rect GetTransformedBounds(aura::Window* window) {
return ToEnclosingRect(bounds);
}
// Convenvience method to fade in a Window with predefined animation settings.
// Note: The fade in animation will occur after a delay where the delay is how
// long the lay out animations take.
void SetupFadeInAfterLayout(aura::Window* window) {
ui::Layer* layer = window->layer();
layer->SetOpacity(0.0f);
ScopedOverviewAnimationSettings animation_settings(
OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
window);
layer->SetOpacity(1.0f);
}
// An image button with a close window icon.
class OverviewCloseButton : public views::ImageButton {
public:
......@@ -118,10 +87,8 @@ WindowSelectorItem::WindowSelectorItem(aura::Window* window)
root_window_(window->GetRootWindow()),
transform_window_(window),
in_bounds_update_(false),
window_label_view_(nullptr),
close_button_(new OverviewCloseButton(this)),
selector_item_activate_window_button_(
new TransparentActivateWindowButton(root_window_, this)) {
overview_window_button_(new OverviewWindowButton(window)) {
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_POPUP;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
......@@ -179,7 +146,7 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
target_bounds_ = target_bounds;
UpdateWindowLabels(target_bounds, animation_type);
overview_window_button_->SetBounds(target_bounds, animation_type);
gfx::Rect inset_bounds(target_bounds);
inset_bounds.Inset(kWindowMargin, kWindowMargin);
......@@ -188,7 +155,6 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
// SetItemBounds is called before UpdateCloseButtonLayout so the close button
// can properly use the updated windows bounds.
UpdateCloseButtonLayout(animation_type);
UpdateSelectorButtons();
}
void WindowSelectorItem::RecomputeWindowTransforms() {
......@@ -198,13 +164,11 @@ void WindowSelectorItem::RecomputeWindowTransforms() {
gfx::Rect inset_bounds(target_bounds_);
inset_bounds.Inset(kWindowMargin, kWindowMargin);
SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
UpdateSelectorButtons();
}
void WindowSelectorItem::SendFocusAlert() const {
selector_item_activate_window_button_->SendFocusAlert();
overview_window_button_->SendFocusAlert();
}
void WindowSelectorItem::SetDimmed(bool dimmed) {
......@@ -225,18 +189,8 @@ void WindowSelectorItem::OnWindowDestroying(aura::Window* window) {
void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
// TODO(flackr): Maybe add the new title to a vector of titles so that we can
// filter any of the titles the window had while in the overview session.
if (window == GetWindow()) {
window_label_view_->SetText(window->title());
UpdateCloseButtonAccessibilityName();
}
UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
UpdateSelectorButtons();
}
void WindowSelectorItem::Select() {
aura::Window* selection_window = GetWindow();
if (selection_window)
wm::GetWindowState(selection_window)->Activate();
overview_window_button_->SetLabelText(window->title());
UpdateCloseButtonAccessibilityName();
}
void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
......@@ -256,87 +210,18 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
}
void WindowSelectorItem::SetOpacity(float opacity) {
window_label_->GetNativeWindow()->layer()->SetOpacity(opacity);
overview_window_button_->SetOpacity(opacity);
close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity);
transform_window_.SetOpacity(opacity);
}
void WindowSelectorItem::UpdateWindowLabels(
const gfx::Rect& window_bounds,
OverviewAnimationType animation_type) {
if (!window_label_) {
CreateWindowLabel(GetWindow()->title());
SetupFadeInAfterLayout(window_label_->GetNativeWindow());
}
gfx::Rect converted_bounds = ScreenUtil::ConvertRectFromScreen(root_window_,
window_bounds);
gfx::Rect label_bounds(converted_bounds.x(),
converted_bounds.bottom(),
converted_bounds.width(),
0);
label_bounds.set_height(window_label_->GetContentsView()->
GetPreferredSize().height());
label_bounds.set_y(label_bounds.y() - window_label_->
GetContentsView()->GetPreferredSize().height());
ScopedOverviewAnimationSettings animation_settings(animation_type,
window_label_->GetNativeWindow());
window_label_->GetNativeWindow()->SetBounds(label_bounds);
}
void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
window_label_.reset(new views::Widget);
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_POPUP;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.parent = Shell::GetContainer(root_window_,
kShellWindowId_OverlayContainer);
params.accept_events = false;
params.visible_on_all_workspaces = true;
window_label_->set_focus_on_creation(false);
window_label_->Init(params);
window_label_view_ = new views::Label;
window_label_view_->SetEnabledColor(kLabelColor);
window_label_view_->SetBackgroundColor(kLabelBackground);
window_label_view_->SetShadows(gfx::ShadowValues(
1,
gfx::ShadowValue(
gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kLabelShadow)));
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
window_label_view_->SetFontList(
bundle.GetFontList(ui::ResourceBundle::BoldFont));
window_label_view_->SetText(title);
views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
0,
kVerticalLabelPadding,
0);
window_label_view_->SetLayoutManager(layout);
window_label_->SetContentsView(window_label_view_);
window_label_->Show();
}
void WindowSelectorItem::UpdateSelectorButtons() {
aura::Window* window = GetWindow();
selector_item_activate_window_button_->SetBounds(target_bounds());
selector_item_activate_window_button_->SetAccessibleName(window->title());
TransparentActivateWindowButton* activate_button =
transform_window_.activate_button();
activate_button->SetBounds(target_bounds());
activate_button->SetAccessibleName(window->title());
}
void WindowSelectorItem::UpdateCloseButtonLayout(
OverviewAnimationType animation_type) {
if (!close_button_->visible()) {
close_button_->SetVisible(true);
SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow());
ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
close_button_widget_.GetNativeWindow());
}
ScopedOverviewAnimationSettings animation_settings(animation_type,
close_button_widget_.GetNativeWindow());
......
......@@ -7,10 +7,9 @@
#include "ash/ash_export.h"
#include "ash/wm/overview/scoped_transform_overview_window.h"
#include "ash/wm/overview/transparent_activate_window_button.h"
#include "ash/wm/overview/transparent_activate_window_button_delegate.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/button/button.h"
......@@ -21,17 +20,17 @@ class Window;
}
namespace views {
class Label;
class LabelButton;
class Widget;
}
namespace ash {
class OverviewWindowButton;
// This class represents an item in overview mode.
class ASH_EXPORT WindowSelectorItem
: public views::ButtonListener,
public aura::WindowObserver,
public TransparentActivateWindowButtonDelegate {
class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
public aura::WindowObserver {
public:
explicit WindowSelectorItem(aura::Window* window);
~WindowSelectorItem() override;
......@@ -83,9 +82,6 @@ class ASH_EXPORT WindowSelectorItem
void OnWindowDestroying(aura::Window* window) override;
void OnWindowTitleChanged(aura::Window* window) override;
// ash::TransparentActivateWindowButtonDelegate:
void Select() override;
private:
friend class WindowSelectorTest;
......@@ -98,19 +94,6 @@ class ASH_EXPORT WindowSelectorItem
// Changes the opacity of all the windows the item owns.
void SetOpacity(float opacity);
// Updates the window label's bounds to |target_bounds|. Will create a new
// window label and fade it in if it doesn't exist. The bounds change is
// animated as specified by the |animation_type|.
void UpdateWindowLabels(const gfx::Rect& target_bounds,
OverviewAnimationType animation_type);
// Initializes window_label_.
void CreateWindowLabel(const base::string16& title);
// Updates the bounds and accessibility names for all the transparent
// overlays.
void UpdateSelectorButtons();
// Updates the close button's bounds. Any change in bounds will be animated
// from the current bounds to the new bounds as per the |animation_type|.
void UpdateCloseButtonLayout(OverviewAnimationType animation_type);
......@@ -136,12 +119,6 @@ class ASH_EXPORT WindowSelectorItem
// a window layer for display on another monitor.
bool in_bounds_update_;
// Label under the window displaying its active tab name.
scoped_ptr<views::Widget> window_label_;
// View for the label under the window.
views::Label* window_label_view_;
// The close buttons widget container.
views::Widget close_button_widget_;
......@@ -149,11 +126,8 @@ class ASH_EXPORT WindowSelectorItem
// close_button_widget_.
views::ImageButton* close_button_;
// Transparent overlay that covers the entire bounds of the
// WindowSelectorItem and is stacked in front of all windows but behind each
// Windows' own TransparentActivateWindowButton.
scoped_ptr<TransparentActivateWindowButton>
selector_item_activate_window_button_;
// Button that handles window activation.
scoped_ptr<OverviewWindowButton> overview_window_button_;
DISALLOW_COPY_AND_ASSIGN(WindowSelectorItem);
};
......
......@@ -19,6 +19,7 @@
#include "ash/test/test_shelf_delegate.h"
#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_window_button.h"
#include "ash/wm/overview/window_grid.h"
#include "ash/wm/overview/window_selector.h"
#include "ash/wm/overview/window_selector_controller.h"
......@@ -46,7 +47,7 @@
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/widget/native_widget_aura.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/window_util.h"
......@@ -214,8 +215,9 @@ class WindowSelectorTest : public test::AshTestBase {
return &(window->close_button_widget_);
}
views::Label* GetLabelView(ash::WindowSelectorItem* window) {
return window->window_label_view_;
views::LabelButton* GetLabelButtonView(ash::WindowSelectorItem* window) {
return static_cast<views::LabelButton*>(
window->overview_window_button_->window_label_->GetContentsView());
}
// Tests that a window is contained within a given WindowSelectorItem, and
......@@ -346,9 +348,9 @@ TEST_F(WindowSelectorTest, NoCrashWithDesktopTap) {
event_generator.PressTouchId(kTouchId);
// Tap on the desktop, which should not cause a crash. Overview mode should
// remain engaged because the transparent widget over the window has capture.
// be disengaged.
event_generator.GestureTapAt(gfx::Point(0, 0));
EXPECT_TRUE(IsSelecting());
EXPECT_FALSE(IsSelecting());
event_generator.ReleaseTouchId(kTouchId);
}
......@@ -371,15 +373,16 @@ TEST_F(WindowSelectorTest, ClickOnWindowDuringTouch) {
window1_bounds.CenterPoint());
// Clicking on |window2| while touching on |window1| should not cause a
// crash, and overview mode should remain engaged because |window1|
// has capture.
// crash, and |window2| should be selected.
const int kTouchId = 19;
event_generator.PressTouchId(kTouchId);
event_generator.MoveMouseToCenterOf(window2.get());
event_generator.ClickLeftButton();
EXPECT_TRUE(IsSelecting());
EXPECT_FALSE(IsSelecting());
event_generator.ReleaseTouchId(kTouchId);
ToggleOverview();
// Clicking on |window1| while touching on |window1| should not cause
// a crash, overview mode should be disengaged, and |window1| should
// be active.
......@@ -910,17 +913,17 @@ TEST_F(WindowSelectorTest, CreateLabelUnderWindow) {
window->SetTitle(window_title);
ToggleOverview();
WindowSelectorItem* window_item = GetWindowItemsForRoot(0).back();
views::Label* label = GetLabelView(window_item);
views::LabelButton* label = GetLabelButtonView(window_item);
// Has the label view been created?
ASSERT_TRUE(label);
// Verify the label matches the window title.
EXPECT_EQ(label->text(), window_title);
EXPECT_EQ(label->GetText(), window_title);
// Update the window title and check that the label is updated, too.
base::string16 updated_title = base::UTF8ToUTF16("Updated title");
window->SetTitle(updated_title);
EXPECT_EQ(label->text(), updated_title);
EXPECT_EQ(label->GetText(), updated_title);
// Labels are located based on target_bounds, not the actual window item
// bounds.
......
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