Skip to content

Commit

Permalink
2nd display should show the same background as login/lock screen:
Browse files Browse the repository at this point in the history
Added special container for background on lock screen.
Background view can now be created in specific container.
Disabled lock screen wallpaper implementation based on serving PNG image via data source.

BUG=136853,137581
TEST=Lock screen on multimonitor configuration. Check that windows on secondary display are hidden with background.

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=149869

Review URL: https://chromiumcodereview.appspot.com/10810039

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150271 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
antrim@chromium.org committed Aug 7, 2012
1 parent 140860c commit b4ddc7a
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 124 deletions.
2 changes: 2 additions & 0 deletions ash/ash.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
'desktop_background/desktop_background_resources.h',
'desktop_background/desktop_background_view.cc',
'desktop_background/desktop_background_view.h',
'desktop_background/desktop_background_widget_controller.cc',
'desktop_background/desktop_background_widget_controller.h',
'display/display_controller.cc',
'display/display_controller.h',
'display/mouse_cursor_event_filter.cc',
Expand Down
197 changes: 140 additions & 57 deletions ash/desktop_background/desktop_background_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ash/desktop_background/desktop_background_controller.h"

#include "ash/desktop_background/desktop_background_view.h"
#include "ash/desktop_background/desktop_background_widget_controller.h"
#include "ash/shell.h"
#include "ash/shell_factory.h"
#include "ash/shell_window_ids.h"
Expand All @@ -18,6 +19,7 @@
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/image/image.h"
#include "ui/views/widget/widget.h"

Expand Down Expand Up @@ -99,9 +101,11 @@ class DesktopBackgroundController::WallpaperOperation
};

DesktopBackgroundController::DesktopBackgroundController()
: desktop_background_mode_(BACKGROUND_IMAGE),
: locked_(false),
desktop_background_mode_(BACKGROUND_SOLID_COLOR),
background_color_(SK_ColorGRAY),
weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
InstallComponentForAllWindows();
}

DesktopBackgroundController::~DesktopBackgroundController() {
Expand All @@ -128,38 +132,32 @@ SkBitmap DesktopBackgroundController::GetCurrentWallpaperImage() {

void DesktopBackgroundController::OnRootWindowAdded(
aura::RootWindow* root_window) {
switch (desktop_background_mode_) {
case BACKGROUND_IMAGE:
if (current_wallpaper_.get()) {
gfx::Size root_window_size = root_window->GetHostSize();
int wallpaper_width = current_wallpaper_->wallpaper_image.width();
int wallpaper_height = current_wallpaper_->wallpaper_image.height();
// Loads a higher resolution wallpaper if needed.
if ((wallpaper_width < root_window_size.width() ||
wallpaper_height < root_window_size.height()) &&
current_wallpaper_->wallpaper_index != -1 &&
current_wallpaper_->wallpaper_layout != TILE)
SetDefaultWallpaper(current_wallpaper_->wallpaper_index, true);
else
SetDesktopBackgroundImage(root_window);
} else {
internal::CreateDesktopBackground(root_window);
}
break;
case BACKGROUND_SOLID_COLOR:
SetDesktopBackgroundSolidColorMode(background_color_);
break;
// Handle resolution change for "built-in" images."
if (BACKGROUND_IMAGE == desktop_background_mode_) {
if (current_wallpaper_.get()) {
gfx::Size root_window_size = root_window->GetHostSize();
int wallpaper_width = current_wallpaper_->wallpaper_image.width();
int wallpaper_height = current_wallpaper_->wallpaper_image.height();
// Loads a higher resolution wallpaper if needed.
if ((wallpaper_width < root_window_size.width() ||
wallpaper_height < root_window_size.height()) &&
current_wallpaper_->wallpaper_index != -1 &&
current_wallpaper_->wallpaper_layout != TILE)
SetDefaultWallpaper(current_wallpaper_->wallpaper_index, true);
}
}

InstallComponent(root_window);
}

void DesktopBackgroundController::SetDefaultWallpaper(int index,
bool force_reload) {
// We should not change background when index is invalid. For instance, at
// login screen or stub_user login.
if (index == ash::GetInvalidWallpaperIndex()) {
if (index == GetInvalidWallpaperIndex()) {
CreateEmptyWallpaper();
return;
} else if (index == ash::GetSolidColorIndex()) {
} else if (index == GetSolidColorIndex()) {
SetDesktopBackgroundSolidColorMode(kLoginWallpaperColor);
return;
}
Expand Down Expand Up @@ -195,8 +193,7 @@ void DesktopBackgroundController::SetCustomWallpaper(
WallpaperLayout layout) {
CancelPendingWallpaperOperation();
current_wallpaper_.reset(new WallpaperData(layout, wallpaper));
desktop_background_mode_ = BACKGROUND_IMAGE;
UpdateDesktopBackgroundImageMode();
SetDesktopBackgroundImageMode();
}

void DesktopBackgroundController::CancelPendingWallpaperOperation() {
Expand All @@ -210,65 +207,151 @@ void DesktopBackgroundController::CancelPendingWallpaperOperation() {

void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode(
SkColor color) {
// Set a solid black background.
// TODO(derat): Remove this in favor of having the compositor only clear the
// viewport when there are regions not covered by a layer:
// http://crbug.com/113445
current_wallpaper_.reset(NULL);
background_color_ = color;
desktop_background_mode_ = BACKGROUND_SOLID_COLOR;
if (desktop_background_mode_ != BACKGROUND_SOLID_COLOR) {
desktop_background_mode_ = BACKGROUND_SOLID_COLOR;
InstallComponentForAllWindows();
return;
}

Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (Shell::RootWindowList::iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
background_layer->SetColor(color);
aura::RootWindow* root_window = *iter;
Shell::GetContainer(
root_window,
internal::kShellWindowId_DesktopBackgroundContainer)->
layer()->Add(background_layer);
GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(
background_layer);
GetRootWindowLayoutManager(root_window)->SetBackgroundWidget(NULL);
internal::DesktopBackgroundWidgetController* component = root_window->
GetProperty(internal::kWindowDesktopComponent);
DCHECK(component);
DCHECK(component->layer());
component->layer()->SetColor(background_color_ );
}
}

void DesktopBackgroundController::SetDesktopBackgroundImage(
aura::RootWindow* root_window) {
GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL);
if (current_wallpaper_.get() &&
!current_wallpaper_->wallpaper_image.empty())
internal::CreateDesktopBackground(root_window);
void DesktopBackgroundController::CreateEmptyWallpaper() {
current_wallpaper_.reset(NULL);
SetDesktopBackgroundImageMode();
}

void DesktopBackgroundController::UpdateDesktopBackgroundImageMode() {
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
void DesktopBackgroundController::MoveDesktopToLockedContainer() {
if (locked_)
return;
locked_ = true;
ReparentBackgroundWidgets(GetBackgroundContainerId(false),
GetBackgroundContainerId(true));
}

void DesktopBackgroundController::MoveDesktopToUnlockedContainer() {
if (!locked_)
return;
locked_ = false;
ReparentBackgroundWidgets(GetBackgroundContainerId(true),
GetBackgroundContainerId(false));
}

void DesktopBackgroundController::OnWindowDestroying(aura::Window* window) {
window->SetProperty(internal::kWindowDesktopComponent,
static_cast<internal::DesktopBackgroundWidgetController*>(NULL));
}

void DesktopBackgroundController::SetDesktopBackgroundImageMode() {
if (desktop_background_mode_ != BACKGROUND_IMAGE) {
desktop_background_mode_ = BACKGROUND_IMAGE;
InstallComponentForAllWindows();
return;
}

Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (Shell::RootWindowList::iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
SetDesktopBackgroundImage(*iter);
iter != root_windows.end(); ++iter) {
aura::RootWindow* root_window = *iter;
internal::DesktopBackgroundWidgetController* component = root_window->
GetProperty(internal::kWindowDesktopComponent);
DCHECK(component);
DCHECK(component->widget());
aura::Window* window = component->widget()->GetNativeView();
gfx::Rect bounds = window->bounds();
window->SchedulePaintInRect(gfx::Rect(0, 0,
bounds.width(), bounds.height()));
}
desktop_background_mode_ = BACKGROUND_IMAGE;
}

void DesktopBackgroundController::OnWallpaperLoadCompleted(
scoped_refptr<WallpaperOperation> wo) {
current_wallpaper_.reset(wo->ReleaseWallpaperData());

UpdateDesktopBackgroundImageMode();
SetDesktopBackgroundImageMode();

DCHECK(wo.get() == wallpaper_op_.get());
wallpaper_op_ = NULL;
}

void DesktopBackgroundController::CreateEmptyWallpaper() {
current_wallpaper_.reset(NULL);
desktop_background_mode_ = BACKGROUND_IMAGE;
ui::Layer* DesktopBackgroundController::SetColorLayerForContainer(
SkColor color,
aura::RootWindow* root_window,
int container_id) {
ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
background_layer->SetColor(color);

Shell::GetContainer(root_window,container_id)->
layer()->Add(background_layer);
return background_layer;
}

void DesktopBackgroundController::InstallComponent(
aura::RootWindow* root_window) {
internal::DesktopBackgroundWidgetController* component = NULL;
int container_id = GetBackgroundContainerId(locked_);

switch (desktop_background_mode_) {
case BACKGROUND_IMAGE: {
views::Widget* widget = internal::CreateDesktopBackground(root_window,
container_id);
component = new internal::DesktopBackgroundWidgetController(widget);
break;
}
case BACKGROUND_SOLID_COLOR: {
ui::Layer* layer = SetColorLayerForContainer(background_color_,
root_window,
container_id);
component = new internal::DesktopBackgroundWidgetController(layer);
break;
}
default: {
NOTREACHED();
}
}
if (NULL == root_window->GetProperty(internal::kWindowDesktopComponent)) {
// First time for this root window
root_window->AddObserver(this);
}
root_window->SetProperty(internal::kWindowDesktopComponent, component);
}

void DesktopBackgroundController::InstallComponentForAllWindows() {
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (Shell::RootWindowList::iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
internal::CreateDesktopBackground(*iter);
InstallComponent(*iter);
}
}

void DesktopBackgroundController::ReparentBackgroundWidgets(int src_container,
int dst_container) {
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (Shell::RootWindowList::iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
aura::RootWindow* root_window = *iter;
internal::DesktopBackgroundWidgetController* component = root_window->
GetProperty(internal::kWindowDesktopComponent);
DCHECK(component);
component->Reparent(root_window,
src_container,
dst_container);
}
}

int DesktopBackgroundController::GetBackgroundContainerId(bool locked) {
return locked ? internal::kShellWindowId_LockScreenBackgroundContainer :
internal::kShellWindowId_DesktopBackgroundContainer;
}

} // namespace ash
46 changes: 38 additions & 8 deletions ash/desktop_background/desktop_background_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "base/memory/weak_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/image/image_skia.h"

namespace aura {
Expand Down Expand Up @@ -47,7 +50,7 @@ class UserWallpaperDelegate {

// Loads selected desktop wallpaper from file system asynchronously and updates
// background layer if loaded successfully.
class ASH_EXPORT DesktopBackgroundController {
class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver {
public:
enum BackgroundMode {
BACKGROUND_IMAGE,
Expand Down Expand Up @@ -99,25 +102,52 @@ class ASH_EXPORT DesktopBackgroundController {
// is SystemGestureEventFilterTest.ThreeFingerSwipe.
void CreateEmptyWallpaper();

// Move all desktop widgets to locked container.
void MoveDesktopToLockedContainer();

// Move all desktop widgets to unlocked container.
void MoveDesktopToUnlockedContainer();

// WindowObserver implementation.
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;

private:
// An operation to asynchronously loads wallpaper.
class WallpaperOperation;

struct WallpaperData;

// Creates a new background widget using the current wallpapaer image and
// use it as a background of the |root_window|. Deletes the old widget if any.
void SetDesktopBackgroundImage(aura::RootWindow* root_window);

// Update the background of all root windows using the current wallpaper image
// in |current_wallpaper_|.
void UpdateDesktopBackgroundImageMode();
// Creates view for all root windows, or notifies them to repaint if they
// already exist.
void SetDesktopBackgroundImageMode();

// Creates a new background widget and sets the background mode to image mode.
// Called after wallpaper loaded successfully.
void OnWallpaperLoadCompleted(scoped_refptr<WallpaperOperation> wo);

// Adds layer with solid |color| to container |container_id| in |root_window|.
ui::Layer* SetColorLayerForContainer(SkColor color,
aura::RootWindow* root_window,
int container_id);

// Creates and adds component for current mode (either Widget or Layer) to
// |root_window|.
void InstallComponent(aura::RootWindow* root_window);

// Creates and adds component for current mode (either Widget or Layer) to
// all root windows.
void InstallComponentForAllWindows();

// Moves all descktop components from one container to other across all root
// windows.
void ReparentBackgroundWidgets(int src_container, int dst_container);

// Returns id for background container for unlocked and locked states.
int GetBackgroundContainerId(bool locked);

// Can change at runtime.
bool locked_;

BackgroundMode desktop_background_mode_;

SkColor background_color_;
Expand Down
Loading

0 comments on commit b4ddc7a

Please sign in to comment.