summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/accelerators/accelerator_controller.cc28
-rw-r--r--ash/accelerators/debug_commands.cc66
-rw-r--r--ash/accelerators/debug_commands.h22
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/desktop_background/desktop_background_controller.cc64
-rw-r--r--ash/desktop_background/desktop_background_controller.h13
-rw-r--r--ash/desktop_background/desktop_background_controller_unittest.cc82
-rw-r--r--ash/desktop_background/desktop_background_view.cc40
8 files changed, 245 insertions, 72 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index aa4786d..135e0f7 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -11,11 +11,10 @@
#include "ash/accelerators/accelerator_commands.h"
#include "ash/accelerators/accelerator_table.h"
+#include "ash/accelerators/debug_commands.h"
#include "ash/ash_switches.h"
#include "ash/caps_lock_delegate.h"
#include "ash/debug.h"
-#include "ash/desktop_background/desktop_background_controller.h"
-#include "ash/desktop_background/user_wallpaper_delegate.h"
#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
#include "ash/focus_cycler.h"
@@ -270,29 +269,6 @@ bool HandleRotateScreen() {
return true;
}
-bool HandleToggleDesktopBackgroundMode() {
- static int index = 0;
- static const SkColor kColorOptions[] = {
- SK_ColorBLACK, SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN
- };
- DesktopBackgroundController* desktop_background_controller =
- Shell::GetInstance()->desktop_background_controller();
- SkColor color = kColorOptions[++index % arraysize(kColorOptions)];
- if (color == SK_ColorBLACK) {
- ash::Shell::GetInstance()->user_wallpaper_delegate()->
- InitializeWallpaper();
- } else {
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0);
- bitmap.allocPixels();
- bitmap.eraseColor(color);
- desktop_background_controller->SetCustomWallpaper(
- gfx::ImageSkia::CreateFrom1xBitmap(bitmap), WALLPAPER_LAYOUT_STRETCH);
-
- }
- return true;
-}
-
bool HandleToggleRootWindowFullScreen() {
Shell::GetPrimaryRootWindow()->ToggleFullScreen();
return true;
@@ -882,7 +858,7 @@ bool AcceleratorController::PerformAction(int action,
case ROTATE_SCREEN:
return HandleRotateScreen();
case TOGGLE_DESKTOP_BACKGROUND_MODE:
- return HandleToggleDesktopBackgroundMode();
+ return debug::CycleDesktopBackgroundMode();
case TOGGLE_ROOT_WINDOW_FULL_SCREEN:
return HandleToggleRootWindowFullScreen();
case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
new file mode 100644
index 0000000..4ca1720
--- /dev/null
+++ b/ash/accelerators/debug_commands.cc
@@ -0,0 +1,66 @@
+// Copyright 2013 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/accelerators/accelerator_commands.h"
+
+#include "ash/desktop_background/desktop_background_controller.h"
+#include "ash/desktop_background/user_wallpaper_delegate.h"
+#include "ash/shell.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace ash {
+namespace debug {
+namespace {
+
+gfx::ImageSkia CreateWallpaperImage(SkColor fill, SkColor rect) {
+ // TODO(oshima): Consider adding a command line option to control
+ // wallpaper images for testing.
+ // The size is randomly picked.
+ gfx::Size image_size(1366, 768);
+ gfx::Canvas canvas(image_size, 1.0f, true);
+ canvas.DrawColor(fill);
+ SkPaint paint;
+ paint.setColor(rect);
+ paint.setStrokeWidth(10);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+ canvas.DrawRoundRect(gfx::Rect(image_size), 100, paint);
+ return gfx::ImageSkia(canvas.ExtractImageRep());
+}
+
+} // namespace
+
+bool CycleDesktopBackgroundMode() {
+ static int index = 0;
+ DesktopBackgroundController* desktop_background_controller =
+ Shell::GetInstance()->desktop_background_controller();
+ switch (++index % 4) {
+ case 0:
+ ash::Shell::GetInstance()->user_wallpaper_delegate()->
+ InitializeWallpaper();
+ break;
+ case 1:
+ desktop_background_controller->SetCustomWallpaper(
+ CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE),
+ WALLPAPER_LAYOUT_STRETCH);
+ break;
+ case 2:
+ desktop_background_controller->SetCustomWallpaper(
+ CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN),
+ WALLPAPER_LAYOUT_CENTER);
+ break;
+ case 3:
+ desktop_background_controller->SetCustomWallpaper(
+ CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED),
+ WALLPAPER_LAYOUT_CENTER_CROPPED);
+ break;
+ }
+ return true;
+}
+
+} // namespace debug
+} // namespace ash
diff --git a/ash/accelerators/debug_commands.h b/ash/accelerators/debug_commands.h
new file mode 100644
index 0000000..a064d4f
--- /dev/null
+++ b/ash/accelerators/debug_commands.h
@@ -0,0 +1,22 @@
+// Copyright 2013 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_ACCELERATORS_DEBUG_COMMANDS_H_
+#define ASH_ACCELERATORS_DEBUG_COMMANDS_H_
+
+#include "ash/ash_export.h"
+
+// This file contains implementations of commands that are used only
+// when running on desktop for debugging.
+namespace ash {
+namespace debug {
+
+// Cycle through different wallpaper modes. This is used when running
+// on desktop for testing.
+ASH_EXPORT bool CycleDesktopBackgroundMode();
+
+} // namespace debug
+} // namespace ash
+
+#endif // ASH_ACCELERATORS_DEBUG_COMMANDS_H_
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 6e89c95..3b0604f 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -57,6 +57,8 @@
'accelerators/accelerator_filter.h',
'accelerators/accelerator_table.cc',
'accelerators/accelerator_table.h',
+ 'accelerators/debug_commands.cc',
+ 'accelerators/debug_commands.h',
'accelerators/exit_warning_handler.cc',
'accelerators/exit_warning_handler.h',
'accelerators/focus_manager_factory.cc',
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc
index d91f383..b8fef38 100644
--- a/ash/desktop_background/desktop_background_controller.cc
+++ b/ash/desktop_background/desktop_background_controller.cc
@@ -10,6 +10,8 @@
#include "ash/desktop_background/desktop_background_widget_controller.h"
#include "ash/desktop_background/user_wallpaper_delegate.h"
#include "ash/desktop_background/wallpaper_resizer.h"
+#include "ash/display/display_info.h"
+#include "ash/display/display_manager.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/shell_factory.h"
@@ -45,22 +47,6 @@ internal::RootWindowLayoutManager* GetRootWindowLayoutManager(
root_window->layout_manager());
}
-// Returns the maximum width and height of all root windows.
-gfx::Size GetRootWindowsSize() {
- int width = 0;
- int height = 0;
- Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- for (Shell::RootWindowList::iterator iter = root_windows.begin();
- iter != root_windows.end(); ++iter) {
- gfx::Size root_window_size = (*iter)->GetHostSize();
- if (root_window_size.width() > width)
- width = root_window_size.width();
- if (root_window_size.height() > height)
- height = root_window_size.height();
- }
- return gfx::Size(width, height);
-}
-
} // namespace
const int kSmallWallpaperMaxWidth = 1366;
@@ -139,10 +125,10 @@ class DesktopBackgroundController::WallpaperLoader
if (file_bitmap_) {
gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(*file_bitmap_);
wallpaper_resizer_.reset(new WallpaperResizer(
- image, GetRootWindowsSize(), file_layout_));
+ image, GetMaxDisplaySizeInNative(), file_layout_));
} else {
wallpaper_resizer_.reset(new WallpaperResizer(
- resource_id_, GetRootWindowsSize(), resource_layout_));
+ resource_id_, GetMaxDisplaySizeInNative(), resource_layout_));
}
}
@@ -275,7 +261,7 @@ void DesktopBackgroundController::SetCustomWallpaper(
return;
current_wallpaper_.reset(new WallpaperResizer(
- image, GetRootWindowsSize(), layout));
+ image, GetMaxDisplaySizeInNative(), layout));
current_wallpaper_->StartResize();
current_default_wallpaper_path_ = base::FilePath();
@@ -302,19 +288,10 @@ void DesktopBackgroundController::CreateEmptyWallpaper() {
WallpaperResolution DesktopBackgroundController::GetAppropriateResolution() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- for (Shell::RootWindowList::iterator iter = root_windows.begin();
- iter != root_windows.end(); ++iter) {
- // Compare to host size as constants are defined in terms of
- // physical pixel size.
- // TODO(oshima): This may not be ideal for fractional scaling
- // scenario. Revisit and fix if necessary.
- gfx::Size host_window_size = (*iter)->GetHostSize();
- if (host_window_size.width() > kSmallWallpaperMaxWidth ||
- host_window_size.height() > kSmallWallpaperMaxHeight)
- return WALLPAPER_RESOLUTION_LARGE;
- }
- return WALLPAPER_RESOLUTION_SMALL;
+ gfx::Size size = GetMaxDisplaySizeInNative();
+ return (size.width() > kSmallWallpaperMaxWidth ||
+ size.height() > kSmallWallpaperMaxHeight) ?
+ WALLPAPER_RESOLUTION_LARGE : WALLPAPER_RESOLUTION_SMALL;
}
bool DesktopBackgroundController::MoveDesktopToLockedContainer() {
@@ -443,4 +420,27 @@ int DesktopBackgroundController::GetBackgroundContainerId(bool locked) {
internal::kShellWindowId_DesktopBackgroundContainer;
}
+// static
+gfx::Size DesktopBackgroundController::GetMaxDisplaySizeInNative() {
+ int width = 0;
+ int height = 0;
+ std::vector<gfx::Display> displays = Shell::GetScreen()->GetAllDisplays();
+ internal::DisplayManager* display_manager =
+ Shell::GetInstance()->display_manager();
+
+ for (std::vector<gfx::Display>::iterator iter = displays.begin();
+ iter != displays.end(); ++iter) {
+ // Don't use size_in_pixel because we want to use the native pixel size.
+ gfx::Size size_in_pixel =
+ display_manager->GetDisplayInfo(iter->id()).bounds_in_native().size();
+ if (iter->rotation() == gfx::Display::ROTATE_90 ||
+ iter->rotation() == gfx::Display::ROTATE_270) {
+ size_in_pixel = gfx::Size(size_in_pixel.height(), size_in_pixel.width());
+ }
+ width = std::max(size_in_pixel.width(), width);
+ height = std::max(size_in_pixel.height(), height);
+ }
+ return gfx::Size(width, height);
+}
+
} // namespace ash
diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h
index 24399c9..4955d20 100644
--- a/ash/desktop_background/desktop_background_controller.h
+++ b/ash/desktop_background/desktop_background_controller.h
@@ -8,6 +8,7 @@
#include "ash/ash_export.h"
#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -24,9 +25,6 @@ class RootWindow;
}
namespace ash {
-namespace internal {
-class DesktopBackgroundControllerTest;
-} // namespace internal
enum WallpaperLayout {
// Center the wallpaper on the desktop without scaling it. The wallpaper
@@ -131,7 +129,8 @@ class ASH_EXPORT DesktopBackgroundController {
bool MoveDesktopToUnlockedContainer();
private:
- friend class internal::DesktopBackgroundControllerTest;
+ friend class DesktopBackgroundControllerTest;
+ FRIEND_TEST_ALL_PREFIXES(DesktopBackgroundControllerTest, GetMaxDisplaySize);
// An operation to asynchronously loads wallpaper.
class WallpaperLoader;
@@ -171,6 +170,12 @@ class ASH_EXPORT DesktopBackgroundController {
// Send notification that background animation finished.
void NotifyAnimationFinished();
+ // Returns the maximum size of all displays combined in native
+ // resolutions. Note that this isn't the bounds of the display who
+ // has maximum resolutions. Instead, this returns the size of the
+ // maximum width of all displays, and the maximum height of all displays.
+ static gfx::Size GetMaxDisplaySizeInNative();
+
// If non-NULL, used in place of the real command line.
CommandLine* command_line_for_testing_;
diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc
index fa13434..c29c96d 100644
--- a/ash/desktop_background/desktop_background_controller_unittest.cc
+++ b/ash/desktop_background/desktop_background_controller_unittest.cc
@@ -34,8 +34,6 @@ using aura::RootWindow;
using aura::Window;
namespace ash {
-namespace internal {
-
namespace {
// Containers IDs used for tests.
@@ -109,7 +107,7 @@ class DesktopBackgroundControllerTest : public test::AshTestBase {
test::AshTestBase::SetUp();
// Ash shell initialization creates wallpaper. Reset it so we can manually
// control wallpaper creation and animation in our tests.
- RootWindowController* root_window_controller =
+ internal::RootWindowController* root_window_controller =
Shell::GetPrimaryRootWindowController();
root_window_controller->SetWallpaperController(NULL);
root_window_controller->SetAnimatingWallpaperController(NULL);
@@ -132,7 +130,7 @@ class DesktopBackgroundControllerTest : public test::AshTestBase {
// Runs kAnimatingDesktopController's animation to completion.
// TODO(bshe): Don't require tests to run animations; it's slow.
void RunDesktopControllerAnimation() {
- DesktopBackgroundWidgetController* controller =
+ internal::DesktopBackgroundWidgetController* controller =
Shell::GetPrimaryRootWindowController()->
animating_wallpaper_controller()->GetController(false);
ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget()));
@@ -300,7 +298,7 @@ TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
// The new wallpaper is ready to start animating. kAnimatingDesktopController
// holds the widget controller instance. kDesktopController will get it later.
- RootWindowController* root_window_controller =
+ internal::RootWindowController* root_window_controller =
Shell::GetPrimaryRootWindowController();
EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
GetController(false));
@@ -342,7 +340,7 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
// In this state we have two desktop background views stored in different
// properties. Both are in the lock screen background container.
- RootWindowController* root_window_controller =
+ internal::RootWindowController* root_window_controller =
Shell::GetPrimaryRootWindowController();
EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
GetController(false));
@@ -384,9 +382,9 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
// Change to a new wallpaper.
controller->CreateEmptyWallpaper();
- RootWindowController* root_window_controller =
+ internal::RootWindowController* root_window_controller =
Shell::GetPrimaryRootWindowController();
- DesktopBackgroundWidgetController* animating_controller =
+ internal::DesktopBackgroundWidgetController* animating_controller =
root_window_controller->animating_wallpaper_controller()->
GetController(false);
EXPECT_TRUE(animating_controller);
@@ -452,6 +450,17 @@ TEST_F(DesktopBackgroundControllerTest, GetAppropriateResolution) {
display_manager_test_api.UpdateDisplay("2560x1700");
EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
controller_->GetAppropriateResolution());
+
+ // Rotated smaller screen may use larger image.
+ display_manager_test_api.UpdateDisplay("800x600/r");
+ EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
+ controller_->GetAppropriateResolution());
+ display_manager_test_api.UpdateDisplay("800x600/r,800x600");
+ EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
+ controller_->GetAppropriateResolution());
+ display_manager_test_api.UpdateDisplay("1366x800/r");
+ EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
+ controller_->GetAppropriateResolution());
}
// Test that DesktopBackgroundController loads the appropriate wallpaper
@@ -494,6 +503,21 @@ TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaper) {
kLargeWallpaperColor));
}
+TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaperWhenRotated) {
+ if (!SupportsMultipleDisplays())
+ return;
+ WriteWallpapersAndSetFlags();
+ TestObserver observer(controller_);
+ test::DisplayManagerTestApi display_manager_test_api(
+ Shell::GetInstance()->display_manager());
+
+ display_manager_test_api.UpdateDisplay("1200x800/r");
+ ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
+ observer.WaitForWallpaperDataChanged();
+ EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
+ kLargeWallpaperColor));
+}
+
TEST_F(DesktopBackgroundControllerTest, SmallGuestWallpaper) {
if (!SupportsMultipleDisplays())
return;
@@ -524,5 +548,45 @@ TEST_F(DesktopBackgroundControllerTest, LargeGuestWallpaper) {
kLargeGuestWallpaperColor));
}
-} // namespace internal
+TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) {
+ // Device scale factor shouldn't affect the native size.
+ UpdateDisplay("1000x300*2");
+ EXPECT_EQ(
+ "1000x300",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+
+ // Rotated display should return the rotated size.
+ UpdateDisplay("1000x300*2/r");
+ EXPECT_EQ(
+ "300x1000",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+
+ // UI Scaling shouldn't affect the native size.
+ UpdateDisplay("1000x300*2@1.5");
+ EXPECT_EQ(
+ "1000x300",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // First display has maximum size.
+ UpdateDisplay("400x300,100x100");
+ EXPECT_EQ(
+ "400x300",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+
+ // Second display has maximum size.
+ UpdateDisplay("400x300,500x600");
+ EXPECT_EQ(
+ "500x600",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+
+ // Maximum width and height belongs to different displays.
+ UpdateDisplay("400x300,100x500");
+ EXPECT_EQ(
+ "400x500",
+ DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
+}
+
} // namespace ash
diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc
index b46109f..db1b27d 100644
--- a/ash/desktop_background/desktop_background_view.cc
+++ b/ash/desktop_background/desktop_background_view.cc
@@ -23,6 +23,8 @@
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
+#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/transform.h"
#include "ui/views/widget/widget.h"
namespace ash {
@@ -34,6 +36,41 @@ int RoundPositive(double x) {
return static_cast<int>(floor(x + 0.5));
}
+// A view that controls the child view's layer so that the layer
+// always has the same size as the display's original, un-scaled size
+// in DIP. The layer then transformed to fit to the virtual screen
+// size when laid-out.
+// This is to avoid scaling the image at painting time, then scaling
+// it back to the screen size in the compositor.
+class LayerControlView : public views::View {
+ public:
+ explicit LayerControlView(views::View* view) {
+ AddChildView(view);
+ view->SetPaintToLayer(true);
+ }
+
+ // Overrides views::View.
+ virtual void Layout() OVERRIDE {
+ gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow(
+ GetWidget()->GetNativeView());
+ DisplayManager* display_manager = Shell::GetInstance()->display_manager();
+ DisplayInfo info = display_manager->GetDisplayInfo(display.id());
+
+ gfx::SizeF pixel_size = display.size();
+ pixel_size.Scale(1.0f / info.ui_scale());
+ gfx::Size rounded_size = gfx::ToCeiledSize(pixel_size);
+ DCHECK_EQ(1, child_count());
+ views::View* child = child_at(0);
+ child->SetBounds(0, 0, rounded_size.width(), rounded_size.height());
+ gfx::Transform transform;
+ transform.Scale(info.ui_scale(), info.ui_scale());
+ child->SetTransform(transform);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerControlView);
+};
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -151,7 +188,8 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window,
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.parent = root_window->GetChildById(container_id);
desktop_widget->Init(params);
- desktop_widget->SetContentsView(new DesktopBackgroundView());
+ desktop_widget->SetContentsView(
+ new LayerControlView(new DesktopBackgroundView()));
int animation_type = wallpaper_delegate->GetAnimationType();
views::corewm::SetWindowVisibilityAnimationType(
desktop_widget->GetNativeView(), animation_type);