diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/ash/display | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/ash/display')
45 files changed, 0 insertions, 10652 deletions
diff --git a/chromium/ash/display/OWNERS b/chromium/ash/display/OWNERS deleted file mode 100644 index 92f3fbb9210..00000000000 --- a/chromium/ash/display/OWNERS +++ /dev/null @@ -1 +0,0 @@ -oshima@chromium.org diff --git a/chromium/ash/display/display_change_observer_chromeos.cc b/chromium/ash/display/display_change_observer_chromeos.cc deleted file mode 100644 index 4215ac89dba..00000000000 --- a/chromium/ash/display/display_change_observer_chromeos.cc +++ /dev/null @@ -1,189 +0,0 @@ -// 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/display/display_change_observer_chromeos.h" - -#include <algorithm> -#include <map> -#include <set> -#include <vector> - -#include "ash/ash_switches.h" -#include "ash/display/display_info.h" -#include "ash/display/display_layout_store.h" -#include "ash/display/display_manager.h" -#include "ash/shell.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "chromeos/display/output_util.h" -#include "grit/ash_strings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/x/x11_util.h" -#include "ui/compositor/dip_util.h" -#include "ui/gfx/display.h" - -namespace ash { -namespace internal { - -using chromeos::OutputConfigurator; - -namespace { - -// The DPI threshold to detect high density screen. -// Higher DPI than this will use device_scale_factor=2. -const unsigned int kHighDensityDPIThreshold = 160; - -// 1 inch in mm. -const float kInchInMm = 25.4f; - -// Resolution list are sorted by the area in pixels and the larger -// one comes first. -struct ResolutionSorter { - bool operator()(const Resolution& a, const Resolution& b) { - return a.size.width() * a.size.height() > b.size.width() * b.size.height(); - } -}; - -} // namespace - -// static -std::vector<Resolution> DisplayChangeObserver::GetResolutionList( - const OutputConfigurator::OutputSnapshot& output) { - typedef std::map<std::pair<int,int>, Resolution> ResolutionMap; - ResolutionMap resolution_map; - - for (std::map<RRMode, OutputConfigurator::ModeInfo>::const_iterator it = - output.mode_infos.begin(); it != output.mode_infos.end(); ++it) { - const OutputConfigurator::ModeInfo& mode_info = it->second; - const std::pair<int, int> size(mode_info.width, mode_info.height); - const Resolution resolution(gfx::Size(mode_info.width, mode_info.height), - mode_info.interlaced); - - // Add the resolution if it isn't already present and override interlaced - // resolutions with non-interlaced ones. - ResolutionMap::iterator resolution_it = resolution_map.find(size); - if (resolution_it == resolution_map.end()) - resolution_map.insert(std::make_pair(size, resolution)); - else if (resolution_it->second.interlaced && !resolution.interlaced) - resolution_it->second = resolution; - } - - std::vector<Resolution> resolution_list; - for (ResolutionMap::const_iterator iter = resolution_map.begin(); - iter != resolution_map.end(); - ++iter) { - resolution_list.push_back(iter->second); - } - std::sort(resolution_list.begin(), resolution_list.end(), ResolutionSorter()); - return resolution_list; -} - -DisplayChangeObserver::DisplayChangeObserver() { - Shell::GetInstance()->AddShellObserver(this); -} - -DisplayChangeObserver::~DisplayChangeObserver() { - Shell::GetInstance()->RemoveShellObserver(this); -} - -chromeos::OutputState DisplayChangeObserver::GetStateForDisplayIds( - const std::vector<int64>& display_ids) const { - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshForceMirrorMode)) { - return chromeos::STATE_DUAL_MIRROR; - } - - CHECK_EQ(2U, display_ids.size()); - DisplayIdPair pair = std::make_pair(display_ids[0], display_ids[1]); - DisplayLayout layout = Shell::GetInstance()->display_manager()-> - layout_store()->GetRegisteredDisplayLayout(pair); - return layout.mirrored ? - chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED; -} - -bool DisplayChangeObserver::GetResolutionForDisplayId(int64 display_id, - int* width, - int* height) const { - gfx::Size resolution; - if (!Shell::GetInstance()->display_manager()-> - GetSelectedResolutionForDisplayId(display_id, &resolution)) { - return false; - } - - *width = resolution.width(); - *height = resolution.height(); - return true; -} - -void DisplayChangeObserver::OnDisplayModeChanged( - const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { - std::vector<DisplayInfo> displays; - std::set<int64> ids; - for (size_t i = 0; i < outputs.size(); ++i) { - const OutputConfigurator::OutputSnapshot& output = outputs[i]; - - if (output.is_internal && - gfx::Display::InternalDisplayId() == gfx::Display::kInvalidDisplayID) { - // Fall back to output index. crbug.com/180100 - gfx::Display::SetInternalDisplayId( - output.display_id == gfx::Display::kInvalidDisplayID ? output.index : - output.display_id); - } - - const OutputConfigurator::ModeInfo* mode_info = - OutputConfigurator::GetModeInfo(output, output.current_mode); - if (!mode_info) - continue; - - float device_scale_factor = 1.0f; - if (!ui::IsXDisplaySizeBlackListed(output.width_mm, output.height_mm) && - (kInchInMm * mode_info->width / output.width_mm) > - kHighDensityDPIThreshold) { - device_scale_factor = 2.0f; - } - gfx::Rect display_bounds( - output.x, output.y, mode_info->width, mode_info->height); - - std::vector<Resolution> resolutions; - if (!output.is_internal) - resolutions = GetResolutionList(output); - - std::string name = output.is_internal ? - l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) : - chromeos::GetDisplayName(output.output); - if (name.empty()) - name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); - - bool has_overscan = false; - chromeos::GetOutputOverscanFlag(output.output, &has_overscan); - - int64 id = output.display_id; - if (id == gfx::Display::kInvalidDisplayID || ids.find(id) != ids.end()) - id = output.index; - ids.insert(id); - - displays.push_back(DisplayInfo(id, name, has_overscan)); - displays.back().set_device_scale_factor(device_scale_factor); - displays.back().SetBounds(display_bounds); - displays.back().set_native(true); - displays.back().set_resolutions(resolutions); - displays.back().set_touch_support( - output.touch_device_id == 0 ? gfx::Display::TOUCH_SUPPORT_UNAVAILABLE : - gfx::Display::TOUCH_SUPPORT_AVAILABLE); - } - - // DisplayManager can be null during the boot. - Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays); -} - -void DisplayChangeObserver::OnAppTerminating() { -#if defined(USE_ASH) - // Stop handling display configuration events once the shutdown - // process starts. crbug.com/177014. - Shell::GetInstance()->output_configurator()->Stop(); -#endif -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_change_observer_chromeos.h b/chromium/ash/display/display_change_observer_chromeos.h deleted file mode 100644 index c75c00be4da..00000000000 --- a/chromium/ash/display/display_change_observer_chromeos.h +++ /dev/null @@ -1,54 +0,0 @@ -// 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_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H -#define ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H - -#include "ash/ash_export.h" -#include "ash/shell_observer.h" -#include "base/basictypes.h" -#include "chromeos/display/output_configurator.h" - -namespace ash { -namespace internal { - -struct Resolution; - -// An object that observes changes in display configuration and -// update DisplayManagers. -class DisplayChangeObserver - : public chromeos::OutputConfigurator::StateController, - public chromeos::OutputConfigurator::Observer, - public ShellObserver { - public: - // Returns the resolution list. - ASH_EXPORT static std::vector<Resolution> GetResolutionList( - const chromeos::OutputConfigurator::OutputSnapshot& output); - - DisplayChangeObserver(); - virtual ~DisplayChangeObserver(); - - // chromeos::OutputConfigurator::StateController overrides: - virtual chromeos::OutputState GetStateForDisplayIds( - const std::vector<int64>& outputs) const OVERRIDE; - virtual bool GetResolutionForDisplayId(int64 display_id, - int* width, - int* height) const OVERRIDE; - - // Overriden from chromeos::OutputConfigurator::Observer: - virtual void OnDisplayModeChanged( - const std::vector<chromeos::OutputConfigurator::OutputSnapshot>& outputs) - OVERRIDE; - - // Overriden from ShellObserver: - virtual void OnAppTerminating() OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(DisplayChangeObserver); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_AURA_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H diff --git a/chromium/ash/display/display_change_observer_chromeos_unittest.cc b/chromium/ash/display/display_change_observer_chromeos_unittest.cc deleted file mode 100644 index 1f64be74adb..00000000000 --- a/chromium/ash/display/display_change_observer_chromeos_unittest.cc +++ /dev/null @@ -1,71 +0,0 @@ -// 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/display/display_change_observer_chromeos.h" - -#include "ash/display/display_info.h" -#include "chromeos/display/output_configurator.h" -#include "testing/gtest/include/gtest/gtest.h" - -using chromeos::OutputConfigurator; - -typedef testing::Test DisplayChangeObserverTest; - -namespace ash { -namespace internal { - -TEST_F(DisplayChangeObserverTest, GetResolutionList) { - OutputConfigurator::OutputSnapshot output; - output.mode_infos[11] = OutputConfigurator::ModeInfo(1920, 1200, false, 60); - - // All non-interlaced (as would be seen with different refresh rates). - output.mode_infos[12] = OutputConfigurator::ModeInfo(1920, 1080, false, 80); - output.mode_infos[13] = OutputConfigurator::ModeInfo(1920, 1080, false, 70); - output.mode_infos[14] = OutputConfigurator::ModeInfo(1920, 1080, false, 60); - - // Interlaced vs non-interlaced. - output.mode_infos[15] = OutputConfigurator::ModeInfo(1280, 720, true, 60); - output.mode_infos[16] = OutputConfigurator::ModeInfo(1280, 720, false, 60); - - // Interlaced only. - output.mode_infos[17] = OutputConfigurator::ModeInfo(1024, 768, true, 70); - output.mode_infos[18] = OutputConfigurator::ModeInfo(1024, 768, true, 60); - - // Mixed. - output.mode_infos[19] = OutputConfigurator::ModeInfo(1024, 600, true, 60); - output.mode_infos[20] = OutputConfigurator::ModeInfo(1024, 600, false, 70); - output.mode_infos[21] = OutputConfigurator::ModeInfo(1024, 600, false, 60); - - // Just one interlaced mode. - output.mode_infos[22] = OutputConfigurator::ModeInfo(640, 480, true, 60); - - std::vector<Resolution> resolutions = - DisplayChangeObserver::GetResolutionList(output); - ASSERT_EQ(6u, resolutions.size()); - EXPECT_EQ("1920x1200", resolutions[0].size.ToString()); - EXPECT_FALSE(resolutions[0].interlaced); - - EXPECT_EQ("1920x1080", resolutions[1].size.ToString()); - EXPECT_FALSE(resolutions[1].interlaced); - - EXPECT_EQ("1280x720", resolutions[2].size.ToString()); - EXPECT_FALSE(resolutions[2].interlaced); - - EXPECT_EQ("1024x768", resolutions[3].size.ToString()); - EXPECT_TRUE(resolutions[3].interlaced); - - EXPECT_EQ("1024x600", resolutions[4].size.ToString()); - EXPECT_FALSE(resolutions[4].interlaced); - - EXPECT_EQ("640x480", resolutions[5].size.ToString()); - EXPECT_TRUE(resolutions[5].interlaced); - - // Outputs without any modes shouldn't cause a crash. - output.mode_infos.clear(); - resolutions = DisplayChangeObserver::GetResolutionList(output); - EXPECT_EQ(0u, resolutions.size()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_controller.cc b/chromium/ash/display/display_controller.cc deleted file mode 100644 index ee5d25a7348..00000000000 --- a/chromium/ash/display/display_controller.cc +++ /dev/null @@ -1,809 +0,0 @@ -// Copyright (c) 2012 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/display/display_controller.h" - -#include <algorithm> -#include <cmath> -#include <map> - -#include "ash/ash_switches.h" -#include "ash/display/display_layout_store.h" -#include "ash/display/display_manager.h" -#include "ash/display/mirror_window_controller.h" -#include "ash/display/root_window_transformers.h" -#include "ash/display/virtual_keyboard_window_controller.h" -#include "ash/host/root_window_host_factory.h" -#include "ash/root_window_controller.h" -#include "ash/root_window_settings.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/wm/coordinate_conversion.h" -#include "base/command_line.h" -#include "base/strings/stringprintf.h" -#include "third_party/skia/include/utils/SkMatrix44.h" -#include "ui/aura/client/activation_client.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/client/cursor_client.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/client/screen_position_client.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_transformer.h" -#include "ui/aura/window.h" -#include "ui/aura/window_property.h" -#include "ui/aura/window_tracker.h" -#include "ui/compositor/compositor.h" -#include "ui/compositor/dip_util.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" - -#if defined(OS_CHROMEOS) -#include "base/sys_info.h" -#include "base/time/time.h" -#if defined(USE_X11) -#include "ash/display/output_configurator_animation.h" -#include "chromeos/display/output_configurator.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/x/x11_types.h" - -// Including this at the bottom to avoid other -// potential conflict with chrome headers. -#include <X11/extensions/Xrandr.h> -#undef RootWindow -#endif // defined(USE_X11) -#endif // defined(OS_CHROMEOS) - -namespace ash { -namespace { - -// Primary display stored in global object as it can be -// accessed after Shell is deleted. A separate display instance is created -// during the shutdown instead of always keeping two display instances -// (one here and another one in display_manager) in sync, which is error prone. -int64 primary_display_id = gfx::Display::kInvalidDisplayID; -gfx::Display* primary_display_for_shutdown = NULL; -// Keeps the number of displays during the shutdown after -// ash::Shell:: is deleted. -int num_displays_for_shutdown = -1; - -// Specifies how long the display change should have been disabled -// after each display change operations. -// |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid -// changing the settings while the system is still configurating -// displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs| -// when the display change happens, so the actual timeout is much shorter. -const int64 kAfterDisplayChangeThrottleTimeoutMs = 500; -const int64 kCycleDisplayThrottleTimeoutMs = 4000; -const int64 kSwapDisplayThrottleTimeoutMs = 500; - -internal::DisplayManager* GetDisplayManager() { - return Shell::GetInstance()->display_manager(); -} - -void SetDisplayPropertiesOnHostWindow(aura::RootWindow* root, - const gfx::Display& display) { - internal::DisplayInfo info = - GetDisplayManager()->GetDisplayInfo(display.id()); -#if defined(OS_CHROMEOS) && defined(USE_X11) - // Native window property (Atom in X11) that specifies the display's - // rotation, scale factor and if it's internal display. They are - // read and used by touchpad/mouse driver directly on X (contact - // adlr@ for more details on touchpad/mouse driver side). The value - // of the rotation is one of 0 (normal), 1 (90 degrees clockwise), 2 - // (180 degree) or 3 (270 degrees clockwise). The value of the - // scale factor is in percent (100, 140, 200 etc). - const char kRotationProp[] = "_CHROME_DISPLAY_ROTATION"; - const char kScaleFactorProp[] = "_CHROME_DISPLAY_SCALE_FACTOR"; - const char kInternalProp[] = "_CHROME_DISPLAY_INTERNAL"; - const char kCARDINAL[] = "CARDINAL"; - int xrandr_rotation = RR_Rotate_0; - switch (info.rotation()) { - case gfx::Display::ROTATE_0: - xrandr_rotation = RR_Rotate_0; - break; - case gfx::Display::ROTATE_90: - xrandr_rotation = RR_Rotate_90; - break; - case gfx::Display::ROTATE_180: - xrandr_rotation = RR_Rotate_180; - break; - case gfx::Display::ROTATE_270: - xrandr_rotation = RR_Rotate_270; - break; - } - - int internal = display.IsInternal() ? 1 : 0; - gfx::AcceleratedWidget xwindow = root->host()->GetAcceleratedWidget(); - ui::SetIntProperty(xwindow, kInternalProp, kCARDINAL, internal); - ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, xrandr_rotation); - ui::SetIntProperty(xwindow, - kScaleFactorProp, - kCARDINAL, - 100 * display.device_scale_factor()); -#endif - scoped_ptr<aura::RootWindowTransformer> transformer( - internal::CreateRootWindowTransformerForDisplay(root->window(), display)); - root->SetRootWindowTransformer(transformer.Pass()); -} - -} // namespace - -namespace internal { - -// A utility class to store/restore focused/active window -// when the display configuration has changed. -class FocusActivationStore { - public: - FocusActivationStore() - : activation_client_(NULL), - capture_client_(NULL), - focus_client_(NULL), - focused_(NULL), - active_(NULL) { - } - - void Store(bool clear_focus) { - if (!activation_client_) { - aura::Window* root = Shell::GetPrimaryRootWindow(); - activation_client_ = aura::client::GetActivationClient(root); - capture_client_ = aura::client::GetCaptureClient(root); - focus_client_ = aura::client::GetFocusClient(root); - } - focused_ = focus_client_->GetFocusedWindow(); - if (focused_) - tracker_.Add(focused_); - active_ = activation_client_->GetActiveWindow(); - if (active_ && focused_ != active_) - tracker_.Add(active_); - - // Deactivate the window to close menu / bubble windows. - if (clear_focus) - activation_client_->DeactivateWindow(active_); - - // Release capture if any. - capture_client_->SetCapture(NULL); - // Clear the focused window if any. This is necessary because a - // window may be deleted when losing focus (fullscreen flash for - // example). If the focused window is still alive after move, it'll - // be re-focused below. - if (clear_focus) - focus_client_->FocusWindow(NULL); - } - - void Restore() { - // Restore focused or active window if it's still alive. - if (focused_ && tracker_.Contains(focused_)) { - focus_client_->FocusWindow(focused_); - } else if (active_ && tracker_.Contains(active_)) { - activation_client_->ActivateWindow(active_); - } - if (focused_) - tracker_.Remove(focused_); - if (active_) - tracker_.Remove(active_); - focused_ = NULL; - active_ = NULL; - } - - private: - aura::client::ActivationClient* activation_client_; - aura::client::CaptureClient* capture_client_; - aura::client::FocusClient* focus_client_; - aura::WindowTracker tracker_; - aura::Window* focused_; - aura::Window* active_; - - DISALLOW_COPY_AND_ASSIGN(FocusActivationStore); -}; - -} // namespace internal - -//////////////////////////////////////////////////////////////////////////////// -// DisplayChangeLimiter - -DisplayController::DisplayChangeLimiter::DisplayChangeLimiter() - : throttle_timeout_(base::Time::Now()) { -} - -void DisplayController::DisplayChangeLimiter::SetThrottleTimeout( - int64 throttle_ms) { - throttle_timeout_ = - base::Time::Now() + base::TimeDelta::FromMilliseconds(throttle_ms); -} - -bool DisplayController::DisplayChangeLimiter::IsThrottled() const { - return base::Time::Now() < throttle_timeout_; -} - -//////////////////////////////////////////////////////////////////////////////// -// DisplayController - -DisplayController::DisplayController() - : primary_root_window_for_replace_(NULL), - focus_activation_store_(new internal::FocusActivationStore()), - mirror_window_controller_(new internal::MirrorWindowController), - virtual_keyboard_window_controller_( - new internal::VirtualKeyboardWindowController) { -#if defined(OS_CHROMEOS) - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && - base::SysInfo::IsRunningOnChromeOS()) - limiter_.reset(new DisplayChangeLimiter); -#endif - // Reset primary display to make sure that tests don't use - // stale display info from previous tests. - primary_display_id = gfx::Display::kInvalidDisplayID; - delete primary_display_for_shutdown; - primary_display_for_shutdown = NULL; - num_displays_for_shutdown = -1; -} - -DisplayController::~DisplayController() { - DCHECK(primary_display_for_shutdown); -} - -void DisplayController::Start() { - Shell::GetScreen()->AddObserver(this); - Shell::GetInstance()->display_manager()->set_delegate(this); -} - -void DisplayController::Shutdown() { - // Unset the display manager's delegate here because - // DisplayManager outlives DisplayController. - Shell::GetInstance()->display_manager()->set_delegate(NULL); - - mirror_window_controller_.reset(); - virtual_keyboard_window_controller_.reset(); - - DCHECK(!primary_display_for_shutdown); - primary_display_for_shutdown = new gfx::Display( - GetDisplayManager()->GetDisplayForId(primary_display_id)); - num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); - - Shell::GetScreen()->RemoveObserver(this); - // Delete all root window controllers, which deletes root window - // from the last so that the primary root window gets deleted last. - for (std::map<int64, aura::Window*>::const_reverse_iterator it = - root_windows_.rbegin(); it != root_windows_.rend(); ++it) { - internal::RootWindowController* controller = - internal::GetRootWindowController(it->second); - DCHECK(controller); - delete controller; - } -} - -// static -const gfx::Display& DisplayController::GetPrimaryDisplay() { - DCHECK_NE(primary_display_id, gfx::Display::kInvalidDisplayID); - if (primary_display_for_shutdown) - return *primary_display_for_shutdown; - return GetDisplayManager()->GetDisplayForId(primary_display_id); -} - -// static -int DisplayController::GetNumDisplays() { - if (num_displays_for_shutdown >= 0) - return num_displays_for_shutdown; - return GetDisplayManager()->GetNumDisplays(); -} - -void DisplayController::InitPrimaryDisplay() { - const gfx::Display& primary_candidate = - GetDisplayManager()->GetPrimaryDisplayCandidate(); - primary_display_id = primary_candidate.id(); - AddRootWindowForDisplay(primary_candidate); -} - -void DisplayController::InitSecondaryDisplays() { - internal::DisplayManager* display_manager = GetDisplayManager(); - for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { - const gfx::Display& display = display_manager->GetDisplayAt(i); - if (primary_display_id != display.id()) { - aura::RootWindow* root = AddRootWindowForDisplay(display); - internal::RootWindowController::CreateForSecondaryDisplay(root); - } - } - UpdateHostWindowNames(); -} - -void DisplayController::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void DisplayController::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -aura::Window* DisplayController::GetPrimaryRootWindow() { - DCHECK(!root_windows_.empty()); - return root_windows_[primary_display_id]; -} - -aura::Window* DisplayController::GetRootWindowForDisplayId(int64 id) { - return root_windows_[id]; -} - -void DisplayController::CloseChildWindows() { - for (std::map<int64, aura::Window*>::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - aura::Window* root_window = it->second; - internal::RootWindowController* controller = - internal::GetRootWindowController(root_window); - if (controller) { - controller->CloseChildWindows(); - } else { - while (!root_window->children().empty()) { - aura::Window* child = root_window->children()[0]; - delete child; - } - } - } -} - -aura::Window::Windows DisplayController::GetAllRootWindows() { - aura::Window::Windows windows; - for (std::map<int64, aura::Window*>::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - DCHECK(it->second); - if (internal::GetRootWindowController(it->second)) - windows.push_back(it->second); - } - return windows; -} - -gfx::Insets DisplayController::GetOverscanInsets(int64 display_id) const { - return GetDisplayManager()->GetOverscanInsets(display_id); -} - -void DisplayController::SetOverscanInsets(int64 display_id, - const gfx::Insets& insets_in_dip) { - GetDisplayManager()->SetOverscanInsets(display_id, insets_in_dip); -} - -std::vector<internal::RootWindowController*> -DisplayController::GetAllRootWindowControllers() { - std::vector<internal::RootWindowController*> controllers; - for (std::map<int64, aura::Window*>::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - internal::RootWindowController* controller = - internal::GetRootWindowController(it->second); - if (controller) - controllers.push_back(controller); - } - return controllers; -} - -void DisplayController::ToggleMirrorMode() { - internal::DisplayManager* display_manager = GetDisplayManager(); - if (display_manager->num_connected_displays() <= 1) - return; - - if (limiter_) { - if (limiter_->IsThrottled()) - return; - limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); - } -#if defined(OS_CHROMEOS) && defined(USE_X11) - Shell* shell = Shell::GetInstance(); - internal::OutputConfiguratorAnimation* animation = - shell->output_configurator_animation(); - animation->StartFadeOutAnimation(base::Bind( - base::IgnoreResult(&internal::DisplayManager::SetMirrorMode), - base::Unretained(display_manager), - !display_manager->IsMirrored())); -#endif -} - -void DisplayController::SwapPrimaryDisplay() { - if (limiter_) { - if (limiter_->IsThrottled()) - return; - limiter_->SetThrottleTimeout(kSwapDisplayThrottleTimeoutMs); - } - - if (Shell::GetScreen()->GetNumDisplays() > 1) { -#if defined(OS_CHROMEOS) && defined(USE_X11) - internal::OutputConfiguratorAnimation* animation = - Shell::GetInstance()->output_configurator_animation(); - if (animation) { - animation->StartFadeOutAnimation(base::Bind( - &DisplayController::OnFadeOutForSwapDisplayFinished, - base::Unretained(this))); - } else { - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); - } -#else - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); -#endif - } -} - -void DisplayController::SetPrimaryDisplayId(int64 id) { - DCHECK_NE(gfx::Display::kInvalidDisplayID, id); - if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id) - return; - - const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id); - if (display.is_valid()) - SetPrimaryDisplay(display); -} - -void DisplayController::SetPrimaryDisplay( - const gfx::Display& new_primary_display) { - internal::DisplayManager* display_manager = GetDisplayManager(); - DCHECK(new_primary_display.is_valid()); - DCHECK(display_manager->IsActiveDisplay(new_primary_display)); - - if (!new_primary_display.is_valid() || - !display_manager->IsActiveDisplay(new_primary_display)) { - LOG(ERROR) << "Invalid or non-existent display is requested:" - << new_primary_display.ToString(); - return; - } - - if (primary_display_id == new_primary_display.id() || - root_windows_.size() < 2) { - return; - } - - aura::Window* non_primary_root = root_windows_[new_primary_display.id()]; - LOG_IF(ERROR, !non_primary_root) - << "Unknown display is requested in SetPrimaryDisplay: id=" - << new_primary_display.id(); - if (!non_primary_root) - return; - - gfx::Display old_primary_display = GetPrimaryDisplay(); - - // Swap root windows between current and new primary display. - aura::Window* primary_root = root_windows_[primary_display_id]; - DCHECK(primary_root); - DCHECK_NE(primary_root, non_primary_root); - - root_windows_[new_primary_display.id()] = primary_root; - internal::GetRootWindowSettings(primary_root)->display_id = - new_primary_display.id(); - - root_windows_[old_primary_display.id()] = non_primary_root; - internal::GetRootWindowSettings(non_primary_root)->display_id = - old_primary_display.id(); - - primary_display_id = new_primary_display.id(); - GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( - display_manager->GetCurrentDisplayIdPair(), primary_display_id); - - UpdateWorkAreaOfDisplayNearestWindow( - primary_root, old_primary_display.GetWorkAreaInsets()); - UpdateWorkAreaOfDisplayNearestWindow( - non_primary_root, new_primary_display.GetWorkAreaInsets()); - - // Update the dispay manager with new display info. - std::vector<internal::DisplayInfo> display_info_list; - display_info_list.push_back(display_manager->GetDisplayInfo( - primary_display_id)); - display_info_list.push_back(display_manager->GetDisplayInfo( - ScreenAsh::GetSecondaryDisplay().id())); - GetDisplayManager()->set_force_bounds_changed(true); - GetDisplayManager()->UpdateDisplays(display_info_list); - GetDisplayManager()->set_force_bounds_changed(false); -} - -void DisplayController::EnsurePointerInDisplays() { - // If the mouse is currently on a display in native location, - // use the same native location. Otherwise find the display closest - // to the current cursor location in screen coordinates. - - gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); - gfx::Point target_location_in_native; - int64 closest_distance_squared = -1; - internal::DisplayManager* display_manager = GetDisplayManager(); - - aura::Window* dst_root_window = NULL; - for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { - const gfx::Display& display = display_manager->GetDisplayAt(i); - const internal::DisplayInfo display_info = - display_manager->GetDisplayInfo(display.id()); - aura::Window* root_window = GetRootWindowForDisplayId(display.id()); - if (display_info.bounds_in_native().Contains( - cursor_location_in_native_coords_for_restore_)) { - dst_root_window = root_window; - target_location_in_native = cursor_location_in_native_coords_for_restore_; - break; - } - gfx::Point center = display.bounds().CenterPoint(); - // Use the distance squared from the center of the dislay. This is not - // exactly "closest" display, but good enough to pick one - // appropriate (and there are at most two displays). - // We don't care about actual distance, only relative to other displays, so - // using the LengthSquared() is cheaper than Length(). - - int64 distance_squared = (center - point_in_screen).LengthSquared(); - if (closest_distance_squared < 0 || - closest_distance_squared > distance_squared) { - aura::Window* root_window = GetRootWindowForDisplayId(display.id()); - aura::client::ScreenPositionClient* client = - aura::client::GetScreenPositionClient(root_window); - client->ConvertPointFromScreen(root_window, ¢er); - root_window->GetDispatcher()->host()->ConvertPointToNativeScreen(¢er); - dst_root_window = root_window; - target_location_in_native = center; - closest_distance_squared = distance_squared; - } - } - dst_root_window->GetDispatcher()->host()->ConvertPointFromNativeScreen( - &target_location_in_native); - dst_root_window->MoveCursorTo(target_location_in_native); -} - -bool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( - const aura::Window* window, - const gfx::Insets& insets) { - const aura::Window* root_window = window->GetRootWindow(); - int64 id = internal::GetRootWindowSettings(root_window)->display_id; - // if id is |kInvaildDisplayID|, it's being deleted. - DCHECK(id != gfx::Display::kInvalidDisplayID); - return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); -} - -const gfx::Display& DisplayController::GetDisplayNearestWindow( - const aura::Window* window) const { - if (!window) - return GetPrimaryDisplay(); - const aura::Window* root_window = window->GetRootWindow(); - if (!root_window) - return GetPrimaryDisplay(); - int64 id = internal::GetRootWindowSettings(root_window)->display_id; - // if id is |kInvaildDisplayID|, it's being deleted. - DCHECK(id != gfx::Display::kInvalidDisplayID); - - internal::DisplayManager* display_manager = GetDisplayManager(); - // RootWindow needs Display to determine its device scale factor - // for non desktop display. - if (display_manager->non_desktop_display().id() == id) - return display_manager->non_desktop_display(); - return display_manager->GetDisplayForId(id); -} - -const gfx::Display& DisplayController::GetDisplayNearestPoint( - const gfx::Point& point) const { - // Fallback to the primary display if there is no root display containing - // the |point|. - const gfx::Display& display = - GetDisplayManager()->FindDisplayContainingPoint(point); - return display.is_valid() ? display : GetPrimaryDisplay(); -} - -const gfx::Display& DisplayController::GetDisplayMatching( - const gfx::Rect& rect) const { - if (rect.IsEmpty()) - return GetDisplayNearestPoint(rect.origin()); - - int max_area = 0; - const gfx::Display* matching = NULL; - for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { - const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); - gfx::Rect intersect = gfx::IntersectRects(display.bounds(), rect); - int area = intersect.width() * intersect.height(); - if (area > max_area) { - max_area = area; - matching = &display; - } - } - // Fallback to the primary display if there is no matching display. - return matching ? *matching : GetPrimaryDisplay(); -} - -void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { - const internal::DisplayInfo& display_info = - GetDisplayManager()->GetDisplayInfo(display.id()); - DCHECK(!display_info.bounds_in_native().IsEmpty()); - aura::WindowEventDispatcher* dispatcher = - root_windows_[display.id()]->GetDispatcher(); - dispatcher->SetHostBounds(display_info.bounds_in_native()); - SetDisplayPropertiesOnHostWindow(dispatcher, display); -} - -void DisplayController::OnDisplayAdded(const gfx::Display& display) { - if (primary_root_window_for_replace_) { - DCHECK(root_windows_.empty()); - primary_display_id = display.id(); - root_windows_[display.id()] = primary_root_window_for_replace_; - internal::GetRootWindowSettings(primary_root_window_for_replace_)-> - display_id = display.id(); - primary_root_window_for_replace_ = NULL; - const internal::DisplayInfo& display_info = - GetDisplayManager()->GetDisplayInfo(display.id()); - aura::WindowEventDispatcher* dispatcher = - root_windows_[display.id()]->GetDispatcher(); - dispatcher->SetHostBounds(display_info.bounds_in_native()); - SetDisplayPropertiesOnHostWindow(dispatcher, display); - } else { - if (primary_display_id == gfx::Display::kInvalidDisplayID) - primary_display_id = display.id(); - DCHECK(!root_windows_.empty()); - aura::RootWindow* root = AddRootWindowForDisplay(display); - internal::RootWindowController::CreateForSecondaryDisplay(root); - } -} - -void DisplayController::OnDisplayRemoved(const gfx::Display& display) { - aura::Window* root_to_delete = root_windows_[display.id()]; - DCHECK(root_to_delete) << display.ToString(); - - // Display for root window will be deleted when the Primary RootWindow - // is deleted by the Shell. - root_windows_.erase(display.id()); - - // When the primary root window's display is removed, move the primary - // root to the other display. - if (primary_display_id == display.id()) { - // Temporarily store the primary root window in - // |primary_root_window_for_replace_| when replacing the display. - if (root_windows_.size() == 0) { - primary_display_id = gfx::Display::kInvalidDisplayID; - primary_root_window_for_replace_ = root_to_delete; - return; - } - DCHECK_EQ(1U, root_windows_.size()); - primary_display_id = ScreenAsh::GetSecondaryDisplay().id(); - aura::Window* primary_root = root_to_delete; - - // Delete the other root instead. - root_to_delete = root_windows_[primary_display_id]; - internal::GetRootWindowSettings(root_to_delete)->display_id = display.id(); - - // Setup primary root. - root_windows_[primary_display_id] = primary_root; - internal::GetRootWindowSettings(primary_root)->display_id = - primary_display_id; - - OnDisplayBoundsChanged( - GetDisplayManager()->GetDisplayForId(primary_display_id)); - } - internal::RootWindowController* controller = - internal::GetRootWindowController(root_to_delete); - DCHECK(controller); - controller->MoveWindowsTo(GetPrimaryRootWindow()); - // Delete most of root window related objects, but don't delete - // root window itself yet because the stack may be using it. - controller->Shutdown(); - base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller); -} - -void DisplayController::OnRootWindowHostResized(const aura::RootWindow* root) { - internal::DisplayManager* display_manager = GetDisplayManager(); - gfx::Display display = GetDisplayNearestWindow(root->window()); - if (display_manager->UpdateDisplayBounds( - display.id(), - root->host()->GetBounds())) { - mirror_window_controller_->UpdateWindow(); - } -} - -void DisplayController::CreateOrUpdateNonDesktopDisplay( - const internal::DisplayInfo& info) { - switch (GetDisplayManager()->second_display_mode()) { - case internal::DisplayManager::MIRRORING: - mirror_window_controller_->UpdateWindow(info); - virtual_keyboard_window_controller_->Close(); - break; - case internal::DisplayManager::VIRTUAL_KEYBOARD: - mirror_window_controller_->Close(); - virtual_keyboard_window_controller_->UpdateWindow(info); - break; - case internal::DisplayManager::EXTENDED: - NOTREACHED(); - } -} - -void DisplayController::CloseNonDesktopDisplay() { - mirror_window_controller_->Close(); - virtual_keyboard_window_controller_->Close(); -} - -void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { - FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); - focus_activation_store_->Store(clear_focus); - - gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); - gfx::Display display = - Shell::GetScreen()->GetDisplayNearestPoint(point_in_screen); - aura::Window* root_window = GetRootWindowForDisplayId(display.id()); - - aura::client::ScreenPositionClient* client = - aura::client::GetScreenPositionClient(root_window); - client->ConvertPointFromScreen(root_window, &point_in_screen); - root_window->GetDispatcher()->host()->ConvertPointToNativeScreen( - &point_in_screen); - cursor_location_in_native_coords_for_restore_ = point_in_screen; -} - -void DisplayController::PostDisplayConfigurationChange() { - if (limiter_) - limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); - - focus_activation_store_->Restore(); - - internal::DisplayManager* display_manager = GetDisplayManager(); - internal::DisplayLayoutStore* layout_store = display_manager->layout_store(); - if (display_manager->num_connected_displays() > 1) { - DisplayIdPair pair = display_manager->GetCurrentDisplayIdPair(); - layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored()); - DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair); - - if (Shell::GetScreen()->GetNumDisplays() > 1 ) { - int64 primary_id = layout.primary_id; - SetPrimaryDisplayId( - primary_id == gfx::Display::kInvalidDisplayID ? - pair.first : primary_id); - // Update the primary_id in case the above call is - // ignored. Happens when a) default layout's primary id - // doesn't exist, or b) the primary_id has already been - // set to the same and didn't update it. - layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); - } - } - FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); - UpdateHostWindowNames(); - EnsurePointerInDisplays(); -} - -aura::RootWindow* DisplayController::AddRootWindowForDisplay( - const gfx::Display& display) { - static int root_window_count = 0; - const internal::DisplayInfo& display_info = - GetDisplayManager()->GetDisplayInfo(display.id()); - const gfx::Rect& bounds_in_native = display_info.bounds_in_native(); - aura::RootWindow::CreateParams params(bounds_in_native); - params.host = Shell::GetInstance()->root_window_host_factory()-> - CreateRootWindowHost(bounds_in_native); - aura::RootWindow* root_window = new aura::RootWindow(params); - root_window->window()->SetName( - base::StringPrintf("RootWindow-%d", root_window_count++)); - root_window->compositor()->SetBackgroundColor(SK_ColorBLACK); - // No need to remove RootWindowObserver because - // the DisplayController object outlives RootWindow objects. - root_window->AddRootWindowObserver(this); - internal::InitRootWindowSettings(root_window->window())->display_id = - display.id(); - root_window->Init(); - - root_windows_[display.id()] = root_window->window(); - SetDisplayPropertiesOnHostWindow(root_window, display); - -#if defined(OS_CHROMEOS) - static bool force_constrain_pointer_to_root = - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshConstrainPointerToRoot); - if (base::SysInfo::IsRunningOnChromeOS() || force_constrain_pointer_to_root) - root_window->host()->ConfineCursorToRootWindow(); -#endif - return root_window; -} - -void DisplayController::OnFadeOutForSwapDisplayFinished() { -#if defined(OS_CHROMEOS) && defined(USE_X11) - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); - Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); -#endif -} - -void DisplayController::UpdateHostWindowNames() { -#if defined(USE_X11) - // crbug.com/120229 - set the window title for the primary dislpay - // to "aura_root_0" so gtalk can find the primary root window to broadcast. - // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. - aura::Window* primary = Shell::GetPrimaryRootWindow(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - for (size_t i = 0; i < root_windows.size(); ++i) { - std::string name = - root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; - gfx::AcceleratedWidget xwindow = - root_windows[i]->GetDispatcher()->host()->GetAcceleratedWidget(); - XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); - } -#endif -} - -} // namespace ash diff --git a/chromium/ash/display/display_controller.h b/chromium/ash/display/display_controller.h deleted file mode 100644 index 75fe22cd473..00000000000 --- a/chromium/ash/display/display_controller.h +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_DISPLAY_CONTROLLER_H_ -#define ASH_DISPLAY_DISPLAY_CONTROLLER_H_ - -#include <map> -#include <vector> - -#include "ash/ash_export.h" -#include "ash/display/display_manager.h" -#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 "base/time/time.h" -#include "ui/aura/root_window_observer.h" -#include "ui/aura/window.h" -#include "ui/gfx/display_observer.h" -#include "ui/gfx/point.h" - -namespace aura { -class Display; -class RootWindow; -} - -namespace base { -class Value; -template <typename T> class JSONValueConverter; -} - -namespace gfx { -class Display; -class Insets; -} - -namespace ash { -namespace internal { -class DisplayInfo; -class DisplayManager; -class FocusActivationStore; -class MirrorWindowController; -class RootWindowController; -class VirtualKeyboardWindowController; -} - -// DisplayController owns and maintains RootWindows for each attached -// display, keeping them in sync with display configuration changes. -class ASH_EXPORT DisplayController : public gfx::DisplayObserver, - public aura::RootWindowObserver, - public internal::DisplayManager::Delegate { - public: - class ASH_EXPORT Observer { - public: - // Invoked when the display configuration change is requested, - // but before the change is applied to aura/ash. - virtual void OnDisplayConfigurationChanging() {} - - // Invoked when the all display configuration changes - // have been applied. - virtual void OnDisplayConfigurationChanged() {}; - - protected: - virtual ~Observer() {} - }; - - DisplayController(); - virtual ~DisplayController(); - - void Start(); - void Shutdown(); - - // Returns primary display. This is safe to use after ash::Shell is - // deleted. - static const gfx::Display& GetPrimaryDisplay(); - - // Returns the number of display. This is safe to use after - // ash::Shell is deleted. - static int GetNumDisplays(); - - internal::MirrorWindowController* mirror_window_controller() { - return mirror_window_controller_.get(); - } - - internal::VirtualKeyboardWindowController* - virtual_keyboard_window_controller() { - return virtual_keyboard_window_controller_.get(); - } - - // Initializes primary display. - void InitPrimaryDisplay(); - - // Initialize secondary displays. - void InitSecondaryDisplays(); - - // Add/Remove observers. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - // Returns the root window for primary display. - aura::Window* GetPrimaryRootWindow(); - - // Returns the root window for |display_id|. - aura::Window* GetRootWindowForDisplayId(int64 id); - - // Toggle mirror mode. - void ToggleMirrorMode(); - - // Swap primary and secondary display. - void SwapPrimaryDisplay(); - - // Sets the ID of the primary display. If the display is not connected, it - // will switch the primary display when connected. - void SetPrimaryDisplayId(int64 id); - - // Sets primary display. This re-assigns the current root - // window to given |display|. - void SetPrimaryDisplay(const gfx::Display& display); - - // Closes all child windows in the all root windows. - void CloseChildWindows(); - - // Returns all root windows. In non extended desktop mode, this - // returns the primary root window only. - aura::Window::Windows GetAllRootWindows(); - - // Returns all oot window controllers. In non extended desktop - // mode, this return a RootWindowController for the primary root window only. - std::vector<internal::RootWindowController*> GetAllRootWindowControllers(); - - // Gets/Sets/Clears the overscan insets for the specified |display_id|. See - // display_manager.h for the details. - gfx::Insets GetOverscanInsets(int64 display_id) const; - void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip); - - // Checks if the mouse pointer is on one of displays, and moves to - // the center of the nearest display if it's outside of all displays. - void EnsurePointerInDisplays(); - - // Sets the work area's |insets| to the display assigned to |window|. - bool UpdateWorkAreaOfDisplayNearestWindow(const aura::Window* window, - const gfx::Insets& insets); - - // Returns the display object nearest given |point|. - const gfx::Display& GetDisplayNearestPoint( - const gfx::Point& point) const; - - // Returns the display object nearest given |window|. - const gfx::Display& GetDisplayNearestWindow( - const aura::Window* window) const; - - // Returns the display that most closely intersects |match_rect|. - const gfx::Display& GetDisplayMatching( - const gfx::Rect& match_rect)const; - - // aura::DisplayObserver overrides: - virtual void OnDisplayBoundsChanged( - const gfx::Display& display) OVERRIDE; - virtual void OnDisplayAdded(const gfx::Display& display) OVERRIDE; - virtual void OnDisplayRemoved(const gfx::Display& display) OVERRIDE; - - // RootWindowObserver overrides: - virtual void OnRootWindowHostResized(const aura::RootWindow* root) OVERRIDE; - - // aura::DisplayManager::Delegate overrides: - virtual void CreateOrUpdateNonDesktopDisplay( - const internal::DisplayInfo& info) OVERRIDE; - virtual void CloseNonDesktopDisplay() OVERRIDE; - virtual void PreDisplayConfigurationChange(bool clear_focus) OVERRIDE; - virtual void PostDisplayConfigurationChange() OVERRIDE; - - private: - FRIEND_TEST_ALL_PREFIXES(DisplayControllerTest, BoundsUpdated); - FRIEND_TEST_ALL_PREFIXES(DisplayControllerTest, SecondaryDisplayLayout); - friend class internal::DisplayManager; - friend class internal::MirrorWindowController; - - // Creates a root window for |display| and stores it in the |root_windows_| - // map. - aura::RootWindow* AddRootWindowForDisplay(const gfx::Display& display); - - void OnFadeOutForSwapDisplayFinished(); - - void UpdateHostWindowNames(); - - class DisplayChangeLimiter { - public: - DisplayChangeLimiter(); - - // Sets how long the throttling should last. - void SetThrottleTimeout(int64 throttle_ms); - - bool IsThrottled() const; - - private: - // The time when the throttling ends. - base::Time throttle_timeout_; - - DISALLOW_COPY_AND_ASSIGN(DisplayChangeLimiter); - }; - - // The limiter to throttle how fast a user can - // change the display configuration. - scoped_ptr<DisplayChangeLimiter> limiter_; - - // The mapping from display ID to its root window. - std::map<int64, aura::Window*> root_windows_; - - ObserverList<Observer> observers_; - - // Store the primary root window temporarily while replacing - // display. - aura::Window* primary_root_window_for_replace_; - - scoped_ptr<internal::FocusActivationStore> focus_activation_store_; - - scoped_ptr<internal::MirrorWindowController> mirror_window_controller_; - scoped_ptr<internal::VirtualKeyboardWindowController> - virtual_keyboard_window_controller_; - - // Stores the curent cursor location (in native coordinates) used to - // restore the cursor location when display configuration - // changed. - gfx::Point cursor_location_in_native_coords_for_restore_; - - DISALLOW_COPY_AND_ASSIGN(DisplayController); -}; - -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_CONTROLLER_H_ diff --git a/chromium/ash/display/display_controller_unittest.cc b/chromium/ash/display/display_controller_unittest.cc deleted file mode 100644 index 35b585fc841..00000000000 --- a/chromium/ash/display/display_controller_unittest.cc +++ /dev/null @@ -1,1294 +0,0 @@ -// Copyright (c) 2012 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/display/display_controller.h" - -#include "ash/ash_switches.h" -#include "ash/display/display_info.h" -#include "ash/display/display_layout_store.h" -#include "ash/display/display_manager.h" -#include "ash/launcher/launcher.h" -#include "ash/screen_ash.h" -#include "ash/shelf/shelf_widget.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/cursor_manager_test_api.h" -#include "ash/test/display_manager_test_api.h" -#include "ash/wm/window_state.h" -#include "base/command_line.h" -#include "ui/aura/client/activation_change_observer.h" -#include "ui/aura/client/activation_client.h" -#include "ui/aura/client/focus_change_observer.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/test/event_generator.h" -#include "ui/aura/window_tracker.h" -#include "ui/events/event_handler.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" -#include "ui/views/widget/widget.h" - -#if defined(USE_X11) -#include "ui/gfx/x/x11_types.h" -#include <X11/Xlib.h> -#undef RootWindow -#endif - -namespace ash { -namespace { - -const char kDesktopBackgroundView[] = "DesktopBackgroundView"; - -template<typename T> -class Resetter { - public: - explicit Resetter(T* value) : value_(*value) { - *value = 0; - } - ~Resetter() { } - T value() { return value_; } - - private: - T value_; - DISALLOW_COPY_AND_ASSIGN(Resetter); -}; - -class TestObserver : public DisplayController::Observer, - public gfx::DisplayObserver, - public aura::client::FocusChangeObserver, - public aura::client::ActivationChangeObserver { - public: - TestObserver() - : changing_count_(0), - changed_count_(0), - bounds_changed_count_(0), - changed_display_id_(0), - focus_changed_count_(0), - activation_changed_count_(0) { - Shell::GetInstance()->display_controller()->AddObserver(this); - Shell::GetScreen()->AddObserver(this); - aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())-> - AddObserver(this); - aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> - AddObserver(this); - } - - virtual ~TestObserver() { - Shell::GetInstance()->display_controller()->RemoveObserver(this); - Shell::GetScreen()->RemoveObserver(this); - aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())-> - RemoveObserver(this); - aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> - RemoveObserver(this); - } - - // Overridden from DisplayController::Observer - virtual void OnDisplayConfigurationChanging() OVERRIDE { - ++changing_count_; - } - virtual void OnDisplayConfigurationChanged() OVERRIDE { - ++changed_count_; - } - - // Overrideen from gfx::DisplayObserver - virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { - changed_display_id_ = display.id(); - bounds_changed_count_ ++; - } - virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { - } - virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { - } - - // Overridden from aura::client::FocusChangeObserver - virtual void OnWindowFocused(aura::Window* gained_focus, - aura::Window* lost_focus) OVERRIDE { - focus_changed_count_++; - } - - // Overridden from aura::client::ActivationChangeObserver - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - activation_changed_count_++; - } - virtual void OnAttemptToReactivateWindow( - aura::Window* request_active, - aura::Window* actual_active) OVERRIDE { - } - - int CountAndReset() { - EXPECT_EQ(changing_count_, changed_count_); - changed_count_ = 0; - return Resetter<int>(&changing_count_).value(); - } - - int64 GetBoundsChangedCountAndReset() { - return Resetter<int>(&bounds_changed_count_).value(); - } - - int64 GetChangedDisplayIdAndReset() { - return Resetter<int64>(&changed_display_id_).value(); - } - - int GetFocusChangedCountAndReset() { - return Resetter<int>(&focus_changed_count_).value(); - } - - int GetActivationChangedCountAndReset() { - return Resetter<int>(&activation_changed_count_).value(); - } - - private: - int changing_count_; - int changed_count_; - - int bounds_changed_count_; - int64 changed_display_id_; - - int focus_changed_count_; - int activation_changed_count_; - - DISALLOW_COPY_AND_ASSIGN(TestObserver); -}; - -gfx::Display GetPrimaryDisplay() { - return Shell::GetScreen()->GetDisplayNearestWindow( - Shell::GetAllRootWindows()[0]); -} - -gfx::Display GetSecondaryDisplay() { - return Shell::GetScreen()->GetDisplayNearestWindow( - Shell::GetAllRootWindows()[1]); -} - -void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position, - int offset) { - DisplayLayout layout(position, offset); - ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1); - Shell::GetInstance()->display_manager()-> - SetLayoutForCurrentDisplays(layout); -} - -void SetSecondaryDisplayLayout(DisplayLayout::Position position) { - SetSecondaryDisplayLayoutAndOffset(position, 0); -} - -void SetDefaultDisplayLayout(DisplayLayout::Position position) { - Shell::GetInstance()->display_manager()->layout_store()-> - SetDefaultDisplayLayout(DisplayLayout(position, 0)); -} - -class DisplayControllerShutdownTest : public test::AshTestBase { - public: - virtual void TearDown() OVERRIDE { - test::AshTestBase::TearDown(); - if (!SupportsMultipleDisplays()) - return; - - // Make sure that primary display is accessible after shutdown. - gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay(); - EXPECT_EQ("0,0 444x333", primary.bounds().ToString()); - EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - } -}; - -class TestEventHandler : public ui::EventHandler { - public: - TestEventHandler() : target_root_(NULL), - touch_radius_x_(0.0), - touch_radius_y_(0.0), - scroll_x_offset_(0.0), - scroll_y_offset_(0.0), - scroll_x_offset_ordinal_(0.0), - scroll_y_offset_ordinal_(0.0) {} - virtual ~TestEventHandler() {} - - virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { - if (event->flags() & ui::EF_IS_SYNTHESIZED && - event->type() != ui::ET_MOUSE_EXITED && - event->type() != ui::ET_MOUSE_ENTERED) { - return; - } - aura::Window* target = static_cast<aura::Window*>(event->target()); - mouse_location_ = event->root_location(); - target_root_ = target->GetRootWindow(); - event->StopPropagation(); - } - - virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { - aura::Window* target = static_cast<aura::Window*>(event->target()); - // Only record when the target is the background which covers - // entire root window. - if (target->name() != kDesktopBackgroundView) - return; - touch_radius_x_ = event->radius_x(); - touch_radius_y_ = event->radius_y(); - event->StopPropagation(); - } - - virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { - aura::Window* target = static_cast<aura::Window*>(event->target()); - // Only record when the target is the background which covers - // entire root window. - if (target->name() != kDesktopBackgroundView) - return; - - if (event->type() == ui::ET_SCROLL) { - scroll_x_offset_ = event->x_offset(); - scroll_y_offset_ = event->y_offset(); - scroll_x_offset_ordinal_ = event->x_offset_ordinal(); - scroll_y_offset_ordinal_ = event->y_offset_ordinal(); - } - event->StopPropagation(); - } - - std::string GetLocationAndReset() { - std::string result = mouse_location_.ToString(); - mouse_location_.SetPoint(0, 0); - target_root_ = NULL; - return result; - } - - float touch_radius_x() { return touch_radius_x_; } - float touch_radius_y() { return touch_radius_y_; } - float scroll_x_offset() { return scroll_x_offset_; } - float scroll_y_offset() { return scroll_y_offset_; } - float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; } - float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; } - - private: - gfx::Point mouse_location_; - aura::Window* target_root_; - - float touch_radius_x_; - float touch_radius_y_; - float scroll_x_offset_; - float scroll_y_offset_; - float scroll_x_offset_ordinal_; - float scroll_y_offset_ordinal_; - - DISALLOW_COPY_AND_ASSIGN(TestEventHandler); -}; - -gfx::Display::Rotation GetStoredRotation(int64 id) { - return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation(); -} - -float GetStoredUIScale(int64 id) { - return Shell::GetInstance()->display_manager()->GetDisplayInfo(id). - GetEffectiveUIScale(); -} - -#if defined(USE_X11) -void GetPrimaryAndSeconary(aura::Window** primary, - aura::Window** secondary) { - *primary = Shell::GetPrimaryRootWindow(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - *secondary = root_windows[0] == *primary ? root_windows[1] : root_windows[0]; -} - -std::string GetXWindowName(aura::RootWindow* window) { - char* name = NULL; - XFetchName(gfx::GetXDisplay(), window->host()->GetAcceleratedWidget(), &name); - std::string ret(name); - XFree(name); - return ret; -} -#endif - -} // namespace - -typedef test::AshTestBase DisplayControllerTest; - -TEST_F(DisplayControllerShutdownTest, Shutdown) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("444x333, 200x200"); -} - -TEST_F(DisplayControllerTest, SecondaryDisplayLayout) { - if (!SupportsMultipleDisplays()) - return; - - // Creates windows to catch activation change event. - scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); - w1->Focus(); - - TestObserver observer; - UpdateDisplay("500x500,400x400"); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - gfx::Insets insets(5, 5, 5, 5); - int64 secondary_display_id = ScreenAsh::GetSecondaryDisplay().id(); - Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay( - secondary_display_id, insets); - - // Default layout is RIGHT. - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - - // Layout the secondary display to the bottom of the primary. - SetSecondaryDisplayLayout(DisplayLayout::BOTTOM); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString()); - - // Layout the secondary display to the left of the primary. - SetSecondaryDisplayLayout(DisplayLayout::LEFT); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString()); - - // Layout the secondary display to the top of the primary. - SetSecondaryDisplayLayout(DisplayLayout::TOP); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString()); - - // Layout to the right with an offset. - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString()); - - // Keep the minimum 100. - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString()); - - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString()); - - // Layout to the bottom with an offset. - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString()); - - // Keep the minimum 100. - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString()); - - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400); - EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(1, observer.CountAndReset()); // resize and add - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString()); - - // Setting the same layout shouldn't invoke observers. - SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400); - EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(0, observer.CountAndReset()); // resize and add - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString()); - - UpdateDisplay("500x500"); - EXPECT_LE(1, observer.GetFocusChangedCountAndReset()); - EXPECT_LE(1, observer.GetActivationChangedCountAndReset()); -} - -namespace { - -internal::DisplayInfo CreateDisplayInfo(int64 id, - const gfx::Rect& bounds, - float device_scale_factor) { - internal::DisplayInfo info(id, "", false); - info.SetBounds(bounds); - info.set_device_scale_factor(device_scale_factor); - return info; -} - -} // namespace - -TEST_F(DisplayControllerTest, MirrorToDockedWithFullscreen) { - // Creates windows to catch activation change event. - scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); - w1->Focus(); - - // Docked mode. - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - const internal::DisplayInfo internal_display_info = - CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f); - const internal::DisplayInfo external_display_info = - CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f); - - std::vector<internal::DisplayInfo> display_info_list; - // Mirror. - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - const int64 internal_display_id = - test::DisplayManagerTestApi(display_manager). - SetFirstDisplayAsInternalDisplay(); - EXPECT_EQ(1, internal_display_id); - EXPECT_EQ(2U, display_manager->num_connected_displays()); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - - wm::WindowState* window_state = wm::GetWindowState(w1.get()); - window_state->ToggleFullscreen(); - EXPECT_TRUE(window_state->IsFullscreen()); - EXPECT_EQ("0,0 250x250", w1->bounds().ToString()); - // Dock mode. - TestObserver observer; - display_info_list.clear(); - display_info_list.push_back(external_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_EQ(1U, display_manager->num_connected_displays()); - EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset()); - EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset()); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - - EXPECT_TRUE(window_state->IsFullscreen()); - EXPECT_EQ("0,0 500x500", w1->bounds().ToString()); -} - -TEST_F(DisplayControllerTest, BoundsUpdated) { - if (!SupportsMultipleDisplays()) - return; - - // Creates windows to catch activation change event. - scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); - w1->Focus(); - - TestObserver observer; - SetDefaultDisplayLayout(DisplayLayout::BOTTOM); - UpdateDisplay("200x200,300x300"); // layout, resize and add. - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - gfx::Insets insets(5, 5, 5, 5); - display_manager->UpdateWorkAreaOfDisplay( - ScreenAsh::GetSecondaryDisplay().id(), insets); - - EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString()); - - UpdateDisplay("400x400,200x200"); - EXPECT_EQ(1, observer.CountAndReset()); // two resizes - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString()); - - UpdateDisplay("400x400,300x300"); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString()); - - UpdateDisplay("400x400"); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_LE(1, observer.GetFocusChangedCountAndReset()); - EXPECT_LE(1, observer.GetActivationChangedCountAndReset()); - EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); - - UpdateDisplay("400x500*2,300x300"); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString()); - - // No change - UpdateDisplay("400x500*2,300x300"); - EXPECT_EQ(0, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - - // Rotation - int64 primary_id = GetPrimaryDisplay().id(); - display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90); - EXPECT_EQ(0, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - - // UI scale is eanbled only on internal display. - int64 secondary_id = GetSecondaryDisplay().id(); - gfx::Display::SetInternalDisplayId(secondary_id); - display_manager->SetDisplayUIScale(secondary_id, 1.125f); - EXPECT_EQ(1, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - display_manager->SetDisplayUIScale(secondary_id, 1.125f); - EXPECT_EQ(0, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - display_manager->SetDisplayUIScale(primary_id, 1.125f); - EXPECT_EQ(0, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); - display_manager->SetDisplayUIScale(primary_id, 1.125f); - EXPECT_EQ(0, observer.CountAndReset()); - EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); - EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); -} - -TEST_F(DisplayControllerTest, SwapPrimary) { - if (!SupportsMultipleDisplays()) - return; - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - UpdateDisplay("200x200,300x300"); - gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); - - DisplayLayout display_layout(DisplayLayout::RIGHT, 50); - display_manager->SetLayoutForCurrentDisplays(display_layout); - - EXPECT_NE(primary_display.id(), secondary_display.id()); - aura::Window* primary_root = - display_controller->GetRootWindowForDisplayId(primary_display.id()); - aura::Window* secondary_root = - display_controller->GetRootWindowForDisplayId(secondary_display.id()); - EXPECT_NE(primary_root, secondary_root); - aura::Window* launcher_window = - Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - - EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString()); - EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString()); - EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString()); - EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString()); - EXPECT_EQ("right, 50", - display_manager->GetCurrentDisplayLayout().ToString()); - - // Switch primary and secondary - display_controller->SetPrimaryDisplay(secondary_display); - const DisplayLayout& inverted_layout = - display_manager->GetCurrentDisplayLayout(); - EXPECT_EQ("left, -50", inverted_layout.ToString()); - - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - - EXPECT_EQ( - primary_root, - display_controller->GetRootWindowForDisplayId(secondary_display.id())); - EXPECT_EQ( - secondary_root, - display_controller->GetRootWindowForDisplayId(primary_display.id())); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - - // Test if the bounds are correctly swapped. - gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); - EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); - EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString()); - EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); - - EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString()); - - aura::WindowTracker tracker; - tracker.Add(primary_root); - tracker.Add(secondary_root); - - // Deleting 2nd display should move the primary to original primary display. - UpdateDisplay("200x200"); - RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. - EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - EXPECT_TRUE(tracker.Contains(primary_root)); - EXPECT_FALSE(tracker.Contains(secondary_root)); - EXPECT_TRUE(primary_root->Contains(launcher_window)); -} - -TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { - if (!SupportsMultipleDisplays()) - return; - - CommandLine::ForCurrentProcess()->AppendSwitch( - ash::switches::kAshDisableAlternateShelfLayout); - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - UpdateDisplay("200x200,300x300"); - gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); - - DisplayLayout display_layout(DisplayLayout::RIGHT, 50); - display_manager->SetLayoutForCurrentDisplays(display_layout); - - EXPECT_NE(primary_display.id(), secondary_display.id()); - aura::Window* primary_root = - display_controller->GetRootWindowForDisplayId(primary_display.id()); - aura::Window* secondary_root = - display_controller->GetRootWindowForDisplayId(secondary_display.id()); - EXPECT_NE(primary_root, secondary_root); - aura::Window* launcher_window = - Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - - EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString()); - EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString()); - EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString()); - EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString()); - EXPECT_EQ("right, 50", - display_manager->GetCurrentDisplayLayout().ToString()); - - // Switch primary and secondary - display_controller->SetPrimaryDisplay(secondary_display); - const DisplayLayout& inverted_layout = - display_manager->GetCurrentDisplayLayout(); - EXPECT_EQ("left, -50", inverted_layout.ToString()); - - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - - EXPECT_EQ( - primary_root, - display_controller->GetRootWindowForDisplayId(secondary_display.id())); - EXPECT_EQ( - secondary_root, - display_controller->GetRootWindowForDisplayId(primary_display.id())); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - - // Test if the bounds are correctly swapped. - gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); - EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); - EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString()); - EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); - - EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString()); - - aura::WindowTracker tracker; - tracker.Add(primary_root); - tracker.Add(secondary_root); - - // Deleting 2nd display should move the primary to original primary display. - UpdateDisplay("200x200"); - RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. - EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - EXPECT_TRUE(tracker.Contains(primary_root)); - EXPECT_FALSE(tracker.Contains(secondary_root)); - EXPECT_TRUE(primary_root->Contains(launcher_window)); -} - -TEST_F(DisplayControllerTest, SwapPrimaryById) { - if (!SupportsMultipleDisplays()) - return; - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - UpdateDisplay("200x200,300x300"); - gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); - - DisplayLayout display_layout(DisplayLayout::RIGHT, 50); - display_manager->SetLayoutForCurrentDisplays(display_layout); - - EXPECT_NE(primary_display.id(), secondary_display.id()); - aura::Window* primary_root = - display_controller->GetRootWindowForDisplayId(primary_display.id()); - aura::Window* secondary_root = - display_controller->GetRootWindowForDisplayId(secondary_display.id()); - aura::Window* launcher_window = - Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - EXPECT_NE(primary_root, secondary_root); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - - // Switch primary and secondary by display ID. - TestObserver observer; - display_controller->SetPrimaryDisplayId(secondary_display.id()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); - EXPECT_LT(0, observer.CountAndReset()); - - EXPECT_EQ( - primary_root, - display_controller->GetRootWindowForDisplayId(secondary_display.id())); - EXPECT_EQ( - secondary_root, - display_controller->GetRootWindowForDisplayId(primary_display.id())); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - EXPECT_FALSE(secondary_root->Contains(launcher_window)); - - const DisplayLayout& inverted_layout = - display_manager->GetCurrentDisplayLayout(); - - EXPECT_EQ("left, -50", inverted_layout.ToString()); - - // Calling the same ID don't do anything. - display_controller->SetPrimaryDisplayId(secondary_display.id()); - EXPECT_EQ(0, observer.CountAndReset()); - - aura::WindowTracker tracker; - tracker.Add(primary_root); - tracker.Add(secondary_root); - - // Deleting 2nd display should move the primary to original primary display. - UpdateDisplay("200x200"); - RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. - EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestPoint( - gfx::Point(-100, -100)).id()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); - EXPECT_TRUE(tracker.Contains(primary_root)); - EXPECT_FALSE(tracker.Contains(secondary_root)); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - - // Adding 2nd display with the same ID. The 2nd display should become primary - // since secondary id is still stored as desirable_primary_id. - std::vector<internal::DisplayInfo> display_info_list; - display_info_list.push_back( - display_manager->GetDisplayInfo(primary_display.id())); - display_info_list.push_back( - display_manager->GetDisplayInfo(secondary_display.id())); - display_manager->OnNativeDisplaysChanged(display_info_list); - - EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(secondary_display.id(), - Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); - EXPECT_EQ( - primary_root, - display_controller->GetRootWindowForDisplayId(secondary_display.id())); - EXPECT_NE( - primary_root, - display_controller->GetRootWindowForDisplayId(primary_display.id())); - EXPECT_TRUE(primary_root->Contains(launcher_window)); - - // Deleting 2nd display and adding 2nd display with a different ID. The 2nd - // display shouldn't become primary. - UpdateDisplay("200x200"); - internal::DisplayInfo third_display_info( - secondary_display.id() + 1, std::string(), false); - third_display_info.SetBounds(secondary_display.bounds()); - ASSERT_NE(primary_display.id(), third_display_info.id()); - - const internal::DisplayInfo& primary_display_info = - display_manager->GetDisplayInfo(primary_display.id()); - std::vector<internal::DisplayInfo> display_info_list2; - display_info_list2.push_back(primary_display_info); - display_info_list2.push_back(third_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list2); - EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(primary_display.id(), - Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id()); - EXPECT_EQ( - primary_root, - display_controller->GetRootWindowForDisplayId(primary_display.id())); - EXPECT_NE( - primary_root, - display_controller->GetRootWindowForDisplayId(third_display_info.id())); - EXPECT_TRUE(primary_root->Contains(launcher_window)); -} - -TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) { - if (!SupportsMultipleDisplays()) - return; - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - - UpdateDisplay("200x200,200x200*2"); - gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); - - aura::Window* primary_root = - display_controller->GetRootWindowForDisplayId(primary_display.id()); - aura::Window* secondary_root = - display_controller->GetRootWindowForDisplayId(secondary_display.id()); - EXPECT_NE(primary_root, secondary_root); - - test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager()); - - EXPECT_EQ(1.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> - GetDeviceScaleFactor()); - primary_root->MoveCursorTo(gfx::Point(50, 50)); - EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); - EXPECT_EQ(2.0f, secondary_root->GetDispatcher()->AsRootWindowHostDelegate()-> - GetDeviceScaleFactor()); - secondary_root->MoveCursorTo(gfx::Point(50, 50)); - EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor()); - - // Switch primary and secondary - display_controller->SetPrimaryDisplay(secondary_display); - - // Cursor's device scale factor should be updated accroding to the swap of - // primary and secondary. - EXPECT_EQ(1.0f, secondary_root->GetDispatcher()->AsRootWindowHostDelegate()-> - GetDeviceScaleFactor()); - secondary_root->MoveCursorTo(gfx::Point(50, 50)); - EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); - primary_root->MoveCursorTo(gfx::Point(50, 50)); - EXPECT_EQ(2.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> - GetDeviceScaleFactor()); - EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor()); - - // Deleting 2nd display. - UpdateDisplay("200x200"); - RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. - - // Cursor's device scale factor should be updated even without moving cursor. - EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); - - primary_root->MoveCursorTo(gfx::Point(50, 50)); - EXPECT_EQ(1.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> - GetDeviceScaleFactor()); - EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); -} - -TEST_F(DisplayControllerTest, OverscanInsets) { - if (!SupportsMultipleDisplays()) - return; - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("120x200,300x400*2"); - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - display_controller->SetOverscanInsets(display1.id(), - gfx::Insets(10, 15, 20, 25)); - EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString()); - EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("80,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - aura::test::EventGenerator generator(root_windows[0]); - generator.MoveMouseToInHost(20, 25); - EXPECT_EQ("5,15", event_handler.GetLocationAndReset()); - - display_controller->SetOverscanInsets(display1.id(), gfx::Insets()); - EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString()); - EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - generator.MoveMouseToInHost(30, 20); - EXPECT_EQ("30,20", event_handler.GetLocationAndReset()); - - // Make sure the root window transformer uses correct scale - // factor when swapping display. Test crbug.com/253690. - UpdateDisplay("400x300*2,600x400/o"); - root_windows = Shell::GetAllRootWindows(); - gfx::Point point; - Shell::GetAllRootWindows()[1]->GetDispatcher()-> - GetRootTransform().TransformPoint(&point); - EXPECT_EQ("15,10", point.ToString()); - - display_controller->SwapPrimaryDisplay(); - point.SetPoint(0, 0); - Shell::GetAllRootWindows()[1]->GetDispatcher()-> - GetRootTransform().TransformPoint(&point); - EXPECT_EQ("15,10", point.ToString()); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(DisplayControllerTest, Rotate) { - if (!SupportsMultipleDisplays()) - return; - - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("120x200,300x400*2"); - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::test::EventGenerator generator1(root_windows[0]); - - EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator1.MoveMouseToInHost(50, 40); - EXPECT_EQ("50,40", event_handler.GetLocationAndReset()); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); - - display_manager->SetDisplayRotation(display1.id(), - gfx::Display::ROTATE_90); - EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("200,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator1.MoveMouseToInHost(50, 40); - EXPECT_EQ("40,69", event_handler.GetLocationAndReset()); - EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); - - DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); - display_manager->SetLayoutForCurrentDisplays(display_layout); - EXPECT_EQ("50,120 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - display_manager->SetDisplayRotation(display2_id, - gfx::Display::ROTATE_270); - EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("50,120 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); - -#if !defined(OS_WIN) - aura::test::EventGenerator generator2(root_windows[1]); - generator2.MoveMouseToInHost(50, 40); - EXPECT_EQ("179,25", event_handler.GetLocationAndReset()); - display_manager->SetDisplayRotation(display1.id(), - gfx::Display::ROTATE_180); - - EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); - // Dislay must share at least 100, so the x's offset becomes 20. - EXPECT_EQ("20,200 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); - - generator1.MoveMouseToInHost(50, 40); - EXPECT_EQ("69,159", event_handler.GetLocationAndReset()); -#endif - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(DisplayControllerTest, ScaleRootWindow) { - if (!SupportsMultipleDisplays()) - return; - - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("600x400*2@1.5,500x300"); - - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display::SetInternalDisplayId(display1.id()); - - gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); - EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); - EXPECT_EQ("450,0 500x300", display2.bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); - - aura::test::EventGenerator generator(root_windows[0]); - generator.MoveMouseToInHost(599, 200); - EXPECT_EQ("449,150", event_handler.GetLocationAndReset()); - - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - display_manager->SetDisplayUIScale(display1.id(), 1.25f); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - display2 = ScreenAsh::GetSecondaryDisplay(); - EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); - EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); - EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); - EXPECT_EQ(1.25f, GetStoredUIScale(display1.id())); - EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(DisplayControllerTest, TouchScale) { - if (!SupportsMultipleDisplays()) - return; - - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("200x200*2"); - gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Window* root_window = root_windows[0]; - aura::test::EventGenerator generator(root_window); - - generator.PressMoveAndReleaseTouchTo(50, 50); - // Default test touches have radius_x/y = 1.0, with device scale - // factor = 2, the scaled radius_x/y should be 0.5. - EXPECT_EQ(0.5, event_handler.touch_radius_x()); - EXPECT_EQ(0.5, event_handler.touch_radius_y()); - - generator.ScrollSequence(gfx::Point(0,0), - base::TimeDelta::FromMilliseconds(100), - 10.0, 1.0, 5, 1); - - // ordinal_offset is invariant to the device scale factor. - EXPECT_EQ(event_handler.scroll_x_offset(), - event_handler.scroll_x_offset_ordinal()); - EXPECT_EQ(event_handler.scroll_y_offset(), - event_handler.scroll_y_offset_ordinal()); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(DisplayControllerTest, ConvertHostToRootCoords) { - if (!SupportsMultipleDisplays()) - return; - - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("600x400*2/r@1.5"); - - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); - EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - aura::test::EventGenerator generator(root_windows[0]); - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("0,449", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 0); - EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 399); - EXPECT_EQ("299,0", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 399); - EXPECT_EQ("299,449", event_handler.GetLocationAndReset()); - - UpdateDisplay("600x400*2/u@1.5"); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); - EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("449,299", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 0); - EXPECT_EQ("0,299", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 399); - EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 399); - EXPECT_EQ("449,0", event_handler.GetLocationAndReset()); - - UpdateDisplay("600x400*2/l@1.5"); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); - EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("299,0", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 0); - EXPECT_EQ("299,449", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(599, 399); - EXPECT_EQ("0,449", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 399); - EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -namespace { - -internal::DisplayInfo CreateDisplayInfo(int64 id, - int y, - gfx::Display::Rotation rotation) { - internal::DisplayInfo info(id, "", false); - info.SetBounds(gfx::Rect(0, y, 500, 500)); - info.set_rotation(rotation); - return info; -} - -} // namespace - -// Make sure that the compositor based mirroring can switch -// from/to dock mode. -TEST_F(DisplayControllerTest, DockToSingle) { - if (!SupportsMultipleDisplays()) - return; - - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - const int64 internal_id = 1; - - const internal::DisplayInfo internal_display_info = - CreateDisplayInfo(internal_id, 0, gfx::Display::ROTATE_0); - const internal::DisplayInfo external_display_info = - CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90); - - std::vector<internal::DisplayInfo> display_info_list; - // Extended - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - const int64 internal_display_id = - test::DisplayManagerTestApi(display_manager). - SetFirstDisplayAsInternalDisplay(); - EXPECT_EQ(internal_id, internal_display_id); - EXPECT_EQ(2U, display_manager->GetNumDisplays()); - - // Dock mode. - display_info_list.clear(); - display_info_list.push_back(external_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetDispatcher()-> - GetRootTransform().IsIdentityOrIntegerTranslation()); - - // Switch to single mode and make sure the transform is the one - // for the internal display. - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetDispatcher()-> - GetRootTransform().IsIdentityOrIntegerTranslation()); -} - -#if defined(USE_X11) -TEST_F(DisplayControllerTest, XWidowNameForRootWindow) { - EXPECT_EQ("aura_root_0", GetXWindowName( - Shell::GetPrimaryRootWindow()->GetDispatcher())); - - // Multiple display. - UpdateDisplay("200x200,300x300"); - aura::Window* primary, *secondary; - GetPrimaryAndSeconary(&primary, &secondary); - EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetDispatcher())); - EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetDispatcher())); - - // Swap primary. - primary = secondary = NULL; - Shell::GetInstance()->display_controller()->SwapPrimaryDisplay(); - GetPrimaryAndSeconary(&primary, &secondary); - EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetDispatcher())); - EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetDispatcher())); - - // Switching back to single display. - UpdateDisplay("300x400"); - EXPECT_EQ("aura_root_0", GetXWindowName( - Shell::GetPrimaryRootWindow()->GetDispatcher())); -} -#endif - -} // namespace ash diff --git a/chromium/ash/display/display_error_observer_chromeos.cc b/chromium/ash/display/display_error_observer_chromeos.cc deleted file mode 100644 index 34e1bc2e5df..00000000000 --- a/chromium/ash/display/display_error_observer_chromeos.cc +++ /dev/null @@ -1,73 +0,0 @@ -// 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/display/display_error_observer_chromeos.h" - -#include "ash/system/system_notifier.h" -#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" -#include "ui/message_center/notification_delegate.h" -#include "ui/message_center/notification_list.h" - -using message_center::Notification; - -namespace ash { -namespace internal { -namespace { - -const char kDisplayErrorNotificationId[] = "chrome://settings/display/error"; - -} // namespace - -DisplayErrorObserver::DisplayErrorObserver() { -} - -DisplayErrorObserver::~DisplayErrorObserver() { -} - -void DisplayErrorObserver::OnDisplayModeChangeFailed( - chromeos::OutputState new_state) { - // Always remove the notification to make sure the notification appears - // as a popup in any situation. - message_center::MessageCenter::Get()->RemoveNotification( - kDisplayErrorNotificationId, false /* by_user */); - - int message_id = (new_state == chromeos::STATE_DUAL_MIRROR) ? - IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING : - IDS_ASH_DISPLAY_FAILURE_ON_NON_MIRRORING; - - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - scoped_ptr<Notification> notification(new Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, - kDisplayErrorNotificationId, - l10n_util::GetStringUTF16(message_id), - base::string16(), // message - bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY), - base::string16(), // display_source - message_center::NotifierId( - message_center::NotifierId::SYSTEM_COMPONENT, - system_notifier::kNotifierDisplayError), - message_center::RichNotificationData(), - NULL)); - message_center::MessageCenter::Get()->AddNotification(notification.Pass()); -} - -string16 DisplayErrorObserver::GetTitleOfDisplayErrorNotificationForTest() { - message_center::NotificationList::Notifications notifications = - message_center::MessageCenter::Get()->GetVisibleNotifications(); - for (message_center::NotificationList::Notifications::const_iterator iter = - notifications.begin(); iter != notifications.end(); ++iter) { - if ((*iter)->id() == kDisplayErrorNotificationId) - return (*iter)->title(); - } - - return base::string16(); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_error_observer_chromeos.h b/chromium/ash/display/display_error_observer_chromeos.h deleted file mode 100644 index b8bb1c1ea3b..00000000000 --- a/chromium/ash/display/display_error_observer_chromeos.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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_DISPLAY_DISPLAY_ERROR_OBSERVER_CHROMEOS_H_ -#define ASH_DISPLAY_DISPLAY_ERROR_OBSERVER_CHROMEOS_H_ - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/strings/string16.h" -#include "chromeos/display/output_configurator.h" - -namespace ash { -namespace internal { - -// The class to observe the output failures and shows the error dialog when -// necessary. -class ASH_EXPORT DisplayErrorObserver - : public chromeos::OutputConfigurator::Observer { - public: - DisplayErrorObserver(); - virtual ~DisplayErrorObserver(); - - // chromeos::OutputConfigurator::Observer overrides: - virtual void OnDisplayModeChangeFailed( - chromeos::OutputState failed_new_state) OVERRIDE; - - private: - friend class DisplayErrorObserverTest; - - base::string16 GetTitleOfDisplayErrorNotificationForTest(); - - DISALLOW_COPY_AND_ASSIGN(DisplayErrorObserver); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_ERROR_OBSERVER_CHROMEOS_H_ diff --git a/chromium/ash/display/display_error_observer_chromeos_unittest.cc b/chromium/ash/display/display_error_observer_chromeos_unittest.cc deleted file mode 100644 index 7cd0503b287..00000000000 --- a/chromium/ash/display/display_error_observer_chromeos_unittest.cc +++ /dev/null @@ -1,85 +0,0 @@ -// 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/display/display_error_observer_chromeos.h" - -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "grit/ash_strings.h" -#include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/views/controls/label.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" - -namespace ash { -namespace internal { - -class DisplayErrorObserverTest : public test::AshTestBase { - protected: - DisplayErrorObserverTest() { - } - - virtual ~DisplayErrorObserverTest() { - } - - virtual void SetUp() OVERRIDE { - test::AshTestBase::SetUp(); - observer_.reset(new DisplayErrorObserver()); - } - - protected: - DisplayErrorObserver* observer() { return observer_.get(); } - - base::string16 GetMessageContents() { - return observer_->GetTitleOfDisplayErrorNotificationForTest(); - } - - private: - scoped_ptr<DisplayErrorObserver> observer_; - - DISALLOW_COPY_AND_ASSIGN(DisplayErrorObserverTest); -}; - -TEST_F(DisplayErrorObserverTest, Normal) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("200x200,300x300"); - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING), - GetMessageContents()); -} - -TEST_F(DisplayErrorObserverTest, CallTwice) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("200x200,300x300"); - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR); - base::string16 message = GetMessageContents(); - EXPECT_FALSE(message.empty()); - - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR); - base::string16 message2 = GetMessageContents(); - EXPECT_FALSE(message2.empty()); - EXPECT_EQ(message, message2); -} - -TEST_F(DisplayErrorObserverTest, CallWithDifferentState) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("200x200,300x300"); - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_MIRROR); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING), - GetMessageContents()); - - observer()->OnDisplayModeChangeFailed(chromeos::STATE_DUAL_EXTENDED); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_NON_MIRRORING), - GetMessageContents()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_info.cc b/chromium/ash/display/display_info.cc deleted file mode 100644 index 01c604f7a62..00000000000 --- a/chromium/ash/display/display_info.cc +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 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 <stdio.h> -#include <string> -#include <vector> - -#include "ash/display/display_info.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "ui/gfx/display.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/size_f.h" - -#if defined(OS_WIN) -#include "ui/aura/window_tree_host.h" -#endif - -namespace ash { -namespace internal { - -Resolution::Resolution(const gfx::Size& size, bool interlaced) - : size(size), - interlaced(interlaced) { -} - -// satic -DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) { - return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID); -} - -// static -DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, - int64 id) { - // Default bounds for a display. - const int kDefaultHostWindowX = 200; - const int kDefaultHostWindowY = 200; - const int kDefaultHostWindowWidth = 1366; - const int kDefaultHostWindowHeight = 768; - - // Use larger than max int to catch overflow early. - static int64 synthesized_display_id = 2200000000LL; - -#if defined(OS_WIN) - gfx::Rect bounds_in_native(aura::RootWindowHost::GetNativeScreenSize()); -#else - gfx::Rect bounds_in_native(kDefaultHostWindowX, kDefaultHostWindowY, - kDefaultHostWindowWidth, kDefaultHostWindowHeight); -#endif - std::string main_spec = spec; - - float ui_scale = 1.0f; - std::vector<std::string> parts; - if (Tokenize(main_spec, "@", &parts) == 2) { - double scale_in_double = 0; - if (base::StringToDouble(parts[1], &scale_in_double)) - ui_scale = scale_in_double; - main_spec = parts[0]; - } - - size_t count = Tokenize(main_spec, "/", &parts); - gfx::Display::Rotation rotation(gfx::Display::ROTATE_0); - bool has_overscan = false; - if (count) { - main_spec = parts[0]; - if (count >= 2) { - std::string options = parts[1]; - for (size_t i = 0; i < options.size(); ++i) { - char c = options[i]; - switch (c) { - case 'o': - has_overscan = true; - break; - case 'r': // rotate 90 degrees to 'right'. - rotation = gfx::Display::ROTATE_90; - break; - case 'u': // 180 degrees, 'u'pside-down. - rotation = gfx::Display::ROTATE_180; - break; - case 'l': // rotate 90 degrees to 'left'. - rotation = gfx::Display::ROTATE_270; - break; - } - } - } - } - - int x = 0, y = 0, width, height; - float device_scale_factor = 1.0f; - if (sscanf(main_spec.c_str(), "%dx%d*%f", - &width, &height, &device_scale_factor) >= 2 || - sscanf(main_spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height, - &device_scale_factor) >= 4) { - bounds_in_native.SetRect(x, y, width, height); - } - - std::vector<Resolution> resolutions; - if (Tokenize(main_spec, "#", &parts) == 2) { - main_spec = parts[0]; - std::string resolution_list = parts[1]; - count = Tokenize(resolution_list, "|", &parts); - for (size_t i = 0; i < count; ++i) { - std::string resolution = parts[i]; - int width, height; - if (sscanf(resolution.c_str(), "%dx%d", &width, &height) == 2) - resolutions.push_back(Resolution(gfx::Size(width, height), false)); - } - } - - if (id == gfx::Display::kInvalidDisplayID) - id = synthesized_display_id++; - DisplayInfo display_info( - id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan); - display_info.set_device_scale_factor(device_scale_factor); - display_info.set_rotation(rotation); - display_info.set_configured_ui_scale(ui_scale); - display_info.SetBounds(bounds_in_native); - display_info.set_resolutions(resolutions); - - // To test the overscan, it creates the default 5% overscan. - if (has_overscan) { - int width = bounds_in_native.width() / device_scale_factor / 40; - int height = bounds_in_native.height() / device_scale_factor / 40; - display_info.SetOverscanInsets(gfx::Insets(height, width, height, width)); - display_info.UpdateDisplaySize(); - } - - DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString() - << ", spec=" << spec; - return display_info; -} - -DisplayInfo::DisplayInfo() - : id_(gfx::Display::kInvalidDisplayID), - has_overscan_(false), - rotation_(gfx::Display::ROTATE_0), - touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - device_scale_factor_(1.0f), - overscan_insets_in_dip_(0, 0, 0, 0), - configured_ui_scale_(1.0f), - native_(false) { -} - -DisplayInfo::DisplayInfo(int64 id, - const std::string& name, - bool has_overscan) - : id_(id), - name_(name), - has_overscan_(has_overscan), - rotation_(gfx::Display::ROTATE_0), - touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - device_scale_factor_(1.0f), - overscan_insets_in_dip_(0, 0, 0, 0), - configured_ui_scale_(1.0f), - native_(false) { -} - -DisplayInfo::~DisplayInfo() { -} - -void DisplayInfo::Copy(const DisplayInfo& native_info) { - DCHECK(id_ == native_info.id_); - name_ = native_info.name_; - has_overscan_ = native_info.has_overscan_; - - DCHECK(!native_info.bounds_in_native_.IsEmpty()); - bounds_in_native_ = native_info.bounds_in_native_; - size_in_pixel_ = native_info.size_in_pixel_; - device_scale_factor_ = native_info.device_scale_factor_; - resolutions_ = native_info.resolutions_; - touch_support_ = native_info.touch_support_; - - // Copy overscan_insets_in_dip_ if it's not empty. This is for test - // cases which use "/o" annotation which sets the overscan inset - // to native, and that overscan has to be propagated. This does not - // happen on the real environment. - if (!native_info.overscan_insets_in_dip_.empty()) - overscan_insets_in_dip_ = native_info.overscan_insets_in_dip_; - - // Rotation_ and ui_scale_ are given by preference, or unit - // tests. Don't copy if this native_info came from - // DisplayChangeObserver. - if (!native_info.native()) { - rotation_ = native_info.rotation_; - configured_ui_scale_ = native_info.configured_ui_scale_; - } - // Don't copy insets as it may be given by preference. |rotation_| - // is treated as a native so that it can be specified in - // |CreateFromSpec|. -} - -void DisplayInfo::SetBounds(const gfx::Rect& new_bounds_in_native) { - bounds_in_native_ = new_bounds_in_native; - size_in_pixel_ = new_bounds_in_native.size(); - UpdateDisplaySize(); -} - -float DisplayInfo::GetEffectiveUIScale() const { - if (device_scale_factor_ == 2.0f && configured_ui_scale_ == 2.0f) - return 1.0f; - return configured_ui_scale_; -} - -void DisplayInfo::UpdateDisplaySize() { - size_in_pixel_ = bounds_in_native_.size(); - if (!overscan_insets_in_dip_.empty()) { - gfx::Insets insets_in_pixel = - overscan_insets_in_dip_.Scale(device_scale_factor_); - size_in_pixel_.Enlarge(-insets_in_pixel.width(), -insets_in_pixel.height()); - } else { - overscan_insets_in_dip_.Set(0, 0, 0, 0); - } - - if (rotation_ == gfx::Display::ROTATE_90 || - rotation_ == gfx::Display::ROTATE_270) - size_in_pixel_.SetSize(size_in_pixel_.height(), size_in_pixel_.width()); - gfx::SizeF size_f(size_in_pixel_); - size_f.Scale(GetEffectiveUIScale()); - size_in_pixel_ = gfx::ToFlooredSize(size_f); -} - -void DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) { - overscan_insets_in_dip_ = insets_in_dip; -} - -gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const { - return overscan_insets_in_dip_.Scale(device_scale_factor_); -} - -std::string DisplayInfo::ToString() const { - int rotation_degree = static_cast<int>(rotation_) * 90; - return base::StringPrintf( - "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, " - "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s", - static_cast<long long int>(id_), - bounds_in_native_.ToString().c_str(), - size_in_pixel_.ToString().c_str(), - device_scale_factor_, - overscan_insets_in_dip_.ToString().c_str(), - rotation_degree, - configured_ui_scale_, - touch_support_ == gfx::Display::TOUCH_SUPPORT_AVAILABLE ? "yes" : - touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE ? "no" : - "unknown"); -} - -std::string DisplayInfo::ToFullString() const { - std::string resolutions_str; - std::vector<Resolution>::const_iterator iter = resolutions_.begin(); - for (; iter != resolutions_.end(); ++iter) { - if (!resolutions_str.empty()) - resolutions_str += ","; - resolutions_str += iter->size.ToString(); - if (iter->interlaced) - resolutions_str += "(i)"; - } - return ToString() + ", resolutions=" + resolutions_str; -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_info.h b/chromium/ash/display/display_info.h deleted file mode 100644 index 69b83dce53d..00000000000 --- a/chromium/ash/display/display_info.h +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) 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_DISPLAY_DISPLAY_INFO_H_ -#define ASH_DISPLAY_DISPLAY_INFO_H_ - -#include <string> -#include <vector> - -#include "ash/ash_export.h" -#include "ui/gfx/display.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/rect.h" - -namespace ash { -namespace internal { - -// A struct that represents the display's resolution and -// interlaced info. -struct ASH_EXPORT Resolution { - Resolution(const gfx::Size& size, bool interlaced); - - gfx::Size size; - bool interlaced; -}; - -// DisplayInfo contains metadata for each display. This is used to -// create |gfx::Display| as well as to maintain extra infomation -// to manage displays in ash environment. -// This class is intentionally made copiable. -class ASH_EXPORT DisplayInfo { - public: - // Creates a DisplayInfo from string spec. 100+200-1440x800 creates display - // whose size is 1440x800 at the location (100, 200) in host coordinates. - // The format is - // - // [origin-]widthxheight[*device_scale_factor][#resolutions list] - // [/<properties>][@ui-scale] - // - // where [] are optional: - // - |origin| is given in x+y- format. - // - |device_scale_factor| is either 2 or 1 (or empty). - // - properties can combination of 'o', which adds default overscan insets - // (5%), and one rotation property where 'r' is 90 degree clock-wise - // (to the 'r'ight) 'u' is 180 degrees ('u'pside-down) and 'l' is - // 270 degrees (to the 'l'eft). - // - ui-scale is floating value, e.g. @1.5 or @1.25. - // - |resolution list| is the list of size that is given in - // |width x height| separated by '|'. - // - // A couple of examples: - // "100x100" - // 100x100 window at 0,0 origin. 1x device scale factor. no overscan. - // no rotation. 1.0 ui scale. - // "5+5-300x200*2" - // 300x200 window at 5,5 origin. 2x device scale factor. - // no overscan, no rotation. 1.0 ui scale. - // "300x200/ol" - // 300x200 window at 0,0 origin. 1x device scale factor. - // with 5% overscan. rotated to left (90 degree counter clockwise). - // 1.0 ui scale. - // "10+20-300x200/u@1.5" - // 300x200 window at 10,20 origin. 1x device scale factor. - // no overscan. flipped upside-down (180 degree) and 1.5 ui scale. - // "200x100#300x200|200x100|100x100" - // 200x100 window at 0,0 origin, with 3 possible resolutions, - // 300x200, 200x100 and 100x100. - static DisplayInfo CreateFromSpec(const std::string& spec); - - // Creates a DisplayInfo from string spec using given |id|. - static DisplayInfo CreateFromSpecWithID(const std::string& spec, - int64 id); - - DisplayInfo(); - DisplayInfo(int64 id, const std::string& name, bool has_overscan); - ~DisplayInfo(); - - int64 id() const { return id_; } - - // The name of the display. - const std::string& name() const { return name_; } - - // True if the display EDID has the overscan flag. This does not create the - // actual overscan automatically, but used in the message. - bool has_overscan() const { return has_overscan_; } - - void set_rotation(gfx::Display::Rotation rotation) { rotation_ = rotation; } - gfx::Display::Rotation rotation() const { return rotation_; } - - void set_touch_support(gfx::Display::TouchSupport support) { - touch_support_ = support; - } - gfx::Display::TouchSupport touch_support() const { return touch_support_; } - - // Gets/Sets the device scale factor of the display. - float device_scale_factor() const { return device_scale_factor_; } - void set_device_scale_factor(float scale) { device_scale_factor_ = scale; } - - // The native bounds for the display. The size of this can be - // different from the |size_in_pixel| when overscan insets are set - // and/or |configured_ui_scale_| is set. - const gfx::Rect bounds_in_native() const { - return bounds_in_native_; - } - - // The size for the display in pixels. - const gfx::Size& size_in_pixel() const { return size_in_pixel_; } - - // The overscan insets for the display in DIP. - const gfx::Insets& overscan_insets_in_dip() const { - return overscan_insets_in_dip_; - } - - // Sets/gets configured ui scale. This can be different from the ui - // scale actually used when the scale is 2.0 and DSF is 2.0. - // (the effective ui scale is 1.0 in this case). - float configured_ui_scale() const { return configured_ui_scale_; } - void set_configured_ui_scale(float scale) { configured_ui_scale_ = scale; } - - // Returns the ui scale used for the device scale factor. This - // return 1.0f if the ui scale and dsf are both set to 2.0. - float GetEffectiveUIScale() const; - - // Copy the display info except for fields that can be modified by a - // user (|rotation_| and |configured_ui_scale_|). |rotation_| and - // |configured_ui_scale_| are copied when the |another_info| isn't native one. - void Copy(const DisplayInfo& another_info); - - // Update the |bounds_in_native_| and |size_in_pixel_| using - // given |bounds_in_native|. - void SetBounds(const gfx::Rect& bounds_in_native); - - // Update the |bounds_in_native| according to the current overscan - // and rotation settings. - void UpdateDisplaySize(); - - // Sets/Clears the overscan insets. - void SetOverscanInsets(const gfx::Insets& insets_in_dip); - gfx::Insets GetOverscanInsetsInPixel() const; - - void set_native(bool native) { native_ = native; } - bool native() const { return native_; } - - const std::vector<Resolution>& resolutions() const { - return resolutions_; - } - void set_resolutions(std::vector<Resolution>& resolution) { - resolutions_.swap(resolution); - } - - // Returns a string representation of the DisplayInfo - // excluding resolutions. - std::string ToString() const; - - // Returns a string representation of the DisplayInfo - // including resolutions. - std::string ToFullString() const; - - private: - int64 id_; - std::string name_; - bool has_overscan_; - gfx::Display::Rotation rotation_; - gfx::Display::TouchSupport touch_support_; - - // This specifies the device's pixel density. (For example, a - // display whose DPI is higher than the threshold is considered to have - // device_scale_factor = 2.0 on Chrome OS). This is used by the - // grapics layer to choose and draw appropriate images and scale - // layers properly. - float device_scale_factor_; - gfx::Rect bounds_in_native_; - - // The size of the display in use. The size can be different from the size - // of |bounds_in_native_| if the display has overscan insets and/or rotation. - gfx::Size size_in_pixel_; - gfx::Insets overscan_insets_in_dip_; - - // The pixel scale of the display. This is used to simply expand (or - // shrink) the desktop over the native display resolution (useful in - // HighDPI display). Note that this should not be confused with the - // device scale factor, which specifies the pixel density of the - // display. The actuall scale value to be used depends on the device - // scale factor. See |GetEffectiveScaleFactor()|. - float configured_ui_scale_; - - // True if this comes from native platform (DisplayChangeObserver). - bool native_; - - // The list of resolutions supported by this display. - std::vector<Resolution> resolutions_; -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_INFO_H_ diff --git a/chromium/ash/display/display_info_unittest.cc b/chromium/ash/display/display_info_unittest.cc deleted file mode 100644 index 9faa0aa9863..00000000000 --- a/chromium/ash/display/display_info_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 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/display/display_info.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace ash { -namespace internal { - -typedef testing::Test DisplayInfoTest; - -TEST_F(DisplayInfoTest, CreateFromSpec) { - DisplayInfo info = DisplayInfo::CreateFromSpecWithID("200x100", 10); - EXPECT_EQ(10, info.id()); - EXPECT_EQ("0,0 200x100", info.bounds_in_native().ToString()); - EXPECT_EQ("200x100", info.size_in_pixel().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_0, info.rotation()); - EXPECT_EQ("0,0,0,0", info.overscan_insets_in_dip().ToString()); - EXPECT_EQ(1.0f, info.configured_ui_scale()); - - info = DisplayInfo::CreateFromSpecWithID("10+20-300x400*2/o", 10); - EXPECT_EQ("10,20 300x400", info.bounds_in_native().ToString()); - EXPECT_EQ("288x380", info.size_in_pixel().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_0, info.rotation()); - EXPECT_EQ("5,3,5,3", info.overscan_insets_in_dip().ToString()); - - info = DisplayInfo::CreateFromSpecWithID("10+20-300x400*2/ob", 10); - EXPECT_EQ("10,20 300x400", info.bounds_in_native().ToString()); - EXPECT_EQ("288x380", info.size_in_pixel().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_0, info.rotation()); - EXPECT_EQ("5,3,5,3", info.overscan_insets_in_dip().ToString()); - - info = DisplayInfo::CreateFromSpecWithID("10+20-300x400*2/or", 10); - EXPECT_EQ("10,20 300x400", info.bounds_in_native().ToString()); - EXPECT_EQ("380x288", info.size_in_pixel().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_90, info.rotation()); - // TODO(oshima): This should be rotated too. Fix this. - EXPECT_EQ("5,3,5,3", info.overscan_insets_in_dip().ToString()); - - info = DisplayInfo::CreateFromSpecWithID("10+20-300x400*2/l@1.5", 10); - EXPECT_EQ("10,20 300x400", info.bounds_in_native().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_270, info.rotation()); - EXPECT_EQ(1.5f, info.configured_ui_scale()); - - info = DisplayInfo::CreateFromSpecWithID( - "200x200#300x200|200x200|100x100", 10); - EXPECT_EQ("0,0 200x200", info.bounds_in_native().ToString()); - EXPECT_EQ(3u, info.resolutions().size()); - EXPECT_EQ("300x200", info.resolutions()[0].size.ToString()); - EXPECT_EQ("200x200", info.resolutions()[1].size.ToString()); - EXPECT_EQ("100x100", info.resolutions()[2].size.ToString()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_layout.cc b/chromium/ash/display/display_layout.cc deleted file mode 100644 index a733e762a82..00000000000 --- a/chromium/ash/display/display_layout.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 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/display/display_layout.h" - -#include "ash/display/display_pref_util.h" -#include "base/json/json_value_converter.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" -#include "base/strings/stringprintf.h" -#include "base/values.h" -#include "ui/gfx/display.h" - -namespace ash { -namespace { - -// The maximum value for 'offset' in DisplayLayout in case of outliers. Need -// to change this value in case to support even larger displays. -const int kMaxValidOffset = 10000; - -// Persistent key names -const char kPositionKey[] = "position"; -const char kOffsetKey[] = "offset"; -const char kMirroredKey[] = "mirrored"; -const char kPrimaryIdKey[] = "primary-id"; - -typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap; - -const PositionToStringMap* GetPositionToStringMap() { - static const PositionToStringMap* map = CreateToStringMap( - DisplayLayout::TOP, "top", - DisplayLayout::BOTTOM, "bottom", - DisplayLayout::RIGHT, "right", - DisplayLayout::LEFT, "left"); - return map; -} - -bool GetPositionFromString(const base::StringPiece& position, - DisplayLayout::Position* field) { - if (ReverseFind(GetPositionToStringMap(), position, field)) - return true; - LOG(ERROR) << "Invalid position value:" << position; - return false; -} - -std::string GetStringFromPosition(DisplayLayout::Position position) { - const PositionToStringMap* map = GetPositionToStringMap(); - PositionToStringMap::const_iterator iter = map->find(position); - return iter != map->end() ? iter->second : std::string("unknown"); -} - -bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) { - return base::StringToInt64(position, field); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// DisplayLayout - -// static -DisplayLayout DisplayLayout::FromInts(int position, int offsets) { - return DisplayLayout(static_cast<Position>(position), offsets); -} - -DisplayLayout::DisplayLayout() - : position(RIGHT), - offset(0), - mirrored(false), - primary_id(gfx::Display::kInvalidDisplayID) { -} - -DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) - : position(position), - offset(offset), - mirrored(false), - primary_id(gfx::Display::kInvalidDisplayID) { - DCHECK_LE(TOP, position); - DCHECK_GE(LEFT, position); - - // Set the default value to |position| in case position is invalid. DCHECKs - // above doesn't stop in Release builds. - if (TOP > position || LEFT < position) - this->position = RIGHT; - - DCHECK_GE(kMaxValidOffset, abs(offset)); -} - -DisplayLayout DisplayLayout::Invert() const { - Position inverted_position = RIGHT; - switch (position) { - case TOP: - inverted_position = BOTTOM; - break; - case BOTTOM: - inverted_position = TOP; - break; - case RIGHT: - inverted_position = LEFT; - break; - case LEFT: - inverted_position = RIGHT; - break; - } - DisplayLayout ret = DisplayLayout(inverted_position, -offset); - ret.primary_id = primary_id; - return ret; -} - -// static -bool DisplayLayout::ConvertFromValue(const base::Value& value, - DisplayLayout* layout) { - base::JSONValueConverter<DisplayLayout> converter; - return converter.Convert(value, layout); -} - -// static -bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, - base::Value* value) { - base::DictionaryValue* dict_value = NULL; - if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) - return false; - - const std::string position_str = GetStringFromPosition(layout.position); - dict_value->SetString(kPositionKey, position_str); - dict_value->SetInteger(kOffsetKey, layout.offset); - dict_value->SetBoolean(kMirroredKey, layout.mirrored); - dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); - return true; -} - -std::string DisplayLayout::ToString() const { - const std::string position_str = GetStringFromPosition(position); - return base::StringPrintf( - "%s, %d%s", - position_str.c_str(), offset, mirrored ? ", mirrored" : ""); -} - -// static -void DisplayLayout::RegisterJSONConverter( - base::JSONValueConverter<DisplayLayout>* converter) { - converter->RegisterCustomField<Position>( - kPositionKey, &DisplayLayout::position, &GetPositionFromString); - converter->RegisterIntField(kOffsetKey, &DisplayLayout::offset); - converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored); - converter->RegisterCustomField<int64>( - kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString); -} - -} // namespace ash diff --git a/chromium/ash/display/display_layout.h b/chromium/ash/display/display_layout.h deleted file mode 100644 index dc322087c2f..00000000000 --- a/chromium/ash/display/display_layout.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 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_DISPLAY_DISPLAY_LAYOUT_H_ -#define ASH_DISPLAY_DISPLAY_LAYOUT_H_ - -#include <map> -#include <string> - -#include "ash/ash_export.h" -#include "base/basictypes.h" -#include "base/compiler_specific.h" - -namespace base { -class Value; -template <typename T> class JSONValueConverter; -} - -namespace ash { - -typedef std::pair<int64, int64> DisplayIdPair; - -struct ASH_EXPORT DisplayLayout { - // Layout options where the secondary display should be positioned. - enum Position { - TOP, - RIGHT, - BOTTOM, - LEFT - }; - - // Factory method to create DisplayLayout from ints. The |mirrored| is - // set to false and |primary_id| is set to gfx::Display::kInvalidDisplayId. - // Used for persistence and webui. - static DisplayLayout FromInts(int position, int offsets); - - DisplayLayout(); - DisplayLayout(Position position, int offset); - - // Returns an inverted display layout. - DisplayLayout Invert() const WARN_UNUSED_RESULT; - - // Converter functions to/from base::Value. - static bool ConvertFromValue(const base::Value& value, DisplayLayout* layout); - static bool ConvertToValue(const DisplayLayout& layout, base::Value* value); - - // This method is used by base::JSONValueConverter, you don't need to call - // this directly. Instead consider using converter functions above. - static void RegisterJSONConverter( - base::JSONValueConverter<DisplayLayout>* converter); - - Position position; - - // The offset of the position of the secondary display. The offset is - // based on the top/left edge of the primary display. - int offset; - - // True if displays are mirrored. - bool mirrored; - - // The id of the display used as a primary display. - int64 primary_id; - - // Returns string representation of the layout for debugging/testing. - std::string ToString() const; -}; - -} // namespace ash - -#endif diff --git a/chromium/ash/display/display_layout_store.cc b/chromium/ash/display/display_layout_store.cc deleted file mode 100644 index 63b1d60b2c8..00000000000 --- a/chromium/ash/display/display_layout_store.cc +++ /dev/null @@ -1,94 +0,0 @@ -// 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 <stdio.h> - -#include "ash/ash_switches.h" -#include "ash/display/display_layout_store.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "ui/gfx/display.h" - -namespace ash { -namespace internal { - -DisplayLayoutStore::DisplayLayoutStore() { - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { - std::string value = command_line->GetSwitchValueASCII( - switches::kAshSecondaryDisplayLayout); - char layout; - int offset = 0; - if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) { - if (layout == 't') - default_display_layout_.position = DisplayLayout::TOP; - else if (layout == 'b') - default_display_layout_.position = DisplayLayout::BOTTOM; - else if (layout == 'r') - default_display_layout_.position = DisplayLayout::RIGHT; - else if (layout == 'l') - default_display_layout_.position = DisplayLayout::LEFT; - default_display_layout_.offset = offset; - } - } -} - -DisplayLayoutStore::~DisplayLayoutStore() { -} - -void DisplayLayoutStore::SetDefaultDisplayLayout(const DisplayLayout& layout) { - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) - default_display_layout_ = layout; -} - -void DisplayLayoutStore::RegisterLayoutForDisplayIdPair( - int64 id1, - int64 id2, - const DisplayLayout& layout) { - paired_layouts_[std::make_pair(id1, id2)] = layout; -} - -DisplayLayout DisplayLayoutStore::GetRegisteredDisplayLayout( - const DisplayIdPair& pair) { - std::map<DisplayIdPair, DisplayLayout>::const_iterator iter = - paired_layouts_.find(pair); - return - iter != paired_layouts_.end() ? iter->second : CreateDisplayLayout(pair); -} - -DisplayLayout DisplayLayoutStore::ComputeDisplayLayoutForDisplayIdPair( - const DisplayIdPair& pair) { - DisplayLayout layout = GetRegisteredDisplayLayout(pair); - DCHECK_NE(layout.primary_id, gfx::Display::kInvalidDisplayID); - // Invert if the primary was swapped. If mirrored, first is always - // primary. - return (layout.primary_id == gfx::Display::kInvalidDisplayID || - pair.first == layout.primary_id) ? layout : layout.Invert(); -} - -void DisplayLayoutStore::UpdateMirrorStatus(const DisplayIdPair& pair, - bool mirrored) { - if (paired_layouts_.find(pair) == paired_layouts_.end()) - CreateDisplayLayout(pair); - paired_layouts_[pair].mirrored = mirrored; -} - -void DisplayLayoutStore::UpdatePrimaryDisplayId(const DisplayIdPair& pair, - int64 display_id) { - if (paired_layouts_.find(pair) == paired_layouts_.end()) - CreateDisplayLayout(pair); - paired_layouts_[pair].primary_id = display_id; -} - -DisplayLayout DisplayLayoutStore::CreateDisplayLayout( - const DisplayIdPair& pair) { - DisplayLayout layout = default_display_layout_; - layout.primary_id = pair.first; - paired_layouts_[pair] = layout; - return layout; -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_layout_store.h b/chromium/ash/display/display_layout_store.h deleted file mode 100644 index 67c3c2e523c..00000000000 --- a/chromium/ash/display/display_layout_store.h +++ /dev/null @@ -1,69 +0,0 @@ -// 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_DISPLAY_DISPLAY_LAYOUT_STORE_H_ -#define ASH_DISPLAY_DISPLAY_LAYOUT_STORE_H_ - -#include <map> - -#include "ash/ash_export.h" -#include "ash/display/display_layout.h" - -namespace ash { -namespace internal { - -class ASH_EXPORT DisplayLayoutStore { - public: - DisplayLayoutStore(); - ~DisplayLayoutStore(); - - const DisplayLayout& default_display_layout() const { - return default_display_layout_; - } - void SetDefaultDisplayLayout(const DisplayLayout& layout); - - // Registeres the display layout info for the specified display(s). - void RegisterLayoutForDisplayIdPair(int64 id1, - int64 id2, - const DisplayLayout& layout); - - // If no layout is registered, it creatas new layout using - // |default_display_layout_|. - DisplayLayout GetRegisteredDisplayLayout(const DisplayIdPair& pair); - - // Returns the display layout for the display id pair - // with display swapping applied. That is, this returns - // flipped layout if the displays are swapped. - DisplayLayout ComputeDisplayLayoutForDisplayIdPair( - const DisplayIdPair& display_pair); - - // Update the mirrored flag in the display layout for - // |display_pair|. This creates new display layout if no layout is - // registered for |display_pair|. - void UpdateMirrorStatus(const DisplayIdPair& display_pair, - bool mirrored); - - // Update the |primary_id| in the display layout for - // |display_pair|. This creates new display layout if no layout is - // registered for |display_pair|. - void UpdatePrimaryDisplayId(const DisplayIdPair& display_pair, - int64 display_id); - - private: - // Creates new layout for display pair from |default_display_layout_|. - DisplayLayout CreateDisplayLayout(const DisplayIdPair& display_pair); - - // The default display layout. - DisplayLayout default_display_layout_; - - // Display layout per pair of devices. - std::map<DisplayIdPair, DisplayLayout> paired_layouts_; - - DISALLOW_COPY_AND_ASSIGN(DisplayLayoutStore); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_LAYOUT_STORE_H_ diff --git a/chromium/ash/display/display_manager.cc b/chromium/ash/display/display_manager.cc deleted file mode 100644 index 0377484bede..00000000000 --- a/chromium/ash/display/display_manager.cc +++ /dev/null @@ -1,1048 +0,0 @@ -// Copyright (c) 2012 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/display/display_manager.h" - -#include <cmath> -#include <set> -#include <string> -#include <vector> - -#include "ash/ash_switches.h" -#include "ash/display/display_layout_store.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "base/auto_reset.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "grit/ash_strings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/display.h" -#include "ui/gfx/rect.h" -#include "ui/gfx/screen.h" -#include "ui/gfx/size_conversions.h" - -#if defined(USE_X11) -#include "ui/base/x/x11_util.h" -#endif - -#if defined(OS_CHROMEOS) -#include "ash/display/output_configurator_animation.h" -#include "base/sys_info.h" -#include "chromeos/display/output_configurator.h" -#endif - -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif - -namespace ash { -namespace internal { -typedef std::vector<gfx::Display> DisplayList; -typedef std::vector<DisplayInfo> DisplayInfoList; - -namespace { - -// The number of pixels to overlap between the primary and secondary displays, -// in case that the offset value is too large. -const int kMinimumOverlapForInvalidOffset = 100; - -// List of value UI Scale values. Scales for 2x are equivalent to 640, -// 800, 1024, 1280, 1440, 1600 and 1920 pixel width respectively on -// 2560 pixel width 2x density display. Please see crbug.com/233375 -// for the full list of resolutions. -const float kUIScalesFor2x[] = - {0.5f, 0.625f, 0.8f, 1.0f, 1.125f, 1.25f, 1.5f, 2.0f}; -const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f }; -const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f }; - -struct DisplaySortFunctor { - bool operator()(const gfx::Display& a, const gfx::Display& b) { - return a.id() < b.id(); - } -}; - -struct DisplayInfoSortFunctor { - bool operator()(const DisplayInfo& a, const DisplayInfo& b) { - return a.id() < b.id(); - } -}; - -struct ResolutionMatcher { - ResolutionMatcher(const gfx::Size& size) : size(size) {} - bool operator()(const Resolution& resolution) { - return resolution.size == size; - } - gfx::Size size; -}; - -struct ScaleComparator { - ScaleComparator(float s) : scale(s) {} - - bool operator()(float s) const { - const float kEpsilon = 0.0001f; - return std::abs(scale - s) < kEpsilon; - } - float scale; -}; - -gfx::Display& GetInvalidDisplay() { - static gfx::Display* invalid_display = new gfx::Display(); - return *invalid_display; -} - -void MaybeInitInternalDisplay(int64 id) { - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) - gfx::Display::SetInternalDisplayId(id); -} - -// Scoped objects used to either create or close the non desktop window -// at specific timing. -class NonDesktopDisplayUpdater { - public: - NonDesktopDisplayUpdater(DisplayManager* manager, - DisplayManager::Delegate* delegate) - : manager_(manager), - delegate_(delegate), - enabled_(manager_->second_display_mode() != DisplayManager::EXTENDED && - manager_->non_desktop_display().is_valid()) { - } - - ~NonDesktopDisplayUpdater() { - if (!delegate_) - return; - - if (enabled_) { - DisplayInfo display_info = manager_->GetDisplayInfo( - manager_->non_desktop_display().id()); - delegate_->CreateOrUpdateNonDesktopDisplay(display_info); - } else { - delegate_->CloseNonDesktopDisplay(); - } - } - - bool enabled() const { return enabled_; } - - private: - DisplayManager* manager_; - DisplayManager::Delegate* delegate_; - bool enabled_; - DISALLOW_COPY_AND_ASSIGN(NonDesktopDisplayUpdater); -}; - -} // namespace - -using std::string; -using std::vector; - -DisplayManager::DisplayManager() - : delegate_(NULL), - layout_store_(new DisplayLayoutStore), - first_display_id_(gfx::Display::kInvalidDisplayID), - num_connected_displays_(0), - force_bounds_changed_(false), - change_display_upon_host_resize_(false), - second_display_mode_(EXTENDED), - mirrored_display_id_(gfx::Display::kInvalidDisplayID) { -#if defined(OS_CHROMEOS) - change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); -#endif -} - -DisplayManager::~DisplayManager() { -} - -// static -std::vector<float> DisplayManager::GetScalesForDisplay( - const DisplayInfo& info) { - std::vector<float> ret; - if (info.device_scale_factor() == 2.0f) { - ret.assign(kUIScalesFor2x, kUIScalesFor2x + arraysize(kUIScalesFor2x)); - return ret; - } - switch (info.bounds_in_native().width()) { - case 1280: - ret.assign(kUIScalesFor1280, - kUIScalesFor1280 + arraysize(kUIScalesFor1280)); - break; - case 1366: - ret.assign(kUIScalesFor1366, - kUIScalesFor1366 + arraysize(kUIScalesFor1366)); - break; - default: - ret.assign(kUIScalesFor1280, - kUIScalesFor1280 + arraysize(kUIScalesFor1280)); -#if defined(OS_CHROMEOS) - if (base::SysInfo::IsRunningOnChromeOS()) - NOTREACHED() << "Unknown resolution:" << info.ToString(); -#endif - } - return ret; -} - -// static -float DisplayManager::GetNextUIScale(const DisplayInfo& info, bool up) { - float scale = info.configured_ui_scale(); - std::vector<float> scales = GetScalesForDisplay(info); - for (size_t i = 0; i < scales.size(); ++i) { - if (ScaleComparator(scales[i])(scale)) { - if (up && i != scales.size() - 1) - return scales[i + 1]; - if (!up && i != 0) - return scales[i - 1]; - return scales[i]; - } - } - // Fallback to 1.0f if the |scale| wasn't in the list. - return 1.0f; -} - -bool DisplayManager::InitFromCommandLine() { - DisplayInfoList info_list; - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kAshHostWindowBounds)) - return false; - const string size_str = - command_line->GetSwitchValueASCII(switches::kAshHostWindowBounds); - vector<string> parts; - base::SplitString(size_str, ',', &parts); - for (vector<string>::const_iterator iter = parts.begin(); - iter != parts.end(); ++iter) { - info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); - } - MaybeInitInternalDisplay(info_list[0].id()); - if (info_list.size() > 1 && - command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { - SetSecondDisplayMode(MIRRORING); - } - OnNativeDisplaysChanged(info_list); - return true; -} - -void DisplayManager::InitDefaultDisplay() { - DisplayInfoList info_list; - info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); - MaybeInitInternalDisplay(info_list[0].id()); - OnNativeDisplaysChanged(info_list); -} - -// static -void DisplayManager::UpdateDisplayBoundsForLayoutById( - const DisplayLayout& layout, - const gfx::Display& primary_display, - int64 secondary_display_id) { - DCHECK_NE(gfx::Display::kInvalidDisplayID, secondary_display_id); - UpdateDisplayBoundsForLayout( - layout, primary_display, - Shell::GetInstance()->display_manager()-> - FindDisplayForId(secondary_display_id)); -} - -bool DisplayManager::IsActiveDisplay(const gfx::Display& display) const { - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - if ((*iter).id() == display.id()) - return true; - } - return false; -} - -bool DisplayManager::HasInternalDisplay() const { - return gfx::Display::InternalDisplayId() != gfx::Display::kInvalidDisplayID; -} - -bool DisplayManager::IsInternalDisplayId(int64 id) const { - return gfx::Display::InternalDisplayId() == id; -} - -DisplayLayout DisplayManager::GetCurrentDisplayLayout() { - DCHECK_EQ(2U, num_connected_displays()); - // Invert if the primary was swapped. - if (num_connected_displays() > 1) { - DisplayIdPair pair = GetCurrentDisplayIdPair(); - return layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); - } - NOTREACHED() << "DisplayLayout is requested for single display"; - // On release build, just fallback to default instead of blowing up. - DisplayLayout layout = - layout_store_->default_display_layout(); - layout.primary_id = displays_[0].id(); - return layout; -} - -DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { - if (IsMirrored()) { - if (software_mirroring_enabled()) { - CHECK_EQ(2u, num_connected_displays()); - // This comment is to make it easy to distinguish the crash - // between two checks. - CHECK_EQ(1u, displays_.size()); - } - return std::make_pair(displays_[0].id(), mirrored_display_id_); - } else { - CHECK_GE(2u, displays_.size()); - int64 id_at_zero = displays_[0].id(); - if (id_at_zero == gfx::Display::InternalDisplayId() || - id_at_zero == first_display_id()) { - return std::make_pair(id_at_zero, displays_[1].id()); - } else { - return std::make_pair(displays_[1].id(), id_at_zero); - } - } -} - -void DisplayManager::SetLayoutForCurrentDisplays( - const DisplayLayout& layout_relative_to_primary) { - DCHECK_EQ(2U, GetNumDisplays()); - if (GetNumDisplays() < 2) - return; - const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); - const DisplayIdPair pair = GetCurrentDisplayIdPair(); - // Invert if the primary was swapped. - DisplayLayout to_set = pair.first == primary.id() ? - layout_relative_to_primary : layout_relative_to_primary.Invert(); - - DisplayLayout current_layout = - layout_store_->GetRegisteredDisplayLayout(pair); - if (to_set.position != current_layout.position || - to_set.offset != current_layout.offset) { - to_set.primary_id = primary.id(); - layout_store_->RegisterLayoutForDisplayIdPair( - pair.first, pair.second, to_set); - if (delegate_) - delegate_->PreDisplayConfigurationChange(false); - // PreDisplayConfigurationChange(false); - // TODO(oshima): Call UpdateDisplays instead. - const DisplayLayout layout = GetCurrentDisplayLayout(); - UpdateDisplayBoundsForLayoutById( - layout, primary, - ScreenAsh::GetSecondaryDisplay().id()); - - //UpdateCurrentDisplayBoundsForLayout(); - // Primary's bounds stay the same. Just notify bounds change - // on the secondary. - Shell::GetInstance()->screen()->NotifyBoundsChanged( - ScreenAsh::GetSecondaryDisplay()); - if (delegate_) - delegate_->PostDisplayConfigurationChange(); - } -} - -const gfx::Display& DisplayManager::GetDisplayForId(int64 id) const { - gfx::Display* display = - const_cast<DisplayManager*>(this)->FindDisplayForId(id); - return display ? *display : GetInvalidDisplay(); -} - -const gfx::Display& DisplayManager::FindDisplayContainingPoint( - const gfx::Point& point_in_screen) const { - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - const gfx::Display& display = *iter; - if (display.bounds().Contains(point_in_screen)) - return display; - } - return GetInvalidDisplay(); -} - -bool DisplayManager::UpdateWorkAreaOfDisplay(int64 display_id, - const gfx::Insets& insets) { - gfx::Display* display = FindDisplayForId(display_id); - DCHECK(display); - gfx::Rect old_work_area = display->work_area(); - display->UpdateWorkAreaFromInsets(insets); - return old_work_area != display->work_area(); -} - -void DisplayManager::SetOverscanInsets(int64 display_id, - const gfx::Insets& insets_in_dip) { - display_info_[display_id].SetOverscanInsets(insets_in_dip); - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - display_info_list.push_back(GetDisplayInfo(iter->id())); - } - AddMirrorDisplayInfoIfAny(&display_info_list); - UpdateDisplays(display_info_list); -} - -void DisplayManager::SetDisplayRotation(int64 display_id, - gfx::Display::Rotation rotation) { - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - DisplayInfo info = GetDisplayInfo(iter->id()); - if (info.id() == display_id) { - if (info.rotation() == rotation) - return; - info.set_rotation(rotation); - } - display_info_list.push_back(info); - } - AddMirrorDisplayInfoIfAny(&display_info_list); - if (virtual_keyboard_root_window_enabled() && - display_id == non_desktop_display_.id()) { - DisplayInfo info = GetDisplayInfo(display_id); - info.set_rotation(rotation); - display_info_list.push_back(info); - } - UpdateDisplays(display_info_list); -} - -void DisplayManager::SetDisplayUIScale(int64 display_id, - float ui_scale) { - if (!IsDisplayUIScalingEnabled() || - gfx::Display::InternalDisplayId() != display_id) { - return; - } - - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - DisplayInfo info = GetDisplayInfo(iter->id()); - if (info.id() == display_id) { - if (info.configured_ui_scale() == ui_scale) - return; - std::vector<float> scales = GetScalesForDisplay(info); - ScaleComparator comparator(ui_scale); - if (std::find_if(scales.begin(), scales.end(), comparator) == - scales.end()) { - return; - } - info.set_configured_ui_scale(ui_scale); - } - display_info_list.push_back(info); - } - AddMirrorDisplayInfoIfAny(&display_info_list); - UpdateDisplays(display_info_list); -} - -void DisplayManager::SetDisplayResolution(int64 display_id, - const gfx::Size& resolution) { - DCHECK_NE(gfx::Display::InternalDisplayId(), display_id); - if (gfx::Display::InternalDisplayId() == display_id) - return; - const DisplayInfo& display_info = GetDisplayInfo(display_id); - const std::vector<Resolution>& resolutions = display_info.resolutions(); - DCHECK_NE(0u, resolutions.size()); - std::vector<Resolution>::const_iterator iter = - std::find_if(resolutions.begin(), - resolutions.end(), - ResolutionMatcher(resolution)); - if (iter == resolutions.end()) { - LOG(WARNING) << "Unsupported resolution was requested:" - << resolution.ToString(); - return; - } else if (iter == resolutions.begin()) { - // The best resolution was set, so forget it. - resolutions_.erase(display_id); - } else { - resolutions_[display_id] = resolution; - } -#if defined(OS_CHROMEOS) && defined(USE_X11) - if (base::SysInfo::IsRunningOnChromeOS()) - Shell::GetInstance()->output_configurator()->ScheduleConfigureOutputs(); -#endif -} - -void DisplayManager::RegisterDisplayProperty( - int64 display_id, - gfx::Display::Rotation rotation, - float ui_scale, - const gfx::Insets* overscan_insets, - const gfx::Size& resolution_in_pixels) { - if (display_info_.find(display_id) == display_info_.end()) { - display_info_[display_id] = - DisplayInfo(display_id, std::string(""), false); - } - - display_info_[display_id].set_rotation(rotation); - // Just in case the preference file was corrupted. - if (0.5f <= ui_scale && ui_scale <= 2.0f) - display_info_[display_id].set_configured_ui_scale(ui_scale); - if (overscan_insets) - display_info_[display_id].SetOverscanInsets(*overscan_insets); - if (!resolution_in_pixels.IsEmpty()) - resolutions_[display_id] = resolution_in_pixels; -} - -bool DisplayManager::GetSelectedResolutionForDisplayId( - int64 id, - gfx::Size* resolution_out) const { - std::map<int64, gfx::Size>::const_iterator iter = - resolutions_.find(id); - if (iter == resolutions_.end()) - return false; - *resolution_out = iter->second; - return true; -} - -bool DisplayManager::IsDisplayUIScalingEnabled() const { - return GetDisplayIdForUIScaling() != gfx::Display::kInvalidDisplayID; -} - -gfx::Insets DisplayManager::GetOverscanInsets(int64 display_id) const { - std::map<int64, DisplayInfo>::const_iterator it = - display_info_.find(display_id); - return (it != display_info_.end()) ? - it->second.overscan_insets_in_dip() : gfx::Insets(); -} - -void DisplayManager::OnNativeDisplaysChanged( - const std::vector<DisplayInfo>& updated_displays) { - if (updated_displays.empty()) { - VLOG(1) << "OnNativeDisplayChanged(0): # of current displays=" - << displays_.size(); - // If the device is booted without display, or chrome is started - // without --ash-host-window-bounds on linux desktop, use the - // default display. - if (displays_.empty()) { - std::vector<DisplayInfo> init_displays; - init_displays.push_back(DisplayInfo::CreateFromSpec(std::string())); - MaybeInitInternalDisplay(init_displays[0].id()); - OnNativeDisplaysChanged(init_displays); - } else { - // Otherwise don't update the displays when all displays are disconnected. - // This happens when: - // - the device is idle and powerd requested to turn off all displays. - // - the device is suspended. (kernel turns off all displays) - // - the internal display's brightness is set to 0 and no external - // display is connected. - // - the internal display's brightness is 0 and external display is - // disconnected. - // The display will be updated when one of displays is turned on, and the - // display list will be updated correctly. - } - return; - } - first_display_id_ = updated_displays[0].id(); - std::set<gfx::Point> origins; - - if (updated_displays.size() == 1) { - VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); - } else { - VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() - << ") [0]=" << updated_displays[0].ToString() - << ", [1]=" << updated_displays[1].ToString(); - } - - bool internal_display_connected = false; - num_connected_displays_ = updated_displays.size(); - mirrored_display_id_ = gfx::Display::kInvalidDisplayID; - non_desktop_display_ = gfx::Display(); - DisplayInfoList new_display_info_list; - for (DisplayInfoList::const_iterator iter = updated_displays.begin(); - iter != updated_displays.end(); - ++iter) { - if (!internal_display_connected) - internal_display_connected = IsInternalDisplayId(iter->id()); - // Mirrored monitors have the same origins. - gfx::Point origin = iter->bounds_in_native().origin(); - if (origins.find(origin) != origins.end()) { - InsertAndUpdateDisplayInfo(*iter); - mirrored_display_id_ = iter->id(); - } else { - origins.insert(origin); - new_display_info_list.push_back(*iter); - } - } - if (HasInternalDisplay() && - !internal_display_connected && - display_info_.find(gfx::Display::InternalDisplayId()) == - display_info_.end()) { - DisplayInfo internal_display_info( - gfx::Display::InternalDisplayId(), - l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME), - false /*Internal display must not have overscan */); - internal_display_info.SetBounds(gfx::Rect(0, 0, 800, 600)); - display_info_[gfx::Display::InternalDisplayId()] = internal_display_info; - } - UpdateDisplays(new_display_info_list); -} - -void DisplayManager::UpdateDisplays() { - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - display_info_list.push_back(GetDisplayInfo(iter->id())); - } - AddMirrorDisplayInfoIfAny(&display_info_list); - UpdateDisplays(display_info_list); -} - -void DisplayManager::UpdateDisplays( - const std::vector<DisplayInfo>& updated_display_info_list) { -#if defined(OS_WIN) - if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - DCHECK_EQ(1u, updated_display_info_list.size()) << - "Multiple display test does not work on Win8 bots. Please " - "skip (don't disable) the test using SupportsMultipleDisplays()"; - } -#endif - - DisplayInfoList new_display_info_list = updated_display_info_list; - std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor()); - std::sort(new_display_info_list.begin(), - new_display_info_list.end(), - DisplayInfoSortFunctor()); - DisplayList removed_displays; - std::vector<size_t> changed_display_indices; - std::vector<size_t> added_display_indices; - - DisplayList::iterator curr_iter = displays_.begin(); - DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); - - DisplayList new_displays; - - // Use the internal display or 1st as the mirror source, then scale - // the root window so that it matches the external display's - // resolution. This is necessary in order for scaling to work while - // mirrored. - int64 non_desktop_display_id = gfx::Display::kInvalidDisplayID; - - if (second_display_mode_ != EXTENDED && new_display_info_list.size() == 2) { - bool zero_is_source = - first_display_id_ == new_display_info_list[0].id() || - gfx::Display::InternalDisplayId() == new_display_info_list[0].id(); - if (second_display_mode_ == MIRRORING) { - mirrored_display_id_ = new_display_info_list[zero_is_source ? 1 : 0].id(); - non_desktop_display_id = mirrored_display_id_; - } else { - // TODO(oshima|bshe): The virtual keyboard is currently assigned to - // the 1st display. - non_desktop_display_id = - new_display_info_list[zero_is_source ? 0 : 1].id(); - } - } - - while (curr_iter != displays_.end() || - new_info_iter != new_display_info_list.end()) { - if (new_info_iter != new_display_info_list.end() && - non_desktop_display_id == new_info_iter->id()) { - DisplayInfo info = *new_info_iter; - info.SetOverscanInsets(gfx::Insets()); - InsertAndUpdateDisplayInfo(info); - non_desktop_display_ = - CreateDisplayFromDisplayInfoById(non_desktop_display_id); - ++new_info_iter; - // Remove existing external dispaly if it is going to be used as - // non desktop. - if (curr_iter != displays_.end() && - curr_iter->id() == non_desktop_display_id) { - removed_displays.push_back(*curr_iter); - ++curr_iter; - } - continue; - } - - if (curr_iter == displays_.end()) { - // more displays in new list. - added_display_indices.push_back(new_displays.size()); - InsertAndUpdateDisplayInfo(*new_info_iter); - new_displays.push_back( - CreateDisplayFromDisplayInfoById(new_info_iter->id())); - ++new_info_iter; - } else if (new_info_iter == new_display_info_list.end()) { - // more displays in current list. - removed_displays.push_back(*curr_iter); - ++curr_iter; - } else if (curr_iter->id() == new_info_iter->id()) { - const gfx::Display& current_display = *curr_iter; - // Copy the info because |CreateDisplayFromInfo| updates the instance. - const DisplayInfo current_display_info = - GetDisplayInfo(current_display.id()); - InsertAndUpdateDisplayInfo(*new_info_iter); - gfx::Display new_display = - CreateDisplayFromDisplayInfoById(new_info_iter->id()); - const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id()); - - bool host_window_bounds_changed = - current_display_info.bounds_in_native() != - new_display_info.bounds_in_native(); - - if (force_bounds_changed_ || - host_window_bounds_changed || - (current_display.device_scale_factor() != - new_display.device_scale_factor()) || - (current_display_info.size_in_pixel() != - new_display.GetSizeInPixel()) || - (current_display.rotation() != new_display.rotation())) { - - changed_display_indices.push_back(new_displays.size()); - } - - new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); - new_displays.push_back(new_display); - ++curr_iter; - ++new_info_iter; - } else if (curr_iter->id() < new_info_iter->id()) { - // more displays in current list between ids, which means it is deleted. - removed_displays.push_back(*curr_iter); - ++curr_iter; - } else { - // more displays in new list between ids, which means it is added. - added_display_indices.push_back(new_displays.size()); - InsertAndUpdateDisplayInfo(*new_info_iter); - new_displays.push_back( - CreateDisplayFromDisplayInfoById(new_info_iter->id())); - ++new_info_iter; - } - } - - scoped_ptr<NonDesktopDisplayUpdater> non_desktop_display_updater( - new NonDesktopDisplayUpdater(this, delegate_)); - - // Do not update |displays_| if there's nothing to be updated. Without this, - // it will not update the display layout, which causes the bug - // http://crbug.com/155948. - if (changed_display_indices.empty() && added_display_indices.empty() && - removed_displays.empty()) { - return; - } - // Clear focus if the display has been removed, but don't clear focus if - // the destkop has been moved from one display to another - // (mirror -> docked, docked -> single internal). - bool clear_focus = - !removed_displays.empty() && - !(removed_displays.size() == 1 && added_display_indices.size() == 1); - if (delegate_) - delegate_->PreDisplayConfigurationChange(clear_focus); - - size_t updated_index; - if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) && - std::find(added_display_indices.begin(), - added_display_indices.end(), - updated_index) == added_display_indices.end() && - std::find(changed_display_indices.begin(), - changed_display_indices.end(), - updated_index) == changed_display_indices.end()) { - changed_display_indices.push_back(updated_index); - } - - displays_ = new_displays; - - base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); - - // Temporarily add displays to be removed because display object - // being removed are accessed during shutting down the root. - displays_.insert(displays_.end(), removed_displays.begin(), - removed_displays.end()); - - for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); - iter != removed_displays.rend(); ++iter) { - Shell::GetInstance()->screen()->NotifyDisplayRemoved(displays_.back()); - displays_.pop_back(); - } - // Close the non desktop window here to avoid creating two compositor on - // one display. - if (!non_desktop_display_updater->enabled()) - non_desktop_display_updater.reset(); - for (std::vector<size_t>::iterator iter = added_display_indices.begin(); - iter != added_display_indices.end(); ++iter) { - Shell::GetInstance()->screen()->NotifyDisplayAdded(displays_[*iter]); - } - // Create the non destkop window after all displays are added so that - // it can mirror the display newly added. This can happen when switching - // from dock mode to software mirror mode. - non_desktop_display_updater.reset(); - for (std::vector<size_t>::iterator iter = changed_display_indices.begin(); - iter != changed_display_indices.end(); ++iter) { - Shell::GetInstance()->screen()->NotifyBoundsChanged(displays_[*iter]); - } - if (delegate_) - delegate_->PostDisplayConfigurationChange(); - -#if defined(USE_X11) && defined(OS_CHROMEOS) - if (!changed_display_indices.empty() && base::SysInfo::IsRunningOnChromeOS()) - ui::ClearX11DefaultRootWindow(); -#endif -} - -const gfx::Display& DisplayManager::GetDisplayAt(size_t index) const { - DCHECK_LT(index, displays_.size()); - return displays_[index]; -} - -const gfx::Display& DisplayManager::GetPrimaryDisplayCandidate() const { - if (GetNumDisplays() == 1) - return displays_[0]; - DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout( - GetCurrentDisplayIdPair()); - return GetDisplayForId(layout.primary_id); -} - -size_t DisplayManager::GetNumDisplays() const { - return displays_.size(); -} - -bool DisplayManager::IsMirrored() const { - return mirrored_display_id_ != gfx::Display::kInvalidDisplayID; -} - -const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { - std::map<int64, DisplayInfo>::const_iterator iter = - display_info_.find(display_id); - CHECK(iter != display_info_.end()) << display_id; - return iter->second; -} - -std::string DisplayManager::GetDisplayNameForId(int64 id) { - if (id == gfx::Display::kInvalidDisplayID) - return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); - - std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); - if (iter != display_info_.end() && !iter->second.name().empty()) - return iter->second.name(); - - return base::StringPrintf("Display %d", static_cast<int>(id)); -} - -int64 DisplayManager::GetDisplayIdForUIScaling() const { - // UI Scaling is effective only on internal display. - int64 display_id = gfx::Display::InternalDisplayId(); -#if defined(OS_WIN) - display_id = first_display_id(); -#endif - return display_id; -} - -void DisplayManager::SetMirrorMode(bool mirrored) { - if (num_connected_displays() <= 1) - return; - -#if defined(OS_CHROMEOS) - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::OutputState new_state = mirrored ? - chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED; - Shell::GetInstance()->output_configurator()->SetDisplayMode(new_state); - return; - } -#endif - // This is fallback path to emulate mirroroing on desktop. - SetSecondDisplayMode(mirrored ? MIRRORING : EXTENDED); - DisplayInfoList display_info_list; - int count = 0; - for (std::map<int64, DisplayInfo>::const_iterator iter = - display_info_.begin(); - count < 2; ++iter, ++count) { - display_info_list.push_back(GetDisplayInfo(iter->second.id())); - } - UpdateDisplays(display_info_list); -#if defined(OS_CHROMEOS) - if (Shell::GetInstance()->output_configurator_animation()) { - Shell::GetInstance()->output_configurator_animation()-> - StartFadeInAnimation(); - } -#endif -} - -void DisplayManager::AddRemoveDisplay() { - DCHECK(!displays_.empty()); - std::vector<DisplayInfo> new_display_info_list; - const DisplayInfo& first_display = GetDisplayInfo(displays_[0].id()); - new_display_info_list.push_back(first_display); - // Add if there is only one display connected. - if (num_connected_displays() == 1) { - // Layout the 2nd display below the primary as with the real device. - gfx::Rect host_bounds = first_display.bounds_in_native(); - new_display_info_list.push_back(DisplayInfo::CreateFromSpec( - base::StringPrintf( - "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); - } - num_connected_displays_ = new_display_info_list.size(); - mirrored_display_id_ = gfx::Display::kInvalidDisplayID; - non_desktop_display_ = gfx::Display(); - UpdateDisplays(new_display_info_list); -} - -void DisplayManager::ToggleDisplayScaleFactor() { - DCHECK(!displays_.empty()); - std::vector<DisplayInfo> new_display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - DisplayInfo display_info = GetDisplayInfo(iter->id()); - display_info.set_device_scale_factor( - display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); - new_display_info_list.push_back(display_info); - } - AddMirrorDisplayInfoIfAny(&new_display_info_list); - UpdateDisplays(new_display_info_list); -} - -#if defined(OS_CHROMEOS) -void DisplayManager::SetSoftwareMirroring(bool enabled) { - // TODO(oshima|bshe): Support external display on the system - // that has virtual keyboard display. - if (second_display_mode_ == VIRTUAL_KEYBOARD) - return; - SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED); -} -#endif - -void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) { - second_display_mode_ = mode; - mirrored_display_id_ = gfx::Display::kInvalidDisplayID; - non_desktop_display_ = gfx::Display(); -} - -bool DisplayManager::UpdateDisplayBounds(int64 display_id, - const gfx::Rect& new_bounds) { - if (change_display_upon_host_resize_) { - display_info_[display_id].SetBounds(new_bounds); - // Don't notify observers if the mirrored window has changed. - if (software_mirroring_enabled() && mirrored_display_id_ == display_id) - return false; - gfx::Display* display = FindDisplayForId(display_id); - display->SetSize(display_info_[display_id].size_in_pixel()); - Shell::GetInstance()->screen()->NotifyBoundsChanged(*display); - return true; - } - return false; -} - -void DisplayManager::CreateMirrorWindowIfAny() { - NonDesktopDisplayUpdater updater(this, delegate_); -} - -gfx::Display* DisplayManager::FindDisplayForId(int64 id) { - for (DisplayList::iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - if ((*iter).id() == id) - return &(*iter); - } - DLOG(WARNING) << "Could not find display:" << id; - return NULL; -} - -void DisplayManager::AddMirrorDisplayInfoIfAny( - std::vector<DisplayInfo>* display_info_list) { - if (software_mirroring_enabled() && IsMirrored()) - display_info_list->push_back(GetDisplayInfo(mirrored_display_id_)); -} - -void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { - std::map<int64, DisplayInfo>::iterator info = - display_info_.find(new_info.id()); - if (info != display_info_.end()) - info->second.Copy(new_info); - else { - display_info_[new_info.id()] = new_info; - display_info_[new_info.id()].set_native(false); - } - display_info_[new_info.id()].UpdateDisplaySize(); -} - -gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { - DCHECK(display_info_.find(id) != display_info_.end()); - const DisplayInfo& display_info = display_info_[id]; - - gfx::Display new_display(display_info.id()); - gfx::Rect bounds_in_native(display_info.size_in_pixel()); - float device_scale_factor = display_info.device_scale_factor(); - if (device_scale_factor == 2.0f && display_info.configured_ui_scale() == 2.0f) - device_scale_factor = 1.0f; - - // Simply set the origin to (0,0). The primary display's origin is - // always (0,0) and the secondary display's bounds will be updated - // in |UpdateSecondaryDisplayBoundsForLayout| called in |UpdateDisplay|. - new_display.SetScaleAndBounds( - device_scale_factor, gfx::Rect(bounds_in_native.size())); - new_display.set_rotation(display_info.rotation()); - new_display.set_touch_support(display_info.touch_support()); - return new_display; -} - -bool DisplayManager::UpdateSecondaryDisplayBoundsForLayout( - DisplayList* displays, - size_t* updated_index) const { - if (displays->size() != 2U) - return false; - - int64 id_at_zero = displays->at(0).id(); - DisplayIdPair pair = - (id_at_zero == first_display_id_ || - id_at_zero == gfx::Display::InternalDisplayId()) ? - std::make_pair(id_at_zero, displays->at(1).id()) : - std::make_pair(displays->at(1).id(), id_at_zero) ; - DisplayLayout layout = - layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); - - // Ignore if a user has a old format (should be extremely rare) - // and this will be replaced with DCHECK. - if (layout.primary_id != gfx::Display::kInvalidDisplayID) { - size_t primary_index, secondary_index; - if (displays->at(0).id() == layout.primary_id) { - primary_index = 0; - secondary_index = 1; - } else { - primary_index = 1; - secondary_index = 0; - } - // This function may be called before the secondary display is - // registered. The bounds is empty in that case and will - // return true. - gfx::Rect bounds = - GetDisplayForId(displays->at(secondary_index).id()).bounds(); - UpdateDisplayBoundsForLayout( - layout, displays->at(primary_index), &displays->at(secondary_index)); - *updated_index = secondary_index; - return bounds != displays->at(secondary_index).bounds(); - } - return false; -} - -// static -void DisplayManager::UpdateDisplayBoundsForLayout( - const DisplayLayout& layout, - const gfx::Display& primary_display, - gfx::Display* secondary_display) { - DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); - - const gfx::Rect& primary_bounds = primary_display.bounds(); - const gfx::Rect& secondary_bounds = secondary_display->bounds(); - gfx::Point new_secondary_origin = primary_bounds.origin(); - - DisplayLayout::Position position = layout.position; - - // Ignore the offset in case the secondary display doesn't share edges with - // the primary display. - int offset = layout.offset; - if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { - offset = std::min( - offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); - offset = std::max( - offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); - } else { - offset = std::min( - offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); - offset = std::max( - offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); - } - switch (position) { - case DisplayLayout::TOP: - new_secondary_origin.Offset(offset, -secondary_bounds.height()); - break; - case DisplayLayout::RIGHT: - new_secondary_origin.Offset(primary_bounds.width(), offset); - break; - case DisplayLayout::BOTTOM: - new_secondary_origin.Offset(offset, primary_bounds.height()); - break; - case DisplayLayout::LEFT: - new_secondary_origin.Offset(-secondary_bounds.width(), offset); - break; - } - gfx::Insets insets = secondary_display->GetWorkAreaInsets(); - secondary_display->set_bounds( - gfx::Rect(new_secondary_origin, secondary_bounds.size())); - secondary_display->UpdateWorkAreaFromInsets(insets); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_manager.h b/chromium/ash/display/display_manager.h deleted file mode 100644 index ef6780981c5..00000000000 --- a/chromium/ash/display/display_manager.h +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_DISPLAY_MANAGER_H_ -#define ASH_DISPLAY_DISPLAY_MANAGER_H_ - -#include <string> -#include <vector> - -#include "ash/ash_export.h" -#include "ash/display/display_info.h" -#include "ash/display/display_layout.h" -#include "base/compiler_specific.h" -#include "base/gtest_prod_util.h" -#include "base/memory/scoped_ptr.h" -#include "ui/gfx/display.h" - -#if defined(OS_CHROMEOS) -#include "chromeos/display/output_configurator.h" -#endif - -namespace gfx { -class Display; -class Insets; -class Rect; -} - -namespace ash { -class AcceleratorControllerTest; -class DisplayController; - -namespace test { -class DisplayManagerTestApi; -class SystemGestureEventFilterTest; -} -namespace internal { -class DisplayLayoutStore; - -// DisplayManager maintains the current display configurations, -// and notifies observers when configuration changes. -// -// TODO(oshima): Make this non internal. -class ASH_EXPORT DisplayManager -#if defined(OS_CHROMEOS) - : public chromeos::OutputConfigurator::SoftwareMirroringController -#endif - { - public: - class ASH_EXPORT Delegate { - public: - virtual ~Delegate() {} - - // Create or updates the non desktop window with |display_info|. - virtual void CreateOrUpdateNonDesktopDisplay( - const DisplayInfo& display_info) = 0; - - // Closes the mirror window if exists. - virtual void CloseNonDesktopDisplay() = 0; - - // Called before and after the display configuration changes. - // When |clear_focus| is true, the implementation should - // deactivate the active window and set the focus window to NULL. - virtual void PreDisplayConfigurationChange(bool clear_focus) = 0; - virtual void PostDisplayConfigurationChange() = 0; - }; - - // How the second display will be used. - // 1) EXTENDED mode extends the desktop to the second dislpay. - // 2) MIRRORING mode copies the content of the primary display to - // the 2nd display. (Software Mirroring). - // 3) In VIRTUAL_KEYBOARD mode, the 2nd display is used as a - // dedicated display for virtual keyboard, and it is not - // recognized as a part of desktop. - enum SecondDisplayMode { - EXTENDED, - MIRRORING, - VIRTUAL_KEYBOARD - }; - - // Returns the list of possible UI scales for the display. - static std::vector<float> GetScalesForDisplay(const DisplayInfo& info); - - // Returns next valid UI scale. - static float GetNextUIScale(const DisplayInfo& info, bool up); - - // Updates the bounds of the display given by |secondary_display_id| - // according to |layout|. - static void UpdateDisplayBoundsForLayoutById( - const DisplayLayout& layout, - const gfx::Display& primary_display, - int64 secondary_display_id); - - DisplayManager(); - virtual ~DisplayManager(); - - DisplayLayoutStore* layout_store() { - return layout_store_.get(); - } - - void set_delegate(Delegate* delegate) { delegate_ = delegate; } - - // When set to true, the MonitorManager calls OnDisplayBoundsChanged - // even if the display's bounds didn't change. Used to swap primary - // display. - void set_force_bounds_changed(bool force_bounds_changed) { - force_bounds_changed_ = force_bounds_changed; - } - - // Returns the display id of the first display in the outupt list. - int64 first_display_id() const { return first_display_id_; } - - // Initializes displays using command line flag. Returns false - // if no command line flag was provided. - bool InitFromCommandLine(); - - // Initialize default display. - void InitDefaultDisplay(); - - // True if the given |display| is currently connected. - bool IsActiveDisplay(const gfx::Display& display) const; - - // True if there is an internal display. - bool HasInternalDisplay() const; - - bool IsInternalDisplayId(int64 id) const; - - // Returns the display layout used for current displays. - DisplayLayout GetCurrentDisplayLayout(); - - // Returns the current display pair. - DisplayIdPair GetCurrentDisplayIdPair() const; - - // Sets the layout for the current display pair. The |layout| specifies - // the locaion of the secondary display relative to the primary. - void SetLayoutForCurrentDisplays( - const DisplayLayout& layout_relative_to_primary); - - // Returns display for given |id|; - const gfx::Display& GetDisplayForId(int64 id) const; - - // Finds the display that contains |point| in screeen coordinates. - // Returns invalid display if there is no display that can satisfy - // the condition. - const gfx::Display& FindDisplayContainingPoint( - const gfx::Point& point_in_screen) const; - - // Sets the work area's |insets| to the display given by |display_id|. - bool UpdateWorkAreaOfDisplay(int64 display_id, const gfx::Insets& insets); - - // Registers the overscan insets for the display of the specified ID. Note - // that the insets size should be specified in DIP size. It also triggers the - // display's bounds change. - void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip); - - // Sets the display's rotation. - void SetDisplayRotation(int64 display_id, gfx::Display::Rotation rotation); - - // Sets the display's ui scale. - void SetDisplayUIScale(int64 display_id, float ui_scale); - - // Sets the display's resolution. - void SetDisplayResolution(int64 display_id, const gfx::Size& resolution); - - // Register per display properties. |overscan_insets| is NULL if - // the display has no custom overscan insets. - void RegisterDisplayProperty(int64 display_id, - gfx::Display::Rotation rotation, - float ui_scale, - const gfx::Insets* overscan_insets, - const gfx::Size& resolution_in_pixels); - - // Returns the display's selected resolution. - bool GetSelectedResolutionForDisplayId(int64 display_id, - gfx::Size* resolution_out) const; - - // Tells if the virtual resolution feature is enabled. - bool IsDisplayUIScalingEnabled() const; - - // Returns the current overscan insets for the specified |display_id|. - // Returns an empty insets (0, 0, 0, 0) if no insets are specified for - // the display. - gfx::Insets GetOverscanInsets(int64 display_id) const; - - // Called when display configuration has changed. The new display - // configurations is passed as a vector of Display object, which - // contains each display's new infomration. - void OnNativeDisplaysChanged( - const std::vector<DisplayInfo>& display_info_list); - - // Updates the internal display data and notifies observers about the changes. - void UpdateDisplays(const std::vector<DisplayInfo>& display_info_list); - - // Updates current displays using current |display_info_|. - void UpdateDisplays(); - - // Returns the display at |index|. The display at 0 is - // no longer considered "primary". - const gfx::Display& GetDisplayAt(size_t index) const; - - const gfx::Display& GetPrimaryDisplayCandidate() const; - - // Returns the logical number of displays. This returns 1 - // when displays are mirrored. - size_t GetNumDisplays() const; - - const std::vector<gfx::Display>& displays() const { return displays_; } - - // Returns the number of connected displays. This returns 2 - // when displays are mirrored. - size_t num_connected_displays() const { return num_connected_displays_; } - - // Returns the mirroring status. - bool IsMirrored() const; - int64 mirrored_display_id() const { return mirrored_display_id_; } - - // Returns the display object that is not a part of desktop. - const gfx::Display& non_desktop_display() const { - return non_desktop_display_; - } - - // Retuns the display info associated with |display_id|. - const DisplayInfo& GetDisplayInfo(int64 display_id) const; - - // Returns the human-readable name for the display |id|. - std::string GetDisplayNameForId(int64 id); - - // Returns the display id that is capable of UI scaling. On device, - // this returns internal display's ID if its device scale factor is 2, - // or invalid ID if such internal display doesn't exist. On linux - // desktop, this returns the first display ID. - int64 GetDisplayIdForUIScaling() const; - - // Change the mirror mode. - void SetMirrorMode(bool mirrored); - - // Used to emulate display change when run in a desktop environment instead - // of on a device. - void AddRemoveDisplay(); - void ToggleDisplayScaleFactor(); - - // SoftwareMirroringController override: -#if defined(OS_CHROMEOS) - virtual void SetSoftwareMirroring(bool enabled) OVERRIDE; -#endif - bool software_mirroring_enabled() const { - return second_display_mode_ == MIRRORING; - }; - - bool virtual_keyboard_root_window_enabled() const { - return second_display_mode_ == VIRTUAL_KEYBOARD; - }; - - // Sets/gets second display mode. - void SetSecondDisplayMode(SecondDisplayMode mode); - SecondDisplayMode second_display_mode() const { - return second_display_mode_; - } - - // Update the bounds of the display given by |display_id|. - bool UpdateDisplayBounds(int64 display_id, - const gfx::Rect& new_bounds); - - // Creates mirror window if the software mirror mode is enabled. - // This is used only for bootstrap. - void CreateMirrorWindowIfAny(); - -private: - FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint); - FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged); - FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, - NativeDisplaysChangedAfterPrimaryChange); - FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets); - friend class ash::AcceleratorControllerTest; - friend class test::DisplayManagerTestApi; - friend class test::SystemGestureEventFilterTest; - friend class DisplayManagerTest; - - typedef std::vector<gfx::Display> DisplayList; - - void set_change_display_upon_host_resize(bool value) { - change_display_upon_host_resize_ = value; - } - - gfx::Display* FindDisplayForId(int64 id); - - // Add the mirror display's display info if the software based - // mirroring is in use. - void AddMirrorDisplayInfoIfAny(std::vector<DisplayInfo>* display_info_list); - - // Inserts and update the DisplayInfo according to the overscan - // state. Note that The DisplayInfo stored in the |internal_display_info_| - // can be different from |new_info| (due to overscan state), so - // you must use |GetDisplayInfo| to get the correct DisplayInfo for - // a display. - void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info); - - // Creates a display object from the DisplayInfo for |display_id|. - gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id); - - // Updates the bounds of the secondary display in |display_list| - // using the layout registered for the display pair and set the - // index of display updated to |updated_index|. Returns true - // if the secondary display's bounds has been changed from current - // value, or false otherwise. - bool UpdateSecondaryDisplayBoundsForLayout(DisplayList* display_list, - size_t* updated_index) const; - - static void UpdateDisplayBoundsForLayout( - const DisplayLayout& layout, - const gfx::Display& primary_display, - gfx::Display* secondary_display); - - Delegate* delegate_; // not owned. - - scoped_ptr<DisplayLayoutStore> layout_store_; - - int64 first_display_id_; - - // List of current active displays. - DisplayList displays_; - - int num_connected_displays_; - - bool force_bounds_changed_; - - // The mapping from the display ID to its internal data. - std::map<int64, DisplayInfo> display_info_; - - // Selected resolutions for displays. Key is the displays' ID. - std::map<int64, gfx::Size> resolutions_; - - // When set to true, the host window's resize event updates - // the display's size. This is set to true when running on - // desktop environment (for debugging) so that resizing the host - // window will update the display properly. This is set to false - // on device as well as during the unit tests. - bool change_display_upon_host_resize_; - - SecondDisplayMode second_display_mode_; - int64 mirrored_display_id_; - gfx::Display non_desktop_display_; - - DISALLOW_COPY_AND_ASSIGN(DisplayManager); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_MANAGER_H_ diff --git a/chromium/ash/display/display_manager_unittest.cc b/chromium/ash/display/display_manager_unittest.cc deleted file mode 100644 index 162f9a90a81..00000000000 --- a/chromium/ash/display/display_manager_unittest.cc +++ /dev/null @@ -1,1138 +0,0 @@ -// Copyright (c) 2012 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/display/display_manager.h" - -#include "ash/display/display_controller.h" -#include "ash/display/display_layout_store.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/display_manager_test_api.h" -#include "ash/test/mirror_window_test_api.h" -#include "base/format_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/test/event_generator.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/display_observer.h" -#include "ui/gfx/display.h" - -namespace ash { -namespace internal { - -using std::vector; -using std::string; - -using base::StringPrintf; - -namespace { - -std::string ToDisplayName(int64 id) { - return "x-" + base::Int64ToString(id); -} - -} // namespace - -class DisplayManagerTest : public test::AshTestBase, - public gfx::DisplayObserver, - public aura::WindowObserver { - public: - DisplayManagerTest() - : removed_count_(0U), - root_window_destroyed_(false) { - } - virtual ~DisplayManagerTest() {} - - virtual void SetUp() OVERRIDE { - AshTestBase::SetUp(); - Shell::GetScreen()->AddObserver(this); - Shell::GetPrimaryRootWindow()->AddObserver(this); - } - virtual void TearDown() OVERRIDE { - Shell::GetPrimaryRootWindow()->RemoveObserver(this); - Shell::GetScreen()->RemoveObserver(this); - AshTestBase::TearDown(); - } - - DisplayManager* display_manager() { - return Shell::GetInstance()->display_manager(); - } - const vector<gfx::Display>& changed() const { return changed_; } - const vector<gfx::Display>& added() const { return added_; } - - string GetCountSummary() const { - return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS, - changed_.size(), added_.size(), removed_count_); - } - - void reset() { - changed_.clear(); - added_.clear(); - removed_count_ = 0U; - root_window_destroyed_ = false; - } - - bool root_window_destroyed() const { - return root_window_destroyed_; - } - - const DisplayInfo& GetDisplayInfo(const gfx::Display& display) { - return display_manager()->GetDisplayInfo(display.id()); - } - - const DisplayInfo& GetDisplayInfoAt(int index) { - return GetDisplayInfo(display_manager()->GetDisplayAt(index)); - } - - const gfx::Display& GetDisplayForId(int64 id) { - return display_manager()->GetDisplayForId(id); - } - - const DisplayInfo& GetDisplayInfoForId(int64 id) { - return GetDisplayInfo(display_manager()->GetDisplayForId(id)); - } - - // aura::DisplayObserver overrides: - virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { - changed_.push_back(display); - } - virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { - added_.push_back(new_display); - } - virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { - ++removed_count_; - } - - // aura::WindowObserver overrides: - virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { - ASSERT_EQ(Shell::GetPrimaryRootWindow(), window); - root_window_destroyed_ = true; - } - - private: - vector<gfx::Display> changed_; - vector<gfx::Display> added_; - size_t removed_count_; - bool root_window_destroyed_; - - DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest); -}; - -TEST_F(DisplayManagerTest, UpdateDisplayTest) { - if (!SupportsMultipleDisplays()) - return; - - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - - // Update primary and add seconary. - UpdateDisplay("100+0-500x500,0+501-400x400"); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 500x500", - display_manager()->GetDisplayAt(0).bounds().ToString()); - - EXPECT_EQ("1 1 0", GetCountSummary()); - EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); - EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id()); - EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString()); - // Secondary display is on right. - EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString()); - EXPECT_EQ("0,501 400x400", - GetDisplayInfo(added()[0]).bounds_in_native().ToString()); - reset(); - - // Delete secondary. - UpdateDisplay("100+0-500x500"); - EXPECT_EQ("0 0 1", GetCountSummary()); - reset(); - - // Change primary. - UpdateDisplay("1+1-1000x600"); - EXPECT_EQ("1 0 0", GetCountSummary()); - EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); - EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString()); - reset(); - - // Add secondary. - UpdateDisplay("1+1-1000x600,1002+0-600x400"); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0 1 0", GetCountSummary()); - EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id()); - // Secondary display is on right. - EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString()); - EXPECT_EQ("1002,0 600x400", - GetDisplayInfo(added()[0]).bounds_in_native().ToString()); - reset(); - - // Secondary removed, primary changed. - UpdateDisplay("1+1-800x300"); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("1 0 1", GetCountSummary()); - EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); - EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString()); - reset(); - - // # of display can go to zero when screen is off. - const vector<DisplayInfo> empty; - display_manager()->OnNativeDisplaysChanged(empty); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0 0 0", GetCountSummary()); - EXPECT_FALSE(root_window_destroyed()); - // Display configuration stays the same - EXPECT_EQ("0,0 800x300", - display_manager()->GetDisplayAt(0).bounds().ToString()); - reset(); - - // Connect to display again - UpdateDisplay("100+100-500x400"); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("1 0 0", GetCountSummary()); - EXPECT_FALSE(root_window_destroyed()); - EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString()); - EXPECT_EQ("100,100 500x400", - GetDisplayInfo(changed()[0]).bounds_in_native().ToString()); - reset(); - - // Go back to zero and wake up with multiple displays. - display_manager()->OnNativeDisplaysChanged(empty); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_FALSE(root_window_destroyed()); - reset(); - - // Add secondary. - UpdateDisplay("0+0-1000x600,1000+1000-600x400"); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 1000x600", - display_manager()->GetDisplayAt(0).bounds().ToString()); - // Secondary display is on right. - EXPECT_EQ("1000,0 600x400", - display_manager()->GetDisplayAt(1).bounds().ToString()); - EXPECT_EQ("1000,1000 600x400", - GetDisplayInfoAt(1).bounds_in_native().ToString()); - reset(); - - // Changing primary will update secondary as well. - UpdateDisplay("0+0-800x600,1000+1000-600x400"); - EXPECT_EQ("2 0 0", GetCountSummary()); - reset(); - EXPECT_EQ("0,0 800x600", - display_manager()->GetDisplayAt(0).bounds().ToString()); - EXPECT_EQ("800,0 600x400", - display_manager()->GetDisplayAt(1).bounds().ToString()); -} - -// Test in emulation mode (use_fullscreen_host_window=false) -TEST_F(DisplayManagerTest, EmulatorTest) { - if (!SupportsMultipleDisplays()) - return; - - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - - display_manager()->AddRemoveDisplay(); - // Update primary and add seconary. - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0 1 0", GetCountSummary()); - reset(); - - display_manager()->AddRemoveDisplay(); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0 0 1", GetCountSummary()); - reset(); - - display_manager()->AddRemoveDisplay(); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0 1 0", GetCountSummary()); - reset(); -} - -TEST_F(DisplayManagerTest, OverscanInsetsTest) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("0+0-500x500,0+501-400x400"); - reset(); - ASSERT_EQ(2u, display_manager()->GetNumDisplays()); - const DisplayInfo& display_info1 = GetDisplayInfoAt(0); - const DisplayInfo& display_info2 = GetDisplayInfoAt(1); - display_manager()->SetOverscanInsets( - display_info2.id(), gfx::Insets(13, 12, 11, 10)); - - std::vector<gfx::Display> changed_displays = changed(); - EXPECT_EQ(1u, changed_displays.size()); - EXPECT_EQ(display_info2.id(), changed_displays[0].id()); - EXPECT_EQ("0,0 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - DisplayInfo updated_display_info2 = GetDisplayInfoAt(1); - EXPECT_EQ("0,501 400x400", - updated_display_info2.bounds_in_native().ToString()); - EXPECT_EQ("378x376", - updated_display_info2.size_in_pixel().ToString()); - EXPECT_EQ("13,12,11,10", - updated_display_info2.overscan_insets_in_dip().ToString()); - EXPECT_EQ("500,0 378x376", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - // Make sure that SetOverscanInsets() is idempotent. - display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets()); - display_manager()->SetOverscanInsets( - display_info2.id(), gfx::Insets(13, 12, 11, 10)); - EXPECT_EQ("0,0 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - updated_display_info2 = GetDisplayInfoAt(1); - EXPECT_EQ("0,501 400x400", - updated_display_info2.bounds_in_native().ToString()); - EXPECT_EQ("378x376", - updated_display_info2.size_in_pixel().ToString()); - EXPECT_EQ("13,12,11,10", - updated_display_info2.overscan_insets_in_dip().ToString()); - - display_manager()->SetOverscanInsets( - display_info2.id(), gfx::Insets(10, 11, 12, 13)); - EXPECT_EQ("0,0 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - EXPECT_EQ("376x378", - GetDisplayInfoAt(1).size_in_pixel().ToString()); - EXPECT_EQ("10,11,12,13", - GetDisplayInfoAt(1).overscan_insets_in_dip().ToString()); - - // Recreate a new 2nd display. It won't apply the overscan inset because the - // new display has a different ID. - UpdateDisplay("0+0-500x500"); - UpdateDisplay("0+0-500x500,0+501-400x400"); - EXPECT_EQ("0,0 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - EXPECT_EQ("0,501 400x400", - GetDisplayInfoAt(1).bounds_in_native().ToString()); - - // Recreate the displays with the same ID. It should apply the overscan - // inset. - UpdateDisplay("0+0-500x500"); - std::vector<DisplayInfo> display_info_list; - display_info_list.push_back(display_info1); - display_info_list.push_back(display_info2); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ("1,1 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - updated_display_info2 = GetDisplayInfoAt(1); - EXPECT_EQ("376x378", - updated_display_info2.size_in_pixel().ToString()); - EXPECT_EQ("10,11,12,13", - updated_display_info2.overscan_insets_in_dip().ToString()); - - // HiDPI but overscan display. The specified insets size should be doubled. - UpdateDisplay("0+0-500x500,0+501-400x400*2"); - display_manager()->SetOverscanInsets( - display_manager()->GetDisplayAt(1).id(), gfx::Insets(4, 5, 6, 7)); - EXPECT_EQ("0,0 500x500", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - updated_display_info2 = GetDisplayInfoAt(1); - EXPECT_EQ("0,501 400x400", - updated_display_info2.bounds_in_native().ToString()); - EXPECT_EQ("376x380", - updated_display_info2.size_in_pixel().ToString()); - EXPECT_EQ("4,5,6,7", - updated_display_info2.overscan_insets_in_dip().ToString()); - EXPECT_EQ("8,10,12,14", - updated_display_info2.GetOverscanInsetsInPixel().ToString()); - - // Make sure switching primary display applies the overscan offset only once. - ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( - ScreenAsh::GetSecondaryDisplay()); - EXPECT_EQ("-500,0 500x500", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - EXPECT_EQ("0,0 500x500", - GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()). - bounds_in_native().ToString()); - EXPECT_EQ("0,501 400x400", - GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()). - bounds_in_native().ToString()); - EXPECT_EQ("0,0 188x190", - Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); -} - -TEST_F(DisplayManagerTest, ZeroOverscanInsets) { - if (!SupportsMultipleDisplays()) - return; - - // Make sure the display change events is emitted for overscan inset changes. - UpdateDisplay("0+0-500x500,0+501-400x400"); - ASSERT_EQ(2u, display_manager()->GetNumDisplays()); - int64 display2_id = display_manager()->GetDisplayAt(1).id(); - - reset(); - display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); - EXPECT_EQ(0u, changed().size()); - - reset(); - display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0)); - EXPECT_EQ(1u, changed().size()); - EXPECT_EQ(display2_id, changed()[0].id()); - - reset(); - display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); - EXPECT_EQ(1u, changed().size()); - EXPECT_EQ(display2_id, changed()[0].id()); -} - -TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) { - if (!SupportsHostWindowResize()) - return; - - UpdateDisplay("1000x600"); - aura::WindowEventDispatcher* dispatcher = - Shell::GetPrimaryRootWindow()->GetDispatcher(); - EXPECT_EQ(1, dispatcher->compositor()->device_scale_factor()); - EXPECT_EQ("1000x600", - Shell::GetPrimaryRootWindow()->bounds().size().ToString()); - UpdateDisplay("1000x600*2"); - EXPECT_EQ(2, dispatcher->compositor()->device_scale_factor()); - EXPECT_EQ("500x300", - Shell::GetPrimaryRootWindow()->bounds().size().ToString()); -} - -DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { - DisplayInfo info(id, ToDisplayName(id), false); - info.SetBounds(bounds); - return info; -} - -TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) { - const int64 internal_display_id = - test::DisplayManagerTestApi(display_manager()). - SetFirstDisplayAsInternalDisplay(); - const int external_id = 10; - const int mirror_id = 11; - const int64 invalid_id = gfx::Display::kInvalidDisplayID; - const DisplayInfo internal_display_info = - CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); - const DisplayInfo external_display_info = - CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); - const DisplayInfo mirrored_display_info = - CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500)); - - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - std::string default_bounds = - display_manager()->GetDisplayAt(0).bounds().ToString(); - - std::vector<DisplayInfo> display_info_list; - // Primary disconnected. - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ(default_bounds, - display_manager()->GetDisplayAt(0).bounds().ToString()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - if (!SupportsMultipleDisplays()) - return; - - // External connected while primary was disconnected. - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - - EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); - EXPECT_EQ("1,1 100x100", - GetDisplayInfoForId(external_id).bounds_in_native().ToString()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id()); - - EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId()); - - // Primary connected, with different bounds. - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id()); - - // This combinatino is new, so internal display becomes primary. - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("1,1 100x100", - GetDisplayInfoForId(10).bounds_in_native().ToString()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - EXPECT_EQ(ToDisplayName(internal_display_id), - display_manager()->GetDisplayNameForId(internal_display_id)); - - // Emulate suspend. - display_info_list.clear(); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("1,1 100x100", - GetDisplayInfoForId(10).bounds_in_native().ToString()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - EXPECT_EQ(ToDisplayName(internal_display_id), - display_manager()->GetDisplayNameForId(internal_display_id)); - - // External display has disconnected then resumed. - display_info_list.push_back(internal_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - // External display was changed during suspend. - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - // suspend... - display_info_list.clear(); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - // and resume with different external display. - display_info_list.push_back(internal_display_info); - display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100))); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - // mirrored... - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(mirrored_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_EQ(11U, display_manager()->mirrored_display_id()); - EXPECT_TRUE(display_manager()->IsMirrored()); - - // Test display name. - EXPECT_EQ(ToDisplayName(internal_display_id), - display_manager()->GetDisplayNameForId(internal_display_id)); - EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10)); - EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11)); - EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12)); - // Default name for the id that doesn't exist. - EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100)); - - // and exit mirroring. - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("500,0 100x100", - GetDisplayForId(10).bounds().ToString()); - - // Turn off internal - display_info_list.clear(); - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); - EXPECT_EQ("1,1 100x100", - GetDisplayInfoForId(external_id).bounds_in_native().ToString()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); - - // Switched to another display - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ( - "0,0 500x500", - GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString()); - EXPECT_EQ(1U, display_manager()->num_connected_displays()); - EXPECT_FALSE(display_manager()->IsMirrored()); -} - -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_TestNativeDisplaysChangedNoInternal \ - DISABLED_TestNativeDisplaysChangedNoInternal -#else -#define MAYBE_TestNativeDisplaysChangedNoInternal \ - TestNativeDisplaysChangedNoInternal -#endif - -TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) { - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - - // Don't change the display info if all displays are disconnected. - std::vector<DisplayInfo> display_info_list; - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - - // Connect another display which will become primary. - const DisplayInfo external_display_info = - CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); - display_info_list.push_back(external_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager()->GetNumDisplays()); - EXPECT_EQ("1,1 100x100", - GetDisplayInfoForId(10).bounds_in_native().ToString()); - EXPECT_EQ("100x100", ash::Shell::GetPrimaryRootWindow()->GetDispatcher()-> - host()->GetBounds().size().ToString()); -} - -#if defined(OS_WIN) -// Tests that rely on the actual host size/location does not work on windows. -#define MAYBE_EnsurePointerInDisplays DISABLED_EnsurePointerInDisplays -#define MAYBE_EnsurePointerInDisplays_2ndOnLeft DISABLED_EnsurePointerInDisplays_2ndOnLeft -#else -#define MAYBE_EnsurePointerInDisplays EnsurePointerInDisplays -#define MAYBE_EnsurePointerInDisplays_2ndOnLeft EnsurePointerInDisplays_2ndOnLeft -#endif - -TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays) { - UpdateDisplay("200x200,300x300"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - aura::Env* env = aura::Env::GetInstance(); - - aura::test::EventGenerator generator(root_windows[0]); - - // Set the initial position. - generator.MoveMouseToInHost(350, 150); - EXPECT_EQ("350,150", env->last_mouse_location().ToString()); - - // A mouse pointer will stay in the 2nd display. - UpdateDisplay("300x300,200x200"); - EXPECT_EQ("450,50", env->last_mouse_location().ToString()); - - // A mouse pointer will be outside of displays and move to the - // center of 2nd display. - UpdateDisplay("300x300,100x100"); - EXPECT_EQ("350,50", env->last_mouse_location().ToString()); - - // 2nd display was disconnected, and the cursor is - // now in the 1st display. - UpdateDisplay("400x400"); - EXPECT_EQ("50,350", env->last_mouse_location().ToString()); - - // 1st display's resolution has changed, and the mouse pointer is - // now outside. Move the mouse pointer to the center of 1st display. - UpdateDisplay("300x300"); - EXPECT_EQ("150,150", env->last_mouse_location().ToString()); - - // Move the mouse pointer to the bottom of 1st display. - generator.MoveMouseToInHost(150, 290); - EXPECT_EQ("150,290", env->last_mouse_location().ToString()); - - // The mouse pointer is now on 2nd display. - UpdateDisplay("300x280,200x200"); - EXPECT_EQ("450,10", env->last_mouse_location().ToString()); -} - -TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays_2ndOnLeft) { - // Set the 2nd display on the left. - DisplayLayoutStore* layout_store = - Shell::GetInstance()->display_manager()->layout_store(); - DisplayLayout layout = layout_store->default_display_layout(); - layout.position = DisplayLayout::LEFT; - layout_store->SetDefaultDisplayLayout(layout); - - UpdateDisplay("200x200,300x300"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - EXPECT_EQ("-300,0 300x300", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - aura::Env* env = aura::Env::GetInstance(); - - // Set the initial position. - root_windows[0]->MoveCursorTo(gfx::Point(-150, 250)); - EXPECT_EQ("-150,250", env->last_mouse_location().ToString()); - - // A mouse pointer will stay in 2nd display. - UpdateDisplay("300x300,200x300"); - EXPECT_EQ("-50,150", env->last_mouse_location().ToString()); - - // A mouse pointer will be outside of displays and move to the - // center of 2nd display. - UpdateDisplay("300x300,200x100"); - EXPECT_EQ("-100,50", env->last_mouse_location().ToString()); - - // 2nd display was disconnected. Mouse pointer should move to - // 1st display. - UpdateDisplay("300x300"); - EXPECT_EQ("150,150", env->last_mouse_location().ToString()); -} - -TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) { - if (!SupportsMultipleDisplays()) - return; - - const int64 internal_display_id = - test::DisplayManagerTestApi(display_manager()). - SetFirstDisplayAsInternalDisplay(); - const DisplayInfo native_display_info = - CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); - const DisplayInfo secondary_display_info = - CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); - - std::vector<DisplayInfo> display_info_list; - display_info_list.push_back(native_display_info); - display_info_list.push_back(secondary_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString()); - - ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( - GetDisplayForId(secondary_display_info.id())); - EXPECT_EQ("-500,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString()); - - // OnNativeDisplaysChanged may change the display bounds. Here makes sure - // nothing changed if the exactly same displays are specified. - display_manager()->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ("-500,0 500x500", - GetDisplayForId(internal_display_id).bounds().ToString()); - EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString()); -} - -TEST_F(DisplayManagerTest, DontRememberBestResolution) { - int display_id = 1000; - DisplayInfo native_display_info = - CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); - std::vector<Resolution> resolutions; - resolutions.push_back(Resolution(gfx::Size(1000, 500), false)); - resolutions.push_back(Resolution(gfx::Size(800, 300), false)); - resolutions.push_back(Resolution(gfx::Size(400, 500), false)); - - native_display_info.set_resolutions(resolutions); - - std::vector<DisplayInfo> display_info_list; - display_info_list.push_back(native_display_info); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - gfx::Size selected; - EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId( - display_id, &selected)); - - // Unsupported resolution. - display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 4000)); - EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId( - display_id, &selected)); - - // Supported resolution. - display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); - EXPECT_TRUE(display_manager()->GetSelectedResolutionForDisplayId( - display_id, &selected)); - EXPECT_EQ("800x300", selected.ToString()); - - // Best resolution. - display_manager()->SetDisplayResolution(display_id, gfx::Size(1000, 500)); - EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId( - display_id, &selected)); -} - -TEST_F(DisplayManagerTest, Rotate) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("100x200/r,300x400/l"); - EXPECT_EQ("1,1 100x200", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - EXPECT_EQ("200x100", - GetDisplayInfoAt(0).size_in_pixel().ToString()); - - EXPECT_EQ("1,201 300x400", - GetDisplayInfoAt(1).bounds_in_native().ToString()); - EXPECT_EQ("400x300", - GetDisplayInfoAt(1).size_in_pixel().ToString()); - reset(); - UpdateDisplay("100x200/b,300x400"); - EXPECT_EQ("2 0 0", GetCountSummary()); - reset(); - - EXPECT_EQ("1,1 100x200", - GetDisplayInfoAt(0).bounds_in_native().ToString()); - EXPECT_EQ("100x200", - GetDisplayInfoAt(0).size_in_pixel().ToString()); - - EXPECT_EQ("1,201 300x400", - GetDisplayInfoAt(1).bounds_in_native().ToString()); - EXPECT_EQ("300x400", - GetDisplayInfoAt(1).size_in_pixel().ToString()); - - // Just Rotating display will change the bounds on both display. - UpdateDisplay("100x200/l,300x400"); - EXPECT_EQ("2 0 0", GetCountSummary()); - reset(); - - // Updating tothe same configuration should report no changes. - UpdateDisplay("100x200/l,300x400"); - EXPECT_EQ("0 0 0", GetCountSummary()); - reset(); - - UpdateDisplay("100x200/l,300x400"); - EXPECT_EQ("0 0 0", GetCountSummary()); - reset(); - - UpdateDisplay("200x200"); - EXPECT_EQ("1 0 1", GetCountSummary()); - reset(); - - UpdateDisplay("200x200/l"); - EXPECT_EQ("1 0 0", GetCountSummary()); -} - -TEST_F(DisplayManagerTest, UIScale) { - UpdateDisplay("1280x800"); - int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id(); - display_manager()->SetDisplayUIScale(display_id, 1.125f); - EXPECT_EQ(1.0, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.8f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.75f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.625f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - - gfx::Display::SetInternalDisplayId(display_id); - - display_manager()->SetDisplayUIScale(display_id, 1.5f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.25f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.125f); - EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.8f); - EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.75f); - EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.625f); - EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.6f); - EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.5f); - EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); - - UpdateDisplay("1366x768"); - display_manager()->SetDisplayUIScale(display_id, 1.5f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.25f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.125f); - EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.8f); - EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.75f); - EXPECT_EQ(0.75f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.6f); - EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.625f); - EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.5f); - EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); - - UpdateDisplay("1280x850*2"); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.5f); - EXPECT_EQ(1.5f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.25f); - EXPECT_EQ(1.25f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.125f); - EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 1.0f); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); - gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); - EXPECT_EQ(2.0f, display.device_scale_factor()); - EXPECT_EQ("640x425", display.bounds().size().ToString()); - - display_manager()->SetDisplayUIScale(display_id, 0.8f); - EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.75f); - EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.625f); - EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.6f); - EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); - display_manager()->SetDisplayUIScale(display_id, 0.5f); - EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); - - display_manager()->SetDisplayUIScale(display_id, 2.0f); - EXPECT_EQ(2.0f, GetDisplayInfoAt(0).configured_ui_scale()); - EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale()); - display = Shell::GetScreen()->GetPrimaryDisplay(); - EXPECT_EQ(1.0f, display.device_scale_factor()); - EXPECT_EQ("1280x850", display.bounds().size().ToString()); -} - - -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom -#else -#define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom -#endif - -TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) { - // Make sure just rotating will not change native location. - UpdateDisplay("300x200,200x150"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Env* env = aura::Env::GetInstance(); - - aura::test::EventGenerator generator1(root_windows[0]); - aura::test::EventGenerator generator2(root_windows[1]); - - // Test on 1st display. - generator1.MoveMouseToInHost(150, 50); - EXPECT_EQ("150,50", env->last_mouse_location().ToString()); - UpdateDisplay("300x200/r,200x150"); - EXPECT_EQ("50,149", env->last_mouse_location().ToString()); - - // Test on 2nd display. - generator2.MoveMouseToInHost(50, 100); - EXPECT_EQ("250,100", env->last_mouse_location().ToString()); - UpdateDisplay("300x200/r,200x150/l"); - EXPECT_EQ("249,50", env->last_mouse_location().ToString()); - - // The native location is now outside, so move to the center - // of closest display. - UpdateDisplay("300x200/r,100x50/l"); - EXPECT_EQ("225,50", env->last_mouse_location().ToString()); - - // Make sure just zooming will not change native location. - UpdateDisplay("600x400*2,400x300"); - - // Test on 1st display. - generator1.MoveMouseToInHost(200, 300); - EXPECT_EQ("100,150", env->last_mouse_location().ToString()); - UpdateDisplay("600x400*2@1.5,400x300"); - EXPECT_EQ("150,225", env->last_mouse_location().ToString()); - - // Test on 2nd display. - UpdateDisplay("600x400,400x300*2"); - generator2.MoveMouseToInHost(200, 250); - EXPECT_EQ("700,125", env->last_mouse_location().ToString()); - UpdateDisplay("600x400,400x300*2@1.5"); - EXPECT_EQ("750,187", env->last_mouse_location().ToString()); - - // The native location is now outside, so move to the - // center of closest display. - UpdateDisplay("600x400,400x200*2@1.5"); - EXPECT_EQ("750,75", env->last_mouse_location().ToString()); -} - -class TestDisplayObserver : public gfx::DisplayObserver { - public: - TestDisplayObserver() : changed_(false) {} - virtual ~TestDisplayObserver() {} - - // gfx::DisplayObserver overrides: - virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { - } - virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { - // Mirror window should already be delete before restoring - // the external dispay. - EXPECT_FALSE(test_api.GetRootWindow()); - changed_ = true; - } - virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { - // Mirror window should not be created until the external display - // is removed. - EXPECT_FALSE(test_api.GetRootWindow()); - changed_ = true; - } - - bool changed_and_reset() { - bool changed = changed_; - changed_ = false; - return changed; - } - - private: - test::MirrorWindowTestApi test_api; - bool changed_; - - DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver); -}; - -TEST_F(DisplayManagerTest, SoftwareMirroring) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x400,400x500"); - - test::MirrorWindowTestApi test_api; - EXPECT_EQ(NULL, test_api.GetRootWindow()); - - TestDisplayObserver display_observer; - Shell::GetScreen()->AddObserver(&display_observer); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - display_manager->UpdateDisplays(); - EXPECT_TRUE(display_observer.changed_and_reset()); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_EQ("0,0 300x400", - Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); - EXPECT_EQ("400x500", - test_api.GetRootWindow()->host()->GetBounds().size().ToString()); - EXPECT_EQ("300x400", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - EXPECT_TRUE(display_manager->IsMirrored()); - - display_manager->SetMirrorMode(false); - EXPECT_TRUE(display_observer.changed_and_reset()); - EXPECT_EQ(NULL, test_api.GetRootWindow()); - EXPECT_EQ(2U, display_manager->GetNumDisplays()); - EXPECT_FALSE(display_manager->IsMirrored()); - - // Make sure the mirror window has the pixel size of the - // source display. - display_manager->SetMirrorMode(true); - EXPECT_TRUE(display_observer.changed_and_reset()); - - UpdateDisplay("300x400@0.5,400x500"); - EXPECT_FALSE(display_observer.changed_and_reset()); - EXPECT_EQ("300x400", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - - UpdateDisplay("310x410*2,400x500"); - EXPECT_FALSE(display_observer.changed_and_reset()); - EXPECT_EQ("310x410", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - - UpdateDisplay("320x420/r,400x500"); - EXPECT_FALSE(display_observer.changed_and_reset()); - EXPECT_EQ("320x420", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - - UpdateDisplay("330x440/r,400x500"); - EXPECT_FALSE(display_observer.changed_and_reset()); - EXPECT_EQ("330x440", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - - // Overscan insets are ignored. - UpdateDisplay("400x600/o,600x800/o"); - EXPECT_FALSE(display_observer.changed_and_reset()); - EXPECT_EQ("400x600", - test_api.GetRootWindow()->window()->bounds().size().ToString()); - - Shell::GetScreen()->RemoveObserver(&display_observer); -} - -TEST_F(DisplayManagerTest, MirroredLayout) { - if (!SupportsMultipleDisplays()) - return; - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - UpdateDisplay("500x500,400x400"); - EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager->num_connected_displays()); - - UpdateDisplay("1+0-500x500,1+0-500x500"); - EXPECT_TRUE(display_manager->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager->num_connected_displays()); - - UpdateDisplay("500x500,500x500"); - EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager->num_connected_displays()); -} - -TEST_F(DisplayManagerTest, InvertLayout) { - EXPECT_EQ("left, 0", - DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString()); - EXPECT_EQ("left, -100", - DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString()); - EXPECT_EQ("left, 50", - DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString()); - - EXPECT_EQ("right, 0", - DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString()); - EXPECT_EQ("right, -90", - DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString()); - EXPECT_EQ("right, 60", - DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString()); - - EXPECT_EQ("bottom, 0", - DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString()); - EXPECT_EQ("bottom, -80", - DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString()); - EXPECT_EQ("bottom, 70", - DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString()); - - EXPECT_EQ("top, 0", - DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString()); - EXPECT_EQ("top, -70", - DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString()); - EXPECT_EQ("top, 80", - DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString()); -} - -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin -#else -#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin -#endif - -TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) { - UpdateDisplay("100x200,300x400"); - ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - ASSERT_EQ(2U, root_windows.size()); - aura::WindowEventDispatcher* dispatcher0 = root_windows[0]->GetDispatcher(); - aura::WindowEventDispatcher* dispatcher1 = root_windows[1]->GetDispatcher(); - - EXPECT_EQ("1,1", dispatcher0->host()->GetBounds().origin().ToString()); - EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); - // UpdateDisplay set the origin if it's not set. - EXPECT_NE("1,1", dispatcher1->host()->GetBounds().origin().ToString()); - EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); - - UpdateDisplay("100x200,200+300-300x400"); - ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ("0,0", dispatcher0->host()->GetBounds().origin().ToString()); - EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); - EXPECT_EQ("200,300", dispatcher1->host()->GetBounds().origin().ToString()); - EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); - - UpdateDisplay("400+500-200x300,300x400"); - ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ("400,500", dispatcher0->host()->GetBounds().origin().ToString()); - EXPECT_EQ("200x300", dispatcher0->host()->GetBounds().size().ToString()); - EXPECT_EQ("0,0", dispatcher1->host()->GetBounds().origin().ToString()); - EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); - - UpdateDisplay("100+200-100x200,300+500-200x300"); - ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); - EXPECT_EQ("100,200", dispatcher0->host()->GetBounds().origin().ToString()); - EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); - EXPECT_EQ("300,500", dispatcher1->host()->GetBounds().origin().ToString()); - EXPECT_EQ("200x300", dispatcher1->host()->GetBounds().size().ToString()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/display_pref_util.h b/chromium/ash/display/display_pref_util.h deleted file mode 100644 index 5047774c479..00000000000 --- a/chromium/ash/display/display_pref_util.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 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_DISPLAY_DISPLAY_PREF_UTIL_H -#define ASH_DISPLAY_DISPLAY_PREF_UTIL_H - -#include <map> -#include <string> - -#include "base/strings/string_piece.h" - -namespace ash { - -// Utility templates to create enum to string map and -// a function to find an enum value from a string. -template<typename T> -std::map<T, std::string>* CreateToStringMap(T k1, const std::string& v1, - T k2, const std::string& v2, - T k3, const std::string& v3, - T k4, const std::string& v4) { - std::map<T, std::string>* map = new std::map<T, std::string>(); - (*map)[k1] = v1; - (*map)[k2] = v2; - (*map)[k3] = v3; - (*map)[k4] = v4; - return map; -} - -template<typename T> -std::map<T, std::string>* CreateToStringMap(T k1, const std::string& v1, - T k2, const std::string& v2, - T k3, const std::string& v3) { - std::map<T, std::string>* map = new std::map<T, std::string>(); - (*map)[k1] = v1; - (*map)[k2] = v2; - (*map)[k3] = v3; - return map; -} - -template<typename T> -bool ReverseFind(const std::map<T, std::string>* map, - const base::StringPiece& value, - T* key) { - typename std::map<T, std::string>::const_iterator iter = map->begin(); - for (; - iter != map->end(); - ++iter) { - if (iter->second == value) { - *key = iter->first; - return true; - } - } - return false; -} - -} // namespace ash - -#endif // ASH_DISPLAY_DISPLAY_PREF_UTIL_H diff --git a/chromium/ash/display/event_transformation_handler.cc b/chromium/ash/display/event_transformation_handler.cc deleted file mode 100644 index aaac56c256a..00000000000 --- a/chromium/ash/display/event_transformation_handler.cc +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 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/display/event_transformation_handler.h" - -#include <cmath> - -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/wm/coordinate_conversion.h" -#include "ash/wm/window_util.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/compositor/dip_util.h" -#include "ui/events/event.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" - -#if defined(OS_CHROMEOS) -#include "chromeos/display/output_configurator.h" -#endif // defined(OS_CHROMEOS) - -namespace ash { -namespace internal { -namespace { - -// Boost factor for non-integrated displays. -const float kBoostForNonIntegrated = 1.20f; -} - -EventTransformationHandler::EventTransformationHandler() - : transformation_mode_(TRANSFORM_AUTO) { -} - -EventTransformationHandler::~EventTransformationHandler() { -} - -void EventTransformationHandler::OnScrollEvent(ui::ScrollEvent* event) { - if (transformation_mode_ == TRANSFORM_NONE) - return; - - // It is unnecessary to scale the event for the device scale factor since - // the event locations etc. are already in DIP. - gfx::Point point_in_screen(event->location()); - aura::Window* target = static_cast<aura::Window*>(event->target()); - wm::ConvertPointToScreen(target, &point_in_screen); - const gfx::Display& display = - Shell::GetScreen()->GetDisplayNearestPoint(point_in_screen); - - // Apply some additional scaling if the display is non-integrated. - if (!display.IsInternal()) - event->Scale(kBoostForNonIntegrated); -} - -#if defined(OS_CHROMEOS) -// This is to scale the TouchEvent's radius when the touch display is in -// mirror mode. TouchEvent's radius is often reported in the touchscreen's -// native resolution. In mirror mode, the touch display could be configured -// at a lower resolution. We scale down the radius using the ratio defined as -// the sqrt of -// (mirror_width * mirror_height) / (native_width * native_height) -void EventTransformationHandler::OnTouchEvent(ui::TouchEvent* event) { - using chromeos::OutputConfigurator; - OutputConfigurator* output_configurator = - ash::Shell::GetInstance()->output_configurator(); - - // Check output_configurator's output_state instead of checking - // DisplayManager::IsMirrored() because the compositor based mirroring - // won't cause the scaling issue. - if (output_configurator->output_state() != chromeos::STATE_DUAL_MIRROR) - return; - - const std::map<int, float>& area_ratio_map = - output_configurator->GetMirroredDisplayAreaRatioMap(); - - // TODO(miletus): When there are more than 1 touchscreen (e.g. Link connected - // to an external touchscreen), the correct way to do is to have a way - // to find out which touchscreen is the event originating from and use the - // area ratio of that touchscreen to scale the event's radius. - // Tracked here crbug.com/233245 - if (area_ratio_map.size() != 1) { - LOG(ERROR) << "Mirroring mode with " << area_ratio_map.size() - << " touch display found"; - return; - } - - float area_ratio_sqrt = std::sqrt(area_ratio_map.begin()->second); - event->set_radius_x(event->radius_x() * area_ratio_sqrt); - event->set_radius_y(event->radius_y() * area_ratio_sqrt); -} -#endif // defined(OS_CHROMEOS) - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/event_transformation_handler.h b/chromium/ash/display/event_transformation_handler.h deleted file mode 100644 index da9560f81a3..00000000000 --- a/chromium/ash/display/event_transformation_handler.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 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_DISPLAY_EVENT_TRANSFORMATION_HANDLER_H_ -#define ASH_DISPLAY_EVENT_TRANSFORMATION_HANDLER_H_ - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "ui/events/event_handler.h" - -namespace ash { - -namespace internal { - -// An event filter that transforms input event properties in extended desktop -// environment. -class ASH_EXPORT EventTransformationHandler : public ui::EventHandler { - public: - enum TransformationMode { - TRANSFORM_AUTO, // Transform events by the default amount. - // 1. Linear scaling w.r.t. the device scale factor. - // 2. Add 20% more for non-integrated displays. - TRANSFORM_NONE, // No transformation. - }; - - EventTransformationHandler(); - virtual ~EventTransformationHandler(); - - void set_transformation_mode(TransformationMode transformation_mode) { - transformation_mode_ = transformation_mode; - } - - // Overridden from ui::EventHandler. - virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; -#if defined(OS_CHROMEOS) - virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE; -#endif // defined(OS_CHROMEOS) - - private: - TransformationMode transformation_mode_; - - DISALLOW_COPY_AND_ASSIGN(EventTransformationHandler); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_EVENT_TRANSFORMATION_HANDLER_H_ diff --git a/chromium/ash/display/mirror_window_controller.cc b/chromium/ash/display/mirror_window_controller.cc deleted file mode 100644 index 7e812a4ca79..00000000000 --- a/chromium/ash/display/mirror_window_controller.cc +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) 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/display/mirror_window_controller.h" - -#if defined(USE_X11) -#include <X11/Xlib.h> - -// Xlib.h defines RootWindow. -#undef RootWindow -#endif - -#include "ash/display/display_controller.h" -#include "ash/display/display_info.h" -#include "ash/display/display_manager.h" -#include "ash/display/root_window_transformers.h" -#include "ash/host/root_window_host_factory.h" -#include "ash/root_window_settings.h" -#include "ash/shell.h" -#include "base/strings/stringprintf.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_transformer.h" -#include "ui/aura/window_delegate.h" -#include "ui/base/cursor/cursors_aura.h" -#include "ui/base/hit_test.h" -#include "ui/base/layout.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/compositor/reflector.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/image/image_skia_operations.h" -#include "ui/gfx/native_widget_types.h" - -#if defined(USE_X11) -#include "ui/gfx/x/x11_types.h" -#endif - -namespace ash { -namespace internal { -namespace { - -#if defined(USE_X11) -// Mirror window shouldn't handle input events. -void DisableInput(XID window) { - long event_mask = ExposureMask | VisibilityChangeMask | - StructureNotifyMask | PropertyChangeMask; - XSelectInput(gfx::GetXDisplay(), window, event_mask); -} -#endif - -class NoneCaptureClient : public aura::client::CaptureClient { - public: - NoneCaptureClient() {} - virtual ~NoneCaptureClient() {} - - private: - // Does a capture on the |window|. - virtual void SetCapture(aura::Window* window) OVERRIDE {} - - // Releases a capture from the |window|. - virtual void ReleaseCapture(aura::Window* window) OVERRIDE {} - - // Returns the current capture window. - virtual aura::Window* GetCaptureWindow() OVERRIDE { - return NULL; - } - virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE { - return NULL; - } - - DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); -}; - -} // namespace - -class CursorWindowDelegate : public aura::WindowDelegate { - public: - CursorWindowDelegate() {} - virtual ~CursorWindowDelegate() {} - - // aura::WindowDelegate overrides: - virtual gfx::Size GetMinimumSize() const OVERRIDE { - return size_; - } - virtual gfx::Size GetMaximumSize() const OVERRIDE { - return 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 { - canvas->DrawImageInt(cursor_image_, 0, 0); - } - virtual void OnDeviceScaleFactorChanged( - float device_scale_factor) OVERRIDE { - } - virtual void OnWindowDestroying() OVERRIDE {} - virtual void OnWindowDestroyed() OVERRIDE {} - virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE { - } - virtual bool HasHitTestMask() const OVERRIDE { - return false; - } - virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {} - virtual void DidRecreateLayer(ui::Layer* old_layer, - ui::Layer* new_layer) OVERRIDE {} - - // Set the cursor image for the |display|'s scale factor. Note that - // mirror window's scale factor is always 1.0f, therefore we need to - // take 2x's image and paint as if it's 1x image. - void SetCursorImage(const gfx::ImageSkia& image, - const gfx::Display& display) { - const gfx::ImageSkiaRep& image_rep = - image.GetRepresentation(display.device_scale_factor()); - size_ = image_rep.pixel_size(); - cursor_image_ = gfx::ImageSkia::CreateFrom1xBitmap(image_rep.sk_bitmap()); - } - - const gfx::Size size() const { return size_; } - - private: - gfx::ImageSkia cursor_image_; - gfx::Size size_; - - DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate); -}; - -MirrorWindowController::MirrorWindowController() - : current_cursor_type_(ui::kCursorNone), - current_cursor_rotation_(gfx::Display::ROTATE_0), - cursor_window_(NULL), - cursor_window_delegate_(new CursorWindowDelegate) { -} - -MirrorWindowController::~MirrorWindowController() { - // Make sure the root window gets deleted before cursor_window_delegate. - Close(); -} - -void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { - static int mirror_root_window_count = 0; - - if (!root_window_.get()) { - const gfx::Rect& bounds_in_native = display_info.bounds_in_native(); - aura::RootWindow::CreateParams params(bounds_in_native); - params.host = Shell::GetInstance()->root_window_host_factory()-> - CreateRootWindowHost(bounds_in_native); - root_window_.reset(new aura::RootWindow(params)); - root_window_->window()->SetName( - base::StringPrintf("MirrorRootWindow-%d", mirror_root_window_count++)); - root_window_->compositor()->SetBackgroundColor(SK_ColorBLACK); - // No need to remove RootWindowObserver because - // the DisplayController object outlives RootWindow objects. - root_window_->AddRootWindowObserver( - Shell::GetInstance()->display_controller()); - root_window_->AddRootWindowObserver(this); - // TODO(oshima): TouchHUD is using idkey. - InitRootWindowSettings(root_window_->window())->display_id = - display_info.id(); - root_window_->Init(); -#if defined(USE_X11) - DisableInput(root_window_->host()->GetAcceleratedWidget()); -#endif - - aura::client::SetCaptureClient(root_window_->window(), - new NoneCaptureClient()); - root_window_->host()->Show(); - - // TODO(oshima): Start mirroring. - aura::Window* mirror_window = new aura::Window(NULL); - mirror_window->Init(ui::LAYER_TEXTURED); - root_window_->window()->AddChild(mirror_window); - mirror_window->SetBounds(root_window_->window()->bounds()); - mirror_window->Show(); - reflector_ = ui::ContextFactory::GetInstance()->CreateReflector( - Shell::GetPrimaryRootWindow()->GetDispatcher()->compositor(), - mirror_window->layer()); - - cursor_window_ = new aura::Window(cursor_window_delegate_.get()); - cursor_window_->SetTransparent(true); - cursor_window_->Init(ui::LAYER_TEXTURED); - root_window_->window()->AddChild(cursor_window_); - cursor_window_->Show(); - } else { - GetRootWindowSettings(root_window_->window())->display_id = - display_info.id(); - root_window_->SetHostBounds(display_info.bounds_in_native()); - } - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( - Shell::GetScreen()->GetPrimaryDisplay().id()); - DCHECK(display_manager->IsMirrored()); - scoped_ptr<aura::RootWindowTransformer> transformer( - internal::CreateRootWindowTransformerForMirroredDisplay( - source_display_info, - display_info)); - root_window_->SetRootWindowTransformer(transformer.Pass()); - - UpdateCursorLocation(); -} - -void MirrorWindowController::UpdateWindow() { - if (root_window_.get()) { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( - display_manager->mirrored_display_id()); - UpdateWindow(mirror_display_info); - } -} - -void MirrorWindowController::Close() { - if (root_window_.get()) { - ui::ContextFactory::GetInstance()->RemoveReflector(reflector_); - reflector_ = NULL; - NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( - aura::client::GetCaptureClient(root_window_->window())); - aura::client::SetCaptureClient(root_window_->window(), NULL); - delete capture_client; - - root_window_->RemoveRootWindowObserver( - Shell::GetInstance()->display_controller()); - root_window_->RemoveRootWindowObserver(this); - root_window_.reset(); - cursor_window_ = NULL; - } -} - -void MirrorWindowController::UpdateCursorLocation() { - if (cursor_window_) { - // TODO(oshima): Rotate cursor image (including hotpoint). - gfx::Point point = aura::Env::GetInstance()->last_mouse_location(); - Shell::GetPrimaryRootWindow()->GetDispatcher()->ConvertPointToHost(&point); - point.Offset(-hot_point_.x(), -hot_point_.y()); - gfx::Rect bounds = cursor_window_->bounds(); - bounds.set_origin(point); - cursor_window_->SetBounds(bounds); - } -} - -void MirrorWindowController::SetMirroredCursor(gfx::NativeCursor cursor) { - const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay(); - if (current_cursor_type_ == cursor.native_type() && - current_cursor_rotation_ == display.rotation()) - return; - current_cursor_type_ = cursor.native_type(); - current_cursor_rotation_ = display.rotation(); - int resource_id; - bool success = ui::GetCursorDataFor( - ui::CURSOR_SET_NORMAL, // Not support custom cursor set. - current_cursor_type_, - display.device_scale_factor(), - &resource_id, - &hot_point_); - if (!success) - return; - const gfx::ImageSkia* image = - ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); - gfx::ImageSkia rotated = *image; - switch (current_cursor_rotation_) { - case gfx::Display::ROTATE_0: - break; - case gfx::Display::ROTATE_90: - rotated = gfx::ImageSkiaOperations::CreateRotatedImage( - *image, SkBitmapOperations::ROTATION_90_CW); - hot_point_.SetPoint( - rotated.width() - hot_point_.y(), - hot_point_.x()); - break; - case gfx::Display::ROTATE_180: - rotated = gfx::ImageSkiaOperations::CreateRotatedImage( - *image, SkBitmapOperations::ROTATION_180_CW); - hot_point_.SetPoint( - rotated.height() - hot_point_.x(), - rotated.width() - hot_point_.y()); - break; - case gfx::Display::ROTATE_270: - rotated = gfx::ImageSkiaOperations::CreateRotatedImage( - *image, SkBitmapOperations::ROTATION_270_CW); - hot_point_.SetPoint( - hot_point_.y(), - rotated.height() - hot_point_.x()); - break; - } - cursor_window_delegate_->SetCursorImage(rotated, display); - - if (cursor_window_) { - cursor_window_->SetBounds(gfx::Rect(cursor_window_delegate_->size())); - cursor_window_->SchedulePaintInRect( - gfx::Rect(cursor_window_->bounds().size())); - UpdateCursorLocation(); - } -} - -void MirrorWindowController::SetMirroredCursorVisibility(bool visible) { - if (cursor_window_) - visible ? cursor_window_->Show() : cursor_window_->Hide(); -} - -void MirrorWindowController::OnRootWindowHostResized( - const aura::RootWindow* root) { - // Do not use |old_size| as it contains RootWindow's (but not host's) size, - // and this parameter wil be removed soon. - if (mirror_window_host_size_ == root->host()->GetBounds().size()) - return; - mirror_window_host_size_ = root->host()->GetBounds().size(); - reflector_->OnMirroringCompositorResized(); - root_window_->SetRootWindowTransformer( - CreateRootWindowTransformer().Pass()); - UpdateCursorLocation(); -} - - -scoped_ptr<aura::RootWindowTransformer> -MirrorWindowController::CreateRootWindowTransformer() const { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( - display_manager->mirrored_display_id()); - const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( - Shell::GetScreen()->GetPrimaryDisplay().id()); - DCHECK(display_manager->IsMirrored()); - return scoped_ptr<aura::RootWindowTransformer>( - internal::CreateRootWindowTransformerForMirroredDisplay( - source_display_info, - mirror_display_info)); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/mirror_window_controller.h b/chromium/ash/display/mirror_window_controller.h deleted file mode 100644 index 13460d7239b..00000000000 --- a/chromium/ash/display/mirror_window_controller.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 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_DISPLAY_MIRROR_WINDOW_CONTROLLER_H_ -#define ASH_DISPLAY_MIRROR_WINDOW_CONTROLLER_H_ - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "ui/aura/root_window_observer.h" -#include "ui/gfx/display.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/gfx/point.h" -#include "ui/gfx/size.h" - -namespace aura { -class RootWindow; -class RootWindowTransformer; -class Window; -} - -namespace ui { -class Reflector; -} - -namespace ash { -namespace test{ -class MirrorWindowTestApi; -} - -namespace internal { -class DisplayInfo; -class CursorWindowDelegate; - -// An object that copies the content of the primary root window to a -// mirror window. This also draws a mouse cursor as the mouse cursor -// is typically drawn by the window system. -class ASH_EXPORT MirrorWindowController : public aura::RootWindowObserver { - public: - MirrorWindowController(); - virtual ~MirrorWindowController(); - - // Updates the root window's bounds using |display_info|. - // Creates the new root window if one doesn't exist. - void UpdateWindow(const DisplayInfo& display_info); - - // Same as above, but using existing display info - // for the mirrored display. - void UpdateWindow(); - - // Close the mirror window. - void Close(); - - // Updates the mirrored cursor location,shape and - // visibility. - void UpdateCursorLocation(); - void SetMirroredCursor(gfx::NativeCursor cursor); - void SetMirroredCursorVisibility(bool visible); - - // aura::RootWindowObserver overrides: - virtual void OnRootWindowHostResized(const aura::RootWindow* root) OVERRIDE; - - private: - friend class test::MirrorWindowTestApi; - - // Creates a RootWindowTransformer for current display - // configuration. - scoped_ptr<aura::RootWindowTransformer> CreateRootWindowTransformer() const; - - int current_cursor_type_; - gfx::Display::Rotation current_cursor_rotation_; - aura::Window* cursor_window_; // owned by root window. - scoped_ptr<aura::RootWindow> root_window_; - scoped_ptr<CursorWindowDelegate> cursor_window_delegate_; - gfx::Point hot_point_; - gfx::Size mirror_window_host_size_; - scoped_refptr<ui::Reflector> reflector_; - - DISALLOW_COPY_AND_ASSIGN(MirrorWindowController); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_MIRROR_WINDOW_CONTROLLER_H_ diff --git a/chromium/ash/display/mirror_window_controller_unittest.cc b/chromium/ash/display/mirror_window_controller_unittest.cc deleted file mode 100644 index a94f285700a..00000000000 --- a/chromium/ash/display/mirror_window_controller_unittest.cc +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) 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/display/mirror_window_controller.h" - -#include "ash/ash_switches.h" -#include "ash/display/display_manager.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/display_manager_test_api.h" -#include "ash/test/mirror_window_test_api.h" -#include "base/command_line.h" -#include "base/strings/stringprintf.h" -#include "ui/aura/root_window.h" -#include "ui/aura/test/event_generator.h" -#include "ui/aura/test/test_window_delegate.h" -#include "ui/aura/test/test_windows.h" -#include "ui/aura/window.h" -#include "ui/base/hit_test.h" - -namespace ash { -namespace internal { - -namespace { -DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { - DisplayInfo info(id, base::StringPrintf("x-%d", static_cast<int>(id)), false); - info.SetBounds(bounds); - return info; -} - -class MirrorOnBootTest : public test::AshTestBase { - public: - MirrorOnBootTest() {} - virtual ~MirrorOnBootTest() {} - - virtual void SetUp() OVERRIDE { - CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kAshHostWindowBounds, "1+1-300x300,1+301-300x300"); - CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAshEnableSoftwareMirroring); - test::AshTestBase::SetUp(); - } - virtual void TearDown() OVERRIDE { - test::AshTestBase::TearDown(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MirrorOnBootTest); -}; - -} - -typedef test::AshTestBase MirrorWindowControllerTest; - -#if defined(OS_WIN) -// Software mirroring does not work on win. -#define MAYBE_MirrorCursorBasic DISABLED_MirrorCursorBasic -#define MAYBE_MirrorCursorLocations DISABLED_MirrorCursorLocations -#define MAYBE_MirrorCursorRotate DISABLED_MirrorCursorRotate -#define MAYBE_DockMode DISABLED_DockMode -#define MAYBE_MirrorOnBoot DISABLED_MirrorOnBoot -#else -#define MAYBE_MirrorCursorBasic MirrorCursorBasic -#define MAYBE_MirrorCursorLocations MirrorCursorLocations -#define MAYBE_MirrorCursorRotate MirrorCursorRotate -#define MAYBE_DockMode DockMode -#define MAYBE_MirrorOnBoot MirrorOnBoot -#endif - -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorBasic) { - test::MirrorWindowTestApi test_api; - aura::test::TestWindowDelegate test_window_delegate; - test_window_delegate.set_window_component(HTTOP); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - UpdateDisplay("400x400,400x400"); - aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); - scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( - &test_window_delegate, - 0, - gfx::Rect(50, 50, 100, 100), - root)); - window->Show(); - window->SetName("foo"); - - EXPECT_TRUE(test_api.GetCursorWindow()); - EXPECT_EQ("50,50 100x100", window->bounds().ToString()); - - aura::test::EventGenerator generator(root); - generator.MoveMouseTo(10, 10); - - // Test if cursor movement is propertly reflected in mirror window. - gfx::Point hot_point = test_api.GetCursorHotPoint(); - gfx::Point cursor_window_origin = - test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ("4,4", hot_point.ToString()); - EXPECT_EQ(10 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(10 - hot_point.y(), cursor_window_origin.y()); - EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType()); - EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible()); - - // Test if cursor type change is propertly reflected in mirror window. - generator.MoveMouseTo(100, 100); - hot_point = test_api.GetCursorHotPoint(); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); - EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); - - // Test if visibility change is propertly reflected in mirror window. - // A key event hides cursor. - generator.PressKey(ui::VKEY_A, 0); - generator.ReleaseKey(ui::VKEY_A, 0); - EXPECT_FALSE(test_api.GetCursorWindow()->IsVisible()); - - // Mouse event makes it visible again. - generator.MoveMouseTo(300, 300); - hot_point = test_api.GetCursorHotPoint(); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); - EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType()); - EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible()); -} - -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorRotate) { - test::MirrorWindowTestApi test_api; - aura::test::TestWindowDelegate test_window_delegate; - test_window_delegate.set_window_component(HTTOP); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - UpdateDisplay("400x400,400x400"); - aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); - scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( - &test_window_delegate, - 0, - gfx::Rect(50, 50, 100, 100), - root)); - window->Show(); - window->SetName("foo"); - - EXPECT_TRUE(test_api.GetCursorWindow()); - EXPECT_EQ("50,50 100x100", window->bounds().ToString()); - - aura::test::EventGenerator generator(root); - generator.MoveMouseToInHost(100, 100); - - // Test if cursor movement is propertly reflected in mirror window. - gfx::Point hot_point = test_api.GetCursorHotPoint(); - gfx::Point cursor_window_origin = - test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ("11,12", hot_point.ToString()); - EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); - EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); - - UpdateDisplay("400x400/r,400x400"); // 90 degrees. - generator.MoveMouseToInHost(300, 100); - hot_point = test_api.GetCursorHotPoint(); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); - // The size of cursor image is 25x25, so the rotated hot point must - // be (25-12, 11). - EXPECT_EQ("13,11", hot_point.ToString()); - EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); - - UpdateDisplay("400x400/u,400x400"); // 180 degrees. - generator.MoveMouseToInHost(300, 300); - hot_point = test_api.GetCursorHotPoint(); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); - // Rotated hot point must be (25-11, 25-12). - EXPECT_EQ("14,13", hot_point.ToString()); - EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); - - UpdateDisplay("400x400/l,400x400"); // 270 degrees. - generator.MoveMouseToInHost(100, 300); - hot_point = test_api.GetCursorHotPoint(); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); - // Rotated hot point must be (12, 25-11). - EXPECT_EQ("12,14", hot_point.ToString()); - EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); -} - -// Make sure that the mirror cursor's location is same as -// the source display's host location in the mirror root window's -// coordinates. -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorLocations) { - test::MirrorWindowTestApi test_api; - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - - // Test with device scale factor. - UpdateDisplay("400x600*2,400x600"); - - aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); - aura::test::EventGenerator generator(root); - generator.MoveMouseToInHost(10, 20); - - gfx::Point hot_point = test_api.GetCursorHotPoint(); - EXPECT_EQ("8,9", hot_point.ToString()); - gfx::Point cursor_window_origin = - test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(10 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(20 - hot_point.y(), cursor_window_origin.y()); - - // Test with ui scale - UpdateDisplay("400x600*0.5,400x600"); - generator.MoveMouseToInHost(20, 30); - - hot_point = test_api.GetCursorHotPoint(); - EXPECT_EQ("4,4", hot_point.ToString()); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(20 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(30 - hot_point.y(), cursor_window_origin.y()); - - // Test with rotation - UpdateDisplay("400x600/r,400x600"); - generator.MoveMouseToInHost(30, 40); - - hot_point = test_api.GetCursorHotPoint(); - EXPECT_EQ("21,4", hot_point.ToString()); - cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); - EXPECT_EQ(30 - hot_point.x(), cursor_window_origin.x()); - EXPECT_EQ(40 - hot_point.y(), cursor_window_origin.y()); -} - -// Make sure that the compositor based mirroring can switch -// from/to dock mode. -TEST_F(MirrorWindowControllerTest, MAYBE_DockMode) { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - const int64 internal_id = 1; - const int64 external_id = 2; - - const DisplayInfo internal_display_info = - CreateDisplayInfo(internal_id, gfx::Rect(0, 0, 500, 500)); - const DisplayInfo external_display_info = - CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); - std::vector<DisplayInfo> display_info_list; - - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - - // software mirroring. - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager->OnNativeDisplaysChanged(display_info_list); - const int64 internal_display_id = - test::DisplayManagerTestApi(display_manager). - SetFirstDisplayAsInternalDisplay(); - EXPECT_EQ(internal_id, internal_display_id); - - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_TRUE(display_manager->IsMirrored()); - EXPECT_EQ(external_id, display_manager->mirrored_display_id()); - - // dock mode. - display_info_list.clear(); - display_info_list.push_back(external_display_info); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_FALSE(display_manager->IsMirrored()); - - // back to software mirroring. - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(1U, display_manager->GetNumDisplays()); - EXPECT_TRUE(display_manager->IsMirrored()); - EXPECT_EQ(external_id, display_manager->mirrored_display_id()); -} - -TEST_F(MirrorOnBootTest, MAYBE_MirrorOnBoot) { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - EXPECT_TRUE(display_manager->IsMirrored()); - RunAllPendingInMessageLoop(); - test::MirrorWindowTestApi test_api; - EXPECT_TRUE(test_api.GetRootWindow()); -} - -} // namsspace internal -} // namespace ash diff --git a/chromium/ash/display/mouse_cursor_event_filter.cc b/chromium/ash/display/mouse_cursor_event_filter.cc deleted file mode 100644 index ebac900a891..00000000000 --- a/chromium/ash/display/mouse_cursor_event_filter.cc +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright (c) 2012 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/display/mouse_cursor_event_filter.h" - -#include "ash/display/display_controller.h" -#include "ash/display/display_manager.h" -#include "ash/display/mirror_window_controller.h" -#include "ash/display/shared_display_edge_indicator.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/wm/coordinate_conversion.h" -#include "ash/wm/window_util.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/base/layout.h" -#include "ui/compositor/dip_util.h" -#include "ui/events/event.h" -#include "ui/gfx/screen.h" - -namespace ash { -namespace internal { -namespace { - -// Maximum size on the display edge that initiate snapping phantom window, -// from the corner of the display. -const int kMaximumSnapHeight = 16; - -// Minimum height of an indicator on the display edge that allows -// dragging a window. If two displays shares the edge smaller than -// this, entire edge will be used as a draggable space. -const int kMinimumIndicatorHeight = 200; - -const int kIndicatorThickness = 1; -} - -MouseCursorEventFilter::MouseCursorEventFilter() - : mouse_warp_mode_(WARP_ALWAYS), - was_mouse_warped_(false), - drag_source_root_(NULL), - scale_when_drag_started_(1.0f), - shared_display_edge_indicator_(new SharedDisplayEdgeIndicator) { -} - -MouseCursorEventFilter::~MouseCursorEventFilter() { - HideSharedEdgeIndicator(); -} - -void MouseCursorEventFilter::ShowSharedEdgeIndicator( - const aura::Window* from) { - HideSharedEdgeIndicator(); - if (Shell::GetScreen()->GetNumDisplays() <= 1 || from == NULL) { - src_indicator_bounds_.SetRect(0, 0, 0, 0); - dst_indicator_bounds_.SetRect(0, 0, 0, 0); - drag_source_root_ = NULL; - return; - } - drag_source_root_ = from; - - DisplayLayout::Position position = Shell::GetInstance()-> - display_manager()->GetCurrentDisplayLayout().position; - if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) - UpdateHorizontalIndicatorWindowBounds(); - else - UpdateVerticalIndicatorWindowBounds(); - - shared_display_edge_indicator_->Show(src_indicator_bounds_, - dst_indicator_bounds_); -} - -void MouseCursorEventFilter::HideSharedEdgeIndicator() { - shared_display_edge_indicator_->Hide(); -} - -void MouseCursorEventFilter::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() == ui::ET_MOUSE_PRESSED) { - aura::Window* target = static_cast<aura::Window*>(event->target()); - scale_when_drag_started_ = ui::GetDeviceScaleFactor(target->layer()); - } else if (event->type() == ui::ET_MOUSE_RELEASED) { - scale_when_drag_started_ = 1.0f; - } - - // Handle both MOVED and DRAGGED events here because when the mouse pointer - // enters the other root window while dragging, the underlying window system - // (at least X11) stops generating a ui::ET_MOUSE_MOVED event. - if (event->type() != ui::ET_MOUSE_MOVED && - event->type() != ui::ET_MOUSE_DRAGGED) { - return; - } - Shell::GetInstance()->display_controller()-> - mirror_window_controller()->UpdateCursorLocation(); - - gfx::Point point_in_screen(event->location()); - aura::Window* target = static_cast<aura::Window*>(event->target()); - wm::ConvertPointToScreen(target, &point_in_screen); - if (WarpMouseCursorIfNecessary(target->GetRootWindow(), point_in_screen)) - event->StopPropagation(); -} - -bool MouseCursorEventFilter::WarpMouseCursorIfNecessary( - aura::Window* target_root, - const gfx::Point& point_in_screen) { - if (Shell::GetScreen()->GetNumDisplays() <= 1 || - mouse_warp_mode_ == WARP_NONE) - return false; - - // Do not warp again right after the cursor was warped. Sometimes the offset - // is not long enough and the cursor moves at the edge of the destination - // display. See crbug.com/278885 - // TODO(mukai): simplify the offset calculation below, it would not be - // necessary anymore with this flag. - if (was_mouse_warped_) { - was_mouse_warped_ = false; - return false; - } - - aura::Window* root_at_point = wm::GetRootWindowAt(point_in_screen); - gfx::Point point_in_root = point_in_screen; - wm::ConvertPointFromScreen(root_at_point, &point_in_root); - gfx::Rect root_bounds = root_at_point->bounds(); - int offset_x = 0; - int offset_y = 0; - - // If the window is dragged between 2x display and 1x display, - // staring from 2x display, pointer location is rounded by the - // source scale factor (2x) so it will never reach the edge (which - // is odd). Shrink by scale factor of the display where the dragging - // started instead. Only integral scale factor is supported for now. - int shrink = scale_when_drag_started_; - // Make the bounds inclusive to detect the edge. - root_bounds.Inset(0, 0, shrink, shrink); - gfx::Rect src_indicator_bounds = src_indicator_bounds_; - src_indicator_bounds.Inset(-shrink, -shrink, -shrink, -shrink); - - if (point_in_root.x() <= root_bounds.x()) { - // Use -2, not -1, to avoid infinite loop of pointer warp. - offset_x = -2 * scale_when_drag_started_; - } else if (point_in_root.x() >= root_bounds.right()) { - offset_x = 2 * scale_when_drag_started_; - } else if (point_in_root.y() <= root_bounds.y()) { - offset_y = -2 * scale_when_drag_started_; - } else if (point_in_root.y() >= root_bounds.bottom()) { - offset_y = 2 * scale_when_drag_started_; - } else { - return false; - } - - gfx::Point point_in_dst_screen(point_in_screen); - point_in_dst_screen.Offset(offset_x, offset_y); - aura::Window* dst_root = wm::GetRootWindowAt(point_in_dst_screen); - - // Warp the mouse cursor only if the location is in the indicator bounds - // or the mouse pointer is in the destination root. - if (mouse_warp_mode_ == WARP_DRAG && - dst_root != drag_source_root_ && - !src_indicator_bounds.Contains(point_in_screen)) { - return false; - } - - wm::ConvertPointFromScreen(dst_root, &point_in_dst_screen); - - if (dst_root->bounds().Contains(point_in_dst_screen)) { - DCHECK_NE(dst_root, root_at_point); - was_mouse_warped_ = true; - dst_root->MoveCursorTo(point_in_dst_screen); - return true; - } - return false; -} - -void MouseCursorEventFilter::UpdateHorizontalIndicatorWindowBounds() { - bool from_primary = Shell::GetPrimaryRootWindow() == drag_source_root_; - // GetPrimaryDisplay returns an object on stack, so copy the bounds - // instead of using reference. - const gfx::Rect primary_bounds = - Shell::GetScreen()->GetPrimaryDisplay().bounds(); - const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds(); - DisplayLayout::Position position = Shell::GetInstance()-> - display_manager()->GetCurrentDisplayLayout().position; - - src_indicator_bounds_.set_x( - std::max(primary_bounds.x(), secondary_bounds.x())); - src_indicator_bounds_.set_width( - std::min(primary_bounds.right(), secondary_bounds.right()) - - src_indicator_bounds_.x()); - src_indicator_bounds_.set_height(kIndicatorThickness); - src_indicator_bounds_.set_y( - position == DisplayLayout::TOP ? - primary_bounds.y() - (from_primary ? 0 : kIndicatorThickness) : - primary_bounds.bottom() - (from_primary ? kIndicatorThickness : 0)); - - dst_indicator_bounds_ = src_indicator_bounds_; - dst_indicator_bounds_.set_height(kIndicatorThickness); - dst_indicator_bounds_.set_y( - position == DisplayLayout::TOP ? - primary_bounds.y() - (from_primary ? kIndicatorThickness : 0) : - primary_bounds.bottom() - (from_primary ? 0 : kIndicatorThickness)); -} - -void MouseCursorEventFilter::UpdateVerticalIndicatorWindowBounds() { - bool in_primary = Shell::GetPrimaryRootWindow() == drag_source_root_; - // GetPrimaryDisplay returns an object on stack, so copy the bounds - // instead of using reference. - const gfx::Rect primary_bounds = - Shell::GetScreen()->GetPrimaryDisplay().bounds(); - const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds(); - DisplayLayout::Position position = Shell::GetInstance()-> - display_manager()->GetCurrentDisplayLayout().position; - - int upper_shared_y = std::max(primary_bounds.y(), secondary_bounds.y()); - int lower_shared_y = std::min(primary_bounds.bottom(), - secondary_bounds.bottom()); - int shared_height = lower_shared_y - upper_shared_y; - - int dst_x = position == DisplayLayout::LEFT ? - primary_bounds.x() - (in_primary ? kIndicatorThickness : 0) : - primary_bounds.right() - (in_primary ? 0 : kIndicatorThickness); - dst_indicator_bounds_.SetRect( - dst_x, upper_shared_y, kIndicatorThickness, shared_height); - - // The indicator on the source display. - src_indicator_bounds_.set_width(kIndicatorThickness); - src_indicator_bounds_.set_x( - position == DisplayLayout::LEFT ? - primary_bounds.x() - (in_primary ? 0 : kIndicatorThickness) : - primary_bounds.right() - (in_primary ? kIndicatorThickness : 0)); - - const gfx::Rect& source_bounds = - in_primary ? primary_bounds : secondary_bounds; - int upper_indicator_y = source_bounds.y() + kMaximumSnapHeight; - int lower_indicator_y = std::min(source_bounds.bottom(), lower_shared_y); - - // This gives a hight that can be used without sacrifying the snap space. - int available_space = lower_indicator_y - - std::max(upper_shared_y, upper_indicator_y); - - if (shared_height < kMinimumIndicatorHeight) { - // If the shared height is smaller than minimum height, use the - // entire height. - upper_indicator_y = upper_shared_y; - } else if (available_space < kMinimumIndicatorHeight) { - // Snap to the bottom. - upper_indicator_y = - std::max(upper_shared_y, lower_indicator_y + kMinimumIndicatorHeight); - } else { - upper_indicator_y = std::max(upper_indicator_y, upper_shared_y); - } - src_indicator_bounds_.set_y(upper_indicator_y); - src_indicator_bounds_.set_height(lower_indicator_y - upper_indicator_y); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/mouse_cursor_event_filter.h b/chromium/ash/display/mouse_cursor_event_filter.h deleted file mode 100644 index b05456e9048..00000000000 --- a/chromium/ash/display/mouse_cursor_event_filter.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H -#define ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/gtest_prod_util.h" -#include "base/memory/scoped_ptr.h" -#include "ui/events/event_handler.h" -#include "ui/gfx/rect.h" - -namespace aura { -class RootWindow; -class Window; -} - -namespace ash { -class DisplayController; - -namespace internal { -class SharedDisplayEdgeIndicator; - -// An event filter that controls mouse location in extended desktop -// environment. -class ASH_EXPORT MouseCursorEventFilter : public ui::EventHandler { - public: - enum MouseWarpMode { - WARP_ALWAYS, // Always warp the mouse when possible. - WARP_DRAG, // Used when dragging a window. Top and bottom - // corner of the shared edge is reserved for window - // snapping. - WARP_NONE, // No mouse warping. Used when resizing the window. - }; - - MouseCursorEventFilter(); - virtual ~MouseCursorEventFilter(); - - void set_mouse_warp_mode(MouseWarpMode mouse_warp_mode) { - mouse_warp_mode_ = mouse_warp_mode; - } - - // Shows/Hide the indicator for window dragging. The |from| - // is the window where the dragging started. - void ShowSharedEdgeIndicator(const aura::Window* from); - void HideSharedEdgeIndicator(); - - // Overridden from ui::EventHandler: - virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; - - private: - friend class DragWindowResizerTest; - friend class MouseCursorEventFilterTest; - FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, DoNotWarpTwice); - FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, SetMouseWarpModeFlag); - FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, - IndicatorBoundsTestOnRight); - FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, - IndicatorBoundsTestOnLeft); - FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, - IndicatorBoundsTestOnTopBottom); - FRIEND_TEST_ALL_PREFIXES(DragWindowResizerTest, WarpMousePointer); - - void reset_was_mouse_warped_for_test() { was_mouse_warped_ = false; } - - // Warps the mouse cursor to an alternate root window when the - // |point_in_screen|, which is the location of the mouse cursor, - // hits or exceeds the edge of the |target_root| and the mouse cursor - // is considered to be in an alternate display. Returns true if - // the cursor was moved. - bool WarpMouseCursorIfNecessary(aura::Window* target_root, - const gfx::Point& point_in_screen); - - void UpdateHorizontalIndicatorWindowBounds(); - void UpdateVerticalIndicatorWindowBounds(); - - MouseWarpMode mouse_warp_mode_; - - // This flag is used to suppress the accidental mouse warp back to the - // original display. - bool was_mouse_warped_; - - // The bounds for warp hole windows. |dst_indicator_bounds_| is kept - // in the instance for testing. - gfx::Rect src_indicator_bounds_; - gfx::Rect dst_indicator_bounds_; - - // The root window in which the dragging started. - const aura::Window* drag_source_root_; - - float scale_when_drag_started_; - - // Shows the area where a window can be dragged in to/out from - // another display. - scoped_ptr<SharedDisplayEdgeIndicator> shared_display_edge_indicator_; - - DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilter); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H diff --git a/chromium/ash/display/mouse_cursor_event_filter_unittest.cc b/chromium/ash/display/mouse_cursor_event_filter_unittest.cc deleted file mode 100644 index 7fa79fd6f3b..00000000000 --- a/chromium/ash/display/mouse_cursor_event_filter_unittest.cc +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright (c) 2012 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/display/mouse_cursor_event_filter.h" - -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/cursor_manager_test_api.h" -#include "ash/display/display_layout_store.h" -#include "ash/display/display_manager.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" - -namespace ash { -namespace internal { - -class MouseCursorEventFilterTest : public test::AshTestBase { - public: - MouseCursorEventFilterTest() {} - virtual ~MouseCursorEventFilterTest() {} - - protected: - MouseCursorEventFilter* event_filter() { - return Shell::GetInstance()->mouse_cursor_filter(); - } - - bool WarpMouseCursorIfNecessary(aura::Window* target_root, - gfx::Point point_in_screen) { - bool is_warped = event_filter()->WarpMouseCursorIfNecessary( - target_root, point_in_screen); - event_filter()->reset_was_mouse_warped_for_test(); - return is_warped; - } - - bool WarpMouseCursorIfNecessaryWithDragRoot( - aura::Window* drag_source_root, - aura::Window* target_root, - gfx::Point point_in_screen) { - gfx::Point location = drag_source_root->bounds().CenterPoint(); - ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, location, - location, 0); - ui::Event::DispatcherApi(&pressed).set_target(drag_source_root); - event_filter()->OnMouseEvent(&pressed); - bool is_warped = event_filter()->WarpMouseCursorIfNecessary( - target_root, point_in_screen); - event_filter()->reset_was_mouse_warped_for_test(); - - ui::MouseEvent released(ui::ET_MOUSE_RELEASED, location, - location, 0); - ui::Event::DispatcherApi(&released).set_target(drag_source_root); - event_filter()->OnMouseEvent(&released); - return is_warped; - } - - private: - MouseCursorEventFilter* event_filter_; - - DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilterTest); -}; - -// Verifies if the mouse pointer correctly moves to another display when there -// are two displays. -TEST_F(MouseCursorEventFilterTest, WarpMouse) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("500x500,500x500"); - - ASSERT_EQ( - DisplayLayout::RIGHT, - Shell::GetInstance()->display_manager()->layout_store()-> - default_display_layout().position); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 11))); - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 11))); - - // Touch the right edge of the primary root window. Pointer should warp. - EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11))); - EXPECT_EQ("501,11", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Touch the left edge of the secondary root window. Pointer should warp. - EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(500, 11))); - EXPECT_EQ("498,11", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Touch the left edge of the primary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(0, 11))); - // Touch the top edge of the primary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 0))); - // Touch the bottom edge of the primary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], - gfx::Point(11, 499))); - // Touch the right edge of the secondary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], - gfx::Point(999, 11))); - // Touch the top edge of the secondary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 0))); - // Touch the bottom edge of the secondary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], - gfx::Point(11, 499))); -} - -// Verifies if the mouse pointer correctly moves to another display even when -// two displays are not the same size. -TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("500x500,600x600"); // the second one is larger. - - ASSERT_EQ( - DisplayLayout::RIGHT, - Shell::GetInstance()->display_manager()-> - GetCurrentDisplayLayout().position); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123)); - - // Touch the left edge of the secondary root window. Pointer should NOT warp - // because 1px left of (0, 500) is outside the primary root window. - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(0, 500))); - EXPECT_EQ("623,123", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Touch the left edge of the secondary root window. Pointer should warp - // because 1px left of (0, 499) is inside the primary root window. - EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], - gfx::Point(500, 499))); - EXPECT_EQ("498,499", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); -} - -// Verifies if the mouse pointer correctly moves between displays with -// different scale factors. -TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplays) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("500x500,600x600*2"); - - ASSERT_EQ( - DisplayLayout::RIGHT, - Shell::GetInstance()->display_manager()-> - GetCurrentDisplayLayout().position); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123)); - - // This emulates the dragging to the 2nd display, which has - // higher scale factor, by having 2nd display's root as target - // but have the edge of 1st display. - EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( - root_windows[1], root_windows[1], gfx::Point(498, 123))); - EXPECT_EQ("502,123", - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Touch the edge of 2nd display again and make sure it warps to - // 1st dislay. - EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( - root_windows[1], root_windows[1], gfx::Point(500, 123))); - EXPECT_EQ("496,123", - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Draging back from 1x to 2x. - EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( - root_windows[1], root_windows[0], gfx::Point(500, 123))); - EXPECT_EQ("496,123", - aura::Env::GetInstance()->last_mouse_location().ToString()); - - UpdateDisplay("500x500*2,600x600"); - // Draging back from 1x to 2x. - EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( - root_windows[0], root_windows[1], gfx::Point(250, 123))); - EXPECT_EQ("246,123", - aura::Env::GetInstance()->last_mouse_location().ToString()); -} - -TEST_F(MouseCursorEventFilterTest, DoNotWarpTwice) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("500x500,600x600"); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123)); - - // Touch the right edge of the primary root window. Pointer should warp. - EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[0], - gfx::Point(499, 11))); - EXPECT_EQ("501,11", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); - - // Touch the left edge of the secondary root window immediately. This should - // be ignored. - EXPECT_FALSE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], - gfx::Point(500, 11))); - - // Touch the left edge of the secondary root window again, pointer should - // warp for this time. - EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], - gfx::Point(500, 11))); - EXPECT_EQ("498,11", // by 2px. - aura::Env::GetInstance()->last_mouse_location().ToString()); -} - -// Verifies if MouseCursorEventFilter::set_mouse_warp_mode() works as expected. -TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("500x500,500x500"); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1)); - - event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE); - EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], - gfx::Point(499, 11))); - EXPECT_EQ("1,1", - aura::Env::GetInstance()->last_mouse_location().ToString()); - - event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS); - EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11))); - EXPECT_EQ("501,11", - aura::Env::GetInstance()->last_mouse_location().ToString()); -} - -// Verifies if MouseCursorEventFilter's bounds calculation works correctly. -TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnRight) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("360x360,700x700"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - DisplayLayout layout(DisplayLayout::RIGHT, 0); - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("360,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - - // Move 2nd display downwards a bit. - layout.offset = 5; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - // This is same as before because the 2nd display's y is above - // the indicator's x. - EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("360,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("360,21 1x339", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("359,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); - - // Move it down further so that the shared edge is shorter than - // minimum hole size (160). - layout.offset = 200; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("359,200 1x160", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("360,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("360,200 1x160", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("359,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); - - // Now move 2nd display upwards - layout.offset = -5; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - // 16 px are reserved on 2nd display from top, so y must be - // (16 - 5) = 11 - EXPECT_EQ("360,11 1x349", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - - event_filter()->HideSharedEdgeIndicator(); -} - -TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnLeft) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("360x360,700x700"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - DisplayLayout layout(DisplayLayout::LEFT, 0); - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("0,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("-1,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("-1,16 1x344", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); - - layout.offset = 250; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("0,250 1x110", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("-1,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("-1,250 1x110", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->HideSharedEdgeIndicator(); -} - -TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnTopBottom) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("360x360,700x700"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - DisplayLayout layout(DisplayLayout::TOP, 0); - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("0,0 360x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,-1 360x1", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("0,-1 360x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,0 360x1", event_filter()->dst_indicator_bounds_.ToString()); - - layout.offset = 250; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("250,0 110x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("250,-1 110x1", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("250,-1 110x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("250,0 110x1", event_filter()->dst_indicator_bounds_.ToString()); - - layout.position = DisplayLayout::BOTTOM; - layout.offset = 0; - display_manager->SetLayoutForCurrentDisplays(layout); - event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - EXPECT_EQ("0,359 360x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,360 360x1", event_filter()->dst_indicator_bounds_.ToString()); - event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ("0,360 360x1", event_filter()->src_indicator_bounds_.ToString()); - EXPECT_EQ("0,359 360x1", event_filter()->dst_indicator_bounds_.ToString()); - - event_filter()->HideSharedEdgeIndicator(); -} - -// Verifies cursor's device scale factor is updated when a cursor has moved -// across root windows with different device scale factors -// (http://crbug.com/154183). -TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("400x400,800x800*2"); - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetLayoutForCurrentDisplays( - DisplayLayout(DisplayLayout::RIGHT, 0)); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - ASSERT_EQ(2U, root_windows.size()); - test::CursorManagerTestApi cursor_test_api( - Shell::GetInstance()->cursor_manager()); - - EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); - WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200)); - EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); - WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200)); - EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/output_configurator_animation.cc b/chromium/ash/display/output_configurator_animation.cc deleted file mode 100644 index 2fb5d5204e8..00000000000 --- a/chromium/ash/display/output_configurator_animation.cc +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2012 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/display/output_configurator_animation.h" - -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "base/bind.h" -#include "base/stl_util.h" -#include "base/time/time.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/compositor/layer.h" -#include "ui/compositor/layer_animation_observer.h" -#include "ui/compositor/layer_animation_sequence.h" -#include "ui/compositor/layer_animator.h" -#include "ui/compositor/scoped_layer_animation_settings.h" - -namespace ash { -namespace internal { -namespace { - -const int kFadingAnimationDurationInMS = 200; -const int kFadingTimeoutDurationInSeconds = 10; - -// CallbackRunningObserver accepts multiple layer animations and -// runs the specified |callback| when all of the animations have finished. -class CallbackRunningObserver { - public: - CallbackRunningObserver(base::Closure callback) - : completed_counter_(0), - animation_aborted_(false), - callback_(callback) {} - - void AddNewAnimator(ui::LayerAnimator* animator) { - Observer* observer = new Observer(animator, this); - animator->AddObserver(observer); - observer_list_.push_back(observer); - } - - private: - void OnSingleTaskCompleted() { - completed_counter_++; - if (completed_counter_ >= observer_list_.size()) { - base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this); - if (!animation_aborted_) - base::MessageLoopForUI::current()->PostTask(FROM_HERE, callback_); - } - } - - void OnSingleTaskAborted() { - animation_aborted_ = true; - OnSingleTaskCompleted(); - } - - // The actual observer to listen each animation completion. - class Observer : public ui::LayerAnimationObserver { - public: - Observer(ui::LayerAnimator* animator, - CallbackRunningObserver* observer) - : animator_(animator), - observer_(observer) {} - - protected: - // ui::LayerAnimationObserver overrides: - virtual void OnLayerAnimationEnded( - ui::LayerAnimationSequence* sequence) OVERRIDE { - animator_->RemoveObserver(this); - observer_->OnSingleTaskCompleted(); - } - virtual void OnLayerAnimationAborted( - ui::LayerAnimationSequence* sequence) OVERRIDE { - animator_->RemoveObserver(this); - observer_->OnSingleTaskAborted(); - } - virtual void OnLayerAnimationScheduled( - ui::LayerAnimationSequence* sequence) OVERRIDE { - } - virtual bool RequiresNotificationWhenAnimatorDestroyed() const OVERRIDE { - return true; - } - - private: - ui::LayerAnimator* animator_; - CallbackRunningObserver* observer_; - - DISALLOW_COPY_AND_ASSIGN(Observer); - }; - - size_t completed_counter_; - bool animation_aborted_; - ScopedVector<Observer> observer_list_; - base::Closure callback_; - - DISALLOW_COPY_AND_ASSIGN(CallbackRunningObserver); -}; - -} // namespace - -OutputConfiguratorAnimation::OutputConfiguratorAnimation() { -} - -OutputConfiguratorAnimation::~OutputConfiguratorAnimation() { - ClearHidingLayers(); -} - -void OutputConfiguratorAnimation::StartFadeOutAnimation( - base::Closure callback) { - CallbackRunningObserver* observer = new CallbackRunningObserver(callback); - ClearHidingLayers(); - - // Make the fade-out animation for all root windows. Instead of actually - // hiding the root windows, we put a black layer over a root window for - // safety. These layers remain to hide root windows and will be deleted - // after the animation of OnDisplayModeChanged(). - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - for (aura::Window::Windows::const_iterator it = root_windows.begin(); - it != root_windows.end(); ++it) { - aura::Window* root_window = *it; - ui::Layer* hiding_layer = new ui::Layer(ui::LAYER_SOLID_COLOR); - hiding_layer->SetColor(SK_ColorBLACK); - hiding_layer->SetBounds(root_window->bounds()); - ui::Layer* parent = ash::Shell::GetContainer( - root_window, - ash::internal::kShellWindowId_OverlayContainer)->layer(); - parent->Add(hiding_layer); - - hiding_layer->SetOpacity(0.0); - - ui::ScopedLayerAnimationSettings settings(hiding_layer->GetAnimator()); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( - kFadingAnimationDurationInMS)); - observer->AddNewAnimator(hiding_layer->GetAnimator()); - hiding_layer->SetOpacity(1.0f); - hiding_layer->SetVisible(true); - hiding_layers_[root_window] = hiding_layer; - } - - // In case that OnDisplayModeChanged() isn't called or its animator is - // canceled due to some unknown errors, we set a timer to clear these - // hiding layers. - timer_.reset(new base::OneShotTimer<OutputConfiguratorAnimation>()); - timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kFadingTimeoutDurationInSeconds), - this, - &OutputConfiguratorAnimation::ClearHidingLayers); -} - -void OutputConfiguratorAnimation::StartFadeInAnimation() { - // We want to make sure clearing all of hiding layers after the animation - // finished. Note that this callback can be canceled, but the cancel only - // happens when the next animation is scheduled. Thus the hiding layers - // should be deleted eventually. - CallbackRunningObserver* observer = new CallbackRunningObserver( - base::Bind(&OutputConfiguratorAnimation::ClearHidingLayers, - base::Unretained(this))); - - // Ensure that layers are not animating. - for (std::map<aura::Window*, ui::Layer*>::iterator it = - hiding_layers_.begin(); it != hiding_layers_.end(); ++it) { - ui::LayerAnimator* animator = it->second->GetAnimator(); - if (animator->is_animating()) - animator->StopAnimating(); - } - - // Schedules the fade-in effect for all root windows. Because we put the - // black layers for fade-out, here we actually turn those black layers - // invisible. - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - for (aura::Window::Windows::const_iterator it = root_windows.begin(); - it != root_windows.end(); ++it) { - aura::Window* root_window = *it; - ui::Layer* hiding_layer = NULL; - if (hiding_layers_.find(root_window) == hiding_layers_.end()) { - // In case of the transition from mirroring->non-mirroring, new root - // windows appear and we do not have the black layers for them. Thus - // we need to create the layer and make it visible. - hiding_layer = new ui::Layer(ui::LAYER_SOLID_COLOR); - hiding_layer->SetColor(SK_ColorBLACK); - hiding_layer->SetBounds(root_window->bounds()); - ui::Layer* parent = ash::Shell::GetContainer( - root_window, - ash::internal::kShellWindowId_OverlayContainer)->layer(); - parent->Add(hiding_layer); - hiding_layer->SetOpacity(1.0f); - hiding_layer->SetVisible(true); - hiding_layers_[root_window] = hiding_layer; - } else { - hiding_layer = hiding_layers_[root_window]; - if (hiding_layer->bounds() != root_window->bounds()) - hiding_layer->SetBounds(root_window->bounds()); - } - - ui::ScopedLayerAnimationSettings settings(hiding_layer->GetAnimator()); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( - kFadingAnimationDurationInMS)); - observer->AddNewAnimator(hiding_layer->GetAnimator()); - hiding_layer->SetOpacity(0.0f); - hiding_layer->SetVisible(false); - } -} - -void OutputConfiguratorAnimation::OnDisplayModeChanged( - const std::vector<chromeos::OutputConfigurator::OutputSnapshot>& outputs) { - if (!hiding_layers_.empty()) - StartFadeInAnimation(); -} - -void OutputConfiguratorAnimation::OnDisplayModeChangeFailed( - chromeos::OutputState failed_new_state) { - if (!hiding_layers_.empty()) - StartFadeInAnimation(); -} - -void OutputConfiguratorAnimation::ClearHidingLayers() { - if (timer_) { - timer_->Stop(); - timer_.reset(); - } - STLDeleteContainerPairSecondPointers( - hiding_layers_.begin(), hiding_layers_.end()); - hiding_layers_.clear(); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/output_configurator_animation.h b/chromium/ash/display/output_configurator_animation.h deleted file mode 100644 index f53ffa58656..00000000000 --- a/chromium/ash/display/output_configurator_animation.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_OUTPUT_CONFIGURATOR_ANIMATION_H_ -#define ASH_DISPLAY_OUTPUT_CONFIGURATOR_ANIMATION_H_ - -#include <map> - -#include "ash/ash_export.h" -#include "base/callback.h" -#include "base/timer/timer.h" -#include "chromeos/display/output_configurator.h" - -namespace aura { -class RootWindow; -class Window; -} // namespace aura - -namespace ui { -class Layer; -} // namespace ui - -namespace ash { -namespace internal { - -// OutputConfiguratorAnimation provides the visual effects for -// chromeos::OutputConfigurator, such like fade-out/in during changing -// the display mode. -class ASH_EXPORT OutputConfiguratorAnimation - : public chromeos::OutputConfigurator::Observer { - public: - OutputConfiguratorAnimation(); - virtual ~OutputConfiguratorAnimation(); - - // Starts the fade-out animation for the all root windows. It will - // call |callback| once all of the animations have finished. - void StartFadeOutAnimation(base::Closure callback); - - // Starts the animation to clear the fade-out animation effect - // for the all root windows. - void StartFadeInAnimation(); - - protected: - // chromeos::OutputConfigurator::Observer overrides: - virtual void OnDisplayModeChanged( - const std::vector<chromeos::OutputConfigurator::OutputSnapshot>& outputs) - OVERRIDE; - virtual void OnDisplayModeChangeFailed( - chromeos::OutputState failed_new_state) OVERRIDE; - - private: - // Clears all hiding layers. Note that in case that this method is called - // during an animation, the method call will cancel all of the animations - // and *not* call the registered callback. - void ClearHidingLayers(); - - std::map<aura::Window*, ui::Layer*> hiding_layers_; - scoped_ptr<base::OneShotTimer<OutputConfiguratorAnimation> > timer_; - - DISALLOW_COPY_AND_ASSIGN(OutputConfiguratorAnimation); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_OUTPUT_CONFIGURATION_CONTROLLER_H_ diff --git a/chromium/ash/display/resolution_notification_controller.cc b/chromium/ash/display/resolution_notification_controller.cc deleted file mode 100644 index 0914772ac01..00000000000 --- a/chromium/ash/display/resolution_notification_controller.cc +++ /dev/null @@ -1,305 +0,0 @@ -// 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/display/resolution_notification_controller.h" - -#include "ash/display/display_controller.h" -#include "ash/display/display_manager.h" -#include "ash/shell.h" -#include "ash/system/system_notifier.h" -#include "base/strings/utf_string_conversions.h" -#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/display.h" -#include "ui/gfx/screen.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/notification.h" -#include "ui/message_center/notification_delegate.h" - -using message_center::Notification; - -namespace ash { -namespace internal { -namespace { - -bool g_use_timer = true; - -class ResolutionChangeNotificationDelegate - : public message_center::NotificationDelegate { - public: - ResolutionChangeNotificationDelegate( - ResolutionNotificationController* controller, - bool has_timeout); - - protected: - virtual ~ResolutionChangeNotificationDelegate(); - - private: - // message_center::NotificationDelegate overrides: - virtual void Display() OVERRIDE; - virtual void Error() OVERRIDE; - virtual void Close(bool by_user) OVERRIDE; - virtual void Click() OVERRIDE; - virtual bool HasClickedListener() OVERRIDE; - virtual void ButtonClick(int button_index) OVERRIDE; - - ResolutionNotificationController* controller_; - bool has_timeout_; - - DISALLOW_COPY_AND_ASSIGN(ResolutionChangeNotificationDelegate); -}; - -ResolutionChangeNotificationDelegate::ResolutionChangeNotificationDelegate( - ResolutionNotificationController* controller, - bool has_timeout) - : controller_(controller), - has_timeout_(has_timeout) { - DCHECK(controller_); -} - -ResolutionChangeNotificationDelegate::~ResolutionChangeNotificationDelegate() { -} - -void ResolutionChangeNotificationDelegate::Display() { -} - -void ResolutionChangeNotificationDelegate::Error() { -} - -void ResolutionChangeNotificationDelegate::Close(bool by_user) { - if (by_user) - controller_->AcceptResolutionChange(false); -} - -void ResolutionChangeNotificationDelegate::Click() { - controller_->AcceptResolutionChange(true); -} - -bool ResolutionChangeNotificationDelegate::HasClickedListener() { - return true; -} - -void ResolutionChangeNotificationDelegate::ButtonClick(int button_index) { - // If there's the timeout, the first button is "Accept". Otherwise the - // button click should be "Revert". - if (has_timeout_ && button_index == 0) - controller_->AcceptResolutionChange(true); - else - controller_->RevertResolutionChange(); -} - -} // namespace - -// static -const int ResolutionNotificationController::kTimeoutInSec = 15; - -// static -const char ResolutionNotificationController::kNotificationId[] = - "chrome://settings/display/resolution"; - -struct ResolutionNotificationController::ResolutionChangeInfo { - ResolutionChangeInfo(int64 display_id, - const gfx::Size& old_resolution, - const gfx::Size& new_resolution, - const base::Closure& accept_callback); - ~ResolutionChangeInfo(); - - // The id of the display where the resolution change happens. - int64 display_id; - - // The resolution before the change. - gfx::Size old_resolution; - - // The new resolution after the change. - gfx::Size new_resolution; - - // The callback when accept is chosen. - base::Closure accept_callback; - - // The remaining timeout in seconds. 0 if the change does not time out. - uint8 timeout_count; - - // The timer to invoke OnTimerTick() every second. This cannot be - // OneShotTimer since the message contains text "automatically closed in xx - // seconds..." which has to be updated every second. - base::RepeatingTimer<ResolutionNotificationController> timer; - - private: - DISALLOW_COPY_AND_ASSIGN(ResolutionChangeInfo); -}; - -ResolutionNotificationController::ResolutionChangeInfo::ResolutionChangeInfo( - int64 display_id, - const gfx::Size& old_resolution, - const gfx::Size& new_resolution, - const base::Closure& accept_callback) - : display_id(display_id), - old_resolution(old_resolution), - new_resolution(new_resolution), - accept_callback(accept_callback), - timeout_count(0) { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - if (!display_manager->HasInternalDisplay() && - display_manager->num_connected_displays() == 1u) { - timeout_count = kTimeoutInSec; - } -} - -ResolutionNotificationController::ResolutionChangeInfo:: - ~ResolutionChangeInfo() { -} - -ResolutionNotificationController::ResolutionNotificationController() { - Shell::GetInstance()->display_controller()->AddObserver(this); - Shell::GetScreen()->AddObserver(this); -} - -ResolutionNotificationController::~ResolutionNotificationController() { - Shell::GetInstance()->display_controller()->RemoveObserver(this); - Shell::GetScreen()->RemoveObserver(this); -} - -void ResolutionNotificationController::SetDisplayResolutionAndNotify( - int64 display_id, - const gfx::Size& old_resolution, - const gfx::Size& new_resolution, - const base::Closure& accept_callback) { - // If multiple resolution changes are invoked for the same display, - // the original resolution for the first resolution change has to be used - // instead of the specified |old_resolution|. - gfx::Size original_resolution; - if (change_info_ && change_info_->display_id == display_id) { - DCHECK(change_info_->new_resolution == old_resolution); - original_resolution = change_info_->old_resolution; - } - - change_info_.reset(new ResolutionChangeInfo( - display_id, old_resolution, new_resolution, accept_callback)); - if (!original_resolution.IsEmpty()) - change_info_->old_resolution = original_resolution; - - // SetDisplayResolution() causes OnConfigurationChanged() and the notification - // will be shown at that point. - Shell::GetInstance()->display_manager()->SetDisplayResolution( - display_id, new_resolution); -} - -bool ResolutionNotificationController::DoesNotificationTimeout() { - return change_info_ && change_info_->timeout_count > 0; -} - -void ResolutionNotificationController::CreateOrUpdateNotification( - bool enable_spoken_feedback) { - message_center::MessageCenter* message_center = - message_center::MessageCenter::Get(); - if (!change_info_) { - message_center->RemoveNotification(kNotificationId, false /* by_user */); - return; - } - - base::string16 timeout_message; - message_center::RichNotificationData data; - if (change_info_->timeout_count > 0) { - data.buttons.push_back(message_center::ButtonInfo( - l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_ACCEPT))); - timeout_message = l10n_util::GetStringFUTF16( - IDS_ASH_DISPLAY_RESOLUTION_TIMEOUT, - ui::TimeFormat::TimeDurationLong( - base::TimeDelta::FromSeconds(change_info_->timeout_count))); - } - data.buttons.push_back(message_center::ButtonInfo( - l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_REVERT))); - - data.should_make_spoken_feedback_for_popup_updates = enable_spoken_feedback; - - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - scoped_ptr<Notification> notification(new Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, - kNotificationId, - l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED, - UTF8ToUTF16(Shell::GetInstance()->display_manager()-> - GetDisplayNameForId(change_info_->display_id)), - UTF8ToUTF16(change_info_->new_resolution.ToString())), - timeout_message, - bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY), - base::string16() /* display_source */, - message_center::NotifierId( - message_center::NotifierId::SYSTEM_COMPONENT, - system_notifier::kNotifierDisplayResolutionChange), - data, - new ResolutionChangeNotificationDelegate( - this, change_info_->timeout_count > 0))); - notification->SetSystemPriority(); - message_center->AddNotification(notification.Pass()); -} - -void ResolutionNotificationController::OnTimerTick() { - if (!change_info_) - return; - - --change_info_->timeout_count; - if (change_info_->timeout_count == 0) - RevertResolutionChange(); - else - CreateOrUpdateNotification(false); -} - -void ResolutionNotificationController::AcceptResolutionChange( - bool close_notification) { - if (close_notification) { - message_center::MessageCenter::Get()->RemoveNotification( - kNotificationId, false /* by_user */); - } - base::Closure callback = change_info_->accept_callback; - change_info_.reset(); - callback.Run(); -} - -void ResolutionNotificationController::RevertResolutionChange() { - message_center::MessageCenter::Get()->RemoveNotification( - kNotificationId, false /* by_user */); - int64 display_id = change_info_->display_id; - gfx::Size old_resolution = change_info_->old_resolution; - change_info_.reset(); - Shell::GetInstance()->display_manager()->SetDisplayResolution( - display_id, old_resolution); -} - -void ResolutionNotificationController::OnDisplayBoundsChanged( - const gfx::Display& display) { -} - -void ResolutionNotificationController::OnDisplayAdded( - const gfx::Display& new_display) { -} - -void ResolutionNotificationController::OnDisplayRemoved( - const gfx::Display& old_display) { - if (change_info_ && change_info_->display_id == old_display.id()) - RevertResolutionChange(); -} - -void ResolutionNotificationController::OnDisplayConfigurationChanged() { - if (!change_info_) - return; - - CreateOrUpdateNotification(true); - if (g_use_timer && change_info_->timeout_count > 0) { - change_info_->timer.Start(FROM_HERE, - base::TimeDelta::FromSeconds(1), - this, - &ResolutionNotificationController::OnTimerTick); - } -} - -void ResolutionNotificationController::SuppressTimerForTest() { - g_use_timer = false; -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/resolution_notification_controller.h b/chromium/ash/display/resolution_notification_controller.h deleted file mode 100644 index bacc9c8bee3..00000000000 --- a/chromium/ash/display/resolution_notification_controller.h +++ /dev/null @@ -1,99 +0,0 @@ -// 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_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_ -#define ASH_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_ - -#include "ash/ash_export.h" -#include "ash/display/display_controller.h" -#include "base/callback.h" -#include "base/gtest_prod_util.h" -#include "base/timer/timer.h" -#include "ui/gfx/display_observer.h" -#include "ui/gfx/size.h" - -namespace chromeos { -FORWARD_DECLARE_TEST(DisplayPreferencesTest, PreventStore); -} // namespace chromeos - -namespace views { -class Label; -class Widget; -} // namespace views - -namespace ash { -namespace internal { -// A class which manages the notification of display resolution change and -// also manages the timeout in case the new resolution is unusable. -class ASH_EXPORT ResolutionNotificationController - : public gfx::DisplayObserver, - public DisplayController::Observer { - public: - ResolutionNotificationController(); - virtual ~ResolutionNotificationController(); - - // Updates the display resolution for |display_id| to |new_resolution| and - // creates a notification for this change which offers a button to revert the - // change in case something goes wrong. The notification times out if there's - // only one display connected and the user is trying to modify its resolution. - // In that case, the timeout has to be set since the user cannot make any - // changes if something goes wrong. - void SetDisplayResolutionAndNotify( - int64 display_id, - const gfx::Size& old_resolution, - const gfx::Size& new_resolution, - const base::Closure& accept_callback); - - // Returns true if the notification is visible or scheduled to be visible and - // the notification times out. - bool DoesNotificationTimeout(); - - // Called by the notification delegate when the user accepts the display - // resolution change. Set |close_notification| to true when the notification - // should be removed. - void AcceptResolutionChange(bool close_notification); - - // Called by the notification delegate when the user wants to revert the - // display resolution change. - void RevertResolutionChange(); - - private: - friend class ResolutionNotificationControllerTest; - FRIEND_TEST_ALL_PREFIXES(ResolutionNotificationControllerTest, Timeout); - FRIEND_TEST_ALL_PREFIXES(chromeos::DisplayPreferencesTest, PreventStore); - - // A struct to bundle the data for a single resolution change. - struct ResolutionChangeInfo; - - static const int kTimeoutInSec; - static const char kNotificationId[]; - - // Create a new notification, or update its content if it already exists. - // |enable_spoken_feedback| is set to false when the notification is updated - // during the countdown so the update isn't necessarily read by the spoken - // feedback. - void CreateOrUpdateNotification(bool enable_spoken_feedback); - - // Called every second for timeout. - void OnTimerTick(); - - // gfx::DisplayObserver overrides: - virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; - virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; - virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; - - // DisplayController::Observer overrides: - virtual void OnDisplayConfigurationChanged() OVERRIDE; - - static void SuppressTimerForTest(); - - scoped_ptr<ResolutionChangeInfo> change_info_; - - DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationController); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_ diff --git a/chromium/ash/display/resolution_notification_controller_unittest.cc b/chromium/ash/display/resolution_notification_controller_unittest.cc deleted file mode 100644 index 0ec8852df05..00000000000 --- a/chromium/ash/display/resolution_notification_controller_unittest.cc +++ /dev/null @@ -1,314 +0,0 @@ -// 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/display/resolution_notification_controller.h" - -#include "ash/display/display_manager.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "base/bind.h" -#include "ui/gfx/size.h" -#include "ui/message_center/message_center.h" - -namespace ash { -namespace internal { - -class ResolutionNotificationControllerTest : public ash::test::AshTestBase { - public: - ResolutionNotificationControllerTest() - : accept_count_(0) { - } - - virtual ~ResolutionNotificationControllerTest() {} - - protected: - virtual void SetUp() OVERRIDE { - ash::test::AshTestBase::SetUp(); - ResolutionNotificationController::SuppressTimerForTest(); - } - - void SetDisplayResolutionAndNotify(const gfx::Display& display, - const gfx::Size& new_resolution) { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - const DisplayInfo& info = display_manager->GetDisplayInfo(display.id()); - Shell::GetInstance()->resolution_notification_controller()-> - SetDisplayResolutionAndNotify( - display.id(), - info.size_in_pixel(), - new_resolution, - base::Bind(&ResolutionNotificationControllerTest::OnAccepted, - base::Unretained(this))); - - // OnConfigurationChanged event won't be emitted in the test environment, - // so invoke UpdateDisplay() to emit that event explicitly. - std::vector<DisplayInfo> info_list; - for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { - int64 id = display_manager->GetDisplayAt(i).id(); - DisplayInfo info = display_manager->GetDisplayInfo(id); - if (display.id() == id) { - gfx::Rect bounds = info.bounds_in_native(); - bounds.set_size(new_resolution); - info.SetBounds(bounds); - } - info_list.push_back(info); - } - display_manager->OnNativeDisplaysChanged(info_list); - RunAllPendingInMessageLoop(); - } - - void ClickOnNotification() { - message_center::MessageCenter::Get()->ClickOnNotification( - ResolutionNotificationController::kNotificationId); - } - - void ClickOnNotificationButton(int index) { - message_center::MessageCenter::Get()->ClickOnNotificationButton( - ResolutionNotificationController::kNotificationId, index); - } - - void CloseNotification() { - message_center::MessageCenter::Get()->RemoveNotification( - ResolutionNotificationController::kNotificationId, true /* by_user */); - } - - bool IsNotificationVisible() { - return message_center::MessageCenter::Get()->HasNotification( - ResolutionNotificationController::kNotificationId); - } - - void TickTimer() { - controller()->OnTimerTick(); - } - - ResolutionNotificationController* controller() { - return Shell::GetInstance()->resolution_notification_controller(); - } - - int accept_count() const { - return accept_count_; - } - - private: - void OnAccepted() { - EXPECT_FALSE(controller()->DoesNotificationTimeout()); - accept_count_++; - } - - int accept_count_; - - DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationControllerTest); -}; - -// Basic behaviors and verifies it doesn't cause crashes. -TEST_F(ResolutionNotificationControllerTest, Basic) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - ASSERT_EQ(0, accept_count()); - EXPECT_FALSE(IsNotificationVisible()); - - // Changes the resolution and apply the result. - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - EXPECT_FALSE(controller()->DoesNotificationTimeout()); - gfx::Size resolution; - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); - - // Click the revert button, which reverts to the best resolution. - ClickOnNotificationButton(0); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(0, accept_count()); - EXPECT_FALSE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); -} - -TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - ASSERT_EQ(0, accept_count()); - EXPECT_FALSE(IsNotificationVisible()); - - // Changes the resolution and apply the result. - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - EXPECT_FALSE(controller()->DoesNotificationTimeout()); - gfx::Size resolution; - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); - - // Click the revert button, which reverts the resolution. - ClickOnNotification(); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(1, accept_count()); - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); -} - -TEST_F(ResolutionNotificationControllerTest, AcceptButton) { - if (!SupportsMultipleDisplays()) - return; - - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - - UpdateDisplay("300x300#300x300|200x200"); - const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay(); - SetDisplayResolutionAndNotify(display, gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - - // If there's a single display only, it will have timeout and the first button - // becomes accept. - EXPECT_TRUE(controller()->DoesNotificationTimeout()); - ClickOnNotificationButton(0); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(1, accept_count()); - gfx::Size resolution; - EXPECT_TRUE(display_manager->GetSelectedResolutionForDisplayId( - display.id(), &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); - - // In that case the second button is revert. - UpdateDisplay("300x300#300x300|200x200"); - SetDisplayResolutionAndNotify(display, gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - - EXPECT_TRUE(controller()->DoesNotificationTimeout()); - ClickOnNotificationButton(1); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(1, accept_count()); - EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId( - display.id(), &resolution)); -} - -TEST_F(ResolutionNotificationControllerTest, Close) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("100x100,150x150#150x150|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - ASSERT_EQ(0, accept_count()); - EXPECT_FALSE(IsNotificationVisible()); - - // Changes the resolution and apply the result. - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - EXPECT_FALSE(controller()->DoesNotificationTimeout()); - gfx::Size resolution; - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); - - // Close the notification (imitates clicking [x] button). Also verifies if - // this does not cause a crash. See crbug.com/271784 - CloseNotification(); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(1, accept_count()); -} - -TEST_F(ResolutionNotificationControllerTest, Timeout) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x300#300x300|200x200"); - const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay(); - SetDisplayResolutionAndNotify(display, gfx::Size(200, 200)); - - for (int i = 0; i < ResolutionNotificationController::kTimeoutInSec; ++i) { - EXPECT_TRUE(IsNotificationVisible()) << "notification is closed after " - << i << "-th timer tick"; - TickTimer(); - RunAllPendingInMessageLoop(); - } - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(0, accept_count()); - gfx::Size resolution; - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId( - display.id(), &resolution)); -} - -TEST_F(ResolutionNotificationControllerTest, DisplayDisconnected) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x300#300x300|200x200,200x200#250x250|200x200|100x100"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(100, 100)); - ASSERT_TRUE(IsNotificationVisible()); - - // Disconnects the secondary display and verifies it doesn't cause crashes. - UpdateDisplay("300x300#300x300|200x200"); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(0, accept_count()); - gfx::Size resolution; - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); -} - -TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); - ash::internal::DisplayManager* display_manager = - ash::Shell::GetInstance()->display_manager(); - - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); - EXPECT_TRUE(IsNotificationVisible()); - EXPECT_FALSE(controller()->DoesNotificationTimeout()); - gfx::Size resolution; - EXPECT_TRUE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - EXPECT_EQ("200x200", resolution.ToString()); - - // Invokes SetDisplayResolutionAndNotify during the previous notification is - // visible. - SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(250, 250)); - EXPECT_FALSE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); - - // Then, click the revert button. Although |old_resolution| for the second - // SetDisplayResolutionAndNotify is 200x200, it should revert to the original - // size 150x150. - ClickOnNotificationButton(0); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsNotificationVisible()); - EXPECT_EQ(0, accept_count()); - EXPECT_FALSE( - display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/root_window_transformers.cc b/chromium/ash/display/root_window_transformers.cc deleted file mode 100644 index 7f808ddbc14..00000000000 --- a/chromium/ash/display/root_window_transformers.cc +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 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/display/root_window_transformers.h" - -#include <cmath> - -#include "ash/display/display_info.h" -#include "ash/display/display_manager.h" -#include "ash/magnifier/magnification_controller.h" -#include "ash/shell.h" -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "third_party/skia/include/utils/SkMatrix44.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_transformer.h" -#include "ui/aura/window_property.h" -#include "ui/compositor/dip_util.h" -#include "ui/gfx/display.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/transform.h" -#include "ui/gfx/transform.h" - -DECLARE_WINDOW_PROPERTY_TYPE(gfx::Display::Rotation); - -namespace ash { -namespace internal { -namespace { - -#if defined(OS_WIN) -DEFINE_WINDOW_PROPERTY_KEY(gfx::Display::Rotation, kRotationPropertyKey, - gfx::Display::ROTATE_0); -#endif - -// Round near zero value to zero. -void RoundNearZero(gfx::Transform* transform) { - const float kEpsilon = 0.001f; - SkMatrix44& matrix = transform->matrix(); - for (int x = 0; x < 4; ++x) { - for (int y = 0; y < 4; ++y) { - if (std::abs(SkMScalarToFloat(matrix.get(x, y))) < kEpsilon) - matrix.set(x, y, SkFloatToMScalar(0.0f)); - } - } -} - -// TODO(oshima): Transformers should be able to adjust itself -// when the device scale factor is changed, instead of -// precalculating the transform using fixed value. - -gfx::Transform CreateRotationTransform(aura::Window* root_window, - const gfx::Display& display) { - DisplayInfo info = - Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id()); - - // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade) -#if defined(OS_WIN) - // Windows 8 bots refused to resize the host window, and - // updating the transform results in incorrectly resizing - // the root window. Don't apply the transform unless - // necessary so that unit tests pass on win8 bots. - if (info.rotation() == root_window->GetProperty(kRotationPropertyKey)) - return gfx::Transform(); - root_window->SetProperty(kRotationPropertyKey, info.rotation()); -#endif - - gfx::Transform rotate; - // The origin is (0, 0), so the translate width/height must be reduced by - // 1 pixel. - float one_pixel = 1.0f / display.device_scale_factor(); - switch (info.rotation()) { - case gfx::Display::ROTATE_0: - break; - case gfx::Display::ROTATE_90: - rotate.Translate(display.bounds().height() - one_pixel, 0); - rotate.Rotate(90); - break; - case gfx::Display::ROTATE_270: - rotate.Translate(0, display.bounds().width() - one_pixel); - rotate.Rotate(270); - break; - case gfx::Display::ROTATE_180: - rotate.Translate(display.bounds().width() - one_pixel, - display.bounds().height() - one_pixel); - rotate.Rotate(180); - break; - } - - RoundNearZero(&rotate); - return rotate; -} - -gfx::Transform CreateMagnifierTransform(aura::Window* root_window) { - MagnificationController* magnifier = - Shell::GetInstance()->magnification_controller(); - float magnifier_scale = 1.f; - gfx::Point magnifier_offset; - if (magnifier && magnifier->IsEnabled()) { - magnifier_scale = magnifier->GetScale(); - magnifier_offset = magnifier->GetWindowPosition(); - } - gfx::Transform transform; - if (magnifier_scale != 1.f) { - transform.Scale(magnifier_scale, magnifier_scale); - transform.Translate(-magnifier_offset.x(), -magnifier_offset.y()); - } - return transform; -} - -gfx::Transform CreateInsetsAndScaleTransform(const gfx::Insets& insets, - float device_scale_factor, - float ui_scale) { - gfx::Transform transform; - if (insets.top() != 0 || insets.left() != 0) { - float x_offset = insets.left() / device_scale_factor; - float y_offset = insets.top() / device_scale_factor; - transform.Translate(x_offset, y_offset); - } - float inverted_scale = 1.0f / ui_scale; - transform.Scale(inverted_scale, inverted_scale); - return transform; -} - -// RootWindowTransformer for ash environment. -class AshRootWindowTransformer : public aura::RootWindowTransformer { - public: - AshRootWindowTransformer(aura::Window* root, - const gfx::Display& display) - : root_window_(root) { - DisplayInfo info = Shell::GetInstance()->display_manager()-> - GetDisplayInfo(display.id()); - host_insets_ = info.GetOverscanInsetsInPixel(); - root_window_ui_scale_ = info.GetEffectiveUIScale(); - root_window_bounds_transform_ = - CreateInsetsAndScaleTransform(host_insets_, - display.device_scale_factor(), - root_window_ui_scale_) * - CreateRotationTransform(root, display); - transform_ = root_window_bounds_transform_ * CreateMagnifierTransform(root); - CHECK(transform_.GetInverse(&invert_transform_)); - - } - - // aura::RootWindowTransformer overrides: - virtual gfx::Transform GetTransform() const OVERRIDE { - return transform_; - } - virtual gfx::Transform GetInverseTransform() const OVERRIDE { - return invert_transform_; - } - virtual gfx::Rect GetRootWindowBounds( - const gfx::Size& host_size) const OVERRIDE { - gfx::Rect bounds(host_size); - bounds.Inset(host_insets_); - bounds = ui::ConvertRectToDIP(root_window_->layer(), bounds); - gfx::RectF new_bounds(bounds); - root_window_bounds_transform_.TransformRect(&new_bounds); - // Apply |root_window_scale_| twice as the downscaling - // is already applied once in |SetTransformInternal()|. - // TODO(oshima): This is a bit ugly. Consider specifying - // the pseudo host resolution instead. - new_bounds.Scale(root_window_ui_scale_ * root_window_ui_scale_); - // Ignore the origin because RootWindow's insets are handled by - // the transform. - // Floor the size because the bounds is no longer aligned to - // backing pixel when |root_window_scale_| is specified - // (850 height at 1.25 scale becomes 1062.5 for example.) - return gfx::Rect(gfx::ToFlooredSize(new_bounds.size())); - } - - virtual gfx::Insets GetHostInsets() const OVERRIDE { - return host_insets_; - } - - private: - virtual ~AshRootWindowTransformer() {} - - aura::Window* root_window_; - gfx::Transform transform_; - - // The accurate representation of the inverse of the |transform_|. - // This is used to avoid computation error caused by - // |gfx::Transform::GetInverse|. - gfx::Transform invert_transform_; - - // The transform of the root window bounds. This is used to calculate - // the size of root window. - gfx::Transform root_window_bounds_transform_; - - // The scale of the root window. See |display_info::ui_scale_| - // for more info. - float root_window_ui_scale_; - - gfx::Insets host_insets_; - - DISALLOW_COPY_AND_ASSIGN(AshRootWindowTransformer); -}; - -// RootWindowTransformer for mirror root window. We simply copy the -// texture (bitmap) of the source display into the mirror window, so -// the root window bounds is the same as the source display's -// pixel size (excluding overscan insets). -class MirrorRootWindowTransformer : public aura::RootWindowTransformer { - public: - MirrorRootWindowTransformer(const DisplayInfo& source_display_info, - const DisplayInfo& mirror_display_info) { - root_bounds_ = gfx::Rect(source_display_info.bounds_in_native().size()); - gfx::Rect mirror_display_rect = - gfx::Rect(mirror_display_info.bounds_in_native().size()); - - bool letterbox = root_bounds_.width() * mirror_display_rect.height() > - root_bounds_.height() * mirror_display_rect.width(); - if (letterbox) { - float mirror_scale_ratio = - (static_cast<float>(root_bounds_.width()) / - static_cast<float>(mirror_display_rect.width())); - float inverted_scale = 1.0f / mirror_scale_ratio; - int margin = static_cast<int>( - (mirror_display_rect.height() - - root_bounds_.height() * inverted_scale) / 2); - insets_.Set(0, margin, 0, margin); - - transform_.Translate(0, margin); - transform_.Scale(inverted_scale, inverted_scale); - } else { - float mirror_scale_ratio = - (static_cast<float>(root_bounds_.height()) / - static_cast<float>(mirror_display_rect.height())); - float inverted_scale = 1.0f / mirror_scale_ratio; - int margin = static_cast<int>( - (mirror_display_rect.width() - - root_bounds_.width() * inverted_scale) / 2); - insets_.Set(margin, 0, margin, 0); - - transform_.Translate(margin, 0); - transform_.Scale(inverted_scale, inverted_scale); - } - } - - // aura::RootWindowTransformer overrides: - virtual gfx::Transform GetTransform() const OVERRIDE { - return transform_; - } - virtual gfx::Transform GetInverseTransform() const OVERRIDE { - gfx::Transform invert; - CHECK(transform_.GetInverse(&invert)); - return invert; - } - virtual gfx::Rect GetRootWindowBounds( - const gfx::Size& host_size) const OVERRIDE { - return root_bounds_; - } - virtual gfx::Insets GetHostInsets() const OVERRIDE { - return insets_; - } - - private: - virtual ~MirrorRootWindowTransformer() {} - - gfx::Transform transform_; - gfx::Rect root_bounds_; - gfx::Insets insets_; - - DISALLOW_COPY_AND_ASSIGN(MirrorRootWindowTransformer); -}; - -} // namespace - -aura::RootWindowTransformer* CreateRootWindowTransformerForDisplay( - aura::Window* root, - const gfx::Display& display) { - return new AshRootWindowTransformer(root, display); -} - -aura::RootWindowTransformer* CreateRootWindowTransformerForMirroredDisplay( - const DisplayInfo& source_display_info, - const DisplayInfo& mirror_display_info) { - return new MirrorRootWindowTransformer(source_display_info, - mirror_display_info); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/root_window_transformers.h b/chromium/ash/display/root_window_transformers.h deleted file mode 100644 index e1d40533343..00000000000 --- a/chromium/ash/display/root_window_transformers.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 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_DISPLAY_ROOT_WINDOW_TRANSFORMERS_H_ -#define ASH_DISPLAY_ROOT_WINDOW_TRANSFORMERS_H_ - -#include "ash/ash_export.h" - -namespace aura { -class RootWindowTransformer; -class Window; -} - -namespace gfx { -class Display; -class Transform; -} - -namespace ash { -namespace internal { -class DisplayInfo; - -ASH_EXPORT aura::RootWindowTransformer* CreateRootWindowTransformerForDisplay( - aura::Window* root, - const gfx::Display& display); - -// Creates a RootWindowTransformers for mirror root window. -// |source_display_info| specifies the display being mirrored, -// and |mirror_display_info| specifies the display used to -// mirror the content. -ASH_EXPORT aura::RootWindowTransformer* -CreateRootWindowTransformerForMirroredDisplay( - const DisplayInfo& source_display_info, - const DisplayInfo& mirror_display_info); - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_ROOT_WINDOW_TRANSFORMERS_H_ diff --git a/chromium/ash/display/root_window_transformers_unittest.cc b/chromium/ash/display/root_window_transformers_unittest.cc deleted file mode 100644 index 7919243ae22..00000000000 --- a/chromium/ash/display/root_window_transformers_unittest.cc +++ /dev/null @@ -1,414 +0,0 @@ -// 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/display/root_window_transformers.h" - -#include "ash/display/display_info.h" -#include "ash/display/display_manager.h" -#include "ash/launcher/launcher.h" -#include "ash/magnifier/magnification_controller.h" -#include "ash/screen_ash.h" -#include "ash/shelf/shelf_widget.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/cursor_manager_test_api.h" -#include "ash/test/mirror_window_test_api.h" -#include "base/synchronization/waitable_event.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_transformer.h" -#include "ui/aura/test/event_generator.h" -#include "ui/aura/window_tracker.h" -#include "ui/events/event_handler.h" -#include "ui/gfx/display.h" -#include "ui/gfx/rect_conversions.h" -#include "ui/gfx/screen.h" -#include "ui/views/widget/widget.h" - -namespace ash { -namespace internal { - -namespace { - -const char kDesktopBackgroundView[] = "DesktopBackgroundView"; - -class TestEventHandler : public ui::EventHandler { - public: - TestEventHandler() : target_root_(NULL), - touch_radius_x_(0.0), - touch_radius_y_(0.0), - scroll_x_offset_(0.0), - scroll_y_offset_(0.0), - scroll_x_offset_ordinal_(0.0), - scroll_y_offset_ordinal_(0.0) {} - virtual ~TestEventHandler() {} - - virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { - if (event->flags() & ui::EF_IS_SYNTHESIZED) - return; - aura::Window* target = static_cast<aura::Window*>(event->target()); - mouse_location_ = event->root_location(); - target_root_ = target->GetRootWindow(); - event->StopPropagation(); - } - - virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { - aura::Window* target = static_cast<aura::Window*>(event->target()); - // Only record when the target is the background which covers - // entire root window. - if (target->name() != kDesktopBackgroundView) - return; - touch_radius_x_ = event->radius_x(); - touch_radius_y_ = event->radius_y(); - event->StopPropagation(); - } - - virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { - aura::Window* target = static_cast<aura::Window*>(event->target()); - // Only record when the target is the background which covers - // entire root window. - if (target->name() != kDesktopBackgroundView) - return; - - if (event->type() == ui::ET_SCROLL) { - scroll_x_offset_ = event->x_offset(); - scroll_y_offset_ = event->y_offset(); - scroll_x_offset_ordinal_ = event->x_offset_ordinal(); - scroll_y_offset_ordinal_ = event->y_offset_ordinal(); - } - event->StopPropagation(); - } - - std::string GetLocationAndReset() { - std::string result = mouse_location_.ToString(); - mouse_location_.SetPoint(0, 0); - target_root_ = NULL; - return result; - } - - float touch_radius_x() const { return touch_radius_x_; } - float touch_radius_y() const { return touch_radius_y_; } - float scroll_x_offset() const { return scroll_x_offset_; } - float scroll_y_offset() const { return scroll_y_offset_; } - float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; } - float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; } - - private: - gfx::Point mouse_location_; - aura::Window* target_root_; - - float touch_radius_x_; - float touch_radius_y_; - float scroll_x_offset_; - float scroll_y_offset_; - float scroll_x_offset_ordinal_; - float scroll_y_offset_ordinal_; - - DISALLOW_COPY_AND_ASSIGN(TestEventHandler); -}; - -gfx::Display::Rotation GetStoredRotation(int64 id) { - return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation(); -} - -float GetStoredUIScale(int64 id) { - return Shell::GetInstance()->display_manager()->GetDisplayInfo(id). - GetEffectiveUIScale(); -} - -} // namespace - -typedef test::AshTestBase RootWindowTransformersTest; - -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy -#define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify -#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords -#else -#define MAYBE_RotateAndMagnify RotateAndMagniy -#define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify -#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords -#endif - -TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { - MagnificationController* magnifier = - Shell::GetInstance()->magnification_controller(); - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("120x200,300x400*2"); - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::test::EventGenerator generator1(root_windows[0]); - aura::test::EventGenerator generator2(root_windows[1]); - - magnifier->SetEnabled(true); - EXPECT_EQ(2.0f, magnifier->GetScale()); - EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator1.MoveMouseToInHost(40, 80); - EXPECT_EQ("50,90", event_handler.GetLocationAndReset()); - EXPECT_EQ("50,90", - aura::Env::GetInstance()->last_mouse_location().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); - magnifier->SetEnabled(false); - - display_manager->SetDisplayRotation(display1.id(), - gfx::Display::ROTATE_90); - // Move the cursor to the center of the first root window. - generator1.MoveMouseToInHost(59, 100); - - magnifier->SetEnabled(true); - EXPECT_EQ(2.0f, magnifier->GetScale()); - EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("200,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator1.MoveMouseToInHost(39, 120); - EXPECT_EQ("110,70", event_handler.GetLocationAndReset()); - EXPECT_EQ("110,70", - aura::Env::GetInstance()->last_mouse_location().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); - magnifier->SetEnabled(false); - - DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); - display_manager->SetLayoutForCurrentDisplays(display_layout); - EXPECT_EQ("50,120 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - - display_manager->SetDisplayRotation(display2_id, - gfx::Display::ROTATE_270); - // Move the cursor to the center of the second root window. - generator2.MoveMouseToInHost(151, 199); - - magnifier->SetEnabled(true); - EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); - EXPECT_EQ("50,120 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator2.MoveMouseToInHost(172, 219); - EXPECT_EQ("95,80", event_handler.GetLocationAndReset()); - EXPECT_EQ("145,200", - aura::Env::GetInstance()->last_mouse_location().ToString()); - EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); - magnifier->SetEnabled(false); - - display_manager->SetDisplayRotation(display1.id(), - gfx::Display::ROTATE_180); - // Move the cursor to the center of the first root window. - generator1.MoveMouseToInHost(59, 99); - - magnifier->SetEnabled(true); - EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); - EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); - // Dislay must share at least 100, so the x's offset becomes 20. - EXPECT_EQ("20,200 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); - generator1.MoveMouseToInHost(39, 59); - EXPECT_EQ("70,120", event_handler.GetLocationAndReset()); - EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); - EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); - magnifier->SetEnabled(false); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(RootWindowTransformersTest, ScaleAndMagnify) { - if (!SupportsMultipleDisplays()) - return; - - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("600x400*2@1.5,500x300"); - - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display::SetInternalDisplayId(display1.id()); - gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - MagnificationController* magnifier = - Shell::GetInstance()->magnification_controller(); - - magnifier->SetEnabled(true); - EXPECT_EQ(2.0f, magnifier->GetScale()); - EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); - EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); - EXPECT_EQ("450,0 500x300", display2.bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); - - aura::test::EventGenerator generator(root_windows[0]); - generator.MoveMouseToInHost(500, 200); - EXPECT_EQ("299,150", event_handler.GetLocationAndReset()); - magnifier->SetEnabled(false); - - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetDisplayUIScale(display1.id(), 1.25); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - display2 = ScreenAsh::GetSecondaryDisplay(); - magnifier->SetEnabled(true); - EXPECT_EQ(2.0f, magnifier->GetScale()); - EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); - EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); - EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); - EXPECT_EQ(1.25f, GetStoredUIScale(display1.id())); - EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); - magnifier->SetEnabled(false); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(RootWindowTransformersTest, MAYBE_TouchScaleAndMagnify) { - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - - UpdateDisplay("200x200*2"); - gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - aura::Window* root_window = root_windows[0]; - aura::test::EventGenerator generator(root_window); - MagnificationController* magnifier = - Shell::GetInstance()->magnification_controller(); - - magnifier->SetEnabled(true); - EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); - magnifier->SetScale(2.5f, false); - EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale()); - generator.PressMoveAndReleaseTouchTo(50, 50); - // Default test touches have radius_x/y = 1.0, with device scale - // factor = 2, the scaled radius_x/y should be 0.5. - EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x()); - EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y()); - - generator.ScrollSequence(gfx::Point(0,0), - base::TimeDelta::FromMilliseconds(100), - 10.0, 1.0, 5, 1); - - // ordinal_offset is invariant to the device scale factor. - EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(), - event_handler.scroll_x_offset_ordinal()); - EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(), - event_handler.scroll_y_offset_ordinal()); - magnifier->SetEnabled(false); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(RootWindowTransformersTest, MAYBE_ConvertHostToRootCoords) { - TestEventHandler event_handler; - Shell::GetInstance()->AddPreTargetHandler(&event_handler); - MagnificationController* magnifier = - Shell::GetInstance()->magnification_controller(); - - // Test 1 - UpdateDisplay("600x400*2/r@1.5"); - - gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); - EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - aura::test::EventGenerator generator(root_windows[0]); - generator.MoveMouseToInHost(300, 200); - magnifier->SetEnabled(true); - EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); - EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); - - generator.MoveMouseToInHost(300, 200); - EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(200, 300); - EXPECT_EQ("187,261", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(100, 400); - EXPECT_EQ("237,299", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("137,348", event_handler.GetLocationAndReset()); - - magnifier->SetEnabled(false); - EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); - - // Test 2 - UpdateDisplay("600x400*2/u@1.5"); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); - EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - generator.MoveMouseToInHost(300, 200); - magnifier->SetEnabled(true); - EXPECT_EQ("224,149", event_handler.GetLocationAndReset()); - EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); - - generator.MoveMouseToInHost(300, 200); - EXPECT_EQ("224,148", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(200, 300); - EXPECT_EQ("261,111", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(100, 400); - EXPECT_EQ("299,60", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("348,159", event_handler.GetLocationAndReset()); - - magnifier->SetEnabled(false); - EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); - - // Test 3 - UpdateDisplay("600x400*2/l@1.5"); - display1 = Shell::GetScreen()->GetPrimaryDisplay(); - root_windows = Shell::GetAllRootWindows(); - EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); - EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); - EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); - - generator.MoveMouseToInHost(300, 200); - magnifier->SetEnabled(true); - EXPECT_EQ("149,225", event_handler.GetLocationAndReset()); - EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); - - generator.MoveMouseToInHost(300, 200); - EXPECT_EQ("148,224", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(200, 300); - EXPECT_EQ("111,187", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(100, 400); - EXPECT_EQ("60,149", event_handler.GetLocationAndReset()); - generator.MoveMouseToInHost(0, 0); - EXPECT_EQ("159,99", event_handler.GetLocationAndReset()); - - magnifier->SetEnabled(false); - EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); - - Shell::GetInstance()->RemovePreTargetHandler(&event_handler); -} - -TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) { - if (!SupportsMultipleDisplays()) - return; - test::MirrorWindowTestApi test_api; - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); - UpdateDisplay("400x200,500x500"); - scoped_ptr<aura::RootWindowTransformer> transformer( - test_api.CreateCurrentRootWindowTransformer()); - // Y margin must be margin is (500 - 500/400 * 200) / 2 = 125. - EXPECT_EQ("0,125,0,125", transformer->GetHostInsets().ToString()); - - UpdateDisplay("200x400,500x500"); - // The aspect ratio is flipped, so X margin is now 125. - transformer = test_api.CreateCurrentRootWindowTransformer(); - EXPECT_EQ("125,0,125,0", transformer->GetHostInsets().ToString()); -} - -} // namespace test -} // namespace ash diff --git a/chromium/ash/display/screen_position_controller.cc b/chromium/ash/display/screen_position_controller.cc deleted file mode 100644 index e9f7a4297f2..00000000000 --- a/chromium/ash/display/screen_position_controller.cc +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) 2012 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/display/screen_position_controller.h" - -#include "ash/display/display_controller.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "ash/wm/coordinate_conversion.h" -#include "ash/wm/system_modal_container_layout_manager.h" -#include "ash/wm/window_properties.h" -#include "ui/aura/client/activation_client.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window_tracker.h" -#include "ui/compositor/dip_util.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" - -namespace ash { -namespace { - -// Return true if the window or its ancestor has |kStayInSameRootWindowkey| -// property. -bool ShouldStayInSameRootWindow(const aura::Window* window) { - return window && - (window->GetProperty(internal::kStayInSameRootWindowKey) || - ShouldStayInSameRootWindow(window->parent())); -} - -// Move all transient children to |dst_root|, including the ones in -// the child windows and transient children of the transient children. -void MoveAllTransientChildrenToNewRoot(const gfx::Display& display, - aura::Window* window) { - aura::Window* dst_root = Shell::GetInstance()->display_controller()-> - GetRootWindowForDisplayId(display.id()); - aura::Window::Windows transient_children = window->transient_children(); - for (aura::Window::Windows::iterator iter = transient_children.begin(); - iter != transient_children.end(); ++iter) { - aura::Window* transient_child = *iter; - int container_id = transient_child->parent()->id(); - DCHECK_GE(container_id, 0); - aura::Window* container = Shell::GetContainer(dst_root, container_id); - gfx::Rect parent_bounds_in_screen = transient_child->GetBoundsInScreen(); - container->AddChild(transient_child); - transient_child->SetBoundsInScreen(parent_bounds_in_screen, display); - - // Transient children may have transient children. - MoveAllTransientChildrenToNewRoot(display, transient_child); - } - // Move transient children of the child windows if any. - aura::Window::Windows children = window->children(); - for (aura::Window::Windows::iterator iter = children.begin(); - iter != children.end(); ++iter) - MoveAllTransientChildrenToNewRoot(display, *iter); -} - -// Finds the root window at |location| in |window|'s coordinates and returns a -// pair of root window and location in that root window's coordinates. The -// function usually returns |window->GetRootWindow()|, but if the mouse pointer -// is moved outside the |window|'s root while the mouse is captured, it returns -// the other root window. -std::pair<aura::Window*, gfx::Point> GetRootWindowRelativeToWindow( - aura::Window* window, - const gfx::Point& location) { - aura::Window* root_window = window->GetRootWindow(); - gfx::Point location_in_root(location); - aura::Window::ConvertPointToTarget(window, root_window, &location_in_root); - -#if defined(USE_X11) - if (!root_window->ContainsPointInRoot(location_in_root)) { - // This conversion is necessary to deal with X's passive input - // grab while dragging window. For example, if we have two - // displays, say 1000x1000 (primary) and 500x500 (extended one - // on the right), and start dragging a window at (999, 123), and - // then move the pointer to the right, the pointer suddenly - // warps to the extended display. The destination is (0, 123) in - // the secondary root window's coordinates, or (1000, 123) in - // the screen coordinates. However, since the mouse is captured - // by X during drag, a weird LocatedEvent, something like (0, 1123) - // in the *primary* root window's coordinates, is sent to Chrome - // (Remember that in the native X11 world, the two root windows - // are always stacked vertically regardless of the display - // layout in Ash). We need to figure out that (0, 1123) in the - // primary root window's coordinates is actually (0, 123) in the - // extended root window's coordinates. - - gfx::Point location_in_native(location_in_root); - root_window->GetDispatcher()->host()->ConvertPointToNativeScreen( - &location_in_native); - - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - for (size_t i = 0; i < root_windows.size(); ++i) { - aura::WindowEventDispatcher* dispatcher = - root_windows[i]->GetDispatcher(); - const gfx::Rect native_bounds = dispatcher->host()->GetBounds(); - if (native_bounds.Contains(location_in_native)) { - root_window = root_windows[i]; - location_in_root = location_in_native; - dispatcher->host()->ConvertPointFromNativeScreen(&location_in_root); - break; - } - } - } -#else - // TODO(yusukes): Support non-X11 platforms if necessary. -#endif - - return std::make_pair(root_window, location_in_root); -} - -} // namespace - -namespace internal { - -void ScreenPositionController::ConvertPointToScreen( - const aura::Window* window, - gfx::Point* point) { - const aura::Window* root = window->GetRootWindow(); - aura::Window::ConvertPointToTarget(window, root, point); - const gfx::Point display_origin = Shell::GetScreen()->GetDisplayNearestWindow( - const_cast<aura::Window*>(root)).bounds().origin(); - point->Offset(display_origin.x(), display_origin.y()); -} - -void ScreenPositionController::ConvertPointFromScreen( - const aura::Window* window, - gfx::Point* point) { - const aura::Window* root = window->GetRootWindow(); - const gfx::Point display_origin = Shell::GetScreen()->GetDisplayNearestWindow( - const_cast<aura::Window*>(root)).bounds().origin(); - point->Offset(-display_origin.x(), -display_origin.y()); - aura::Window::ConvertPointToTarget(root, window, point); -} - -void ScreenPositionController::ConvertHostPointToScreen( - aura::Window* root_window, - gfx::Point* point) { - aura::Window* root = root_window->GetRootWindow(); - root->GetDispatcher()->ConvertPointFromHost(point); - std::pair<aura::Window*, gfx::Point> pair = - GetRootWindowRelativeToWindow(root, *point); - *point = pair.second; - ConvertPointToScreen(pair.first, point); -} - -void ScreenPositionController::SetBounds(aura::Window* window, - const gfx::Rect& bounds, - const gfx::Display& display) { - DCHECK_NE(-1, display.id()); - if (!window->parent()->GetProperty(internal::kUsesScreenCoordinatesKey)) { - window->SetBounds(bounds); - return; - } - - // Don't move a window to other root window if: - // a) the window is a transient window. It moves when its - // transient_parent moves. - // b) if the window or its ancestor has kStayInSameRootWindowkey. It's - // intentionally kept in the same root window even if the bounds is - // outside of the display. - if (!window->transient_parent() && - !ShouldStayInSameRootWindow(window)) { - aura::Window* dst_root = - Shell::GetInstance()->display_controller()->GetRootWindowForDisplayId( - display.id()); - DCHECK(dst_root); - aura::Window* dst_container = NULL; - if (dst_root != window->GetRootWindow()) { - int container_id = window->parent()->id(); - // All containers that uses screen coordinates must have valid window ids. - DCHECK_GE(container_id, 0); - // Don't move modal background. - if (!SystemModalContainerLayoutManager::IsModalBackground(window)) - dst_container = Shell::GetContainer(dst_root, container_id); - } - - if (dst_container && window->parent() != dst_container) { - aura::Window* focused = aura::client::GetFocusClient(window)-> - GetFocusedWindow(); - aura::client::ActivationClient* activation_client = - aura::client::GetActivationClient(window->GetRootWindow()); - aura::Window* active = activation_client->GetActiveWindow(); - - aura::WindowTracker tracker; - if (focused) - tracker.Add(focused); - if (active && focused != active) - tracker.Add(active); - - dst_container->AddChild(window); - - MoveAllTransientChildrenToNewRoot(display, window); - - // Restore focused/active window. - if (tracker.Contains(focused)) { - aura::client::GetFocusClient(window)->FocusWindow(focused); - // TODO(beng): replace with GetRootWindow(). - ash::Shell::GetInstance()->set_target_root_window( - focused->GetRootWindow()); - } else if (tracker.Contains(active)) { - activation_client->ActivateWindow(active); - } - } - } - - gfx::Point origin(bounds.origin()); - const gfx::Point display_origin = Shell::GetScreen()->GetDisplayNearestWindow( - window).bounds().origin(); - origin.Offset(-display_origin.x(), -display_origin.y()); - window->SetBounds(gfx::Rect(origin, bounds.size())); -} - -} // internal -} // ash diff --git a/chromium/ash/display/screen_position_controller.h b/chromium/ash/display/screen_position_controller.h deleted file mode 100644 index ad692f9b1df..00000000000 --- a/chromium/ash/display/screen_position_controller.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_SCREEN_POSITION_CONTROLLER_H_ -#define ASH_DISPLAY_SCREEN_POSITION_CONTROLLER_H_ - -#include "base/basictypes.h" -#include "ui/aura/client/screen_position_client.h" - -namespace ash { -namespace internal { - -class ScreenPositionController : public aura::client::ScreenPositionClient { - public: - ScreenPositionController() {} - virtual ~ScreenPositionController() {} - - // aura::client::ScreenPositionClient overrides: - virtual void ConvertPointToScreen(const aura::Window* window, - gfx::Point* point) OVERRIDE; - virtual void ConvertPointFromScreen(const aura::Window* window, - gfx::Point* point) OVERRIDE; - virtual void ConvertHostPointToScreen(aura::Window* window, - gfx::Point* point) OVERRIDE; - virtual void SetBounds(aura::Window* window, - const gfx::Rect& bounds, - const gfx::Display& display) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(ScreenPositionController); -}; - -} // internal -} // ash - -#endif // ASH_DISPLAY_SCREEN_POSITION_CONTROLLER_H_ diff --git a/chromium/ash/display/screen_position_controller_unittest.cc b/chromium/ash/display/screen_position_controller_unittest.cc deleted file mode 100644 index a9996c25eb0..00000000000 --- a/chromium/ash/display/screen_position_controller_unittest.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2012 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/display/screen_position_controller.h" - -#include "ash/display/display_manager.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/shell_test_api.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/test/test_window_delegate.h" -#include "ui/base/layout.h" -#include "ui/gfx/screen.h" - -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized immediately on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_ConvertHostPointToScreen DISABLED_ConvertHostPointToScreen -#define MAYBE_ConvertHostPointToScreenHiDPI DISABLED_ConvertHostPointToScreenHiDPI -#define MAYBE_ConvertHostPointToScreenRotate DISABLED_ConvertHostPointToScreenRotate -#define MAYBE_ConvertHostPointToScreenUIScale DISABLED_ConvertHostPointToScreenUIScale -#else -#define MAYBE_ConvertHostPointToScreen ConvertHostPointToScreen -#define MAYBE_ConvertHostPointToScreenHiDPI ConvertHostPointToScreenHiDPI -#define MAYBE_ConvertHostPointToScreenRotate ConvertHostPointToScreenRotate -#define MAYBE_ConvertHostPointToScreenUIScale ConvertHostPointToScreenUIScale -#endif - -namespace ash { -namespace test { - -namespace { -void SetSecondaryDisplayLayout(DisplayLayout::Position position) { - DisplayLayout layout = - Shell::GetInstance()->display_manager()->GetCurrentDisplayLayout(); - layout.position = position; - Shell::GetInstance()->display_manager()-> - SetLayoutForCurrentDisplays(layout); -} - -internal::ScreenPositionController* GetScreenPositionController() { - ShellTestApi test_api(Shell::GetInstance()); - return test_api.screen_position_controller(); -} - -class ScreenPositionControllerTest : public test::AshTestBase { - public: - ScreenPositionControllerTest() {} - virtual ~ScreenPositionControllerTest() {} - - virtual void SetUp() OVERRIDE { - AshTestBase::SetUp(); - window_.reset(new aura::Window(&window_delegate_)); - window_->SetType(aura::client::WINDOW_TYPE_NORMAL); - window_->Init(ui::LAYER_NOT_DRAWN); - ParentWindowInPrimaryRootWindow(window_.get()); - window_->set_id(1); - } - - virtual void TearDown() OVERRIDE { - window_.reset(); - AshTestBase::TearDown(); - } - - // Converts a point (x, y) in host window's coordinate to screen and - // returns its string representation. - std::string ConvertHostPointToScreen(int x, int y) const { - gfx::Point point(x, y); - GetScreenPositionController()->ConvertHostPointToScreen( - window_->GetRootWindow(), &point); - return point.ToString(); - } - - protected: - scoped_ptr<aura::Window> window_; - aura::test::TestWindowDelegate window_delegate_; - - private: - DISALLOW_COPY_AND_ASSIGN(ScreenPositionControllerTest); -}; - -} // namespace - -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreen) { - UpdateDisplay("100+100-200x200,100+500-200x200"); - - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - EXPECT_EQ("100,100", root_windows[0]->GetDispatcher()->host()-> - GetBounds().origin().ToString()); - EXPECT_EQ("200x200", root_windows[0]->GetDispatcher()->host()-> - GetBounds().size().ToString()); - EXPECT_EQ("100,500", root_windows[1]->GetDispatcher()->host()-> - GetBounds().origin().ToString()); - EXPECT_EQ("200x200", root_windows[1]->GetDispatcher()->host()-> - GetBounds().size().ToString()); - - const gfx::Point window_pos(100, 100); - window_->SetBoundsInScreen( - gfx::Rect(window_pos, gfx::Size(100, 100)), - Shell::GetScreen()->GetDisplayNearestPoint(window_pos)); - SetSecondaryDisplayLayout(DisplayLayout::RIGHT); - // The point is on the primary root window. - EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250)); - // The point is on the secondary display. - EXPECT_EQ("250,0", ConvertHostPointToScreen(50, 400)); - - SetSecondaryDisplayLayout(DisplayLayout::BOTTOM); - // The point is on the primary root window. - EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250)); - // The point is on the secondary display. - EXPECT_EQ("50,200", ConvertHostPointToScreen(50, 400)); - - SetSecondaryDisplayLayout(DisplayLayout::LEFT); - // The point is on the primary root window. - EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250)); - // The point is on the secondary display. - EXPECT_EQ("-150,0", ConvertHostPointToScreen(50, 400)); - - SetSecondaryDisplayLayout(DisplayLayout::TOP); - // The point is on the primary root window. - EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250)); - // The point is on the secondary display. - EXPECT_EQ("50,-200", ConvertHostPointToScreen(50, 400)); - - - SetSecondaryDisplayLayout(DisplayLayout::RIGHT); - const gfx::Point window_pos2(300, 100); - window_->SetBoundsInScreen( - gfx::Rect(window_pos2, gfx::Size(100, 100)), - Shell::GetScreen()->GetDisplayNearestPoint(window_pos2)); - // The point is on the secondary display. - EXPECT_EQ("250,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("450,250", ConvertHostPointToScreen(250, 250)); - // The point is on the primary root window. - EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400)); - - SetSecondaryDisplayLayout(DisplayLayout::BOTTOM); - // The point is on the secondary display. - EXPECT_EQ("50,250", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,450", ConvertHostPointToScreen(250, 250)); - // The point is on the primary root window. - EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400)); - - SetSecondaryDisplayLayout(DisplayLayout::LEFT); - // The point is on the secondary display. - EXPECT_EQ("-150,50", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("50,250", ConvertHostPointToScreen(250, 250)); - // The point is on the primary root window. - EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400)); - - SetSecondaryDisplayLayout(DisplayLayout::TOP); - // The point is on the secondary display. - EXPECT_EQ("50,-150", ConvertHostPointToScreen(50, 50)); - // The point is out of the all root windows. - EXPECT_EQ("250,50", ConvertHostPointToScreen(250, 250)); - // The point is on the primary root window. - EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400)); -} - -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenHiDPI) { - UpdateDisplay("100+100-200x200*2,100+500-200x200"); - - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - EXPECT_EQ("100,100", - root_windows[0]->GetDispatcher()->host()-> - GetBounds().origin().ToString()); - EXPECT_EQ("200x200", - root_windows[0]->GetDispatcher()->host()-> - GetBounds().size().ToString()); - EXPECT_EQ("100,500", - root_windows[1]->GetDispatcher()->host()-> - GetBounds().origin().ToString()); - EXPECT_EQ("200x200", - root_windows[1]->GetDispatcher()->host()-> - GetBounds().size().ToString()); - - // Put |window_| to the primary 2x display. - window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50), - Shell::GetScreen()->GetPrimaryDisplay()); - // (30, 30) means the host coordinate, so the point is still on the primary - // root window. Since it's 2x, the specified native point was halved. - EXPECT_EQ("15,15", ConvertHostPointToScreen(30, 30)); - // Similar to above but the point is out of the all root windows. - EXPECT_EQ("200,200", ConvertHostPointToScreen(400, 400)); - // Similar to above but the point is on the secondary display. - EXPECT_EQ("100,15", ConvertHostPointToScreen(200, 30)); - - // On secondary display. The position on the 2nd host window is (150,50) - // so the screen position is (100,0) + (150,50). - EXPECT_EQ("250,50", ConvertHostPointToScreen(150, 450)); - - // At the edge but still in the primary display. Remaining of the primary - // display is (50, 50) but adding ~100 since it's 2x-display. - EXPECT_EQ("79,79", ConvertHostPointToScreen(158, 158)); - // At the edge of the secondary display. - EXPECT_EQ("80,80", ConvertHostPointToScreen(160, 160)); -} - -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenRotate) { - // 1st display is rotated 90 clockise, and 2nd display is rotated - // 270 clockwise. - UpdateDisplay("100+100-200x200/r,100+500-200x200/l"); - // Put |window_| to the 1st. - window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50), - Shell::GetScreen()->GetPrimaryDisplay()); - - // The point is on the 1st host. - EXPECT_EQ("70,149", ConvertHostPointToScreen(50, 70)); - // The point is out of the host windows. - EXPECT_EQ("250,-51", ConvertHostPointToScreen(250, 250)); - // The point is on the 2nd host. Point on 2nd host (30,150) - - // rotate 270 clockwise -> (149, 30) - layout [+(200,0)] -> (349,30). - EXPECT_EQ("349,30", ConvertHostPointToScreen(30, 450)); - - // Move |window_| to the 2nd. - window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50), - ScreenAsh::GetSecondaryDisplay()); - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - EXPECT_EQ(root_windows[1], window_->GetRootWindow()); - - // The point is on the 2nd host. (50,70) on 2n host - - // roatate 270 clockwise -> (129,50) -layout [+(200,0)] -> (329,50) - EXPECT_EQ("329,50", ConvertHostPointToScreen(50, 70)); - // The point is out of the host windows. - EXPECT_EQ("449,50", ConvertHostPointToScreen(50, -50)); - // The point is on the 2nd host. Point on 2nd host (50,50) - - // rotate 90 clockwise -> (50, 149) - EXPECT_EQ("50,149", ConvertHostPointToScreen(50, -350)); -} - -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenUIScale) { - // 1st display is 2x density with 1.5 UI scale. - UpdateDisplay("100+100-200x200*2@1.5,100+500-200x200"); - // Put |window_| to the 1st. - window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50), - Shell::GetScreen()->GetPrimaryDisplay()); - - // The point is on the 1st host. - EXPECT_EQ("45,45", ConvertHostPointToScreen(60, 60)); - // The point is out of the host windows. - EXPECT_EQ("45,225", ConvertHostPointToScreen(60, 300)); - // The point is on the 2nd host. Point on 2nd host (60,150) - - // - screen [+(150,0)] - EXPECT_EQ("210,49", ConvertHostPointToScreen(60, 450)); - - // Move |window_| to the 2nd. - window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50), - ScreenAsh::GetSecondaryDisplay()); - aura::Window::Windows root_windows = - Shell::GetInstance()->GetAllRootWindows(); - EXPECT_EQ(root_windows[1], window_->GetRootWindow()); - - // The point is on the 2nd host. (50,70) - ro - EXPECT_EQ("210,70", ConvertHostPointToScreen(60, 70)); - // The point is out of the host windows. - EXPECT_EQ("210,-50", ConvertHostPointToScreen(60, -50)); - // The point is on the 2nd host. Point on 1nd host (60, 60) - // 1/2 * 1.5 = (45,45) - EXPECT_EQ("45,45", ConvertHostPointToScreen(60, -340)); -} - -} // namespace test -} // namespace ash diff --git a/chromium/ash/display/shared_display_edge_indicator.cc b/chromium/ash/display/shared_display_edge_indicator.cc deleted file mode 100644 index 0e16cee0fdb..00000000000 --- a/chromium/ash/display/shared_display_edge_indicator.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2012 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/display/shared_display_edge_indicator.h" - -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "ash/wm/coordinate_conversion.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/aura/client/screen_position_client.h" -#include "ui/aura/root_window.h" -#include "ui/gfx/animation/throb_animation.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" - -namespace ash { -namespace internal { -namespace { - -const int kIndicatorAnimationDurationMs = 1000; - -class IndicatorView : public views::View { - public: - IndicatorView() { - } - virtual ~IndicatorView() { - } - - void SetColor(SkColor color) { - color_ = color; - SchedulePaint(); - } - - // views::Views overrides: - virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { - canvas->FillRect(gfx::Rect(bounds().size()), color_); - } - - private: - SkColor color_; - DISALLOW_COPY_AND_ASSIGN(IndicatorView); -}; - -views::Widget* CreateWidget(const gfx::Rect& bounds, - views::View* contents_view) { - views::Widget* widget = new views::Widget; - views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); - params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; - params.can_activate = false; - params.keep_on_top = true; - // We set the context to the primary root window; this is OK because the ash - // stacking controller will still place us in the correct RootWindow. - params.context = Shell::GetPrimaryRootWindow(); - widget->set_focus_on_creation(false); - widget->Init(params); - widget->SetVisibilityChangedAnimationsEnabled(false); - widget->GetNativeWindow()->SetName("SharedEdgeIndicator"); - widget->SetContentsView(contents_view); - gfx::Display display = Shell::GetScreen()->GetDisplayMatching(bounds); - aura::Window* window = widget->GetNativeWindow(); - aura::client::ScreenPositionClient* screen_position_client = - aura::client::GetScreenPositionClient(window->GetRootWindow()); - screen_position_client->SetBounds(window, bounds, display); - widget->Show(); - return widget; -} - -} // namespace - -SharedDisplayEdgeIndicator::SharedDisplayEdgeIndicator() - : src_indicator_(NULL), - dst_indicator_(NULL) { -} - -SharedDisplayEdgeIndicator::~SharedDisplayEdgeIndicator() { - Hide(); -} - -void SharedDisplayEdgeIndicator::Show(const gfx::Rect& src_bounds, - const gfx::Rect& dst_bounds) { - DCHECK(!src_indicator_); - DCHECK(!dst_indicator_); - src_indicator_ = new IndicatorView; - dst_indicator_ = new IndicatorView; - CreateWidget(src_bounds, src_indicator_); - CreateWidget(dst_bounds, dst_indicator_); - animation_.reset(new gfx::ThrobAnimation(this)); - animation_->SetThrobDuration(kIndicatorAnimationDurationMs); - animation_->StartThrobbing(-1 /* infinite */); -} - -void SharedDisplayEdgeIndicator::Hide() { - if (src_indicator_) - src_indicator_->GetWidget()->Close(); - src_indicator_ = NULL; - if (dst_indicator_) - dst_indicator_->GetWidget()->Close(); - dst_indicator_ = NULL; -} - -void SharedDisplayEdgeIndicator::AnimationProgressed( - const gfx::Animation* animation) { - int value = animation->CurrentValueBetween(0, 255); - SkColor color = SkColorSetARGB(0xFF, value, value, value); - if (src_indicator_) - static_cast<IndicatorView*>(src_indicator_)->SetColor(color); - if (dst_indicator_) - static_cast<IndicatorView*>(dst_indicator_)->SetColor(color); - -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/shared_display_edge_indicator.h b/chromium/ash/display/shared_display_edge_indicator.h deleted file mode 100644 index d0d242d03fb..00000000000 --- a/chromium/ash/display/shared_display_edge_indicator.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012 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_DISPLAY_SHARED_DISPLAY_EDGE_INDICATOR_H_ -#define ASH_DISPLAY_SHARED_DISPLAY_EDGE_INDICATOR_H_ - -#include "ash/ash_export.h" -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "ui/gfx/animation/animation_delegate.h" -#include "ui/gfx/display.h" - -namespace gfx { -class Rect; -class ThrobAnimation; -} - -namespace views { -class View; -class Widget; -} - -namespace ash { -namespace internal { - -// SharedDisplayEdgeIndicator is responsible for showing a window that indicates -// the edge that a window can be dragged into another display. -class ASH_EXPORT SharedDisplayEdgeIndicator : public gfx::AnimationDelegate { - public: - SharedDisplayEdgeIndicator(); - virtual ~SharedDisplayEdgeIndicator(); - - // Shows/Hides the indicator window. The |src_bounds| is for the window on - // the source display, and the |dst_bounds| is for the window on the other - // display. - void Show(const gfx::Rect& src_bounds, const gfx::Rect& dst_bounds); - void Hide(); - - // gfx::AnimationDelegate overrides: - virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; - - private: - // Used to show the displays' shared edge where a window can be moved across. - // |src_widget_| is for the display where drag starts and |dst_widget_| is - // for the other display. - views::View* src_indicator_; - views::View* dst_indicator_; - - // Used to transition the opacity. - scoped_ptr<gfx::ThrobAnimation> animation_; - - DISALLOW_COPY_AND_ASSIGN(SharedDisplayEdgeIndicator); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_SHARED_DISPLAY_EDGE_INDICATOR_H_ diff --git a/chromium/ash/display/virtual_keyboard_window_controller.cc b/chromium/ash/display/virtual_keyboard_window_controller.cc deleted file mode 100644 index dd0c4d8eb71..00000000000 --- a/chromium/ash/display/virtual_keyboard_window_controller.cc +++ /dev/null @@ -1,102 +0,0 @@ -// 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/display/virtual_keyboard_window_controller.h" - -#include "ash/display/display_controller.h" -#include "ash/display/display_info.h" -#include "ash/display/display_manager.h" -#include "ash/display/root_window_transformers.h" -#include "ash/host/root_window_host_factory.h" -#include "ash/root_window_controller.h" -#include "ash/root_window_settings.h" -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_transformer.h" -#include "ui/keyboard/keyboard_controller.h" - -namespace ash { -namespace internal { - -VirtualKeyboardWindowController::VirtualKeyboardWindowController() { -} - -VirtualKeyboardWindowController::~VirtualKeyboardWindowController() { - // Make sure the root window gets deleted before cursor_window_delegate. - Close(); -} - -void VirtualKeyboardWindowController::ActivateKeyboard( - keyboard::KeyboardController* keyboard_controller) { - root_window_controller_->ActivateKeyboard(keyboard_controller); -} - -void VirtualKeyboardWindowController::UpdateWindow( - const DisplayInfo& display_info) { - static int virtual_keyboard_root_window_count = 0; - if (!root_window_controller_.get()) { - const gfx::Rect& bounds_in_native = display_info.bounds_in_native(); - aura::RootWindow::CreateParams params(bounds_in_native); - params.host = Shell::GetInstance()->root_window_host_factory()-> - CreateRootWindowHost(bounds_in_native); - aura::RootWindow* root_window = new aura::RootWindow(params); - - root_window->window()->SetName( - base::StringPrintf("VirtualKeyboardRootWindow-%d", - virtual_keyboard_root_window_count++)); - - // No need to remove RootWindowObserver because - // the DisplayController object outlives RootWindow objects. - root_window->AddRootWindowObserver( - Shell::GetInstance()->display_controller()); - InitRootWindowSettings(root_window->window())->display_id = - display_info.id(); - root_window->Init(); - RootWindowController::CreateForVirtualKeyboardDisplay(root_window); - root_window_controller_.reset(GetRootWindowController( - root_window->window())); - root_window_controller_->dispatcher()->host()->Show(); - root_window_controller_->ActivateKeyboard( - Shell::GetInstance()->keyboard_controller()); - FlipDisplay(); - } else { - aura::RootWindow* root_window = root_window_controller_->dispatcher(); - GetRootWindowSettings(root_window->window())->display_id = - display_info.id(); - root_window->SetHostBounds(display_info.bounds_in_native()); - } -} - -void VirtualKeyboardWindowController::Close() { - if (root_window_controller_.get()) { - root_window_controller_->dispatcher()->RemoveRootWindowObserver( - Shell::GetInstance()->display_controller()); - root_window_controller_->Shutdown(); - root_window_controller_.reset(); - } -} - -void VirtualKeyboardWindowController::FlipDisplay() { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - if (!display_manager->virtual_keyboard_root_window_enabled()) { - NOTREACHED() << "Attempting to flip virtual keyboard root window when it " - << "is not enabled."; - return; - } - display_manager->SetDisplayRotation( - display_manager->non_desktop_display().id(), gfx::Display::ROTATE_180); - - aura::RootWindow* root_window = root_window_controller_->dispatcher(); - scoped_ptr<aura::RootWindowTransformer> transformer( - internal::CreateRootWindowTransformerForDisplay(root_window->window(), - display_manager->non_desktop_display())); - root_window->SetRootWindowTransformer(transformer.Pass()); -} - -} // namespace internal -} // namespace ash diff --git a/chromium/ash/display/virtual_keyboard_window_controller.h b/chromium/ash/display/virtual_keyboard_window_controller.h deleted file mode 100644 index 6a466599723..00000000000 --- a/chromium/ash/display/virtual_keyboard_window_controller.h +++ /dev/null @@ -1,61 +0,0 @@ -// 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_DISPLAY_VIRTUAL_KEYBOARD_WINDOW_CONTROLLER_H_ -#define ASH_DISPLAY_VIRTUAL_KEYBOARD_WINDOW_CONTROLLER_H_ - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "ui/gfx/display.h" - -namespace keyboard { -class KeyboardController; -} - -namespace ash { - -namespace test { -class VirtualKeyboardWindowControllerTest; -} // namespace test - -namespace internal { -class DisplayInfo; -class RootWindowController; - -// This class maintains the RootWindowController dedicated for -// virtual keyboard. -class ASH_EXPORT VirtualKeyboardWindowController { - public: - VirtualKeyboardWindowController(); - virtual ~VirtualKeyboardWindowController(); - - void ActivateKeyboard(keyboard::KeyboardController* keyboard_controller); - - // Updates the root window's bounds using |display_info|. - // Creates the new root window if one doesn't exist. - void UpdateWindow(const DisplayInfo& display_info); - - // Close the mirror window. - void Close(); - - private: - friend class test::VirtualKeyboardWindowControllerTest; - - // Rotates virtual keyboard display by 180 degrees. - void FlipDisplay(); - - RootWindowController* root_window_controller_for_test() { - return root_window_controller_.get(); - } - - scoped_ptr<RootWindowController> root_window_controller_; - - DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardWindowController); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_DISPLAY_VIRTUAL_KEYBOARD_WINDOW_CONTROLLER_H_ diff --git a/chromium/ash/display/virtual_keyboard_window_controller_unittest.cc b/chromium/ash/display/virtual_keyboard_window_controller_unittest.cc deleted file mode 100644 index 720690e85f8..00000000000 --- a/chromium/ash/display/virtual_keyboard_window_controller_unittest.cc +++ /dev/null @@ -1,66 +0,0 @@ -// 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/display/virtual_keyboard_window_controller.h" - -#include "ash/ash_switches.h" -#include "ash/display/display_controller.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "ash/test/ash_test_base.h" -#include "base/command_line.h" -#include "ui/keyboard/keyboard_switches.h" - -namespace ash { -namespace test { - -class VirtualKeyboardWindowControllerTest : public AshTestBase { - public: - VirtualKeyboardWindowControllerTest() - : virtual_keyboard_window_controller_(NULL) {} - virtual ~VirtualKeyboardWindowControllerTest() {} - - virtual void SetUp() OVERRIDE { - if (SupportsMultipleDisplays()) { - CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kAshHostWindowBounds, "1+1-300x300,1+301-300x300"); - CommandLine::ForCurrentProcess()->AppendSwitch( - keyboard::switches::kKeyboardUsabilityExperiment); - } - test::AshTestBase::SetUp(); - } - - void set_virtual_keyboard_window_controller( - internal::VirtualKeyboardWindowController* controller) { - virtual_keyboard_window_controller_ = controller; - } - - internal::RootWindowController* root_window_controller() { - return virtual_keyboard_window_controller_-> - root_window_controller_for_test(); - } - - private: - internal::VirtualKeyboardWindowController* - virtual_keyboard_window_controller_; - DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardWindowControllerTest); -}; - - -TEST_F(VirtualKeyboardWindowControllerTest, VirtualKeyboardWindowTest) { - if (!SupportsMultipleDisplays()) - return; - RunAllPendingInMessageLoop(); - set_virtual_keyboard_window_controller( - Shell::GetInstance()->display_controller()-> - virtual_keyboard_window_controller()); - EXPECT_TRUE(root_window_controller()); - // Keyboard container is added to virtual keyboard window. - EXPECT_TRUE(root_window_controller()->GetContainer( - internal::kShellWindowId_VirtualKeyboardContainer)); -} - -} // namespace test -} // namespace ash |