summaryrefslogtreecommitdiff
path: root/ash
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2013-08-08 10:24:53 +0100
committerBen Murdoch <benm@google.com>2013-08-08 10:24:53 +0100
commitbb1529ce867d8845a77ec7cdf3e3003ef1771a40 (patch)
treef78d0de03cc8aed1a934d921636a0beb8d164378 /ash
parentc95505573d864f17cabf515e32f5b8e0831ae237 (diff)
downloadchromium_org-bb1529ce867d8845a77ec7cdf3e3003ef1771a40.tar.gz
Merge from Chromium at DEPS revision r216370
This commit was generated by merge_to_master.py. Change-Id: I739228187a6f1df6c28c5761160e593a49891113
Diffstat (limited to 'ash')
-rw-r--r--ash/drag_drop/drag_drop_tracker_unittest.cc2
-rw-r--r--ash/launcher/launcher.cc4
-rw-r--r--ash/launcher/launcher.h7
-rw-r--r--ash/launcher/launcher_view.cc6
-rw-r--r--ash/root_window_controller.cc77
-rw-r--r--ash/root_window_controller.h7
-rw-r--r--ash/root_window_controller_unittest.cc19
-rw-r--r--ash/shelf/shelf_layout_manager.cc74
-rw-r--r--ash/shelf/shelf_layout_manager.h14
-rw-r--r--ash/shelf/shelf_layout_manager_unittest.cc94
-rw-r--r--ash/shell.cc7
-rw-r--r--ash/shell.h8
-rw-r--r--ash/shell/shell_delegate_impl.cc10
-rw-r--r--ash/shell/shell_delegate_impl.h3
-rw-r--r--ash/shell_delegate.h9
-rw-r--r--ash/system/chromeos/audio/tray_audio.cc42
-rw-r--r--ash/system/chromeos/power/power_status.cc13
-rw-r--r--ash/system/chromeos/power/power_status_view.cc10
-rw-r--r--ash/system/chromeos/screen_security/screen_capture_tray_item.cc39
-rw-r--r--ash/system/chromeos/screen_security/screen_capture_tray_item.h8
-rw-r--r--ash/system/chromeos/screen_security/screen_share_tray_item.cc39
-rw-r--r--ash/system/chromeos/screen_security/screen_share_tray_item.h6
-rw-r--r--ash/system/chromeos/screen_security/screen_tray_item.cc106
-rw-r--r--ash/system/chromeos/screen_security/screen_tray_item.h49
-rw-r--r--ash/system/chromeos/screen_security/screen_tray_item_unittest.cc10
-rw-r--r--ash/test/ash_test_base.cc5
-rw-r--r--ash/test/ash_test_base.h15
-rw-r--r--ash/test/ash_test_helper.cc11
-rw-r--r--ash/test/ash_test_helper.h4
-rw-r--r--ash/test/ash_test_helper_unittest.cc2
-rw-r--r--ash/test/test_shell_delegate.cc10
-rw-r--r--ash/test/test_shell_delegate.h3
-rw-r--r--ash/wm/app_list_controller.cc14
-rw-r--r--ash/wm/app_list_controller.h2
-rw-r--r--ash/wm/base_layout_manager.cc13
-rw-r--r--ash/wm/base_layout_manager.h20
-rw-r--r--ash/wm/dock/docked_window_layout_manager.cc52
-rw-r--r--ash/wm/dock/docked_window_layout_manager.h8
-rw-r--r--ash/wm/property_util.h2
-rw-r--r--ash/wm/window_util.cc28
-rw-r--r--ash/wm/workspace/workspace_event_handler_unittest.cc9
-rw-r--r--ash/wm/workspace/workspace_layout_manager.cc87
-rw-r--r--ash/wm/workspace/workspace_layout_manager.h6
-rw-r--r--ash/wm/workspace/workspace_layout_manager_unittest.cc86
44 files changed, 741 insertions, 299 deletions
diff --git a/ash/drag_drop/drag_drop_tracker_unittest.cc b/ash/drag_drop/drag_drop_tracker_unittest.cc
index acb87a46a5..c0a9e91fa5 100644
--- a/ash/drag_drop/drag_drop_tracker_unittest.cc
+++ b/ash/drag_drop/drag_drop_tracker_unittest.cc
@@ -19,7 +19,7 @@ class DragDropTrackerTest : public test::AshTestBase {
public:
virtual void SetUp() OVERRIDE {
AshTestBase::SetUp();
- UpdateDisplay("200x200,200x200");
+ UpdateDisplay("200x200,300x300");
}
aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc
index 03e7ff8107..3dd2a14c88 100644
--- a/ash/launcher/launcher.cc
+++ b/ash/launcher/launcher.cc
@@ -186,4 +186,8 @@ gfx::Rect Launcher::GetLauncherViewBounds() const {
return launcher_view_->bounds();
}
+app_list::ApplicationDragAndDropHost* Launcher::GetDragAndDropHostForAppList() {
+ return launcher_view_;
+}
+
} // namespace ash
diff --git a/ash/launcher/launcher.h b/ash/launcher/launcher.h
index f9bdcc0b48..c670801734 100644
--- a/ash/launcher/launcher.h
+++ b/ash/launcher/launcher.h
@@ -13,6 +13,10 @@
#include "ui/gfx/size.h"
#include "ui/views/widget/widget_observer.h"
+namespace app_list {
+class ApplicationDragAndDropHost;
+}
+
namespace aura {
class Window;
}
@@ -103,6 +107,9 @@ class ASH_EXPORT Launcher {
void SetLauncherViewBounds(gfx::Rect bounds);
gfx::Rect GetLauncherViewBounds() const;
+ // Returns ApplicationDragAndDropHost for this Launcher.
+ app_list::ApplicationDragAndDropHost* GetDragAndDropHostForAppList();
+
private:
// LauncherView used to display icons.
internal::LauncherView* launcher_view_;
diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc
index ea027f6f33..3d328929e4 100644
--- a/ash/launcher/launcher_view.cc
+++ b/ash/launcher/launcher_view.cc
@@ -25,7 +25,6 @@
#include "ash/shelf/shelf_widget.h"
#include "ash/shell_delegate.h"
#include "base/auto_reset.h"
-#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
@@ -1524,11 +1523,6 @@ void LauncherView::ButtonPressed(views::Button* sender,
Shell::GetInstance()->delegate()->RecordUserMetricsAction(
UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON);
Shell::GetInstance()->ToggleAppList(GetWidget()->GetNativeView());
- // By setting us as DnD recipient, the app list knows that we can
- // handle items.
- if (!CommandLine::ForCurrentProcess()->HasSwitch(
- ash::switches::kAshDisableDragAndDropAppListToLauncher))
- Shell::GetInstance()->SetDragAndDropHostOfCurrentAppList(this);
break;
}
}
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 33e6873701..6d5fb62777 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -48,7 +48,9 @@
#include "ui/aura/client/tooltip_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_delegate.h"
#include "ui/aura/window_observer.h"
+#include "ui/base/hit_test.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/screen.h"
#include "ui/keyboard/keyboard_controller.h"
@@ -137,6 +139,64 @@ void DescendantShouldStayInSameRootWindow(aura::Window* container) {
container->SetProperty(internal::kStayInSameRootWindowKey, true);
}
+// A window delegate which does nothing. Used to create a window that
+// is a event target, but do nothing.
+class EmptyWindowDelegate : public aura::WindowDelegate {
+ public:
+ EmptyWindowDelegate() {}
+ virtual ~EmptyWindowDelegate() {}
+
+ // aura::WindowDelegate overrides:
+ virtual gfx::Size GetMinimumSize() const OVERRIDE {
+ return gfx::Size();
+ }
+ virtual gfx::Size GetMaximumSize() const OVERRIDE {
+ return gfx::Size();
+ }
+ virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE {
+ }
+ virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
+ return gfx::kNullCursor;
+ }
+ virtual int GetNonClientComponent(
+ const gfx::Point& point) const OVERRIDE {
+ return HTNOWHERE;
+ }
+ virtual bool ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) OVERRIDE {
+ return false;
+ }
+ virtual bool CanFocus() OVERRIDE {
+ return false;
+ }
+ virtual void OnCaptureLost() OVERRIDE {
+ }
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+ }
+ virtual void OnDeviceScaleFactorChanged(
+ float device_scale_factor) OVERRIDE {
+ }
+ virtual void OnWindowDestroying() OVERRIDE {}
+ virtual void OnWindowDestroyed() OVERRIDE {
+ delete this;
+ }
+ virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
+ }
+ virtual bool HasHitTestMask() const OVERRIDE {
+ return false;
+ }
+ virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
+ virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE {
+ NOTREACHED();
+ return scoped_refptr<ui::Texture>();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
+};
+
} // namespace
namespace internal {
@@ -278,6 +338,8 @@ void RootWindowController::OnLauncherCreated() {
void RootWindowController::UpdateAfterLoginStatusChange(
user::LoginStatus status) {
+ if (status != user::LOGGED_IN_NONE)
+ mouse_event_target_.reset();
if (shelf_->status_area_widget())
shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
}
@@ -316,6 +378,8 @@ void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
}
void RootWindowController::CloseChildWindows() {
+ mouse_event_target_.reset();
+
if (!shelf_.get())
return;
// panel_layout_manager_ needs to be shut down before windows are destroyed.
@@ -460,6 +524,19 @@ void RootWindowController::InitLayoutManagers() {
shelf_.reset(new ShelfWidget(
shelf_container, status_container, workspace_controller()));
+ if (!Shell::GetInstance()->session_state_delegate()->
+ IsActiveUserSessionStarted()) {
+ // This window exists only to be a event target on login screen.
+ // It does not have to handle events, nor be visible.
+ mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
+ mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
+
+ aura::Window* lock_background_container =
+ GetContainer(internal::kShellWindowId_LockScreenBackgroundContainer);
+ lock_background_container->AddChild(mouse_event_target_.get());
+ mouse_event_target_->Show();
+ }
+
// Create Docked windows layout manager
aura::Window* docked_container = GetContainer(
internal::kShellWindowId_DockedContainer);
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 05ab29f9fd..bbf29ce1e3 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -241,6 +241,13 @@ class ASH_EXPORT RootWindowController : public ShellObserver {
// The shelf for managing the launcher and the status widget.
scoped_ptr<ShelfWidget> shelf_;
+ // An invisible/empty window used as a event target for
+ // |MouseCursorEventFilter| before a user logs in.
+ // (crbug.com/266987)
+ // Its container is |LockScreenBackgroundContainer| and
+ // this must be deleted before the container is deleted.
+ scoped_ptr<aura::Window> mouse_event_target_;
+
// Manages layout of docked windows. Owned by DockedContainer.
DockedWindowLayoutManager* docked_layout_manager_;
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index b27cc52ca1..0d40125b90 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -473,5 +473,24 @@ TEST_F(RootWindowControllerTest, FocusBlockedWindow) {
}
}
+typedef test::NoSessionAshTestBase NoSessionRootWindowControllerTest;
+
+// Make sure that an event handler exists for entire display area.
+TEST_F(NoSessionRootWindowControllerTest, Event) {
+ aura::RootWindow* root = Shell::GetPrimaryRootWindow();
+ const gfx::Size size = root->bounds().size();
+ aura::Window* event_target = root->GetEventHandlerForPoint(gfx::Point(0, 0));
+ EXPECT_TRUE(event_target);
+ EXPECT_EQ(event_target,
+ root->GetEventHandlerForPoint(gfx::Point(0, size.height() - 1)));
+ EXPECT_EQ(event_target,
+ root->GetEventHandlerForPoint(gfx::Point(size.width() - 1, 0)));
+ EXPECT_EQ(event_target,
+ root->GetEventHandlerForPoint(gfx::Point(0, size.height() - 1)));
+ EXPECT_EQ(event_target,
+ root->GetEventHandlerForPoint(
+ gfx::Point(size.width() - 1, size.height() - 1)));
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 82f2b20952..c0e5f77863 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -60,6 +60,18 @@ const int kAutoHideDelayMS = 200;
// keep the shelf from hiding.
const int kNotificationBubbleGapHeight = 6;
+// The maximum size of the region on the display opposing the shelf managed by
+// this ShelfLayoutManager which can trigger showing the shelf.
+// For instance:
+// - Primary display is left of secondary display.
+// - Shelf is left aligned
+// - This ShelfLayoutManager manages the shelf for the secondary display.
+// |kMaxAutoHideShowShelfRegionSize| refers to the maximum size of the region
+// from the right edge of the primary display which can trigger showing the
+// auto hidden shelf. The region is used to make it easier to trigger showing
+// the auto hidden shelf when the shelf is on the boundary between displays.
+const int kMaxAutoHideShowShelfRegionSize = 10;
+
ui::Layer* GetLayer(views::Widget* widget) {
return widget->GetNativeView()->layer();
}
@@ -187,6 +199,7 @@ ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
shelf_(shelf),
workspace_controller_(NULL),
window_overlaps_shelf_(false),
+ mouse_over_shelf_when_auto_hide_timer_started_(false),
bezel_event_filter_(new ShelfBezelEventFilter(this)),
gesture_drag_status_(GESTURE_DRAG_NONE),
gesture_drag_amount_(0.f),
@@ -332,14 +345,18 @@ void ShelfLayoutManager::UpdateAutoHideState() {
// Hides happen immediately.
SetState(state_.visibility_state);
} else {
- auto_hide_timer_.Stop();
+ if (!auto_hide_timer_.IsRunning()) {
+ mouse_over_shelf_when_auto_hide_timer_started_ =
+ shelf_->GetWindowBoundsInScreen().Contains(
+ Shell::GetScreen()->GetCursorScreenPoint());
+ }
auto_hide_timer_.Start(
FROM_HERE,
base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
this, &ShelfLayoutManager::UpdateAutoHideStateNow);
}
} else {
- auto_hide_timer_.Stop();
+ StopAutoHideTimer();
}
}
@@ -575,7 +592,7 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
auto_hide_event_filter_.reset(NULL);
}
- auto_hide_timer_.Stop();
+ StopAutoHideTimer();
// The transition of background from auto-hide to visible is janky if the
// transition also cause the shelf's slide animation from the bottom edge.
@@ -889,6 +906,34 @@ ShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const {
void ShelfLayoutManager::UpdateAutoHideStateNow() {
SetState(state_.visibility_state);
+
+ // If the state did not change, the auto hide timer may still be running.
+ StopAutoHideTimer();
+}
+
+void ShelfLayoutManager::StopAutoHideTimer() {
+ auto_hide_timer_.Stop();
+ mouse_over_shelf_when_auto_hide_timer_started_ = false;
+}
+
+gfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const {
+ gfx::Rect shelf_bounds_in_screen = shelf_->GetWindowBoundsInScreen();
+ gfx::Vector2d offset = SelectValueForShelfAlignment(
+ gfx::Vector2d(0, shelf_bounds_in_screen.height()),
+ gfx::Vector2d(-kMaxAutoHideShowShelfRegionSize, 0),
+ gfx::Vector2d(shelf_bounds_in_screen.width(), 0),
+ gfx::Vector2d(0, -kMaxAutoHideShowShelfRegionSize));
+
+ gfx::Rect show_shelf_region_in_screen = shelf_bounds_in_screen;
+ show_shelf_region_in_screen += offset;
+ if (IsHorizontalAlignment())
+ show_shelf_region_in_screen.set_height(kMaxAutoHideShowShelfRegionSize);
+ else
+ show_shelf_region_in_screen.set_width(kMaxAutoHideShowShelfRegionSize);
+
+ // TODO: Figure out if we need any special handling when the keyboard is
+ // visible.
+ return show_shelf_region_in_screen;
}
ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
@@ -936,8 +981,29 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
-kNotificationBubbleGapHeight : 0);
}
- if (shelf_region.Contains(Shell::GetScreen()->GetCursorScreenPoint()))
+ gfx::Point cursor_position_in_screen =
+ Shell::GetScreen()->GetCursorScreenPoint();
+ if (shelf_region.Contains(cursor_position_in_screen))
+ return SHELF_AUTO_HIDE_SHOWN;
+
+ // When the shelf is auto hidden and the shelf is on the boundary between two
+ // displays, it is hard to trigger showing the shelf. For instance, if a
+ // user's primary display is left of their secondary display, it is hard to
+ // unautohide a left aligned shelf on the secondary display.
+ // It is hard because:
+ // - It is hard to stop the cursor in the shelf "light bar" and not overshoot.
+ // - The cursor is warped to the other display if the cursor gets to the edge
+ // of the display.
+ // Show the shelf if the cursor started on the shelf and the user overshot the
+ // shelf slightly to make it easier to show the shelf in this situation. We
+ // do not check |auto_hide_timer_|.IsRunning() because it returns false when
+ // the timer's task is running.
+ if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN ||
+ mouse_over_shelf_when_auto_hide_timer_started_) &&
+ GetAutoHideShowShelfRegionInScreen().Contains(
+ cursor_position_in_screen)) {
return SHELF_AUTO_HIDE_SHOWN;
+ }
const std::vector<aura::Window*> windows =
ash::MruWindowTracker::BuildWindowList(false);
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h
index ce69366a26..467fe1a742 100644
--- a/ash/shelf/shelf_layout_manager.h
+++ b/ash/shelf/shelf_layout_manager.h
@@ -277,6 +277,16 @@ class ASH_EXPORT ShelfLayoutManager :
// Updates the auto hide state immediately.
void UpdateAutoHideStateNow();
+ // Stops the auto hide timer and clears
+ // |mouse_over_shelf_when_auto_hide_timer_started_|.
+ void StopAutoHideTimer();
+
+ // Returns the bounds of an additional region which can trigger showing the
+ // shelf. This region exists to make it easier to trigger showing the shelf
+ // when the shelf is auto hidden and the shelf is on the boundary between
+ // two displays.
+ gfx::Rect GetAutoHideShowShelfRegionInScreen() const;
+
// Returns the AutoHideState. This value is determined from the launcher and
// tray.
ShelfAutoHideState CalculateAutoHideState(
@@ -330,6 +340,10 @@ class ASH_EXPORT ShelfLayoutManager :
base::OneShotTimer<ShelfLayoutManager> auto_hide_timer_;
+ // Whether the mouse was over the shelf when the auto hide timer started.
+ // False when neither the auto hide timer nor the timer task are running.
+ bool mouse_over_shelf_when_auto_hide_timer_started_;
+
// EventFilter used to detect when user moves the mouse over the launcher to
// trigger showing the launcher.
scoped_ptr<AutoHideEventFilter> auto_hide_event_filter_;
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index 0a82cebf24..2781e6c2c6 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "ash/accelerators/accelerator_controller.h"
#include "ash/accelerators/accelerator_table.h"
#include "ash/ash_switches.h"
+#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
#include "ash/focus_cycler.h"
#include "ash/launcher/launcher.h"
@@ -777,6 +778,99 @@ TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) {
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
}
+// Test the behavior of the shelf when it is auto hidden and it is on the
+// boundary between the primary and the secondary display.
+TEST_F(ShelfLayoutManagerTest, AutoHideShelfOnScreenBoundary) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("800x600,800x600");
+ DisplayLayout display_layout(DisplayLayout::RIGHT, 0);
+ Shell::GetInstance()->display_controller()->SetLayoutForCurrentDisplays(
+ display_layout);
+ // Put the primary monitor's shelf on the display boundary.
+ ShelfLayoutManager* shelf = GetShelfLayoutManager();
+ shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
+
+ // Create a window because the shelf is always shown when no windows are
+ // visible.
+ CreateTestWidget();
+
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ ASSERT_EQ(root_windows[0],
+ GetShelfWidget()->GetNativeWindow()->GetRootWindow());
+
+ shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+ EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
+
+ int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1;
+ int y = root_windows[0]->GetBoundsInScreen().y();
+
+ // Start off the mouse nowhere near the shelf; the shelf should be hidden.
+ aura::test::EventGenerator& generator(GetEventGenerator());
+ generator.MoveMouseTo(right_edge - 50, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+ // Moving the mouse over the light bar (but not to the edge of the screen)
+ // should show the shelf.
+ generator.MoveMouseTo(right_edge - 1, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+ EXPECT_EQ(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
+
+ // Moving the mouse off the light bar should hide the shelf.
+ generator.MoveMouseTo(right_edge - 50, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+ // Moving the mouse to the right edge of the screen crossing the light bar
+ // should show the shelf despite the mouse cursor getting warped to the
+ // secondary display.
+ generator.MoveMouseTo(right_edge - 1, y);
+ generator.MoveMouseTo(right_edge, y);
+ UpdateAutoHideStateNow();
+ EXPECT_NE(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
+ EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+
+ // Hide the shelf.
+ generator.MoveMouseTo(right_edge - 50, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+ // Moving the mouse to the right edge of the screen crossing the light bar and
+ // overshooting by a lot should keep the shelf hidden.
+ generator.MoveMouseTo(right_edge - 1, y);
+ generator.MoveMouseTo(right_edge + 50, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+ // Moving the mouse to the right edge of the screen crossing the light bar and
+ // overshooting a bit should show the shelf.
+ generator.MoveMouseTo(right_edge - 1, y);
+ generator.MoveMouseTo(right_edge + 2, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+
+ // Keeping the mouse close to the left edge of the secondary display after the
+ // shelf is shown should keep the shelf shown.
+ generator.MoveMouseTo(right_edge + 2, y + 1);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+
+ // Moving the mouse far from the left edge of the secondary display should
+ // hide the shelf.
+ generator.MoveMouseTo(right_edge + 50, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+ // Moving to the left edge of the secondary display without first crossing
+ // the primary display's right aligned shelf first should not show the shelf.
+ generator.MoveMouseTo(right_edge + 2, y);
+ UpdateAutoHideStateNow();
+ EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+}
+
// Assertions around the lock screen showing.
TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) {
// Since ShelfLayoutManager queries for mouse location, move the mouse so
diff --git a/ash/shell.cc b/ash/shell.cc
index c7b4b1f564..1bade434dd 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -675,13 +675,6 @@ void Shell::ToggleAppList(aura::Window* window) {
app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window);
}
-void Shell::SetDragAndDropHostOfCurrentAppList(
- app_list::ApplicationDragAndDropHost* drag_and_drop_host) {
- if (app_list_controller_.get())
- app_list_controller_->SetDragAndDropHostOfCurrentAppList(
- drag_and_drop_host);
-}
-
bool Shell::GetAppListTargetVisibility() const {
return app_list_controller_.get() &&
app_list_controller_->GetTargetVisibility();
diff --git a/ash/shell.h b/ash/shell.h
index 237a1a8866..c3adade53b 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -27,9 +27,6 @@
class CommandLine;
-namespace app_list {
-class ApplicationDragAndDropHost;
-}
namespace aura {
class EventFilter;
class RootWindow;
@@ -224,11 +221,6 @@ class ASH_EXPORT Shell
// will be used.
void ToggleAppList(aura::Window* anchor);
- // If |drag_and_drop_host| is not NULL it will be called upon drag and drop
- // operations outside the application list.
- void SetDragAndDropHostOfCurrentAppList(
- app_list::ApplicationDragAndDropHost* drag_and_drop_host);
-
// Returns app list target visibility.
bool GetAppListTargetVisibility() const;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 318873c608..20d0a7f65f 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -231,16 +231,6 @@ void ShellDelegateImpl::HandleMediaPlayPause() {
void ShellDelegateImpl::HandleMediaPrevTrack() {
}
-base::string16 ShellDelegateImpl::GetTimeRemainingString(
- base::TimeDelta delta) {
- return base::string16();
-}
-
-base::string16 ShellDelegateImpl::GetTimeDurationLongString(
- base::TimeDelta delta) {
- return base::string16();
-}
-
void ShellDelegateImpl::SaveScreenMagnifierScale(double scale) {
}
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h
index c01b201ebd..7a4e5d6f41 100644
--- a/ash/shell/shell_delegate_impl.h
+++ b/ash/shell/shell_delegate_impl.h
@@ -71,9 +71,6 @@ class ShellDelegateImpl : public ash::ShellDelegate {
virtual void HandleMediaNextTrack() OVERRIDE;
virtual void HandleMediaPlayPause() OVERRIDE;
virtual void HandleMediaPrevTrack() OVERRIDE;
- virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
- virtual base::string16 GetTimeDurationLongString(
- base::TimeDelta delta) OVERRIDE;
virtual void SaveScreenMagnifierScale(double scale) OVERRIDE;
virtual double GetSavedScreenMagnifierScale() OVERRIDE;
virtual ui::MenuModel* CreateContextMenu(
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index 2bf08c1766..38164f2add 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -12,7 +12,6 @@
#include "ash/shell.h"
#include "base/callback.h"
#include "base/strings/string16.h"
-#include "base/time/time.h"
namespace app_list {
class AppListViewDelegate;
@@ -235,14 +234,6 @@ class ASH_EXPORT ShellDelegate {
// Handles the Previous Track Media shortcut key.
virtual void HandleMediaPrevTrack() = 0;
- // Produces l10n-ed text of remaining time, e.g.: "13 minutes left" or
- // "13 Minuten links".
- // Used, for example, to display the remaining battery life.
- virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) = 0;
-
- // Produces l10n-ed text for time duration, e.g.: "13 minutes" or "2 hours".
- virtual base::string16 GetTimeDurationLongString(base::TimeDelta delta) = 0;
-
// Saves the zoom scale of the full screen magnifier.
virtual void SaveScreenMagnifierScale(double scale) = 0;
diff --git a/ash/system/chromeos/audio/tray_audio.cc b/ash/system/chromeos/audio/tray_audio.cc
index 20cc1ef8d4..6ad4362a44 100644
--- a/ash/system/chromeos/audio/tray_audio.cc
+++ b/ash/system/chromeos/audio/tray_audio.cc
@@ -153,12 +153,12 @@ class BarSeparator : public views::View {
BarSeparator() {}
virtual ~BarSeparator() {}
- private:
// Overriden from views::View.
virtual gfx::Size GetPreferredSize() OVERRIDE {
return gfx::Size(kBarSeparatorWidth, kBarSeparatorHeight);
}
+ private:
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
canvas->FillRect(gfx::Rect(width() / 2, 0, 1, height()),
kButtonStrokeColor);
@@ -189,12 +189,12 @@ class VolumeView : public ActionableView,
slider_ = new VolumeSlider(this);
AddChildView(slider_);
- device_type_ = new views::ImageView;
- AddChildView(device_type_);
-
bar_ = new BarSeparator;
AddChildView(bar_);
+ device_type_ = new views::ImageView;
+ AddChildView(device_type_);
+
more_ = new views::ImageView;
more_->EnableCanvasFlippingForRTLUI(true);
more_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
@@ -252,15 +252,14 @@ class VolumeView : public ActionableView,
if (!audio_handler->GetActiveOutputDevice(&device))
return;
int device_icon = GetAudioDeviceIconId(device.type);
+ bar_->SetVisible(show_more);
if (device_icon != kNoAudioDeviceIcon) {
device_type_->SetVisible(true);
device_type_->SetImage(
ui::ResourceBundle::GetSharedInstance().GetImageNamed(
device_icon).ToImageSkia());
- bar_->SetVisible(false);
} else {
device_type_->SetVisible(false);
- bar_->SetVisible(show_more);
}
}
@@ -302,24 +301,33 @@ class VolumeView : public ActionableView,
bounds.set_y((height() - size.height()) / 2);
more_->SetBoundsRect(bounds);
- // Layout bar_ or device_type_ at the left of the more_ button.
+ // Layout either bar_ or device_type_ at the left of the more_ button.
views::View* view_left_to_more;
- if (bar_->visible())
- view_left_to_more = bar_;
- else
+ if (device_type_->visible())
view_left_to_more = device_type_;
- gfx::Size bar_size = view_left_to_more->GetPreferredSize();
- gfx::Rect bar_bounds(bar_size);
- bar_bounds.set_x(more_->bounds().x() - bar_size.width() -
+ else
+ view_left_to_more = bar_;
+ gfx::Size view_size = view_left_to_more->GetPreferredSize();
+ gfx::Rect view_bounds(view_size);
+ view_bounds.set_x(more_->bounds().x() - view_size.width() -
kExtraPaddingBetweenBarAndMore);
- bar_bounds.set_y((height() - bar_size.height()) / 2);
- view_left_to_more->SetBoundsRect(bar_bounds);
-
+ view_bounds.set_y((height() - view_size.height()) / 2);
+ view_left_to_more->SetBoundsRect(view_bounds);
+
+ // Layout vertical bar next to view_left_to_more if device_type_ is visible.
+ if (device_type_->visible()) {
+ gfx::Size bar_size = bar_->GetPreferredSize();
+ gfx::Rect bar_bounds(bar_size);
+ bar_bounds.set_x(view_left_to_more->bounds().x() - bar_size.width());
+ bar_bounds.set_y((height() - bar_size.height()) / 2);
+ bar_->SetBoundsRect(bar_bounds);
+ }
// Layout slider, calculate slider width.
gfx::Rect slider_bounds = slider_->bounds();
slider_bounds.set_width(
- view_left_to_more->bounds().x() - kTrayPopupPaddingBetweenItems
+ bar_->bounds().x()
+ - (device_type_->visible() ? 0 : kTrayPopupPaddingBetweenItems)
- slider_bounds.x());
slider_->SetBoundsRect(slider_bounds);
}
diff --git a/ash/system/chromeos/power/power_status.cc b/ash/system/chromeos/power/power_status.cc
index a9f4dbfaae..0283a0c3fe 100644
--- a/ash/system/chromeos/power/power_status.cc
+++ b/ash/system/chromeos/power/power_status.cc
@@ -17,6 +17,7 @@
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/time_format.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
@@ -47,19 +48,15 @@ void SanitizeProto(power_manager::PowerSupplyProperties* proto) {
base::string16 GetBatteryTimeAccessibilityString(int hour, int min) {
DCHECK(hour || min);
if (hour && !min) {
- return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
- base::TimeDelta::FromHours(hour));
+ return ui::TimeFormat::TimeDurationLong(base::TimeDelta::FromHours(hour));
}
if (min && !hour) {
- return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
- base::TimeDelta::FromMinutes(min));
+ return ui::TimeFormat::TimeDurationLong(base::TimeDelta::FromMinutes(min));
}
return l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BATTERY_TIME_ACCESSIBLE,
- Shell::GetInstance()->delegate()->GetTimeDurationLongString(
- base::TimeDelta::FromHours(hour)),
- Shell::GetInstance()->delegate()->GetTimeDurationLongString(
- base::TimeDelta::FromMinutes(min)));
+ ui::TimeFormat::TimeDurationLong(base::TimeDelta::FromHours(hour)),
+ ui::TimeFormat::TimeDurationLong(base::TimeDelta::FromMinutes(min)));
}
static PowerStatus* g_power_status = NULL;
diff --git a/ash/system/chromeos/power/power_status_view.cc b/ash/system/chromeos/power/power_status_view.cc
index a38d31568a..5323f5c1a6 100644
--- a/ash/system/chromeos/power/power_status_view.cc
+++ b/ash/system/chromeos/power/power_status_view.cc
@@ -14,6 +14,7 @@
#include "base/strings/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/time_format.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
@@ -193,13 +194,8 @@ void PowerStatusView::UpdateTextForNotificationView() {
} else {
// This is a low battery warning prompting the user in minutes.
min = hour * 60 + min;
- ShellDelegate* delegate = Shell::GetInstance()->delegate();
- if (delegate) {
- time_label_->SetText(delegate->GetTimeRemainingString(
- base::TimeDelta::FromMinutes(min)));
- } else {
- time_label_->SetText(base::string16());
- }
+ time_label_->SetText(ui::TimeFormat::TimeRemaining(
+ base::TimeDelta::FromMinutes(min)));
}
} else {
time_label_->SetText(base::string16());
diff --git a/ash/system/chromeos/screen_security/screen_capture_tray_item.cc b/ash/system/chromeos/screen_security/screen_capture_tray_item.cc
index f375bf7331..6563e4bad8 100644
--- a/ash/system/chromeos/screen_security/screen_capture_tray_item.cc
+++ b/ash/system/chromeos/screen_security/screen_capture_tray_item.cc
@@ -8,9 +8,19 @@
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/notification.h"
+
+using message_center::Notification;
namespace ash {
namespace internal {
+namespace {
+
+const char kScreenCaptureNotificationId[] = "chrome://screen/capture";
+
+} // namespace
ScreenCaptureTrayItem::ScreenCaptureTrayItem(SystemTray* system_tray)
: ScreenTrayItem(system_tray) {
@@ -33,7 +43,6 @@ views::View* ScreenCaptureTrayItem::CreateDefaultView(
user::LoginStatus status) {
set_default_view(new tray::ScreenStatusView(
this,
- tray::ScreenStatusView::VIEW_DEFAULT,
IDR_AURA_UBER_TRAY_DISPLAY,
screen_capture_status_,
l10n_util::GetStringUTF16(
@@ -41,15 +50,27 @@ views::View* ScreenCaptureTrayItem::CreateDefaultView(
return default_view();
}
-views::View* ScreenCaptureTrayItem::CreateNotificationView(
- user::LoginStatus status) {
- set_notification_view(new tray::ScreenNotificationView(
- this,
- IDR_AURA_UBER_TRAY_DISPLAY,
+void ScreenCaptureTrayItem::CreateOrUpdateNotification() {
+ message_center::RichNotificationData data;
+ data.buttons.push_back(message_center::ButtonInfo(
+ l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP)));
+ ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
+ scoped_ptr<Notification> notification(new Notification(
+ message_center::NOTIFICATION_TYPE_SIMPLE,
+ kScreenCaptureNotificationId,
screen_capture_status_,
- l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP)));
- return notification_view();
+ base::string16() /* body is blank */,
+ resource_bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY),
+ base::string16() /* display_source */,
+ std::string() /* extension_id */,
+ data,
+ new tray::ScreenNotificationDelegate(this)));
+ notification->SetSystemPriority();
+ message_center::MessageCenter::Get()->AddNotification(notification.Pass());
+}
+
+std::string ScreenCaptureTrayItem::GetNotificationId() {
+ return kScreenCaptureNotificationId;
}
void ScreenCaptureTrayItem::OnScreenCaptureStart(
diff --git a/ash/system/chromeos/screen_security/screen_capture_tray_item.h b/ash/system/chromeos/screen_security/screen_capture_tray_item.h
index f1fb4b5295..92f6c8a711 100644
--- a/ash/system/chromeos/screen_security/screen_capture_tray_item.h
+++ b/ash/system/chromeos/screen_security/screen_capture_tray_item.h
@@ -22,11 +22,13 @@ class ASH_EXPORT ScreenCaptureTrayItem : public ScreenTrayItem,
virtual ~ScreenCaptureTrayItem();
private:
- // Overridden from ScreenTrayItem.
+ // Overridden from SystemTrayItem.
virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE;
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
- virtual views::View* CreateNotificationView(
- user::LoginStatus status) OVERRIDE;
+
+ // Overridden from ScreenTrayItem.
+ virtual void CreateOrUpdateNotification() OVERRIDE;
+ virtual std::string GetNotificationId() OVERRIDE;
// Overridden from ScreenCaptureObserver.
virtual void OnScreenCaptureStart(
diff --git a/ash/system/chromeos/screen_security/screen_share_tray_item.cc b/ash/system/chromeos/screen_security/screen_share_tray_item.cc
index 3e107639ae..18dd317883 100644
--- a/ash/system/chromeos/screen_security/screen_share_tray_item.cc
+++ b/ash/system/chromeos/screen_security/screen_share_tray_item.cc
@@ -8,9 +8,19 @@
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/notification.h"
+
+using message_center::Notification;
namespace ash {
namespace internal {
+namespace {
+
+const char kScreenShareNotificationId[] = "chrome://screen/share";
+
+}
ScreenShareTrayItem::ScreenShareTrayItem(SystemTray* system_tray)
: ScreenTrayItem(system_tray) {
@@ -32,7 +42,6 @@ views::View* ScreenShareTrayItem::CreateTrayView(user::LoginStatus status) {
views::View* ScreenShareTrayItem::CreateDefaultView(user::LoginStatus status) {
set_default_view(new tray::ScreenStatusView(
this,
- tray::ScreenStatusView::VIEW_DEFAULT,
IDR_AURA_UBER_TRAY_DISPLAY,
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED),
@@ -41,8 +50,7 @@ views::View* ScreenShareTrayItem::CreateDefaultView(user::LoginStatus status) {
return default_view();
}
-views::View* ScreenShareTrayItem::CreateNotificationView(
- user::LoginStatus status) {
+void ScreenShareTrayItem::CreateOrUpdateNotification() {
base::string16 help_label_text;
if (!helper_name_.empty()) {
help_label_text = l10n_util::GetStringFUTF16(
@@ -53,13 +61,26 @@ views::View* ScreenShareTrayItem::CreateNotificationView(
IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED);
}
- set_notification_view(new tray::ScreenNotificationView(
- this,
- IDR_AURA_UBER_TRAY_DISPLAY,
+ message_center::RichNotificationData data;
+ data.buttons.push_back(message_center::ButtonInfo(
+ l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP)));
+ ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
+ scoped_ptr<Notification> notification(new Notification(
+ message_center::NOTIFICATION_TYPE_SIMPLE,
+ kScreenShareNotificationId,
help_label_text,
- l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP)));
- return notification_view();
+ base::string16() /* body is blank */,
+ resource_bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY),
+ base::string16() /* display_source */,
+ std::string() /* extension_id */,
+ data,
+ new tray::ScreenNotificationDelegate(this)));
+ notification->SetSystemPriority();
+ message_center::MessageCenter::Get()->AddNotification(notification.Pass());
+}
+
+std::string ScreenShareTrayItem::GetNotificationId() {
+ return kScreenShareNotificationId;
}
void ScreenShareTrayItem::OnScreenShareStart(
diff --git a/ash/system/chromeos/screen_security/screen_share_tray_item.h b/ash/system/chromeos/screen_security/screen_share_tray_item.h
index 4624ac2ee6..14f26e5667 100644
--- a/ash/system/chromeos/screen_security/screen_share_tray_item.h
+++ b/ash/system/chromeos/screen_security/screen_share_tray_item.h
@@ -25,8 +25,10 @@ class ASH_EXPORT ScreenShareTrayItem : public ScreenTrayItem,
// Overridden from SystemTrayItem.
virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE;
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
- virtual views::View* CreateNotificationView(
- user::LoginStatus status) OVERRIDE;
+
+ // Overridden from ScreenTrayItem.
+ virtual void CreateOrUpdateNotification() OVERRIDE;
+ virtual std::string GetNotificationId() OVERRIDE;
// Overridden from ScreenShareObserver.
virtual void OnScreenShareStart(
diff --git a/ash/system/chromeos/screen_security/screen_tray_item.cc b/ash/system/chromeos/screen_security/screen_tray_item.cc
index 8c845e7efb..4b10a27072 100644
--- a/ash/system/chromeos/screen_security/screen_tray_item.cc
+++ b/ash/system/chromeos/screen_security/screen_tray_item.cc
@@ -7,14 +7,12 @@
#include "ash/system/tray/fixed_sized_image_view.h"
#include "ash/system/tray/tray_constants.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/message_center/message_center.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
namespace {
-const int kStopButtonRightPaddingDefaultView = 18;
-const int kStopButtonRightPaddingNotificationView = 0;
-const int kStopButtonLeftPaddingNotificationView = 4;
-const int kVerticalPaddingScreenCaptureNotitification = 12;
+const int kStopButtonRightPadding = 18;
} // namespace
namespace ash {
@@ -43,7 +41,6 @@ void ScreenTrayView::Update() {
// ScreenStatusView implementations.
ScreenStatusView::ScreenStatusView(ScreenTrayItem* screen_tray_item,
- ViewType view_type,
int icon_id,
const base::string16& label_text,
const base::string16& stop_button_text)
@@ -51,7 +48,6 @@ ScreenStatusView::ScreenStatusView(ScreenTrayItem* screen_tray_item,
icon_(NULL),
label_(NULL),
stop_button_(NULL),
- view_type_(view_type),
icon_id_(icon_id),
label_text_(label_text),
stop_button_text_(stop_button_text) {
@@ -65,18 +61,10 @@ ScreenStatusView::~ScreenStatusView() {
void ScreenStatusView::Layout() {
views::View::Layout();
- int stop_button_right_padding =
- view_type_ == VIEW_DEFAULT ?
- kStopButtonRightPaddingDefaultView :
- kStopButtonRightPaddingNotificationView;
- int stop_button_left_padding =
- view_type_ == VIEW_DEFAULT ?
- kTrayPopupPaddingBetweenItems :
- kStopButtonLeftPaddingNotificationView;
// Give the stop button the space it requests.
gfx::Size stop_size = stop_button_->GetPreferredSize();
gfx::Rect stop_bounds(stop_size);
- stop_bounds.set_x(width() - stop_size.width() - stop_button_right_padding);
+ stop_bounds.set_x(width() - stop_size.width() - kStopButtonRightPadding);
stop_bounds.set_y((height() - stop_size.height()) / 2);
stop_button_->SetBoundsRect(stop_bounds);
@@ -84,7 +72,7 @@ void ScreenStatusView::Layout() {
if (label_->bounds().Intersects(stop_button_->bounds())) {
gfx::Rect label_bounds = label_->bounds();
label_bounds.set_width(
- stop_button_->x() - stop_button_left_padding - label_->x());
+ stop_button_->x() - kTrayPopupPaddingBetweenItems - label_->x());
label_->SetBoundsRect(label_bounds);
}
}
@@ -99,22 +87,13 @@ void ScreenStatusView::ButtonPressed(
void ScreenStatusView::CreateItems() {
set_background(views::Background::CreateSolidBackground(kBackgroundColor));
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
- if (view_type_ == VIEW_DEFAULT) {
- SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
- kTrayPopupPaddingHorizontal,
- 0,
- kTrayPopupPaddingBetweenItems));
- icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight);
- icon_->SetImage(bundle.GetImageNamed(icon_id_).ToImageSkia());
- AddChildView(icon_);
- } else {
- SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kHorizontal,
- 0,
- kVerticalPaddingScreenCaptureNotitification,
- 0));
- }
-
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
+ kTrayPopupPaddingHorizontal,
+ 0,
+ kTrayPopupPaddingBetweenItems));
+ icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight);
+ icon_->SetImage(bundle.GetImageNamed(icon_id_).ToImageSkia());
+ AddChildView(icon_);
label_ = new views::Label;
label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
label_->SetMultiLine(true);
@@ -126,40 +105,34 @@ void ScreenStatusView::CreateItems() {
}
void ScreenStatusView::Update() {
- if (view_type_ == VIEW_DEFAULT) {
- // Hide the notification bubble when the ash tray bubble opens.
- screen_tray_item_->HideNotificationView();
- SetVisible(screen_tray_item_->is_started());
- }
+ // Hide the notification bubble when the ash tray bubble opens.
+ screen_tray_item_->HideNotificationView();
+ SetVisible(screen_tray_item_->is_started());
}
+ScreenNotificationDelegate::ScreenNotificationDelegate(
+ ScreenTrayItem* screen_tray)
+ : screen_tray_(screen_tray) {
+}
-// ScreenNotificationView implementations.
-ScreenNotificationView::ScreenNotificationView(
- ScreenTrayItem* screen_tray_item,
- int icon_id,
- const base::string16& label_text,
- const base::string16& stop_button_text)
- : TrayNotificationView(screen_tray_item, icon_id),
- screen_tray_item_(screen_tray_item) {
- screen_status_view_ = new ScreenStatusView(
- screen_tray_item,
- ScreenStatusView::VIEW_NOTIFICATION,
- icon_id,
- label_text,
- stop_button_text);
- InitView(screen_status_view_);
- Update();
+ScreenNotificationDelegate::~ScreenNotificationDelegate() {
+}
+
+void ScreenNotificationDelegate::Display() {
}
-ScreenNotificationView::~ScreenNotificationView() {
+void ScreenNotificationDelegate::Error() {
}
-void ScreenNotificationView::Update() {
- if (screen_tray_item_->is_started())
- screen_status_view_->Update();
- else
- screen_tray_item_->HideNotificationView();
+void ScreenNotificationDelegate::Close(bool by_user) {
+}
+
+void ScreenNotificationDelegate::Click() {
+}
+
+void ScreenNotificationDelegate::ButtonClick(int button_index) {
+ DCHECK_EQ(0, button_index);
+ screen_tray_->Stop();
}
} // namespace tray
@@ -168,7 +141,6 @@ ScreenTrayItem::ScreenTrayItem(SystemTray* system_tray)
: SystemTrayItem(system_tray),
tray_view_(NULL),
default_view_(NULL),
- notification_view_(NULL),
is_started_(false),
stop_callback_(base::Bind(&base::DoNothing)) {
}
@@ -180,8 +152,12 @@ void ScreenTrayItem::Update() {
tray_view_->Update();
if (default_view_)
default_view_->Update();
- if (notification_view_)
- notification_view_->Update();
+ if (is_started_) {
+ CreateOrUpdateNotification();
+ } else {
+ message_center::MessageCenter::Get()->RemoveNotification(
+ GetNotificationId(), false /* by_user */);
+ }
}
void ScreenTrayItem::Start(const base::Closure& stop_callback) {
@@ -196,7 +172,7 @@ void ScreenTrayItem::Start(const base::Closure& stop_callback) {
if (!system_tray()->HasSystemBubbleType(
SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) {
- ShowNotificationView();
+ CreateOrUpdateNotification();
}
}
@@ -220,9 +196,5 @@ void ScreenTrayItem::DestroyDefaultView() {
default_view_ = NULL;
}
-void ScreenTrayItem::DestroyNotificationView() {
- notification_view_ = NULL;
-}
-
} // namespace internal
} // namespace ash
diff --git a/ash/system/chromeos/screen_security/screen_tray_item.h b/ash/system/chromeos/screen_security/screen_tray_item.h
index 03b8435d34..f078a39f0e 100644
--- a/ash/system/chromeos/screen_security/screen_tray_item.h
+++ b/ash/system/chromeos/screen_security/screen_tray_item.h
@@ -11,6 +11,7 @@
#include "ash/system/tray/tray_item_view.h"
#include "ash/system/tray/tray_notification_view.h"
#include "ash/system/tray/tray_popup_label_button.h"
+#include "ui/message_center/notification_delegate.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/image_view.h"
@@ -41,13 +42,7 @@ class ScreenTrayView : public TrayItemView {
class ScreenStatusView : public views::View,
public views::ButtonListener {
public:
- enum ViewType {
- VIEW_DEFAULT,
- VIEW_NOTIFICATION
- };
-
ScreenStatusView(ScreenTrayItem* screen_tray_item,
- ViewType view_type,
int icon_id,
const base::string16& label_text,
const base::string16& stop_button_text);
@@ -68,7 +63,6 @@ class ScreenStatusView : public views::View,
views::ImageView* icon_;
views::Label* label_;
TrayPopupLabelButton* stop_button_;
- ViewType view_type_;
int icon_id_;
base::string16 label_text_;
base::string16 stop_button_text_;
@@ -76,21 +70,24 @@ class ScreenStatusView : public views::View,
DISALLOW_COPY_AND_ASSIGN(ScreenStatusView);
};
-class ScreenNotificationView : public TrayNotificationView {
+class ScreenNotificationDelegate : public message_center::NotificationDelegate {
public:
- ScreenNotificationView(ScreenTrayItem* screen_tray_item,
- int icon_id,
- const base::string16& label_text,
- const base::string16& stop_button_text);
- virtual ~ScreenNotificationView();
+ explicit ScreenNotificationDelegate(ScreenTrayItem* screen_tray);
- void Update();
+ // message_center::NotificationDelegate overrides:
+ virtual void Display() OVERRIDE;
+ virtual void Error() OVERRIDE;
+ virtual void Close(bool by_user) OVERRIDE;
+ virtual void Click() OVERRIDE;
+ virtual void ButtonClick(int button_index) OVERRIDE;
+
+ protected:
+ virtual ~ScreenNotificationDelegate();
private:
- ScreenTrayItem* screen_tray_item_;
- ScreenStatusView* screen_status_view_;
+ ScreenTrayItem* screen_tray_;
- DISALLOW_COPY_AND_ASSIGN(ScreenNotificationView);
+ DISALLOW_COPY_AND_ASSIGN(ScreenNotificationDelegate);
};
} // namespace tray
@@ -114,13 +111,6 @@ class ASH_EXPORT ScreenTrayItem : public SystemTrayItem {
default_view_ = default_view;
}
- tray::ScreenNotificationView* notification_view() {
- return notification_view_;
- }
- void set_notification_view(tray::ScreenNotificationView* notification_view) {
- notification_view_ = notification_view;
- }
-
bool is_started() const { return is_started_; }
void set_is_started(bool is_started) { is_started_ = is_started; }
@@ -128,20 +118,21 @@ class ASH_EXPORT ScreenTrayItem : public SystemTrayItem {
void Start(const base::Closure& stop_callback);
void Stop();
+ // Creates or updates the notification for the tray item.
+ virtual void CreateOrUpdateNotification() = 0;
+
+ // Returns the id of the notification for the tray item.
+ virtual std::string GetNotificationId() = 0;
+
// Overridden from SystemTrayItem.
virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE = 0;
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE = 0;
- virtual views::View* CreateNotificationView(
- user::LoginStatus status) OVERRIDE = 0;
-
virtual void DestroyTrayView() OVERRIDE;
virtual void DestroyDefaultView() OVERRIDE;
- virtual void DestroyNotificationView() OVERRIDE;
private:
tray::ScreenTrayView* tray_view_;
tray::ScreenStatusView* default_view_;
- tray::ScreenNotificationView* notification_view_;
bool is_started_;
base::Closure stop_callback_;
diff --git a/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc b/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
index d95bed9372..e51a91fa83 100644
--- a/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
+++ b/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
@@ -12,6 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "ui/base/events/event.h"
#include "ui/gfx/point.h"
+#include "ui/message_center/message_center.h"
#include "ui/views/view.h"
namespace ash {
@@ -177,12 +178,9 @@ void TestNotificationView(ScreenTrayItemTest* test) {
ScreenTrayItem* tray_item = test->tray_item();
test->StartSession();
- EXPECT_TRUE(tray_item->notification_view()->visible());
-
- // Clicking on the notification view should dismiss the view
- ClickViewCenter(tray_item->notification_view());
- EXPECT_FALSE(tray_item->notification_view());
-
+ message_center::MessageCenter* message_center =
+ message_center::MessageCenter::Get();
+ EXPECT_TRUE(message_center->HasNotification(tray_item->GetNotificationId()));
test->StopSession();
}
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 85ba7ae83d..2b0b32a5f2 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -84,7 +84,8 @@ content::WebContents* AshTestViewsDelegate::CreateWebContents(
AshTestBase::AshTestBase()
: setup_called_(false),
- teardown_called_(false) {
+ teardown_called_(false),
+ start_session_(true) {
// Must initialize |ash_test_helper_| here because some tests rely on
// AshTestBase methods before they call AshTestBase::SetUp().
ash_test_helper_.reset(new AshTestHelper(base::MessageLoopForUI::current()));
@@ -109,7 +110,7 @@ void AshTestBase::SetUp() {
#endif
ui::InitializeInputMethodForTesting();
- ash_test_helper_->SetUp();
+ ash_test_helper_->SetUp(start_session_);
Shell::GetPrimaryRootWindow()->Show();
Shell::GetPrimaryRootWindow()->ShowRootWindow();
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h
index c0567be5f2..5e8fdd2adc 100644
--- a/ash/test/ash_test_base.h
+++ b/ash/test/ash_test_base.h
@@ -110,6 +110,8 @@ class AshTestBase : public testing::Test {
// or false otherwise (e.g. win8 bot).
static bool SupportsHostWindowResize();
+ void set_start_session(bool start_session) { start_session_ = start_session; }
+
void RunAllPendingInMessageLoop();
// Utility methods to emulate user logged in or not, session started or not
@@ -127,6 +129,8 @@ class AshTestBase : public testing::Test {
private:
bool setup_called_;
bool teardown_called_;
+ // |SetUp()| doesn't activate session if this is set to false.
+ bool start_session_;
content::TestBrowserThreadBundle thread_bundle_;
scoped_ptr<AshTestHelper> ash_test_helper_;
scoped_ptr<aura::test::EventGenerator> event_generator_;
@@ -141,6 +145,17 @@ class AshTestBase : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(AshTestBase);
};
+class NoSessionAshTestBase : public AshTestBase {
+ public:
+ NoSessionAshTestBase() {
+ set_start_session(false);
+ }
+ virtual ~NoSessionAshTestBase() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NoSessionAshTestBase);
+};
+
} // namespace test
} // namespace ash
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 1d8c7d1774..45a1740953 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -39,7 +39,7 @@ AshTestHelper::AshTestHelper(base::MessageLoopForUI* message_loop)
AshTestHelper::~AshTestHelper() {
}
-void AshTestHelper::SetUp() {
+void AshTestHelper::SetUp(bool start_session) {
// Disable animations during tests.
zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
@@ -60,9 +60,12 @@ void AshTestHelper::SetUp() {
ash::Shell::CreateInstance(test_shell_delegate_);
Shell* shell = Shell::GetInstance();
- test_shell_delegate_->test_session_state_delegate()->
- SetActiveUserSessionStarted(true);
- test_shell_delegate_->test_session_state_delegate()->SetHasActiveUser(true);
+ if (start_session) {
+ test_shell_delegate_->test_session_state_delegate()->
+ SetActiveUserSessionStarted(true);
+ test_shell_delegate_->test_session_state_delegate()->
+ SetHasActiveUser(true);
+ }
test::DisplayManagerTestApi(shell->display_manager()).
DisableChangeDisplayUponHostResize();
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h
index 669ec292f1..f4d7706469 100644
--- a/ash/test/ash_test_helper.h
+++ b/ash/test/ash_test_helper.h
@@ -33,7 +33,9 @@ class AshTestHelper {
~AshTestHelper();
// Creates the ash::Shell and performs associated initialization.
- void SetUp();
+ // Set |start_session| to true if the user should log in before
+ // the test is run.
+ void SetUp(bool start_session);
// Destroys the ash::Shell and performs associated cleanup.
void TearDown();
diff --git a/ash/test/ash_test_helper_unittest.cc b/ash/test/ash_test_helper_unittest.cc
index fdb27f9e46..0de950f43c 100644
--- a/ash/test/ash_test_helper_unittest.cc
+++ b/ash/test/ash_test_helper_unittest.cc
@@ -18,7 +18,7 @@ class AshTestHelperTest : public testing::Test {
virtual void SetUp() OVERRIDE {
testing::Test::SetUp();
ash_test_helper_.reset(new ash::test::AshTestHelper(&message_loop_));
- ash_test_helper_->SetUp();
+ ash_test_helper_->SetUp(true);
}
virtual void TearDown() OVERRIDE {
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 532876ec85..9b51e6a782 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -191,16 +191,6 @@ void TestShellDelegate::HandleMediaPlayPause() {
void TestShellDelegate::HandleMediaPrevTrack() {
}
-base::string16 TestShellDelegate::GetTimeRemainingString(
- base::TimeDelta delta) {
- return base::string16();
-}
-
-base::string16 TestShellDelegate::GetTimeDurationLongString(
- base::TimeDelta delta) {
- return base::string16();
-}
-
void TestShellDelegate::SaveScreenMagnifierScale(double scale) {
}
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index b8a618bcf6..dc8875b136 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -74,9 +74,6 @@ class TestShellDelegate : public ShellDelegate {
virtual void HandleMediaNextTrack() OVERRIDE;
virtual void HandleMediaPlayPause() OVERRIDE;
virtual void HandleMediaPrevTrack() OVERRIDE;
- virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
- virtual base::string16 GetTimeDurationLongString(
- base::TimeDelta delta) OVERRIDE;
virtual void SaveScreenMagnifierScale(double scale) OVERRIDE;
virtual double GetSavedScreenMagnifierScale() OVERRIDE;
virtual ui::MenuModel* CreateContextMenu(aura::RootWindow* root) OVERRIDE;
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index 45a6bcf2fa..ea5e4f4ce9 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -12,6 +12,7 @@
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/property_util.h"
+#include "base/command_line.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/pagination_model.h"
#include "ui/app_list/views/app_list_view.h"
@@ -192,6 +193,13 @@ void AppListController::SetVisible(bool visible, aura::Window* window) {
true /* border_accepts_events */);
}
SetView(view);
+ // By setting us as DnD recipient, the app list knows that we can
+ // handle items.
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ ash::switches::kAshDisableDragAndDropAppListToLauncher)) {
+ SetDragAndDropHostOfCurrentAppList(
+ Launcher::ForWindow(window)->GetDragAndDropHostForAppList());
+ }
}
}
@@ -203,15 +211,15 @@ aura::Window* AppListController::GetWindow() {
return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL;
}
+////////////////////////////////////////////////////////////////////////////////
+// AppListController, private:
+
void AppListController::SetDragAndDropHostOfCurrentAppList(
app_list::ApplicationDragAndDropHost* drag_and_drop_host) {
if (view_ && is_visible_)
view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
}
-////////////////////////////////////////////////////////////////////////////////
-// AppListController, private:
-
void AppListController::SetView(app_list::AppListView* view) {
DCHECK(view_ == NULL);
DCHECK(is_visible_);
diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h
index 8aa7e3012a..b2c7961a7f 100644
--- a/ash/wm/app_list_controller.h
+++ b/ash/wm/app_list_controller.h
@@ -62,12 +62,12 @@ class AppListController : public ui::EventHandler,
// Returns app list window or NULL if it is not visible.
aura::Window* GetWindow();
+ private:
// If |drag_and_drop_host| is not NULL it will be called upon drag and drop
// operations outside the application list.
void SetDragAndDropHostOfCurrentAppList(
app_list::ApplicationDragAndDropHost* drag_and_drop_host);
- private:
// Sets the app list view and attempts to show it.
void SetView(app_list::AppListView* view);
diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc
index 10f8311f61..6842f3e3c0 100644
--- a/ash/wm/base_layout_manager.cc
+++ b/ash/wm/base_layout_manager.cc
@@ -107,7 +107,8 @@ void BaseLayoutManager::SetChildBounds(aura::Window* child,
// BaseLayoutManager, ash::ShellObserver overrides:
void BaseLayoutManager::OnDisplayWorkAreaInsetsChanged() {
- AdjustWindowSizesForScreenChange(ADJUST_WINDOW_DISPLAY_INSETS_CHANGED);
+ AdjustAllWindowsBoundsForWorkAreaChange(
+ ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
}
/////////////////////////////////////////////////////////////////////////////
@@ -145,7 +146,7 @@ void BaseLayoutManager::OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
if (root_window_ == window)
- AdjustWindowSizesForScreenChange(ADJUST_WINDOW_SCREEN_SIZE_CHANGED);
+ AdjustAllWindowsBoundsForWorkAreaChange(ADJUST_WINDOW_DISPLAY_SIZE_CHANGED);
}
//////////////////////////////////////////////////////////////////////////////
@@ -192,12 +193,12 @@ void BaseLayoutManager::ShowStateChanged(aura::Window* window,
}
}
-void BaseLayoutManager::AdjustWindowSizesForScreenChange(
+void BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
AdjustWindowReason reason) {
// Don't do any adjustments of the insets while we are in screen locked mode.
// This would happen if the launcher was auto hidden before the login screen
// was shown and then gets shown when the login screen gets presented.
- if (reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED &&
+ if (reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED &&
Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
return;
@@ -209,11 +210,11 @@ void BaseLayoutManager::AdjustWindowSizesForScreenChange(
for (WindowSet::const_iterator it = windows_.begin();
it != windows_.end();
++it) {
- AdjustWindowSizeForScreenChange(*it, reason);
+ AdjustWindowBoundsForWorkAreaChange(*it, reason);
}
}
-void BaseLayoutManager::AdjustWindowSizeForScreenChange(
+void BaseLayoutManager::AdjustWindowBoundsForWorkAreaChange(
aura::Window* window,
AdjustWindowReason reason) {
if (wm::IsWindowMaximized(window)) {
diff --git a/ash/wm/base_layout_manager.h b/ash/wm/base_layout_manager.h
index 7fe25e5fe6..0fc2b36917 100644
--- a/ash/wm/base_layout_manager.h
+++ b/ash/wm/base_layout_manager.h
@@ -77,27 +77,29 @@ class ASH_EXPORT BaseLayoutManager
protected:
enum AdjustWindowReason {
- ADJUST_WINDOW_SCREEN_SIZE_CHANGED,
- ADJUST_WINDOW_DISPLAY_INSETS_CHANGED,
- ADJUST_WINDOW_WINDOW_ADDED
+ ADJUST_WINDOW_DISPLAY_SIZE_CHANGED,
+ ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED,
};
// Invoked from OnWindowPropertyChanged() if |kShowStateKey| changes.
virtual void ShowStateChanged(aura::Window* window,
ui::WindowShowState last_show_state);
- // Adjusts the window sizes when the screen changes its size or its
- // work area insets. If this is called for a screen size change (i.e. |reason|
- // is ADJUST_WINDOW_SCREEN_SIZE_CHANGED), the non-maximized/non-fullscreen
+ // Adjusts the window's bounds when the display area changes for given
+ // window. This happens when the display size, work area insets or
+ // the display on which the window exists has changed.
+ // If this is called for a display size change (i.e. |reason|
+ // is ADJUST_WINDOW_DISPLAY_SIZE_CHANGED), the non-maximized/non-fullscreen
// windows are readjusted to make sure the window is completely within the
// display region. Otherwise, it makes sure at least some parts of the window
// is on display.
- virtual void AdjustWindowSizesForScreenChange(AdjustWindowReason reason);
+ virtual void AdjustAllWindowsBoundsForWorkAreaChange(
+ AdjustWindowReason reason);
// Adjusts the sizes of the specific window in respond to a screen change or
// display-area size change.
- virtual void AdjustWindowSizeForScreenChange(aura::Window* window,
- AdjustWindowReason reason);
+ virtual void AdjustWindowBoundsForWorkAreaChange(aura::Window* window,
+ AdjustWindowReason reason);
aura::RootWindow* root_window() { return root_window_; }
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc
index d9d1c07897..d73a0ccac7 100644
--- a/ash/wm/dock/docked_window_layout_manager.cc
+++ b/ash/wm/dock/docked_window_layout_manager.cc
@@ -15,6 +15,7 @@
#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "base/auto_reset.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/focus_manager.h"
@@ -33,6 +34,39 @@ const int kWindowIdealSpacing = 4;
namespace {
+const SkColor kDockBackgroundColor = SkColorSetARGB(0xff, 0x10, 0x10, 0x10);
+const float kDockBackgroundOpacity = 0.5f;
+
+class DockedBackgroundWidget : public views::Widget {
+ public:
+ explicit DockedBackgroundWidget(aura::Window* container) {
+ InitWidget(container);
+ }
+
+ private:
+ void InitWidget(aura::Window* parent) {
+ views::Widget::InitParams params;
+ params.type = views::Widget::InitParams::TYPE_POPUP;
+ params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
+ params.can_activate = false;
+ params.keep_on_top = false;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.parent = parent;
+ params.accept_events = false;
+ set_focus_on_creation(false);
+ Init(params);
+ DCHECK_EQ(GetNativeView()->GetRootWindow(), parent->GetRootWindow());
+ views::View* content_view = new views::View;
+ content_view->set_background(
+ views::Background::CreateSolidBackground(kDockBackgroundColor));
+ SetContentsView(content_view);
+ GetNativeWindow()->layer()->SetOpacity(kDockBackgroundOpacity);
+ Hide();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget);
+};
+
DockedWindowLayoutManager* GetDockLayoutManager(aura::Window* window,
const gfx::Point& location) {
gfx::Rect near_location(location, gfx::Size());
@@ -69,7 +103,8 @@ DockedWindowLayoutManager::DockedWindowLayoutManager(
shelf_hidden_(false),
docked_width_(0),
alignment_(DOCKED_ALIGNMENT_NONE),
- last_active_window_(NULL) {
+ last_active_window_(NULL),
+ background_widget_(new DockedBackgroundWidget(dock_container_)) {
DCHECK(dock_container);
aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
AddObserver(this);
@@ -546,6 +581,17 @@ void DockedWindowLayoutManager::UpdateDockBounds() {
DockedWindowLayoutManagerObserver,
observer_list_,
OnDockBoundsChanging(bounds));
+
+ // Show or hide background for docked area.
+ gfx::Rect background_bounds(docked_bounds_);
+ const gfx::Rect work_area =
+ Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area();
+ background_bounds.set_height(work_area.height());
+ background_widget_->SetBounds(background_bounds);
+ if (docked_width_ > 0)
+ background_widget_->Show();
+ else
+ background_widget_->Hide();
}
void DockedWindowLayoutManager::UpdateStacking(aura::Window* active_window) {
@@ -571,13 +617,15 @@ void DockedWindowLayoutManager::UpdateStacking(aura::Window* active_window) {
for (aura::Window::Windows::const_iterator it =
dock_container_->children().begin();
it != dock_container_->children().end(); ++it) {
+ if (!IsUsedByLayout(*it))
+ continue;
gfx::Rect bounds = (*it)->bounds();
window_ordering.insert(std::make_pair(bounds.y() + bounds.height() / 2,
*it));
}
int active_center_y = active_window->bounds().CenterPoint().y();
- aura::Window* previous_window = NULL;
+ aura::Window* previous_window = background_widget_->GetNativeWindow();
for (std::map<int, aura::Window*>::const_iterator it =
window_ordering.begin();
it != window_ordering.end() && it->first < active_center_y; ++it) {
diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h
index 28c81fccd7..aa02b34342 100644
--- a/ash/wm/dock/docked_window_layout_manager.h
+++ b/ash/wm/dock/docked_window_layout_manager.h
@@ -13,6 +13,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "ui/aura/client/activation_change_observer.h"
#include "ui/aura/layout_manager.h"
@@ -28,6 +29,10 @@ namespace gfx {
class Point;
}
+namespace views {
+class Widget;
+}
+
namespace ash {
class Launcher;
@@ -182,6 +187,9 @@ class ASH_EXPORT DockedWindowLayoutManager
// are currently focused.
aura::Window* last_active_window_;
+ // Widget used to paint a background for the docked area.
+ scoped_ptr<views::Widget> background_widget_;
+
// Observers of dock bounds changes.
ObserverList<DockedWindowLayoutManagerObserver> observer_list_;
diff --git a/ash/wm/property_util.h b/ash/wm/property_util.h
index adb983df6d..32ae278ca9 100644
--- a/ash/wm/property_util.h
+++ b/ash/wm/property_util.h
@@ -24,7 +24,7 @@ class RootWindowController;
// Sets the restore bounds property on |window| in the virtual screen
// coordinates. Deletes existing bounds value if exists.
ASH_EXPORT void SetRestoreBoundsInScreen(aura::Window* window,
- const gfx::Rect& screen_bounds);
+ const gfx::Rect& screen_bounds);
// Same as |SetRestoreBoundsInScreen| except that the bounds is in the
// parent's coordinates.
ASH_EXPORT void SetRestoreBoundsInParent(aura::Window* window,
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index f11b3bc65d..67dcd95c4c 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -173,21 +173,19 @@ void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& work_area,
gfx::Rect* bounds) {
bounds->set_width(std::min(bounds->width(), work_area.width()));
bounds->set_height(std::min(bounds->height(), work_area.height()));
- if (!work_area.Intersects(*bounds)) {
- int y_offset = 0;
- if (work_area.bottom() < bounds->y()) {
- y_offset = work_area.bottom() - bounds->y() - min_height;
- } else if (bounds->bottom() < work_area.y()) {
- y_offset = work_area.y() - bounds->bottom() + min_height;
- }
-
- int x_offset = 0;
- if (work_area.right() < bounds->x()) {
- x_offset = work_area.right() - bounds->x() - min_width;
- } else if (bounds->right() < work_area.x()) {
- x_offset = work_area.x() - bounds->right() + min_width;
- }
- bounds->Offset(x_offset, y_offset);
+
+ min_width = std::min(min_width, work_area.width());
+ min_height = std::min(min_height, work_area.height());
+
+ if (bounds->x() + min_width > work_area.right()) {
+ bounds->set_x(work_area.right() - min_width);
+ } else if (bounds->right() - min_width < 0) {
+ bounds->set_x(min_width - bounds->width());
+ }
+ if (bounds->y() + min_height > work_area.bottom()) {
+ bounds->set_y(work_area.bottom() - min_height);
+ } else if (bounds->bottom() - min_height < 0) {
+ bounds->set_y(min_height - bounds->height());
}
}
diff --git a/ash/wm/workspace/workspace_event_handler_unittest.cc b/ash/wm/workspace/workspace_event_handler_unittest.cc
index f97038504d..e592ad5a94 100644
--- a/ash/wm/workspace/workspace_event_handler_unittest.cc
+++ b/ash/wm/workspace/workspace_event_handler_unittest.cc
@@ -248,20 +248,21 @@ TEST_F(WorkspaceEventHandlerTest,
TEST_F(WorkspaceEventHandlerTest, DoubleClickCaptionTogglesMaximize) {
aura::test::TestWindowDelegate wd;
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, gfx::Rect(1, 2, 3, 4)));
+ scoped_ptr<aura::Window> window(
+ CreateTestWindow(&wd, gfx::Rect(1, 2, 30, 40)));
window->SetProperty(aura::client::kCanMaximizeKey, true);
wd.set_window_component(HTCAPTION);
EXPECT_FALSE(wm::IsWindowMaximized(window.get()));
aura::RootWindow* root = Shell::GetPrimaryRootWindow();
aura::test::EventGenerator generator(root, window.get());
generator.DoubleClickLeftButton();
- EXPECT_NE("1,2 3x4", window->bounds().ToString());
+ EXPECT_NE("1,2 30x40", window->bounds().ToString());
EXPECT_TRUE(wm::IsWindowMaximized(window.get()));
generator.DoubleClickLeftButton();
EXPECT_FALSE(wm::IsWindowMaximized(window.get()));
- EXPECT_EQ("1,2 3x4", window->bounds().ToString());
+ EXPECT_EQ("1,2 30x40", window->bounds().ToString());
// Double-clicking the middle button shouldn't toggle the maximized state.
WindowPropertyObserver observer(window.get());
@@ -275,7 +276,7 @@ TEST_F(WorkspaceEventHandlerTest, DoubleClickCaptionTogglesMaximize) {
root->AsRootWindowHostDelegate()->OnHostMouseEvent(&release);
EXPECT_FALSE(wm::IsWindowMaximized(window.get()));
- EXPECT_EQ("1,2 3x4", window->bounds().ToString());
+ EXPECT_EQ("1,2 30x40", window->bounds().ToString());
EXPECT_FALSE(observer.DidPropertyChange(aura::client::kShowStateKey));
}
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 21aa08c604..2fd56af26c 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -32,9 +32,9 @@ namespace internal {
namespace {
-// This specifies how much percent (2/3=66%) of a window must be visible when
-// the window is added to the workspace.
-const float kMinimumPercentOnScreenArea = 0.66f;
+// This specifies how much percent 30% of a window rect (width / height)
+// must be visible when the window is added to the workspace.
+const float kMinimumPercentOnScreenArea = 0.3f;
bool IsMaximizedState(ui::WindowShowState state) {
return state == ui::SHOW_STATE_MAXIMIZED ||
@@ -59,8 +59,14 @@ void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) {
}
void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) {
- // Adjust window bounds in case that the new child is out of the workspace.
- AdjustWindowSizeForScreenChange(child, ADJUST_WINDOW_WINDOW_ADDED);
+ // Adjust window bounds in case that the new child is given the bounds that
+ // is out of the workspace. Exclude the case where bounds is empty
+ // (this happens when a views::Widget is created), or the window
+ // is added with the bounds because a user explicitly moved to
+ // this position (drag and drop for example).
+ if (!child->bounds().IsEmpty() &&
+ !wm::HasUserChangedWindowPositionOrSize(child))
+ AdjustWindowBoundsWhenAdded(child);
BaseLayoutManager::OnWindowAddedToLayout(child);
UpdateDesktopVisibility();
RearrangeVisibleWindowOnShow(child);
@@ -110,8 +116,10 @@ void WorkspaceLayoutManager::SetChildBounds(
void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
window_->parent()));
- if (work_area != work_area_)
- AdjustWindowSizesForScreenChange(ADJUST_WINDOW_DISPLAY_INSETS_CHANGED);
+ if (work_area != work_area_) {
+ AdjustAllWindowsBoundsForWorkAreaChange(
+ ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
+ }
}
void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
@@ -170,13 +178,13 @@ void WorkspaceLayoutManager::ShowStateChanged(
UpdateDesktopVisibility();
}
-void WorkspaceLayoutManager::AdjustWindowSizesForScreenChange(
+void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
AdjustWindowReason reason) {
work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent());
- BaseLayoutManager::AdjustWindowSizesForScreenChange(reason);
+ BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason);
}
-void WorkspaceLayoutManager::AdjustWindowSizeForScreenChange(
+void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange(
Window* window,
AdjustWindowReason reason) {
if (!GetTrackedByWorkspace(window))
@@ -190,7 +198,7 @@ void WorkspaceLayoutManager::AdjustWindowSizeForScreenChange(
// cross fade. I think this is better, but should reconsider if someone
// raises voice for this.
if (wm::IsWindowMaximized(window) &&
- reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) {
+ reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) {
CrossFadeToBounds(window, ScreenAsh::GetMaximizedWindowBoundsInParent(
window->parent()->parent()));
return;
@@ -200,22 +208,38 @@ void WorkspaceLayoutManager::AdjustWindowSizeForScreenChange(
return;
gfx::Rect bounds = window->bounds();
- if (reason == ADJUST_WINDOW_SCREEN_SIZE_CHANGED) {
- // The work area may be smaller than the full screen. Put as much of the
- // window as possible within the display area.
- bounds.AdjustToFit(work_area_);
- } else if (reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) {
- ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds);
- } else if (reason == ADJUST_WINDOW_WINDOW_ADDED) {
- int min_width = bounds.width() * kMinimumPercentOnScreenArea;
- int min_height = bounds.height() * kMinimumPercentOnScreenArea;
- ash::wm::AdjustBoundsToEnsureWindowVisibility(
- work_area_, min_width, min_height, &bounds);
+ switch (reason) {
+ case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
+ // The work area may be smaller than the full screen. Put as much of the
+ // window as possible within the display area.
+ bounds.AdjustToFit(work_area_);
+ break;
+ case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
+ ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds);
+ break;
}
if (window->bounds() != bounds)
window->SetBounds(bounds);
}
+void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
+ Window* window) {
+ if (!GetTrackedByWorkspace(window))
+ return;
+
+ if (SetMaximizedOrFullscreenBounds(window))
+ return;
+
+ gfx::Rect bounds = window->bounds();
+ int min_width = bounds.width() * kMinimumPercentOnScreenArea;
+ int min_height = bounds.height() * kMinimumPercentOnScreenArea;
+ ash::wm::AdjustBoundsToEnsureWindowVisibility(
+ work_area_, min_width, min_height, &bounds);
+
+ if (window->bounds() != bounds)
+ window->SetBounds(bounds);
+}
+
void WorkspaceLayoutManager::UpdateDesktopVisibility() {
if (shelf_)
shelf_->UpdateVisibilityState();
@@ -229,10 +253,27 @@ void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) {
case ui::SHOW_STATE_DEFAULT:
case ui::SHOW_STATE_NORMAL: {
const gfx::Rect* restore = GetRestoreBoundsInScreen(window);
+ // Make sure that the part of the window is always visible
+ // when restored.
+ gfx::Rect bounds_in_parent;
if (restore) {
- gfx::Rect bounds_in_parent =
+ bounds_in_parent =
ScreenAsh::ConvertRectFromScreen(window->parent()->parent(),
*restore);
+
+ ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
+ work_area_, &bounds_in_parent);
+ } else {
+ // Minimized windows have no restore bounds.
+ // Use the current bounds instead.
+ bounds_in_parent = window->bounds();
+ ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
+ work_area_, &bounds_in_parent);
+ // Don't start animation if the bounds didn't change.
+ if (bounds_in_parent == window->bounds())
+ bounds_in_parent.SetRect(0, 0, 0, 0);
+ }
+ if (!bounds_in_parent.IsEmpty()) {
CrossFadeToBounds(
window,
BaseLayoutManager::BoundsWithScreenEdgeVisible(
diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h
index a599d87f60..4476ddc99c 100644
--- a/ash/wm/workspace/workspace_layout_manager.h
+++ b/ash/wm/workspace/workspace_layout_manager.h
@@ -60,12 +60,14 @@ class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager {
// Overridden from BaseLayoutManager:
virtual void ShowStateChanged(aura::Window* window,
ui::WindowShowState last_show_state) OVERRIDE;
- virtual void AdjustWindowSizesForScreenChange(
+ virtual void AdjustAllWindowsBoundsForWorkAreaChange(
AdjustWindowReason reason) OVERRIDE;
- virtual void AdjustWindowSizeForScreenChange(
+ virtual void AdjustWindowBoundsForWorkAreaChange(
aura::Window* window,
AdjustWindowReason reason) OVERRIDE;
+ void AdjustWindowBoundsWhenAdded(aura::Window* window);
+
void UpdateDesktopVisibility();
// Updates the bounds of the window from a show state change.
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 30cdf6b098..3e3a1c7d65 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -62,6 +62,42 @@ TEST_F(WorkspaceLayoutManagerTest, RestoreFromMinimizeKeepsRestore) {
Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
}
+TEST_F(WorkspaceLayoutManagerTest, KeepRestoredWindowInDisplay) {
+ if (!SupportsHostWindowResize())
+ return;
+ scoped_ptr<aura::Window> window(
+ CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
+ // Maximized -> Normal transition.
+ wm::MaximizeWindow(window.get());
+ SetRestoreBoundsInScreen(window.get(), gfx::Rect(-100, -100, 30, 40));
+ wm::RestoreWindow(window.get());
+ EXPECT_TRUE(
+ Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
+ EXPECT_EQ("-20,-30 30x40", window->bounds().ToString());
+
+ // Minimized -> Normal transition.
+ window->SetBounds(gfx::Rect(-100, -100, 30, 40));
+ wm::MinimizeWindow(window.get());
+ EXPECT_FALSE(
+ Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
+ EXPECT_EQ("-100,-100 30x40", window->bounds().ToString());
+ window->Show();
+ EXPECT_TRUE(
+ Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
+ EXPECT_EQ("-20,-30 30x40", window->bounds().ToString());
+
+ // Fullscreen -> Normal transition.
+ window->SetBounds(gfx::Rect(0, 0, 30, 40)); // reset bounds.
+ ASSERT_EQ("0,0 30x40", window->bounds().ToString());
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
+ EXPECT_EQ(window->bounds(), window->GetRootWindow()->bounds());
+ SetRestoreBoundsInScreen(window.get(), gfx::Rect(-100, -100, 30, 40));
+ wm::RestoreWindow(window.get());
+ EXPECT_TRUE(
+ Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
+ EXPECT_EQ("-20,-30 30x40", window->bounds().ToString());
+}
+
// WindowObserver implementation used by DontClobberRestoreBoundsWindowObserver.
// This code mirrors what BrowserFrameAura does. In particular when this code
// sees the window was maximized it changes the bounds of a secondary
@@ -110,7 +146,7 @@ TEST_F(WorkspaceLayoutManagerTest, DontClobberRestoreBounds) {
window->AddObserver(&window_observer);
SetDefaultParentByPrimaryRootWindow(window.get());
window->Show();
- ash::wm::ActivateWindow(window.get());
+ wm::ActivateWindow(window.get());
scoped_ptr<aura::Window> window2(
CreateTestWindowInShellWithBounds(gfx::Rect(12, 20, 30, 40)));
@@ -128,12 +164,12 @@ TEST_F(WorkspaceLayoutManagerTest, ChildBoundsResetOnMaximize) {
scoped_ptr<aura::Window> window(
CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 30, 40)));
window->Show();
- ash::wm::ActivateWindow(window.get());
+ wm::ActivateWindow(window.get());
scoped_ptr<aura::Window> child_window(
aura::test::CreateTestWindowWithBounds(gfx::Rect(5, 6, 7, 8),
window.get()));
child_window->Show();
- ash::wm::MaximizeWindow(window.get());
+ wm::MaximizeWindow(window.get());
EXPECT_EQ("5,6 7x8", child_window->bounds().ToString());
}
@@ -146,7 +182,7 @@ TEST_F(WorkspaceLayoutManagerTest, WindowShouldBeOnScreenWhenAdded) {
// If the window is out of the workspace, it would be moved on screen.
gfx::Rect root_window_bounds =
- ash::Shell::GetInstance()->GetPrimaryRootWindow()->bounds();
+ Shell::GetInstance()->GetPrimaryRootWindow()->bounds();
window_bounds.Offset(root_window_bounds.width(), root_window_bounds.height());
ASSERT_FALSE(window_bounds.Intersects(root_window_bounds));
scoped_ptr<aura::Window> out_window(
@@ -154,9 +190,45 @@ TEST_F(WorkspaceLayoutManagerTest, WindowShouldBeOnScreenWhenAdded) {
EXPECT_EQ(window_bounds.size(), out_window->bounds().size());
gfx::Rect bounds = out_window->bounds();
bounds.Intersect(root_window_bounds);
- // 2/3 of the window must be visible.
- EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.6);
- EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.6);
+
+ // 30% of the window edge must be visible.
+ EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
+ EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
+
+ // Make sure we always make more than 1/3 of the window edge visible even
+ // if the initial bounds intersects with display.
+ window_bounds.SetRect(-150, -150, 200, 200);
+ bounds = window_bounds;
+ bounds.Intersect(root_window_bounds);
+
+ // Make sure that the initial bounds' visible area is less than 26%
+ // so that the auto adjustment logic kicks in.
+ ASSERT_LT(bounds.width(), out_window->bounds().width() * 0.26);
+ ASSERT_LT(bounds.height(), out_window->bounds().height() * 0.26);
+ ASSERT_TRUE(window_bounds.Intersects(root_window_bounds));
+
+ scoped_ptr<aura::Window> partially_out_window(
+ CreateTestWindowInShellWithBounds(window_bounds));
+ EXPECT_EQ(window_bounds.size(), partially_out_window->bounds().size());
+ bounds = partially_out_window->bounds();
+ bounds.Intersect(root_window_bounds);
+ EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
+ EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
+
+ // Make sure the window whose 30% width/height is bigger than display
+ // will be placed correctly.
+ window_bounds.SetRect(-1900, -1900, 3000, 3000);
+ scoped_ptr<aura::Window> window_bigger_than_display(
+ CreateTestWindowInShellWithBounds(window_bounds));
+ EXPECT_GE(root_window_bounds.width(),
+ window_bigger_than_display->bounds().width());
+ EXPECT_GE(root_window_bounds.height(),
+ window_bigger_than_display->bounds().height());
+
+ bounds = window_bigger_than_display->bounds();
+ bounds.Intersect(root_window_bounds);
+ EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
+ EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
}
// Verifies the size of a window is enforced to be smaller than the work area.