From ebc1dea7ab6f535eac8db6de630d7c509d57b6d8 Mon Sep 17 00:00:00 2001 From: "oshima@chromium.org" Date: Wed, 27 Jun 2012 18:50:45 +0000 Subject: Rename the remaining usage of Monitor to Display BUG=none TEST=none Review URL: https://chromiumcodereview.appspot.com/10675011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144499 0039d316-1c4b-4281-b951-d872f2087c98 --- ash/accelerators/accelerator_controller.cc | 18 +- ash/accelerators/accelerator_table.cc | 6 +- ash/accelerators/accelerator_table.h | 6 +- ash/ash.gyp | 18 +- ash/dip_unittest.cc | 6 +- ash/display/display_controller.cc | 269 +++++++ ash/display/display_controller.h | 109 +++ ash/display/mouse_cursor_event_filter.cc | 53 ++ ash/display/mouse_cursor_event_filter.h | 44 ++ ash/display/multi_display_manager.cc | 247 +++++++ ash/display/multi_display_manager.h | 84 +++ ash/display/multi_display_manager_unittest.cc | 235 ++++++ ash/display/secondary_display_view.cc | 111 +++ ash/display/secondary_display_view.h | 25 + ash/extended_desktop_unittest.cc | 50 +- ash/monitor/monitor_controller.cc | 269 ------- ash/monitor/monitor_controller.h | 109 --- ash/monitor/mouse_cursor_event_filter.cc | 53 -- ash/monitor/mouse_cursor_event_filter.h | 44 -- ash/monitor/multi_monitor_manager.cc | 247 ------- ash/monitor/multi_monitor_manager.h | 84 --- ash/monitor/multi_monitor_manager_unittest.cc | 235 ------ ash/monitor/secondary_monitor_view.cc | 111 --- ash/monitor/secondary_monitor_view.h | 25 - ash/root_window_controller_unittest.cc | 22 +- ash/screen_ash.cc | 14 +- ash/shell.cc | 62 +- ash/shell.h | 16 +- ash/shell_observer.h | 2 +- ash/test/ash_test_base.cc | 14 +- ash/test/ash_test_base.h | 8 +- ash/tooltips/tooltip_controller.cc | 14 +- ash/wm/base_layout_manager.cc | 12 +- ash/wm/base_layout_manager.h | 2 +- ash/wm/base_layout_manager_unittest.cc | 10 +- ash/wm/frame_painter.cc | 4 +- ash/wm/screen_dimmer.h | 2 +- ash/wm/shelf_layout_manager.cc | 6 +- ash/wm/shelf_layout_manager_unittest.cc | 24 +- ash/wm/stacking_controller.cc | 4 +- ash/wm/toplevel_window_event_filter_unittest.cc | 2 +- ash/wm/window_resizer.cc | 4 +- ash/wm/window_util.h | 2 +- ash/wm/workspace/snap_sizer.cc | 2 +- ash/wm/workspace/workspace_manager.cc | 2 +- ash/wm/workspace/workspace_window_resizer.cc | 6 +- .../workspace/workspace_window_resizer_unittest.cc | 14 +- chrome/browser/chromeos/power/output_observer.cc | 2 +- chrome/browser/ui/ash/ash_init.cc | 4 +- .../aura/chrome_browser_main_extra_parts_aura.cc | 4 +- .../ash/chrome_browser_main_extra_parts_ash.cc | 4 +- .../options2/chromeos/display_options_handler.cc | 42 +- chromeos/chromeos.gyp | 4 +- chromeos/display/DEPS | 3 + chromeos/display/output_configurator.cc | 804 +++++++++++++++++++++ chromeos/display/output_configurator.h | 165 +++++ chromeos/monitor/DEPS | 3 - chromeos/monitor/output_configurator.cc | 804 --------------------- chromeos/monitor/output_configurator.h | 165 ----- ui/aura/aura.gyp | 12 +- ui/aura/bench/bench_main.cc | 8 +- ui/aura/demo/demo_main.cc | 6 +- ui/aura/display_change_observer_x11.cc | 148 ++++ ui/aura/display_change_observer_x11.h | 47 ++ ui/aura/display_manager.cc | 87 +++ ui/aura/display_manager.h | 101 +++ ui/aura/display_observer.h | 8 +- ui/aura/env.cc | 14 +- ui/aura/env.h | 14 +- ui/aura/monitor_change_observer_x11.cc | 148 ---- ui/aura/monitor_change_observer_x11.h | 47 -- ui/aura/monitor_manager.cc | 87 --- ui/aura/monitor_manager.h | 101 --- ui/aura/root_window.cc | 14 +- ui/aura/single_display_manager.cc | 98 +++ ui/aura/single_display_manager.h | 60 ++ ui/aura/single_monitor_manager.cc | 98 --- ui/aura/single_monitor_manager.h | 60 -- ui/aura/test/aura_test_helper.cc | 8 +- ui/aura/window.cc | 2 +- ui/aura/window.h | 2 +- ui/views/widget/native_widget_aura_unittest.cc | 2 - 82 files changed, 2940 insertions(+), 2942 deletions(-) create mode 100644 ash/display/display_controller.cc create mode 100644 ash/display/display_controller.h create mode 100644 ash/display/mouse_cursor_event_filter.cc create mode 100644 ash/display/mouse_cursor_event_filter.h create mode 100644 ash/display/multi_display_manager.cc create mode 100644 ash/display/multi_display_manager.h create mode 100644 ash/display/multi_display_manager_unittest.cc create mode 100644 ash/display/secondary_display_view.cc create mode 100644 ash/display/secondary_display_view.h delete mode 100644 ash/monitor/monitor_controller.cc delete mode 100644 ash/monitor/monitor_controller.h delete mode 100644 ash/monitor/mouse_cursor_event_filter.cc delete mode 100644 ash/monitor/mouse_cursor_event_filter.h delete mode 100644 ash/monitor/multi_monitor_manager.cc delete mode 100644 ash/monitor/multi_monitor_manager.h delete mode 100644 ash/monitor/multi_monitor_manager_unittest.cc delete mode 100644 ash/monitor/secondary_monitor_view.cc delete mode 100644 ash/monitor/secondary_monitor_view.h create mode 100644 chromeos/display/DEPS create mode 100644 chromeos/display/output_configurator.cc create mode 100644 chromeos/display/output_configurator.h delete mode 100644 chromeos/monitor/DEPS delete mode 100644 chromeos/monitor/output_configurator.cc delete mode 100644 chromeos/monitor/output_configurator.h create mode 100644 ui/aura/display_change_observer_x11.cc create mode 100644 ui/aura/display_change_observer_x11.h create mode 100644 ui/aura/display_manager.cc create mode 100644 ui/aura/display_manager.h delete mode 100644 ui/aura/monitor_change_observer_x11.cc delete mode 100644 ui/aura/monitor_change_observer_x11.h delete mode 100644 ui/aura/monitor_manager.cc delete mode 100644 ui/aura/monitor_manager.h create mode 100644 ui/aura/single_display_manager.cc create mode 100644 ui/aura/single_display_manager.h delete mode 100644 ui/aura/single_monitor_manager.cc delete mode 100644 ui/aura/single_monitor_manager.h diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 287bcec..29380da 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -16,8 +16,8 @@ #include "ash/launcher/launcher_delegate.h" #include "ash/launcher/launcher_model.h" #include "ash/magnifier/magnification_controller.h" -#include "ash/monitor/monitor_controller.h" -#include "ash/monitor/multi_monitor_manager.h" +#include "ash/display/display_controller.h" +#include "ash/display/multi_display_manager.h" #include "ash/root_window_controller.h" #include "ash/screenshot_delegate.h" #include "ash/shell.h" @@ -44,7 +44,7 @@ #include "ui/oak/oak.h" #if defined(OS_CHROMEOS) -#include "chromeos/monitor/output_configurator.h" +#include "chromeos/display/output_configurator.h" #endif // defined(OS_CHROMEOS) namespace ash { @@ -585,17 +585,17 @@ bool AcceleratorController::PerformAction(int action, return HandleToggleDesktopBackgroundMode(); case TOGGLE_ROOT_WINDOW_FULL_SCREEN: return HandleToggleRootWindowFullScreen(); - case MONITOR_ADD_REMOVE: + case DISPLAY_ADD_REMOVE: if (DebugShortcutsEnabled()) - internal::MultiMonitorManager::AddRemoveMonitor(); + internal::MultiDisplayManager::AddRemoveDisplay(); return true; - case MONITOR_CYCLE: + case DISPLAY_CYCLE: if (DebugShortcutsEnabled()) - internal::MultiMonitorManager::CycleMonitor(); + internal::MultiDisplayManager::CycleDisplay(); return true; - case MONITOR_TOGGLE_SCALE: + case DISPLAY_TOGGLE_SCALE: if (DebugShortcutsEnabled()) - internal::MultiMonitorManager::ToggleMonitorScale(); + internal::MultiDisplayManager::ToggleDisplayScale(); return true; case MAGNIFY_SCREEN_ZOOM_IN: return HandleMagnifyScreen(1); diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc index 3c40f73..ba89019 100644 --- a/ash/accelerators/accelerator_table.cc +++ b/ash/accelerators/accelerator_table.cc @@ -123,10 +123,10 @@ const AcceleratorData kAcceleratorData[] = { // For testing on systems where Alt-Tab is already mapped. { true, ui::VKEY_W, ui::EF_ALT_DOWN, CYCLE_FORWARD_MRU }, { true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU }, - { true, ui::VKEY_F4, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, MONITOR_CYCLE }, - { true, ui::VKEY_F4, ui::EF_SHIFT_DOWN, MONITOR_ADD_REMOVE }, + { true, ui::VKEY_F4, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, DISPLAY_CYCLE }, + { true, ui::VKEY_F4, ui::EF_SHIFT_DOWN, DISPLAY_ADD_REMOVE }, { true, ui::VKEY_HOME, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, - MONITOR_TOGGLE_SCALE }, + DISPLAY_TOGGLE_SCALE }, #if !defined(NDEBUG) { true, ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, PRINT_LAYER_HIERARCHY }, diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h index 23961b5..788de46 100644 --- a/ash/accelerators/accelerator_table.h +++ b/ash/accelerators/accelerator_table.h @@ -67,9 +67,9 @@ enum AcceleratorAction { OPEN_FILE_MANAGER_DIALOG, OPEN_FILE_MANAGER_TAB, #endif - MONITOR_ADD_REMOVE, - MONITOR_CYCLE, - MONITOR_TOGGLE_SCALE, + DISPLAY_ADD_REMOVE, + DISPLAY_CYCLE, + DISPLAY_TOGGLE_SCALE, ROTATE_SCREEN, TOGGLE_DESKTOP_BACKGROUND_MODE, TOGGLE_ROOT_WINDOW_FULL_SCREEN, diff --git a/ash/ash.gyp b/ash/ash.gyp index 3f831df..3559d51 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -97,14 +97,14 @@ 'launcher/tabbed_launcher_button.h', 'magnifier/magnification_controller.cc', 'magnifier/magnification_controller.h', - 'monitor/monitor_controller.cc', - 'monitor/monitor_controller.h', - 'monitor/mouse_cursor_event_filter.cc', - 'monitor/mouse_cursor_event_filter.h', - 'monitor/multi_monitor_manager.cc', - 'monitor/multi_monitor_manager.h', - 'monitor/secondary_monitor_view.cc', - 'monitor/secondary_monitor_view.h', + 'display/display_controller.cc', + 'display/display_controller.h', + 'display/mouse_cursor_event_filter.cc', + 'display/mouse_cursor_event_filter.h', + 'display/multi_display_manager.cc', + 'display/multi_display_manager.h', + 'display/secondary_display_view.cc', + 'display/secondary_display_view.h', 'root_window_controller.cc', 'root_window_controller.h', 'screen_ash.cc', @@ -379,6 +379,7 @@ 'accelerators/accelerator_table_unittest.cc', 'accelerators/nested_dispatcher_controller_unittest.cc', 'dip_unittest.cc', + 'display/multi_display_manager_unittest.cc', 'drag_drop/drag_drop_controller_unittest.cc', 'extended_desktop_unittest.cc', 'focus_cycler_unittest.cc', @@ -387,7 +388,6 @@ 'launcher/launcher_navigator_unittest.cc', 'launcher/launcher_unittest.cc', 'launcher/launcher_view_unittest.cc', - 'monitor/multi_monitor_manager_unittest.cc', 'root_window_controller_unittest.cc', 'screensaver/screensaver_view_unittest.cc', 'shell_unittest.cc', diff --git a/ash/dip_unittest.cc b/ash/dip_unittest.cc index a6ebe14..b710e4c 100644 --- a/ash/dip_unittest.cc +++ b/ash/dip_unittest.cc @@ -28,7 +28,7 @@ namespace ash { typedef ash::test::AshTestBase DIPTest; #if defined(OS_WIN) -// Windows/Aura doesn't have DIP support in monitor yet. +// Windows/Aura doesn't have DIP support in display yet. #define MAYBE_WorkArea DISABLED_WorkArea #else #define MAYBE_WorkArea WorkArea @@ -36,7 +36,7 @@ typedef ash::test::AshTestBase DIPTest; // Test if the WM sets correct work area under different density. TEST_F(DIPTest, MAYBE_WorkArea) { - ChangeMonitorConfig(1.0f, gfx::Rect(0, 0, 1000, 900)); + ChangeDisplayConfig(1.0f, gfx::Rect(0, 0, 1000, 900)); aura::RootWindow* root = Shell::GetPrimaryRootWindow(); const gfx::Display display = gfx::Screen::GetDisplayNearestWindow(root); @@ -46,7 +46,7 @@ TEST_F(DIPTest, MAYBE_WorkArea) { EXPECT_EQ("0,0 1000x852", work_area.ToString()); EXPECT_EQ("0,0,48,0", display.bounds().InsetsFrom(work_area).ToString()); - ChangeMonitorConfig(2.0f, gfx::Rect(0, 0, 2000, 1800)); + ChangeDisplayConfig(2.0f, gfx::Rect(0, 0, 2000, 1800)); const gfx::Display display_2x = gfx::Screen::GetDisplayNearestWindow(root); diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc new file mode 100644 index 0000000..895532a --- /dev/null +++ b/ash/display/display_controller.cc @@ -0,0 +1,269 @@ +// 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/multi_display_manager.h" +#include "ash/root_window_controller.h" +#include "ash/shell.h" +#include "ash/wm/window_util.h" +#include "base/command_line.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" + +namespace ash { +namespace internal { +namespace { +// True if the extended desktop mode is enabled. +bool extended_desktop_enabled = false; + +// True if the virtual screen coordinates is enabled. +bool virtual_screen_coordinates_enabled = false; +} + +DisplayController::DisplayController() + : secondary_display_layout_(RIGHT) { + aura::Env::GetInstance()->display_manager()->AddObserver(this); +} + +DisplayController::~DisplayController() { + aura::Env::GetInstance()->display_manager()->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::const_reverse_iterator it = + root_windows_.rbegin(); it != root_windows_.rend(); ++it) { + internal::RootWindowController* controller = + wm::GetRootWindowController(it->second); + // RootWindow may not have RootWindowController in non + // extended desktop mode. + if (controller) + delete controller; + else + delete it->second; + } +} + +void DisplayController::InitPrimaryDisplay() { + aura::DisplayManager* display_manager = + aura::Env::GetInstance()->display_manager(); + const gfx::Display& display = display_manager->GetDisplayAt(0); + DCHECK_EQ(0, display.id()); + aura::RootWindow* root = AddRootWindowForDisplay(display); + root->SetHostBounds(display.bounds_in_pixel()); +} + +void DisplayController::InitSecondaryDisplays() { + aura::DisplayManager* display_manager = + aura::Env::GetInstance()->display_manager(); + for (size_t i = 1; i < display_manager->GetNumDisplays(); ++i) { + const gfx::Display& display = display_manager->GetDisplayAt(i); + aura::RootWindow* root = AddRootWindowForDisplay(display); + Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); + } +} + +aura::RootWindow* DisplayController::GetPrimaryRootWindow() { + DCHECK(!root_windows_.empty()); + return root_windows_[0]; +} + +void DisplayController::CloseChildWindows() { + for (std::map::const_iterator it = + root_windows_.begin(); it != root_windows_.end(); ++it) { + aura::RootWindow* root_window = it->second; + internal::RootWindowController* controller = + wm::GetRootWindowController(root_window); + if (controller) { + controller->CloseChildWindows(); + } else { + while (!root_window->children().empty()) { + aura::Window* child = root_window->children()[0]; + delete child; + } + } + } +} + +std::vector DisplayController::GetAllRootWindows() { + std::vector windows; + for (std::map::const_iterator it = + root_windows_.begin(); it != root_windows_.end(); ++it) { + DCHECK(it->second); + if (wm::GetRootWindowController(it->second)) + windows.push_back(it->second); + } + return windows; +} + +std::vector +DisplayController::GetAllRootWindowControllers() { + std::vector controllers; + for (std::map::const_iterator it = + root_windows_.begin(); it != root_windows_.end(); ++it) { + internal::RootWindowController* controller = + wm::GetRootWindowController(it->second); + if (controller) + controllers.push_back(controller); + } + return controllers; +} + +void DisplayController::SetSecondaryDisplayLayout( + SecondaryDisplayLayout layout) { + secondary_display_layout_ = layout; +} + +bool DisplayController::WarpMouseCursorIfNecessary( + aura::Window* current_root, + const gfx::Point& location_in_root) { + if (root_windows_.size() < 2) + return false; + // Only 1 external display is supported in extended desktop mode. + DCHECK_EQ(2U, root_windows_.size()); + + bool in_primary = current_root == root_windows_[0]; + + std::map::iterator iter = root_windows_.begin(); + aura::RootWindow* alternate_root = iter->second != current_root ? + iter->second : (++iter)->second; + gfx::Rect alternate_bounds = alternate_root->bounds(); + gfx::Point alternate_point; + + gfx::Rect display_area( + gfx::Screen::GetDisplayNearestWindow(current_root).bounds()); + + // TODO(oshima): This is temporary code until the virtual screen + // coordinate is implemented. + if (location_in_root.x() <= display_area.x()) { + if (location_in_root.y() < alternate_bounds.height() && + ((in_primary && secondary_display_layout_ == LEFT) || + (!in_primary && secondary_display_layout_ == RIGHT))) { + alternate_point = gfx::Point( + alternate_bounds.right() - (location_in_root.x() - display_area.x()), + location_in_root.y()); + } else { + alternate_root = NULL; + } + } else if (location_in_root.x() >= display_area.right() - 1) { + if (location_in_root.y() < alternate_bounds.height() && + ((in_primary && secondary_display_layout_ == RIGHT) || + (!in_primary && secondary_display_layout_ == LEFT))) { + alternate_point = gfx::Point(location_in_root.x() - display_area.right(), + location_in_root.y()); + } else { + alternate_root = NULL; + } + } else if (location_in_root.y() < display_area.y()) { + if (location_in_root.x() < alternate_bounds.width() && + ((in_primary && secondary_display_layout_ == TOP) || + (!in_primary && secondary_display_layout_ == BOTTOM))) { + alternate_point = gfx::Point( + location_in_root.x(), + alternate_bounds.bottom() - + (location_in_root.y() - display_area.y())); + } else { + alternate_root = NULL; + } + } else if (location_in_root.y() >= display_area.bottom() - 1) { + if (location_in_root.x() < alternate_bounds.width() && + ((in_primary && secondary_display_layout_ == BOTTOM) || + (!in_primary && secondary_display_layout_ == TOP))) { + alternate_point = gfx::Point( + location_in_root.x(), location_in_root.y() - display_area.bottom()); + } else { + alternate_root = NULL; + } + } else { + alternate_root = NULL; + } + if (alternate_root) { + DCHECK_NE(alternate_root, current_root); + alternate_root->MoveCursorTo(alternate_point); + return true; + } + return false; +} + +void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { + root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); +} + +void DisplayController::OnDisplayAdded(const gfx::Display& display) { + if (root_windows_.empty()) { + DCHECK_EQ(0, display.id()); + root_windows_[display.id()] = Shell::GetPrimaryRootWindow(); + Shell::GetPrimaryRootWindow()->SetHostBounds(display.bounds_in_pixel()); + return; + } + aura::RootWindow* root = AddRootWindowForDisplay(display); + Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); +} + +void DisplayController::OnDisplayRemoved(const gfx::Display& display) { + aura::RootWindow* root = root_windows_[display.id()]; + DCHECK(root); + // Primary display should never be removed by DisplayManager. + DCHECK(root != Shell::GetPrimaryRootWindow()); + // Display for root window will be deleted when the Primary RootWindow + // is deleted by the Shell. + if (root != Shell::GetPrimaryRootWindow()) { + root_windows_.erase(display.id()); + internal::RootWindowController* controller = + wm::GetRootWindowController(root); + if (controller) { + controller->MoveWindowsTo(Shell::GetPrimaryRootWindow()); + delete controller; + } else { + delete root; + } + } +} + +// static +bool DisplayController::IsExtendedDesktopEnabled(){ + return extended_desktop_enabled || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshExtendedDesktop); +} + +// static +void DisplayController::SetExtendedDesktopEnabled(bool enabled) { + extended_desktop_enabled = enabled; +} + +// static +bool DisplayController::IsVirtualScreenCoordinatesEnabled() { + return virtual_screen_coordinates_enabled || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshVirtualScreenCoordinates); +} + +// static +void DisplayController::SetVirtualScreenCoordinatesEnabled(bool enabled) { + virtual_screen_coordinates_enabled = enabled; +} + +aura::RootWindow* DisplayController::AddRootWindowForDisplay( + const gfx::Display& display) { + aura::RootWindow* root = aura::Env::GetInstance()->display_manager()-> + CreateRootWindowForDisplay(display); + root_windows_[display.id()] = root; + // Confine the cursor within the window if + // 1) Extended desktop is enabled or + // 2) the display is primary display and the host window + // is set to be fullscreen (this is old behavior). + if (IsExtendedDesktopEnabled() || + (aura::DisplayManager::use_fullscreen_host_window() && + display.id() == 0)) { + root->ConfineCursorToWindow(); + } + return root; +} + +} // namespace internal +} // namespace ash diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h new file mode 100644 index 0000000..1b66d01 --- /dev/null +++ b/ash/display/display_controller.h @@ -0,0 +1,109 @@ +// 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_ +#pragma once + +#include +#include + +#include "ash/ash_export.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/aura/display_observer.h" +#include "ui/aura/display_manager.h" + +namespace aura { +class Display; +class RootWindow; +} + +namespace ash { +namespace internal { +class RootWindowController; + +// DisplayController owns and maintains RootWindows for each attached +// display, keeping them in sync with display configuration changes. +// TODO(oshima): Rename DisplayXXX to DisplayXXX. +class ASH_EXPORT DisplayController : public aura::DisplayObserver { + public: + // Layout options where the secondary display should be positioned. + enum SecondaryDisplayLayout { + TOP, + RIGHT, + BOTTOM, + LEFT + }; + + DisplayController(); + virtual ~DisplayController(); + + // Initializes primary display. + void InitPrimaryDisplay(); + + // Initialize secondary display. This is separated because in non + // extended desktop mode, this creates background widgets, which + // requires other controllers. + void InitSecondaryDisplays(); + + // Returns the root window for primary display. + aura::RootWindow* GetPrimaryRootWindow(); + + // 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. + std::vector GetAllRootWindows(); + + // Returns all oot window controllers. In non extended desktop + // mode, this return a RootWindowController for the primary root window only. + std::vector GetAllRootWindowControllers(); + + SecondaryDisplayLayout secondary_display_layout() const { + return secondary_display_layout_; + } + void SetSecondaryDisplayLayout(SecondaryDisplayLayout layout); + + // Warps the mouse cursor to an alternate root window when the + // |location_in_root|, which is the location of the mouse cursor, + // hits or exceeds the edge of the |root_window| and the mouse cursor + // is considered to be in an alternate display. Returns true if + // the cursor was moved. + bool WarpMouseCursorIfNecessary(aura::Window* root_window, + const gfx::Point& location_in_root); + + // 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; + + // Is extended desktop enabled? + static bool IsExtendedDesktopEnabled(); + // Change the extended desktop mode. Used for testing. + static void SetExtendedDesktopEnabled(bool enabled); + + // Is virtual screen coordinates enabled? + static bool IsVirtualScreenCoordinatesEnabled(); + // Turns on/off the virtual screen coordinates. + static void SetVirtualScreenCoordinatesEnabled(bool enabled); + + private: + // Creates a root window for |display| and stores it in the |root_windows_| + // map. + aura::RootWindow* AddRootWindowForDisplay(const gfx::Display& display); + + std::map root_windows_; + + SecondaryDisplayLayout secondary_display_layout_; + + DISALLOW_COPY_AND_ASSIGN(DisplayController); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_DISPLAY_DISPLAY_CONTROLLER_H_ diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc new file mode 100644 index 0000000..0ab6f1c --- /dev/null +++ b/ash/display/mouse_cursor_event_filter.cc @@ -0,0 +1,53 @@ +// 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 "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" + +namespace ash { +namespace internal { + +MouseCursorEventFilter::MouseCursorEventFilter( + DisplayController* display_controller) + : display_controller_(display_controller) { + DCHECK(display_controller_); +} + +MouseCursorEventFilter::~MouseCursorEventFilter() { +} + +bool MouseCursorEventFilter::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + return false; +} + +bool MouseCursorEventFilter::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + if (event->type() != ui::ET_MOUSE_MOVED) + return false; + aura::RootWindow* current_root = target->GetRootWindow(); + gfx::Point location_in_root(event->location()); + aura::Window::ConvertPointToWindow(target, current_root, &location_in_root); + return display_controller_->WarpMouseCursorIfNecessary( + current_root, location_in_root); +} + +ui::TouchStatus MouseCursorEventFilter::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +ui::GestureStatus MouseCursorEventFilter::PreHandleGestureEvent( + aura::Window* target, + aura::GestureEvent* event) { + return ui::GESTURE_STATUS_UNKNOWN; +} + +} // namespace internal +} // namespace ash diff --git a/ash/display/mouse_cursor_event_filter.h b/ash/display/mouse_cursor_event_filter.h new file mode 100644 index 0000000..a89a6b7 --- /dev/null +++ b/ash/display/mouse_cursor_event_filter.h @@ -0,0 +1,44 @@ +// 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 +#pragma once + +#include "ash/ash_export.h" +#include "base/compiler_specific.h" +#include "ui/aura/event_filter.h" + +namespace ash { +namespace internal { +class DisplayController; + +// An event filter that controls mouse location in extended desktop +// environment. +class ASH_EXPORT MouseCursorEventFilter : public aura::EventFilter { + public: + MouseCursorEventFilter(DisplayController* display_controller); + virtual ~MouseCursorEventFilter(); + + // Overridden from aura::EventFilter: + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + virtual ui::GestureStatus PreHandleGestureEvent( + aura::Window* target, + aura::GestureEvent* event) OVERRIDE; + + private: + DisplayController* display_controller_; + + DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilter); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H diff --git a/ash/display/multi_display_manager.cc b/ash/display/multi_display_manager.cc new file mode 100644 index 0000000..54b3d74 --- /dev/null +++ b/ash/display/multi_display_manager.cc @@ -0,0 +1,247 @@ +// 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/multi_display_manager.h" + +#include +#include + +#include "base/command_line.h" +#include "base/stl_util.h" +#include "base/string_split.h" +#include "ui/aura/aura_switches.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/aura/root_window_host.h" +#include "ui/aura/window_property.h" +#include "ui/gfx/display.h" +#include "ui/gfx/rect.h" + +DECLARE_WINDOW_PROPERTY_TYPE(int); + +namespace ash { +namespace internal { +namespace { + +gfx::Display& GetInvalidDisplay() { + static gfx::Display* invalid_display = new gfx::Display(); + return *invalid_display; +} + +} // namespace + +using aura::RootWindow; +using aura::Window; +using std::string; +using std::vector; + +DEFINE_WINDOW_PROPERTY_KEY(int, kDisplayIdKey, -1); + +MultiDisplayManager::MultiDisplayManager() { + Init(); +} + +MultiDisplayManager::~MultiDisplayManager() { +} + +// static +void MultiDisplayManager::AddRemoveDisplay() { + MultiDisplayManager* manager = static_cast( + aura::Env::GetInstance()->display_manager()); + manager->AddRemoveDisplayImpl(); +} + +void MultiDisplayManager::CycleDisplay() { + MultiDisplayManager* manager = static_cast( + aura::Env::GetInstance()->display_manager()); + manager->CycleDisplayImpl(); +} + + void MultiDisplayManager::ToggleDisplayScale() { + MultiDisplayManager* manager = static_cast( + aura::Env::GetInstance()->display_manager()); + manager->ScaleDisplayImpl(); +} + +void MultiDisplayManager::OnNativeDisplaysChanged( + const std::vector& new_displays) { + size_t min = std::min(displays_.size(), new_displays.size()); + + // For m19, we only care about 1st display as primary, and + // don't differentiate the rest of displays as all secondary + // displays have the same content. ID for primary display stays the same + // because we never remove it, we don't update IDs for other displays + // , for now, because they're the same. + // TODO(oshima): Fix this so that we can differentiate outputs + // and keep a content on one display stays on the same display + // when a display is added or removed. + for (size_t i = 0; i < min; ++i) { + gfx::Display& current_display = displays_[i]; + const gfx::Display& new_display = new_displays[i]; + if (current_display.bounds_in_pixel() != new_display.bounds_in_pixel() || + current_display.device_scale_factor() != + new_display.device_scale_factor()) { + current_display.SetScaleAndBounds(new_display.device_scale_factor(), + new_display.bounds_in_pixel()); + NotifyBoundsChanged(current_display); + } + } + + if (displays_.size() < new_displays.size()) { + // New displays added + for (size_t i = min; i < new_displays.size(); ++i) { + const gfx::Display& new_display = new_displays[i]; + displays_.push_back(gfx::Display(new_display.id())); + gfx::Display& display = displays_.back(); + // Force the primary display's ID to be 0. + if (i == 0) + display.set_id(0); + display.SetScaleAndBounds(new_display.device_scale_factor(), + new_display.bounds_in_pixel()); + NotifyDisplayAdded(display); + } + } else { + // Displays are removed. We keep the display for the primary + // display (at index 0) because it needs the display information + // even if it doesn't exit. + while (displays_.size() > new_displays.size() && displays_.size() > 1) { + Displays::reverse_iterator iter = displays_.rbegin(); + NotifyDisplayRemoved(*iter); + displays_.erase(iter.base() - 1); + } + } +} + +RootWindow* MultiDisplayManager::CreateRootWindowForDisplay( + const gfx::Display& display) { + RootWindow* root_window = new RootWindow(display.bounds_in_pixel()); + // No need to remove RootWindowObserver because + // the DisplayManager object outlives RootWindow objects. + root_window->AddRootWindowObserver(this); + root_window->SetProperty(kDisplayIdKey, display.id()); + root_window->Init(); + return root_window; +} + +const gfx::Display& MultiDisplayManager::GetDisplayAt(size_t index) { + return index < displays_.size() ? displays_[index] : GetInvalidDisplay(); +} + +size_t MultiDisplayManager::GetNumDisplays() const { + return displays_.size(); +} + +const gfx::Display& MultiDisplayManager::GetDisplayNearestWindow( + const Window* window) const { + if (!window) { + MultiDisplayManager* manager = const_cast(this); + return manager->GetDisplayAt(0); + } + const RootWindow* root = window->GetRootWindow(); + MultiDisplayManager* manager = const_cast(this); + return root ? manager->FindDisplayForRootWindow(root) : GetInvalidDisplay(); +} + +const gfx::Display& MultiDisplayManager::GetDisplayNearestPoint( + const gfx::Point& point) const { + // TODO(oshima): For m19, mouse is constrained within + // the primary window. + MultiDisplayManager* manager = const_cast(this); + return manager->GetDisplayAt(0); +} + +void MultiDisplayManager::OnRootWindowResized(const aura::RootWindow* root, + const gfx::Size& old_size) { + if (!use_fullscreen_host_window()) { + gfx::Display& display = FindDisplayForRootWindow(root); + display.SetSize(root->GetHostSize()); + NotifyBoundsChanged(display); + } +} + +bool MultiDisplayManager::UpdateWorkAreaOfDisplayNearestWindow( + const aura::Window* window, + const gfx::Insets& insets) { + const RootWindow* root = window->GetRootWindow(); + gfx::Display& display = FindDisplayForRootWindow(root); + gfx::Rect old_work_area = display.work_area(); + display.UpdateWorkAreaFromInsets(insets); + return old_work_area != display.work_area(); +} + +void MultiDisplayManager::Init() { + // TODO(oshima): Move this logic to DisplayChangeObserver. + const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kAuraHostWindowSize); + vector parts; + base::SplitString(size_str, ',', &parts); + for (vector::const_iterator iter = parts.begin(); + iter != parts.end(); ++iter) { + displays_.push_back(CreateDisplayFromSpec(*iter)); + } + if (displays_.empty()) + displays_.push_back(CreateDisplayFromSpec("" /* default */)); + // Force the 1st display to be the primary display (id == 0). + displays_[0].set_id(0); +} + +void MultiDisplayManager::AddRemoveDisplayImpl() { + std::vector new_displays; + if (displays_.size() > 1) { + // Remove if there is more than one display. + int count = displays_.size() - 1; + for (Displays::const_iterator iter = displays_.begin(); count-- > 0; ++iter) + new_displays.push_back(*iter); + } else { + // Add if there is only one display. + new_displays.push_back(displays_[0]); + new_displays.push_back(CreateDisplayFromSpec("50+50-1280x768")); + } + if (new_displays.size()) + OnNativeDisplaysChanged(new_displays); +} + +void MultiDisplayManager::CycleDisplayImpl() { + if (displays_.size() > 1) { + std::vector new_displays; + for (Displays::const_iterator iter = displays_.begin() + 1; + iter != displays_.end(); ++iter) { + gfx::Display display = *iter; + new_displays.push_back(display); + } + new_displays.push_back(displays_.front()); + OnNativeDisplaysChanged(new_displays); + } +} + +void MultiDisplayManager::ScaleDisplayImpl() { + if (displays_.size() > 0) { + std::vector new_displays; + for (Displays::const_iterator iter = displays_.begin(); + iter != displays_.end(); ++iter) { + gfx::Display display = *iter; + float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; + display.SetScaleAndBounds( + factor, gfx::Rect(display.bounds_in_pixel().origin(), + display.size().Scale(factor))); + new_displays.push_back(display); + } + OnNativeDisplaysChanged(new_displays); + } +} + +gfx::Display& MultiDisplayManager::FindDisplayForRootWindow( + const aura::RootWindow* root_window) { + int id = root_window->GetProperty(kDisplayIdKey); + for (Displays::iterator iter = displays_.begin(); + iter != displays_.end(); ++iter) { + if ((*iter).id() == id) + return *iter; + } + DLOG(FATAL) << "Could not find display by id:" << id; + return GetInvalidDisplay(); +} + +} // namespace internal +} // namespace ash diff --git a/ash/display/multi_display_manager.h b/ash/display/multi_display_manager.h new file mode 100644 index 0000000..3aae410 --- /dev/null +++ b/ash/display/multi_display_manager.h @@ -0,0 +1,84 @@ +// 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_MULTI_DISPLAY_MANAGER_H_ +#define ASH_DISPLAY_MULTI_DISPLAY_MANAGER_H_ +#pragma once + +#include + +#include "ash/ash_export.h" +#include "base/compiler_specific.h" +#include "base/gtest_prod_util.h" +#include "ui/aura/display_manager.h" +#include "ui/aura/root_window_observer.h" +#include "ui/aura/window.h" + +namespace gfx { +class Insets; +class Display; +} + +namespace ash { +namespace internal { + +// MultiDisplayManager maintains the current display configurations, +// and notifies observers when configuration changes. +// This is exported for unittest. +// +// TODO(oshima): gfx::Screen needs to return translated coordinates +// if the root window is translated. crbug.com/119268. +class ASH_EXPORT MultiDisplayManager : public aura::DisplayManager, + public aura::RootWindowObserver { + public: + MultiDisplayManager(); + virtual ~MultiDisplayManager(); + + // Used to emulate display change when run in a desktop environment instead + // of on a device. + static void AddRemoveDisplay(); + static void CycleDisplay(); + static void ToggleDisplayScale(); + + bool UpdateWorkAreaOfDisplayNearestWindow(const aura::Window* window, + const gfx::Insets& insets); + + // DisplayManager overrides: + virtual void OnNativeDisplaysChanged( + const std::vector& displays) OVERRIDE; + virtual aura::RootWindow* CreateRootWindowForDisplay( + const gfx::Display& display) OVERRIDE; + virtual const gfx::Display& GetDisplayAt(size_t index) OVERRIDE; + + virtual size_t GetNumDisplays() const OVERRIDE; + virtual const gfx::Display& GetDisplayNearestPoint( + const gfx::Point& point) const OVERRIDE; + virtual const gfx::Display& GetDisplayNearestWindow( + const aura::Window* window) const OVERRIDE; + + // RootWindowObserver overrides: + virtual void OnRootWindowResized(const aura::RootWindow* root, + const gfx::Size& new_size) OVERRIDE; + + private: + FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint); + typedef std::vector Displays; + + void Init(); + void AddRemoveDisplayImpl(); + void CycleDisplayImpl(); + void ScaleDisplayImpl(); + gfx::Display& FindDisplayForRootWindow(const aura::RootWindow* root); + + Displays displays_; + + DISALLOW_COPY_AND_ASSIGN(MultiDisplayManager); +}; + +extern const aura::WindowProperty* const kDisplayIdKey; + +} // namespace internal +} // namespace ash + +#endif // ASH_DISPLAY_MULTI_DISPLAY_MANAGER_H_ diff --git a/ash/display/multi_display_manager_unittest.cc b/ash/display/multi_display_manager_unittest.cc new file mode 100644 index 0000000..b1adc53 --- /dev/null +++ b/ash/display/multi_display_manager_unittest.cc @@ -0,0 +1,235 @@ +// 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/multi_display_manager.h" + +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/format_macros.h" +#include "base/stringprintf.h" +#include "ui/aura/display_observer.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window_observer.h" +#include "ui/gfx/display.h" + +namespace ash { +namespace test { + +using std::vector; +using std::string; + +class MultiDisplayManagerTest : public test::AshTestBase, + public aura::DisplayObserver, + public aura::WindowObserver { + public: + MultiDisplayManagerTest() + : removed_count_(0U), + root_window_destroyed_(false) { + } + virtual ~MultiDisplayManagerTest() {} + + virtual void SetUp() OVERRIDE { + AshTestBase::SetUp(); + display_manager()->AddObserver(this); + Shell::GetPrimaryRootWindow()->AddObserver(this); + } + virtual void TearDown() OVERRIDE { + Shell::GetPrimaryRootWindow()->RemoveObserver(this); + display_manager()->RemoveObserver(this); + AshTestBase::TearDown(); + } + + aura::DisplayManager* display_manager() { + return aura::Env::GetInstance()->display_manager(); + } + const vector& changed() const { return changed_; } + const vector& 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_; + } + + // 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) { + ASSERT_EQ(Shell::GetPrimaryRootWindow(), window); + root_window_destroyed_ = true; + } + + private: + vector changed_; + vector added_; + size_t removed_count_; + bool root_window_destroyed_; + + DISALLOW_COPY_AND_ASSIGN(MultiDisplayManagerTest); +}; + +TEST_F(MultiDisplayManagerTest, NativeDisplayTest) { + aura::DisplayManager::set_use_fullscreen_host_window(true); + + EXPECT_EQ(1U, display_manager()->GetNumDisplays()); + + // Update primary and add seconary. + UpdateDisplay("0+0-500x500,0+501-400x400"); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + 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()); + EXPECT_EQ("0,0 400x400", added()[0].bounds().ToString()); + EXPECT_EQ("0,501 400x400", added()[0].bounds_in_pixel().ToString()); + reset(); + + // Delete secondary. + UpdateDisplay("0+0-500x500"); + EXPECT_EQ("0 0 1", GetCountSummary()); + reset(); + + // Change primary. + UpdateDisplay("0+0-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("0+0-1000x600,1001+0-600x400"); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + EXPECT_EQ("0 1 0", GetCountSummary()); + EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id()); + EXPECT_EQ("0,0 600x400", added()[0].bounds().ToString()); + EXPECT_EQ("1001,0 600x400", added()[0].bounds_in_pixel().ToString()); + reset(); + + // Secondary removed, primary changed. + UpdateDisplay("0+0-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 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", changed()[0].bounds_in_pixel().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+0-600x400"); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + EXPECT_EQ("0,0 1000x600", + display_manager()->GetDisplayAt(0).bounds().ToString()); + EXPECT_EQ("0,0 600x400", + display_manager()->GetDisplayAt(1).bounds().ToString()); + EXPECT_EQ("1000,0 600x400", + display_manager()->GetDisplayAt(1).bounds_in_pixel().ToString()); + reset(); + + aura::DisplayManager::set_use_fullscreen_host_window(false); +} + +// Test in emulation mode (use_fullscreen_host_window=false) +TEST_F(MultiDisplayManagerTest, EmulatorTest) { + EXPECT_EQ(1U, display_manager()->GetNumDisplays()); + + internal::MultiDisplayManager::AddRemoveDisplay(); + // Update primary and add seconary. + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); +#if defined(OS_WIN) + // TODO(oshima): Windows receives resize event for some reason. + EXPECT_EQ("1 1 0", GetCountSummary()); +#else + EXPECT_EQ("0 1 0", GetCountSummary()); +#endif + reset(); + + internal::MultiDisplayManager::CycleDisplay(); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + // Observer gets called twice in this mode because + // it gets notified both from |OnNativeDisplayChagned| + // and from |RootWindowObserver|, which is the consequence of + // |SetHostSize()|. + EXPECT_EQ("4 0 0", GetCountSummary()); + reset(); + + internal::MultiDisplayManager::AddRemoveDisplay(); + EXPECT_EQ(1U, display_manager()->GetNumDisplays()); + EXPECT_EQ("0 0 1", GetCountSummary()); + reset(); + + internal::MultiDisplayManager::CycleDisplay(); + EXPECT_EQ(1U, display_manager()->GetNumDisplays()); + EXPECT_EQ("0 0 0", GetCountSummary()); + reset(); +} + +// TODO(oshima): Device scale factor is supported on chromeos only for now. +#if defined(OS_CHROMEOS) +#define MAYBE_TestDeviceScaleOnlyChange TestDeviceScaleOnlyChange +#else +#define MAYBE_TestDeviceScaleOnlyChange DISABLED_TestDeviceScaleOnlyChange +#endif + +TEST_F(MultiDisplayManagerTest, MAYBE_TestDeviceScaleOnlyChange) { + aura::DisplayManager::set_use_fullscreen_host_window(true); + UpdateDisplay("0+0-1000x600"); + EXPECT_EQ(1, + Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); + EXPECT_EQ("1000x600", + Shell::GetPrimaryRootWindow()->bounds().size().ToString()); + UpdateDisplay("0+0-1000x600*2"); + EXPECT_EQ(2, + Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); + EXPECT_EQ("500x300", + Shell::GetPrimaryRootWindow()->bounds().size().ToString()); + aura::DisplayManager::set_use_fullscreen_host_window(false); +} + +} // namespace test +} // namespace ash diff --git a/ash/display/secondary_display_view.cc b/ash/display/secondary_display_view.cc new file mode 100644 index 0000000..ea8963e --- /dev/null +++ b/ash/display/secondary_display_view.cc @@ -0,0 +1,111 @@ +// 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/secondary_display_view.h" + +#include "grit/ash_strings.h" +#include "grit/ui_resources.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/aura/window.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/views/background.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +namespace ash { +namespace { + +// Colors for the background, the message text and the shortcut text. +const SkColor kBackgroundColor = SkColorSetRGB(0x33, 0x33, 0x33); +const SkColor kTextColor = SkColorSetRGB(127, 127, 127); + +// A view to be displayed on secondary display. +class SecondaryDisplayView : public views::WidgetDelegateView { + public: + SecondaryDisplayView() { + Init(); + } + virtual ~SecondaryDisplayView() { + } + + void Init() { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + + set_background(views::Background::CreateSolidBackground(kBackgroundColor)); + message_ = new views::Label( + l10n_util::GetStringUTF16(IDS_ASH_SECONDARY_MONITOR)); + message_->SetAutoColorReadabilityEnabled(false); + message_->SetFont(rb.GetFont(ui::ResourceBundle::LargeFont)); + message_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); + message_->SetEnabledColor(kTextColor); + AddChildView(message_); + + shortcut_text_ = new views::Label( + l10n_util::GetStringUTF16(IDS_ASH_SECONDARY_MONITOR_SHORTCUT)); + shortcut_text_->SetAutoColorReadabilityEnabled(false); + shortcut_text_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); + shortcut_text_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); + shortcut_text_->SetEnabledColor(kTextColor); + AddChildView(shortcut_text_); + + shortcut_image_ = new views::ImageView(); + shortcut_image_->SetImage(rb.GetImageSkiaNamed(IDR_AURA_SWITCH_MONITOR)); + AddChildView(shortcut_image_); + } + + virtual void Layout() { + const int kMessagePositionTopMargin = 40; + const int kShortcutPositionBottomMargin = 40; + const int kShortcutMargin = 4; // margin between text and image. + gfx::Rect b = bounds(); + + int msg_height = message_->GetHeightForWidth(b.width()); + message_->SetBounds( + 0, kMessagePositionTopMargin, bounds().width(), msg_height); + + // TODO(oshima): Figure out what to do for RTL. + // Align the shortcut text & image to the center. + gfx::Size text_size = shortcut_text_->GetPreferredSize(); + gfx::Size image_size = shortcut_image_->GetPreferredSize(); + int height = std::max(text_size.height(), image_size.height()); + int y = b.height() - kShortcutPositionBottomMargin - height; + int x = (b.width() - + (text_size.width() + kShortcutMargin + image_size.width())) / 2; + shortcut_text_->SetBounds(x, y + (height - text_size.height()) / 2, + text_size.width(), text_size.height()); + shortcut_image_->SetBounds( + x + text_size.width() + kShortcutMargin, + y + (height - image_size.height()) / 2, + image_size.width(), image_size.height()); + } + + private: + views::Label* message_; + views::Label* shortcut_text_; + views::ImageView* shortcut_image_; + + DISALLOW_COPY_AND_ASSIGN(SecondaryDisplayView); +}; + +} // namespace + +views::Widget* CreateSecondaryDisplayWidget(aura::Window* parent) { + views::Widget* desktop_widget = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + SecondaryDisplayView* view = new SecondaryDisplayView(); + params.delegate = view; + params.parent = parent; + desktop_widget->Init(params); + desktop_widget->SetContentsView(view); + desktop_widget->Show(); + desktop_widget->GetNativeView()->SetName("SecondaryDisplay"); + return desktop_widget; +} + +} // namespace ash diff --git a/ash/display/secondary_display_view.h b/ash/display/secondary_display_view.h new file mode 100644 index 0000000..60db1e0 --- /dev/null +++ b/ash/display/secondary_display_view.h @@ -0,0 +1,25 @@ +// 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_SECONDARY_DISPLAY_VIEW_H_ +#define ASH_DISPLAY_SECONDARY_DISPLAY_VIEW_H_ +#pragma once + +namespace aura { +class Window; +} + +namespace views { +class Widget; +} + +namespace ash { + +// Creates the widget that hosts the static message displayed on the +// secondary display. +views::Widget* CreateSecondaryDisplayWidget(aura::Window* parent); + +} // namespace ash + +#endif // ASH_DISPLAY_SECONDARY_DISPLAY_VIEW_H_ diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc index 8469eb5..9a70acc 100644 --- a/ash/extended_desktop_unittest.cc +++ b/ash/extended_desktop_unittest.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/monitor/monitor_controller.h" -#include "ash/monitor/multi_monitor_manager.h" +#include "ash/display/display_controller.h" +#include "ash/display/multi_display_manager.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/wm/window_cycle_controller.h" @@ -58,19 +58,19 @@ class ExtendedDesktopTest : public test::AshTestBase { virtual ~ExtendedDesktopTest() {} virtual void SetUp() OVERRIDE { - internal::MonitorController::SetExtendedDesktopEnabled(true); + internal::DisplayController::SetExtendedDesktopEnabled(true); AshTestBase::SetUp(); } virtual void TearDown() OVERRIDE { AshTestBase::TearDown(); - internal::MonitorController::SetExtendedDesktopEnabled(false); + internal::DisplayController::SetExtendedDesktopEnabled(false); } protected: - internal::MultiMonitorManager* monitor_manager() { - return static_cast( - aura::Env::GetInstance()->monitor_manager()); + internal::MultiDisplayManager* display_manager() { + return static_cast( + aura::Env::GetInstance()->display_manager()); } private: @@ -80,7 +80,7 @@ class ExtendedDesktopTest : public test::AshTestBase { // Test conditions that root windows in extended desktop mode // must satisfy. TEST_F(ExtendedDesktopTest, Basic) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // All root windows must have the root window controller. @@ -99,7 +99,7 @@ TEST_F(ExtendedDesktopTest, Basic) { } TEST_F(ExtendedDesktopTest, Activation) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Move the active root window to the secondary. @@ -134,7 +134,7 @@ TEST_F(ExtendedDesktopTest, Activation) { } TEST_F(ExtendedDesktopTest, SystemModal) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); Shell::GetInstance()->set_active_root_window(root_windows[0]); @@ -153,7 +153,7 @@ TEST_F(ExtendedDesktopTest, SystemModal) { EXPECT_EQ(root_windows[1], modal_widget->GetNativeView()->GetRootWindow()); EXPECT_EQ(root_windows[1], Shell::GetActiveRootWindow()); - // Clicking a widget on widget_on_1st monitor should not change activation. + // Clicking a widget on widget_on_1st display should not change activation. aura::test::EventGenerator generator_1st(root_windows[0]); generator_1st.MoveMouseToCenterOf(widget_on_1st->GetNativeView()); generator_1st.ClickLeftButton(); @@ -169,7 +169,7 @@ TEST_F(ExtendedDesktopTest, SystemModal) { } TEST_F(ExtendedDesktopTest, TestCursor) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::GetInstance()->ShowCursor(false); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); EXPECT_FALSE(root_windows[0]->cursor_shown()); @@ -186,8 +186,8 @@ TEST_F(ExtendedDesktopTest, TestCursor) { } TEST_F(ExtendedDesktopTest, CycleWindows) { - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(true); - UpdateMonitor("0+0-700x500,0+0-500x500"); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(true); + UpdateDisplay("0+0-700x500,0+0-500x500"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Emulate virtual screen coordinate system. root_windows[0]->SetBounds(gfx::Rect(0, 0, 700, 500)); @@ -235,12 +235,12 @@ TEST_F(ExtendedDesktopTest, CycleWindows) { EXPECT_TRUE(wm::IsActiveWindow(d2_w1->GetNativeView())); controller->HandleCycleWindow(WindowCycleController::BACKWARD, true); EXPECT_TRUE(wm::IsActiveWindow(d2_w2->GetNativeView())); - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(false); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(false); } TEST_F(ExtendedDesktopTest, GetRootWindowAt) { - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(true); - UpdateMonitor("0+0-700x500,0+0-500x500"); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(true); + UpdateDisplay("0+0-700x500,0+0-500x500"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Emulate virtual screen coordinate system. root_windows[0]->SetBounds(gfx::Rect(500, 0, 700, 500)); @@ -257,12 +257,12 @@ TEST_F(ExtendedDesktopTest, GetRootWindowAt) { // Out of range point should return the primary root window EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(-100, 0))); EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(1201, 100))); - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(false); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(false); } TEST_F(ExtendedDesktopTest, GetRootWindowMatching) { - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(true); - UpdateMonitor("0+0-700x500,0+0-500x500"); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(true); + UpdateDisplay("0+0-700x500,0+0-500x500"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Emulate virtual screen coordinate system. root_windows[0]->SetBounds(gfx::Rect(500, 0, 700, 500)); @@ -297,11 +297,11 @@ TEST_F(ExtendedDesktopTest, GetRootWindowMatching) { Shell::GetRootWindowMatching(gfx::Rect(-100, -300, 50, 50))); EXPECT_EQ(root_windows[0], Shell::GetRootWindowMatching(gfx::Rect(0, 2000, 50, 50))); - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(false); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(false); } TEST_F(ExtendedDesktopTest, Capture) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); aura::test::EventCountDelegate r1_d1; @@ -353,13 +353,13 @@ namespace internal { // Test if the Window::ConvertPointToWindow works across root windows. // TODO(oshima): Move multiple display suport and this test to aura. TEST_F(ExtendedDesktopTest, ConvertPoint) { - UpdateMonitor("0+0-1000x600,1001+0-600x400"); + UpdateDisplay("0+0-1000x600,1001+0-600x400"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); gfx::Display& display_1 = - monitor_manager()->FindDisplayForRootWindow(root_windows[0]); + display_manager()->FindDisplayForRootWindow(root_windows[0]); EXPECT_EQ("0,0", display_1.bounds().origin().ToString()); gfx::Display& display_2 = - monitor_manager()->FindDisplayForRootWindow(root_windows[1]); + display_manager()->FindDisplayForRootWindow(root_windows[1]); Shell::GetInstance()->set_active_root_window(root_windows[0]); aura::Window* d1 = CreateTestWidget(gfx::Rect(10, 10, 100, 100))->GetNativeView(); diff --git a/ash/monitor/monitor_controller.cc b/ash/monitor/monitor_controller.cc deleted file mode 100644 index b8e1e04..0000000 --- a/ash/monitor/monitor_controller.cc +++ /dev/null @@ -1,269 +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/monitor/monitor_controller.h" - -#include "ash/ash_switches.h" -#include "ash/monitor/multi_monitor_manager.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/wm/window_util.h" -#include "base/command_line.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" - -namespace ash { -namespace internal { -namespace { -// True if the extended desktop mode is enabled. -bool extended_desktop_enabled = false; - -// True if the virtual screen coordinates is enabled. -bool virtual_screen_coordinates_enabled = false; -} - -MonitorController::MonitorController() - : secondary_display_layout_(RIGHT) { - aura::Env::GetInstance()->monitor_manager()->AddObserver(this); -} - -MonitorController::~MonitorController() { - aura::Env::GetInstance()->monitor_manager()->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::const_reverse_iterator it = - root_windows_.rbegin(); it != root_windows_.rend(); ++it) { - internal::RootWindowController* controller = - wm::GetRootWindowController(it->second); - // RootWindow may not have RootWindowController in non - // extended desktop mode. - if (controller) - delete controller; - else - delete it->second; - } -} - -void MonitorController::InitPrimaryDisplay() { - aura::MonitorManager* monitor_manager = - aura::Env::GetInstance()->monitor_manager(); - const gfx::Display& display = monitor_manager->GetDisplayAt(0); - DCHECK_EQ(0, display.id()); - aura::RootWindow* root = AddRootWindowForDisplay(display); - root->SetHostBounds(display.bounds_in_pixel()); -} - -void MonitorController::InitSecondaryDisplays() { - aura::MonitorManager* monitor_manager = - aura::Env::GetInstance()->monitor_manager(); - for (size_t i = 1; i < monitor_manager->GetNumDisplays(); ++i) { - const gfx::Display& display = monitor_manager->GetDisplayAt(i); - aura::RootWindow* root = AddRootWindowForDisplay(display); - Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root); - } -} - -aura::RootWindow* MonitorController::GetPrimaryRootWindow() { - DCHECK(!root_windows_.empty()); - return root_windows_[0]; -} - -void MonitorController::CloseChildWindows() { - for (std::map::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - aura::RootWindow* root_window = it->second; - internal::RootWindowController* controller = - wm::GetRootWindowController(root_window); - if (controller) { - controller->CloseChildWindows(); - } else { - while (!root_window->children().empty()) { - aura::Window* child = root_window->children()[0]; - delete child; - } - } - } -} - -std::vector MonitorController::GetAllRootWindows() { - std::vector windows; - for (std::map::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - DCHECK(it->second); - if (wm::GetRootWindowController(it->second)) - windows.push_back(it->second); - } - return windows; -} - -std::vector -MonitorController::GetAllRootWindowControllers() { - std::vector controllers; - for (std::map::const_iterator it = - root_windows_.begin(); it != root_windows_.end(); ++it) { - internal::RootWindowController* controller = - wm::GetRootWindowController(it->second); - if (controller) - controllers.push_back(controller); - } - return controllers; -} - -void MonitorController::SetSecondaryDisplayLayout( - SecondaryDisplayLayout layout) { - secondary_display_layout_ = layout; -} - -bool MonitorController::WarpMouseCursorIfNecessary( - aura::Window* current_root, - const gfx::Point& location_in_root) { - if (root_windows_.size() < 2) - return false; - // Only 1 external display is supported in extended desktop mode. - DCHECK_EQ(2U, root_windows_.size()); - - bool in_primary = current_root == root_windows_[0]; - - std::map::iterator iter = root_windows_.begin(); - aura::RootWindow* alternate_root = iter->second != current_root ? - iter->second : (++iter)->second; - gfx::Rect alternate_bounds = alternate_root->bounds(); - gfx::Point alternate_point; - - gfx::Rect display_area( - gfx::Screen::GetDisplayNearestWindow(current_root).bounds()); - - // TODO(oshima): This is temporary code until the virtual screen - // coordinate is implemented. - if (location_in_root.x() <= display_area.x()) { - if (location_in_root.y() < alternate_bounds.height() && - ((in_primary && secondary_display_layout_ == LEFT) || - (!in_primary && secondary_display_layout_ == RIGHT))) { - alternate_point = gfx::Point( - alternate_bounds.right() - (location_in_root.x() - display_area.x()), - location_in_root.y()); - } else { - alternate_root = NULL; - } - } else if (location_in_root.x() >= display_area.right() - 1) { - if (location_in_root.y() < alternate_bounds.height() && - ((in_primary && secondary_display_layout_ == RIGHT) || - (!in_primary && secondary_display_layout_ == LEFT))) { - alternate_point = gfx::Point(location_in_root.x() - display_area.right(), - location_in_root.y()); - } else { - alternate_root = NULL; - } - } else if (location_in_root.y() < display_area.y()) { - if (location_in_root.x() < alternate_bounds.width() && - ((in_primary && secondary_display_layout_ == TOP) || - (!in_primary && secondary_display_layout_ == BOTTOM))) { - alternate_point = gfx::Point( - location_in_root.x(), - alternate_bounds.bottom() - - (location_in_root.y() - display_area.y())); - } else { - alternate_root = NULL; - } - } else if (location_in_root.y() >= display_area.bottom() - 1) { - if (location_in_root.x() < alternate_bounds.width() && - ((in_primary && secondary_display_layout_ == BOTTOM) || - (!in_primary && secondary_display_layout_ == TOP))) { - alternate_point = gfx::Point( - location_in_root.x(), location_in_root.y() - display_area.bottom()); - } else { - alternate_root = NULL; - } - } else { - alternate_root = NULL; - } - if (alternate_root) { - DCHECK_NE(alternate_root, current_root); - alternate_root->MoveCursorTo(alternate_point); - return true; - } - return false; -} - -void MonitorController::OnDisplayBoundsChanged(const gfx::Display& display) { - root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); -} - -void MonitorController::OnDisplayAdded(const gfx::Display& display) { - if (root_windows_.empty()) { - DCHECK_EQ(0, display.id()); - root_windows_[display.id()] = Shell::GetPrimaryRootWindow(); - Shell::GetPrimaryRootWindow()->SetHostBounds(display.bounds_in_pixel()); - return; - } - aura::RootWindow* root = AddRootWindowForDisplay(display); - Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root); -} - -void MonitorController::OnDisplayRemoved(const gfx::Display& display) { - aura::RootWindow* root = root_windows_[display.id()]; - DCHECK(root); - // Primary monitor should never be removed by MonitorManager. - DCHECK(root != Shell::GetPrimaryRootWindow()); - // Monitor for root window will be deleted when the Primary RootWindow - // is deleted by the Shell. - if (root != Shell::GetPrimaryRootWindow()) { - root_windows_.erase(display.id()); - internal::RootWindowController* controller = - wm::GetRootWindowController(root); - if (controller) { - controller->MoveWindowsTo(Shell::GetPrimaryRootWindow()); - delete controller; - } else { - delete root; - } - } -} - -// static -bool MonitorController::IsExtendedDesktopEnabled(){ - return extended_desktop_enabled || - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshExtendedDesktop); -} - -// static -void MonitorController::SetExtendedDesktopEnabled(bool enabled) { - extended_desktop_enabled = enabled; -} - -// static -bool MonitorController::IsVirtualScreenCoordinatesEnabled() { - return virtual_screen_coordinates_enabled || - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshVirtualScreenCoordinates); -} - -// static -void MonitorController::SetVirtualScreenCoordinatesEnabled(bool enabled) { - virtual_screen_coordinates_enabled = enabled; -} - -aura::RootWindow* MonitorController::AddRootWindowForDisplay( - const gfx::Display& display) { - aura::RootWindow* root = aura::Env::GetInstance()->monitor_manager()-> - CreateRootWindowForMonitor(display); - root_windows_[display.id()] = root; - // Confine the cursor within the window if - // 1) Extended desktop is enabled or - // 2) the display is primary monitor and the host window - // is set to be fullscreen (this is old behavior). - if (IsExtendedDesktopEnabled() || - (aura::MonitorManager::use_fullscreen_host_window() && - display.id() == 0)) { - root->ConfineCursorToWindow(); - } - return root; -} - -} // namespace internal -} // namespace ash diff --git a/ash/monitor/monitor_controller.h b/ash/monitor/monitor_controller.h deleted file mode 100644 index 72afa42..0000000 --- a/ash/monitor/monitor_controller.h +++ /dev/null @@ -1,109 +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_MONITOR_MONITOR_CONTROLLER_H_ -#define ASH_MONITOR_MONITOR_CONTROLLER_H_ -#pragma once - -#include -#include - -#include "ash/ash_export.h" -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ui/aura/display_observer.h" -#include "ui/aura/monitor_manager.h" - -namespace aura { -class Display; -class RootWindow; -} - -namespace ash { -namespace internal { -class RootWindowController; - -// MonitorController owns and maintains RootWindows for each attached -// display, keeping them in sync with display configuration changes. -// TODO(oshima): Rename MonitorXXX to DisplayXXX. -class ASH_EXPORT MonitorController : public aura::DisplayObserver { - public: - // Layout options where the secondary monitor should be positioned. - enum SecondaryDisplayLayout { - TOP, - RIGHT, - BOTTOM, - LEFT - }; - - MonitorController(); - virtual ~MonitorController(); - - // Initializes primary display. - void InitPrimaryDisplay(); - - // Initialize secondary display. This is separated because in non - // extended desktop mode, this creates background widgets, which - // requires other controllers. - void InitSecondaryDisplays(); - - // Returns the root window for primary display. - aura::RootWindow* GetPrimaryRootWindow(); - - // 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. - std::vector GetAllRootWindows(); - - // Returns all oot window controllers. In non extended desktop - // mode, this return a RootWindowController for the primary root window only. - std::vector GetAllRootWindowControllers(); - - SecondaryDisplayLayout secondary_display_layout() const { - return secondary_display_layout_; - } - void SetSecondaryDisplayLayout(SecondaryDisplayLayout layout); - - // Warps the mouse cursor to an alternate root window when the - // |location_in_root|, which is the location of the mouse cursor, - // hits or exceeds the edge of the |root_window| and the mouse cursor - // is considered to be in an alternate display. Returns true if - // the cursor was moved. - bool WarpMouseCursorIfNecessary(aura::Window* root_window, - const gfx::Point& location_in_root); - - // 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; - - // Is extended desktop enabled? - static bool IsExtendedDesktopEnabled(); - // Change the extended desktop mode. Used for testing. - static void SetExtendedDesktopEnabled(bool enabled); - - // Is virtual screen coordinates enabled? - static bool IsVirtualScreenCoordinatesEnabled(); - // Turns on/off the virtual screen coordinates. - static void SetVirtualScreenCoordinatesEnabled(bool enabled); - - private: - // Creates a root window for |display| and stores it in the |root_windows_| - // map. - aura::RootWindow* AddRootWindowForDisplay(const gfx::Display& display); - - std::map root_windows_; - - SecondaryDisplayLayout secondary_display_layout_; - - DISALLOW_COPY_AND_ASSIGN(MonitorController); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_MONITOR_MONITOR_CONTROLLER_H_ diff --git a/ash/monitor/mouse_cursor_event_filter.cc b/ash/monitor/mouse_cursor_event_filter.cc deleted file mode 100644 index 0c451d1..0000000 --- a/ash/monitor/mouse_cursor_event_filter.cc +++ /dev/null @@ -1,53 +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/monitor/mouse_cursor_event_filter.h" - -#include "ash/monitor/monitor_controller.h" -#include "ui/aura/event.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" - -namespace ash { -namespace internal { - -MouseCursorEventFilter::MouseCursorEventFilter( - MonitorController* monitor_controller) - : monitor_controller_(monitor_controller) { - DCHECK(monitor_controller_); -} - -MouseCursorEventFilter::~MouseCursorEventFilter() { -} - -bool MouseCursorEventFilter::PreHandleKeyEvent(aura::Window* target, - aura::KeyEvent* event) { - return false; -} - -bool MouseCursorEventFilter::PreHandleMouseEvent(aura::Window* target, - aura::MouseEvent* event) { - if (event->type() != ui::ET_MOUSE_MOVED) - return false; - aura::RootWindow* current_root = target->GetRootWindow(); - gfx::Point location_in_root(event->location()); - aura::Window::ConvertPointToWindow(target, current_root, &location_in_root); - return monitor_controller_->WarpMouseCursorIfNecessary( - current_root, location_in_root); -} - -ui::TouchStatus MouseCursorEventFilter::PreHandleTouchEvent( - aura::Window* target, - aura::TouchEvent* event) { - return ui::TOUCH_STATUS_UNKNOWN; -} - -ui::GestureStatus MouseCursorEventFilter::PreHandleGestureEvent( - aura::Window* target, - aura::GestureEvent* event) { - return ui::GESTURE_STATUS_UNKNOWN; -} - -} // namespace internal -} // namespace ash diff --git a/ash/monitor/mouse_cursor_event_filter.h b/ash/monitor/mouse_cursor_event_filter.h deleted file mode 100644 index 682547a..0000000 --- a/ash/monitor/mouse_cursor_event_filter.h +++ /dev/null @@ -1,44 +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_MONITOR_MOUSE_CURSOR_EVENT_FILTER_H -#define ASH_MONITOR_MOUSE_CURSOR_EVENT_FILTER_H -#pragma once - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "ui/aura/event_filter.h" - -namespace ash { -namespace internal { -class MonitorController; - -// An event filter that controls mouse location in extended desktop -// environment. -class ASH_EXPORT MouseCursorEventFilter : public aura::EventFilter { - public: - MouseCursorEventFilter(MonitorController* monitor_controller); - virtual ~MouseCursorEventFilter(); - - // Overridden from aura::EventFilter: - virtual bool PreHandleKeyEvent(aura::Window* target, - aura::KeyEvent* event) OVERRIDE; - virtual bool PreHandleMouseEvent(aura::Window* target, - aura::MouseEvent* event) OVERRIDE; - virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, - aura::TouchEvent* event) OVERRIDE; - virtual ui::GestureStatus PreHandleGestureEvent( - aura::Window* target, - aura::GestureEvent* event) OVERRIDE; - - private: - MonitorController* monitor_controller_; - - DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilter); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_MONITOR_MOUSE_CURSOR_EVENT_FILTER_H diff --git a/ash/monitor/multi_monitor_manager.cc b/ash/monitor/multi_monitor_manager.cc deleted file mode 100644 index 70bf90d..0000000 --- a/ash/monitor/multi_monitor_manager.cc +++ /dev/null @@ -1,247 +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/monitor/multi_monitor_manager.h" - -#include -#include - -#include "base/command_line.h" -#include "base/stl_util.h" -#include "base/string_split.h" -#include "ui/aura/aura_switches.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_host.h" -#include "ui/aura/window_property.h" -#include "ui/gfx/display.h" -#include "ui/gfx/rect.h" - -DECLARE_WINDOW_PROPERTY_TYPE(int); - -namespace ash { -namespace internal { -namespace { - -gfx::Display& GetInvalidDisplay() { - static gfx::Display* invalid_display = new gfx::Display(); - return *invalid_display; -} - -} // namespace - -using aura::RootWindow; -using aura::Window; -using std::string; -using std::vector; - -DEFINE_WINDOW_PROPERTY_KEY(int, kMonitorIdKey, -1); - -MultiMonitorManager::MultiMonitorManager() { - Init(); -} - -MultiMonitorManager::~MultiMonitorManager() { -} - -// static -void MultiMonitorManager::AddRemoveMonitor() { - MultiMonitorManager* manager = static_cast( - aura::Env::GetInstance()->monitor_manager()); - manager->AddRemoveMonitorImpl(); -} - -void MultiMonitorManager::CycleMonitor() { - MultiMonitorManager* manager = static_cast( - aura::Env::GetInstance()->monitor_manager()); - manager->CycleMonitorImpl(); -} - - void MultiMonitorManager::ToggleMonitorScale() { - MultiMonitorManager* manager = static_cast( - aura::Env::GetInstance()->monitor_manager()); - manager->ScaleMonitorImpl(); -} - -void MultiMonitorManager::OnNativeMonitorsChanged( - const std::vector& new_displays) { - size_t min = std::min(displays_.size(), new_displays.size()); - - // For m19, we only care about 1st monitor as primary, and - // don't differentiate the rest of monitors as all secondary - // monitors have the same content. ID for primary monitor stays the same - // because we never remove it, we don't update IDs for other monitors - // , for now, because they're the same. - // TODO(oshima): Fix this so that we can differentiate outputs - // and keep a content on one monitor stays on the same monitor - // when a monitor is added or removed. - for (size_t i = 0; i < min; ++i) { - gfx::Display& current_display = displays_[i]; - const gfx::Display& new_display = new_displays[i]; - if (current_display.bounds_in_pixel() != new_display.bounds_in_pixel() || - current_display.device_scale_factor() != - new_display.device_scale_factor()) { - current_display.SetScaleAndBounds(new_display.device_scale_factor(), - new_display.bounds_in_pixel()); - NotifyBoundsChanged(current_display); - } - } - - if (displays_.size() < new_displays.size()) { - // New monitors added - for (size_t i = min; i < new_displays.size(); ++i) { - const gfx::Display& new_display = new_displays[i]; - displays_.push_back(gfx::Display(new_display.id())); - gfx::Display& display = displays_.back(); - // Force the primary display's ID to be 0. - if (i == 0) - display.set_id(0); - display.SetScaleAndBounds(new_display.device_scale_factor(), - new_display.bounds_in_pixel()); - NotifyDisplayAdded(display); - } - } else { - // Monitors are removed. We keep the monitor for the primary - // monitor (at index 0) because it needs the monitor information - // even if it doesn't exit. - while (displays_.size() > new_displays.size() && displays_.size() > 1) { - Displays::reverse_iterator iter = displays_.rbegin(); - NotifyDisplayRemoved(*iter); - displays_.erase(iter.base() - 1); - } - } -} - -RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( - const gfx::Display& display) { - RootWindow* root_window = new RootWindow(display.bounds_in_pixel()); - // No need to remove RootWindowObserver because - // the MonitorManager object outlives RootWindow objects. - root_window->AddRootWindowObserver(this); - root_window->SetProperty(kMonitorIdKey, display.id()); - root_window->Init(); - return root_window; -} - -const gfx::Display& MultiMonitorManager::GetDisplayAt(size_t index) { - return index < displays_.size() ? displays_[index] : GetInvalidDisplay(); -} - -size_t MultiMonitorManager::GetNumDisplays() const { - return displays_.size(); -} - -const gfx::Display& MultiMonitorManager::GetDisplayNearestWindow( - const Window* window) const { - if (!window) { - MultiMonitorManager* manager = const_cast(this); - return manager->GetDisplayAt(0); - } - const RootWindow* root = window->GetRootWindow(); - MultiMonitorManager* manager = const_cast(this); - return root ? manager->FindDisplayForRootWindow(root) : GetInvalidDisplay(); -} - -const gfx::Display& MultiMonitorManager::GetDisplayNearestPoint( - const gfx::Point& point) const { - // TODO(oshima): For m19, mouse is constrained within - // the primary window. - MultiMonitorManager* manager = const_cast(this); - return manager->GetDisplayAt(0); -} - -void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, - const gfx::Size& old_size) { - if (!use_fullscreen_host_window()) { - gfx::Display& display = FindDisplayForRootWindow(root); - display.SetSize(root->GetHostSize()); - NotifyBoundsChanged(display); - } -} - -bool MultiMonitorManager::UpdateWorkAreaOfMonitorNearestWindow( - const aura::Window* window, - const gfx::Insets& insets) { - const RootWindow* root = window->GetRootWindow(); - gfx::Display& display = FindDisplayForRootWindow(root); - gfx::Rect old_work_area = display.work_area(); - display.UpdateWorkAreaFromInsets(insets); - return old_work_area != display.work_area(); -} - -void MultiMonitorManager::Init() { - // TODO(oshima): Move this logic to MonitorChangeObserver. - const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kAuraHostWindowSize); - vector parts; - base::SplitString(size_str, ',', &parts); - for (vector::const_iterator iter = parts.begin(); - iter != parts.end(); ++iter) { - displays_.push_back(CreateMonitorFromSpec(*iter)); - } - if (displays_.empty()) - displays_.push_back(CreateMonitorFromSpec("" /* default */)); - // Force the 1st display to be the primary display (id == 0). - displays_[0].set_id(0); -} - -void MultiMonitorManager::AddRemoveMonitorImpl() { - std::vector new_displays; - if (displays_.size() > 1) { - // Remove if there is more than one display. - int count = displays_.size() - 1; - for (Displays::const_iterator iter = displays_.begin(); count-- > 0; ++iter) - new_displays.push_back(*iter); - } else { - // Add if there is only one display. - new_displays.push_back(displays_[0]); - new_displays.push_back(CreateMonitorFromSpec("50+50-1280x768")); - } - if (new_displays.size()) - OnNativeMonitorsChanged(new_displays); -} - -void MultiMonitorManager::CycleMonitorImpl() { - if (displays_.size() > 1) { - std::vector new_displays; - for (Displays::const_iterator iter = displays_.begin() + 1; - iter != displays_.end(); ++iter) { - gfx::Display display = *iter; - new_displays.push_back(display); - } - new_displays.push_back(displays_.front()); - OnNativeMonitorsChanged(new_displays); - } -} - -void MultiMonitorManager::ScaleMonitorImpl() { - if (displays_.size() > 0) { - std::vector new_displays; - for (Displays::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - gfx::Display display = *iter; - float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; - display.SetScaleAndBounds( - factor, gfx::Rect(display.bounds_in_pixel().origin(), - display.size().Scale(factor))); - new_displays.push_back(display); - } - OnNativeMonitorsChanged(new_displays); - } -} - -gfx::Display& MultiMonitorManager::FindDisplayForRootWindow( - const aura::RootWindow* root_window) { - int id = root_window->GetProperty(kMonitorIdKey); - for (Displays::iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - if ((*iter).id() == id) - return *iter; - } - DLOG(FATAL) << "Could not find display by id:" << id; - return GetInvalidDisplay(); -} - -} // namespace internal -} // namespace ash diff --git a/ash/monitor/multi_monitor_manager.h b/ash/monitor/multi_monitor_manager.h deleted file mode 100644 index 3849dfe..0000000 --- a/ash/monitor/multi_monitor_manager.h +++ /dev/null @@ -1,84 +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_MONITOR_MULTI_MONITOR_MANAGER_H_ -#define ASH_MONITOR_MULTI_MONITOR_MANAGER_H_ -#pragma once - -#include - -#include "ash/ash_export.h" -#include "base/compiler_specific.h" -#include "base/gtest_prod_util.h" -#include "ui/aura/monitor_manager.h" -#include "ui/aura/root_window_observer.h" -#include "ui/aura/window.h" - -namespace gfx { -class Insets; -class Display; -} - -namespace ash { -namespace internal { - -// MultiMonitorManager maintains the current monitor configurations, -// and notifies observers when configuration changes. -// This is exported for unittest. -// -// TODO(oshima): gfx::Screen needs to return translated coordinates -// if the root window is translated. crbug.com/119268. -class ASH_EXPORT MultiMonitorManager : public aura::MonitorManager, - public aura::RootWindowObserver { - public: - MultiMonitorManager(); - virtual ~MultiMonitorManager(); - - // Used to emulate monitor change when run in a desktop environment instead - // of on a device. - static void AddRemoveMonitor(); - static void CycleMonitor(); - static void ToggleMonitorScale(); - - bool UpdateWorkAreaOfMonitorNearestWindow(const aura::Window* window, - const gfx::Insets& insets); - - // MonitorManager overrides: - virtual void OnNativeMonitorsChanged( - const std::vector& displays) OVERRIDE; - virtual aura::RootWindow* CreateRootWindowForMonitor( - const gfx::Display& display) OVERRIDE; - virtual const gfx::Display& GetDisplayAt(size_t index) OVERRIDE; - - virtual size_t GetNumDisplays() const OVERRIDE; - virtual const gfx::Display& GetDisplayNearestPoint( - const gfx::Point& point) const OVERRIDE; - virtual const gfx::Display& GetDisplayNearestWindow( - const aura::Window* window) const OVERRIDE; - - // RootWindowObserver overrides: - virtual void OnRootWindowResized(const aura::RootWindow* root, - const gfx::Size& new_size) OVERRIDE; - - private: - FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint); - typedef std::vector Displays; - - void Init(); - void AddRemoveMonitorImpl(); - void CycleMonitorImpl(); - void ScaleMonitorImpl(); - gfx::Display& FindDisplayForRootWindow(const aura::RootWindow* root); - - Displays displays_; - - DISALLOW_COPY_AND_ASSIGN(MultiMonitorManager); -}; - -extern const aura::WindowProperty* const kMonitorIdKey; - -} // namespace internal -} // namespace ash - -#endif // ASH_MONITOR_MULTI_MONITOR_MANAGER_H_ diff --git a/ash/monitor/multi_monitor_manager_unittest.cc b/ash/monitor/multi_monitor_manager_unittest.cc deleted file mode 100644 index 94a28cd..0000000 --- a/ash/monitor/multi_monitor_manager_unittest.cc +++ /dev/null @@ -1,235 +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/monitor/multi_monitor_manager.h" - -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "base/format_macros.h" -#include "base/stringprintf.h" -#include "ui/aura/display_observer.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/display.h" - -namespace ash { -namespace test { - -using std::vector; -using std::string; - -class MultiMonitorManagerTest : public test::AshTestBase, - public aura::DisplayObserver, - public aura::WindowObserver { - public: - MultiMonitorManagerTest() - : removed_count_(0U), - root_window_destroyed_(false) { - } - virtual ~MultiMonitorManagerTest() {} - - virtual void SetUp() OVERRIDE { - AshTestBase::SetUp(); - monitor_manager()->AddObserver(this); - Shell::GetPrimaryRootWindow()->AddObserver(this); - } - virtual void TearDown() OVERRIDE { - Shell::GetPrimaryRootWindow()->RemoveObserver(this); - monitor_manager()->RemoveObserver(this); - AshTestBase::TearDown(); - } - - aura::MonitorManager* monitor_manager() { - return aura::Env::GetInstance()->monitor_manager(); - } - const vector& changed() const { return changed_; } - const vector& 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_; - } - - // 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) { - ASSERT_EQ(Shell::GetPrimaryRootWindow(), window); - root_window_destroyed_ = true; - } - - private: - vector changed_; - vector added_; - size_t removed_count_; - bool root_window_destroyed_; - - DISALLOW_COPY_AND_ASSIGN(MultiMonitorManagerTest); -}; - -TEST_F(MultiMonitorManagerTest, NativeMonitorTest) { - aura::MonitorManager::set_use_fullscreen_host_window(true); - - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - - // Update primary and add seconary. - UpdateMonitor("0+0-500x500,0+501-400x400"); - EXPECT_EQ(2U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("1 1 0", GetCountSummary()); - EXPECT_EQ(monitor_manager()->GetDisplayAt(0).id(), changed()[0].id()); - EXPECT_EQ(monitor_manager()->GetDisplayAt(1).id(), added()[0].id()); - EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString()); - EXPECT_EQ("0,0 400x400", added()[0].bounds().ToString()); - EXPECT_EQ("0,501 400x400", added()[0].bounds_in_pixel().ToString()); - reset(); - - // Delete secondary. - UpdateMonitor("0+0-500x500"); - EXPECT_EQ("0 0 1", GetCountSummary()); - reset(); - - // Change primary. - UpdateMonitor("0+0-1000x600"); - EXPECT_EQ("1 0 0", GetCountSummary()); - EXPECT_EQ(monitor_manager()->GetDisplayAt(0).id(), changed()[0].id()); - EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString()); - reset(); - - // Add secondary. - UpdateMonitor("0+0-1000x600,1001+0-600x400"); - EXPECT_EQ(2U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("0 1 0", GetCountSummary()); - EXPECT_EQ(monitor_manager()->GetDisplayAt(1).id(), added()[0].id()); - EXPECT_EQ("0,0 600x400", added()[0].bounds().ToString()); - EXPECT_EQ("1001,0 600x400", added()[0].bounds_in_pixel().ToString()); - reset(); - - // Secondary removed, primary changed. - UpdateMonitor("0+0-800x300"); - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("1 0 1", GetCountSummary()); - EXPECT_EQ(monitor_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 empty; - monitor_manager()->OnNativeMonitorsChanged(empty); - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("0 0 0", GetCountSummary()); - EXPECT_FALSE(root_window_destroyed()); - // Monitor configuration stays the same - EXPECT_EQ("0,0 800x300", - monitor_manager()->GetDisplayAt(0).bounds().ToString()); - reset(); - - // Connect to monitor again - UpdateMonitor("100+100-500x400"); - EXPECT_EQ(1U, monitor_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", changed()[0].bounds_in_pixel().ToString()); - reset(); - - // Go back to zero and wake up with multiple monitors. - monitor_manager()->OnNativeMonitorsChanged(empty); - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - EXPECT_FALSE(root_window_destroyed()); - reset(); - - // Add secondary. - UpdateMonitor("0+0-1000x600,1000+0-600x400"); - EXPECT_EQ(2U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("0,0 1000x600", - monitor_manager()->GetDisplayAt(0).bounds().ToString()); - EXPECT_EQ("0,0 600x400", - monitor_manager()->GetDisplayAt(1).bounds().ToString()); - EXPECT_EQ("1000,0 600x400", - monitor_manager()->GetDisplayAt(1).bounds_in_pixel().ToString()); - reset(); - - aura::MonitorManager::set_use_fullscreen_host_window(false); -} - -// Test in emulation mode (use_fullscreen_host_window=false) -TEST_F(MultiMonitorManagerTest, EmulatorTest) { - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - - internal::MultiMonitorManager::AddRemoveMonitor(); - // Update primary and add seconary. - EXPECT_EQ(2U, monitor_manager()->GetNumDisplays()); -#if defined(OS_WIN) - // TODO(oshima): Windows receives resize event for some reason. - EXPECT_EQ("1 1 0", GetCountSummary()); -#else - EXPECT_EQ("0 1 0", GetCountSummary()); -#endif - reset(); - - internal::MultiMonitorManager::CycleMonitor(); - EXPECT_EQ(2U, monitor_manager()->GetNumDisplays()); - // Observer gets called twice in this mode because - // it gets notified both from |OnNativeMonitorChagned| - // and from |RootWindowObserver|, which is the consequence of - // |SetHostSize()|. - EXPECT_EQ("4 0 0", GetCountSummary()); - reset(); - - internal::MultiMonitorManager::AddRemoveMonitor(); - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("0 0 1", GetCountSummary()); - reset(); - - internal::MultiMonitorManager::CycleMonitor(); - EXPECT_EQ(1U, monitor_manager()->GetNumDisplays()); - EXPECT_EQ("0 0 0", GetCountSummary()); - reset(); -} - -// TODO(oshima): Device scale factor is supported on chromeos only for now. -#if defined(OS_CHROMEOS) -#define MAYBE_TestDeviceScaleOnlyChange TestDeviceScaleOnlyChange -#else -#define MAYBE_TestDeviceScaleOnlyChange DISABLED_TestDeviceScaleOnlyChange -#endif - -TEST_F(MultiMonitorManagerTest, MAYBE_TestDeviceScaleOnlyChange) { - aura::MonitorManager::set_use_fullscreen_host_window(true); - UpdateMonitor("0+0-1000x600"); - EXPECT_EQ(1, - Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); - EXPECT_EQ("1000x600", - Shell::GetPrimaryRootWindow()->bounds().size().ToString()); - UpdateMonitor("0+0-1000x600*2"); - EXPECT_EQ(2, - Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); - EXPECT_EQ("500x300", - Shell::GetPrimaryRootWindow()->bounds().size().ToString()); - aura::MonitorManager::set_use_fullscreen_host_window(false); -} - -} // namespace test -} // namespace ash diff --git a/ash/monitor/secondary_monitor_view.cc b/ash/monitor/secondary_monitor_view.cc deleted file mode 100644 index ad9b250..0000000 --- a/ash/monitor/secondary_monitor_view.cc +++ /dev/null @@ -1,111 +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/monitor/secondary_monitor_view.h" - -#include "grit/ash_strings.h" -#include "grit/ui_resources.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/views/background.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" - -namespace ash { -namespace { - -// Colors for the background, the message text and the shortcut text. -const SkColor kBackgroundColor = SkColorSetRGB(0x33, 0x33, 0x33); -const SkColor kTextColor = SkColorSetRGB(127, 127, 127); - -// A view to be displayed on secondary monitor. -class SecondaryMonitorView : public views::WidgetDelegateView { - public: - SecondaryMonitorView() { - Init(); - } - virtual ~SecondaryMonitorView() { - } - - void Init() { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - - set_background(views::Background::CreateSolidBackground(kBackgroundColor)); - message_ = new views::Label( - l10n_util::GetStringUTF16(IDS_ASH_SECONDARY_MONITOR)); - message_->SetAutoColorReadabilityEnabled(false); - message_->SetFont(rb.GetFont(ui::ResourceBundle::LargeFont)); - message_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); - message_->SetEnabledColor(kTextColor); - AddChildView(message_); - - shortcut_text_ = new views::Label( - l10n_util::GetStringUTF16(IDS_ASH_SECONDARY_MONITOR_SHORTCUT)); - shortcut_text_->SetAutoColorReadabilityEnabled(false); - shortcut_text_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); - shortcut_text_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); - shortcut_text_->SetEnabledColor(kTextColor); - AddChildView(shortcut_text_); - - shortcut_image_ = new views::ImageView(); - shortcut_image_->SetImage(rb.GetImageSkiaNamed(IDR_AURA_SWITCH_MONITOR)); - AddChildView(shortcut_image_); - } - - virtual void Layout() { - const int kMessagePositionTopMargin = 40; - const int kShortcutPositionBottomMargin = 40; - const int kShortcutMargin = 4; // margin between text and image. - gfx::Rect b = bounds(); - - int msg_height = message_->GetHeightForWidth(b.width()); - message_->SetBounds( - 0, kMessagePositionTopMargin, bounds().width(), msg_height); - - // TODO(oshima): Figure out what to do for RTL. - // Align the shortcut text & image to the center. - gfx::Size text_size = shortcut_text_->GetPreferredSize(); - gfx::Size image_size = shortcut_image_->GetPreferredSize(); - int height = std::max(text_size.height(), image_size.height()); - int y = b.height() - kShortcutPositionBottomMargin - height; - int x = (b.width() - - (text_size.width() + kShortcutMargin + image_size.width())) / 2; - shortcut_text_->SetBounds(x, y + (height - text_size.height()) / 2, - text_size.width(), text_size.height()); - shortcut_image_->SetBounds( - x + text_size.width() + kShortcutMargin, - y + (height - image_size.height()) / 2, - image_size.width(), image_size.height()); - } - - private: - views::Label* message_; - views::Label* shortcut_text_; - views::ImageView* shortcut_image_; - - DISALLOW_COPY_AND_ASSIGN(SecondaryMonitorView); -}; - -} // namespace - -views::Widget* CreateSecondaryMonitorWidget(aura::Window* parent) { - views::Widget* desktop_widget = new views::Widget; - views::Widget::InitParams params( - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - SecondaryMonitorView* view = new SecondaryMonitorView(); - params.delegate = view; - params.parent = parent; - desktop_widget->Init(params); - desktop_widget->SetContentsView(view); - desktop_widget->Show(); - desktop_widget->GetNativeView()->SetName("SecondaryMonitor"); - return desktop_widget; -} - -} // namespace ash diff --git a/ash/monitor/secondary_monitor_view.h b/ash/monitor/secondary_monitor_view.h deleted file mode 100644 index cca03d2..0000000 --- a/ash/monitor/secondary_monitor_view.h +++ /dev/null @@ -1,25 +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_MONITOR_SECONDARY_MONITOR_VIEW_H_ -#define ASH_MONITOR_SECONDARY_MONITOR_VIEW_H_ -#pragma once - -namespace aura { -class Window; -} - -namespace views { -class Widget; -} - -namespace ash { - -// Creates the widget that hosts the static message displayed on the -// secondary monitor. -views::Widget* CreateSecondaryMonitorWidget(aura::Window* parent); - -} // namespace ash - -#endif // ASH_MONITOR_SECONDARY_MONITOR_VIEW_H_ diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index 050f760..8fd4acc 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/monitor/monitor_controller.h" -#include "ash/monitor/multi_monitor_manager.h" +#include "ash/display/display_controller.h" +#include "ash/display/multi_display_manager.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" #include "ash/test/ash_test_base.h" @@ -67,15 +67,15 @@ class RootWindowControllerTest : public test::AshTestBase { virtual ~RootWindowControllerTest() {} virtual void SetUp() OVERRIDE { - internal::MonitorController::SetExtendedDesktopEnabled(true); - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(true); + internal::DisplayController::SetExtendedDesktopEnabled(true); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(true); AshTestBase::SetUp(); } virtual void TearDown() OVERRIDE { AshTestBase::TearDown(); - internal::MonitorController::SetExtendedDesktopEnabled(false); - internal::MonitorController::SetVirtualScreenCoordinatesEnabled(false); + internal::DisplayController::SetExtendedDesktopEnabled(false); + internal::DisplayController::SetVirtualScreenCoordinatesEnabled(false); } private: @@ -83,7 +83,7 @@ class RootWindowControllerTest : public test::AshTestBase { }; TEST_F(RootWindowControllerTest, MoveWindows_Basic) { - UpdateMonitor("0+0-600x600,600+0-500x500"); + UpdateDisplay("0+0-600x600,600+0-500x500"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Emulate virtual screen coordinate system. root_windows[0]->SetBounds(gfx::Rect(0, 0, 600, 600)); @@ -114,12 +114,12 @@ TEST_F(RootWindowControllerTest, MoveWindows_Basic) { EXPECT_EQ("500x500", fullscreen->GetWindowScreenBounds().size().ToString()); #endif - UpdateMonitor("0+0-600x600"); + UpdateDisplay("0+0-600x600"); EXPECT_EQ(root_windows[0], normal->GetNativeView()->GetRootWindow()); EXPECT_EQ("100x100", normal->GetWindowScreenBounds().size().ToString()); - // Maximized area on primary monitor has 2px (given as + // Maximized area on primary display has 2px (given as // kAutoHideSize in shelf_layout_manager.cc) inset at the bottom. EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow()); EXPECT_EQ("600x598", maximized->GetWindowScreenBounds().size().ToString()); @@ -133,7 +133,7 @@ TEST_F(RootWindowControllerTest, MoveWindows_Basic) { } TEST_F(RootWindowControllerTest, MoveWindows_Modal) { - UpdateMonitor("0+0-500x500,500+0-500x500"); + UpdateDisplay("0+0-500x500,500+0-500x500"); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); // Emulate virtual screen coordinate system. @@ -154,7 +154,7 @@ TEST_F(RootWindowControllerTest, MoveWindows_Modal) { generator_1st.ClickLeftButton(); EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView())); - UpdateMonitor("0+0-500x500"); + UpdateDisplay("0+0-500x500"); EXPECT_EQ(root_windows[0], modal->GetNativeView()->GetRootWindow()); EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView())); generator_1st.ClickLeftButton(); diff --git a/ash/screen_ash.cc b/ash/screen_ash.cc index e444ebf..c98996a 100644 --- a/ash/screen_ash.cc +++ b/ash/screen_ash.cc @@ -8,7 +8,7 @@ #include "ash/wm/shelf_layout_manager.h" #include "base/logging.h" #include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/gfx/display.h" #include "ui/gfx/screen.h" @@ -16,8 +16,8 @@ namespace ash { namespace { -aura::MonitorManager* GetMonitorManager() { - return aura::Env::GetInstance()->monitor_manager(); +aura::DisplayManager* GetDisplayManager() { + return aura::Env::GetInstance()->display_manager(); } } // namespace @@ -55,19 +55,19 @@ gfx::NativeWindow ScreenAsh::GetWindowAtCursorScreenPoint() { } int ScreenAsh::GetNumDisplays() { - return GetMonitorManager()->GetNumDisplays(); + return GetDisplayManager()->GetNumDisplays(); } gfx::Display ScreenAsh::GetDisplayNearestWindow(gfx::NativeView window) const { - return GetMonitorManager()->GetDisplayNearestWindow(window); + return GetDisplayManager()->GetDisplayNearestWindow(window); } gfx::Display ScreenAsh::GetDisplayNearestPoint(const gfx::Point& point) const { - return GetMonitorManager()->GetDisplayNearestPoint(point); + return GetDisplayManager()->GetDisplayNearestPoint(point); } gfx::Display ScreenAsh::GetPrimaryDisplay() const { - return GetMonitorManager()->GetDisplayAt(0); + return GetDisplayManager()->GetDisplayAt(0); } } // namespace ash diff --git a/ash/shell.cc b/ash/shell.cc index d84b700..35eee4b 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -17,10 +17,10 @@ #include "ash/high_contrast/high_contrast_controller.h" #include "ash/launcher/launcher.h" #include "ash/magnifier/magnification_controller.h" -#include "ash/monitor/monitor_controller.h" -#include "ash/monitor/mouse_cursor_event_filter.h" -#include "ash/monitor/multi_monitor_manager.h" -#include "ash/monitor/secondary_monitor_view.h" +#include "ash/display/display_controller.h" +#include "ash/display/mouse_cursor_event_filter.h" +#include "ash/display/multi_display_manager.h" +#include "ash/display/secondary_display_view.h" #include "ash/root_window_controller.h" #include "ash/screen_ash.h" #include "ash/shell_context_menu.h" @@ -73,7 +73,7 @@ #include "ui/aura/env.h" #include "ui/aura/focus_manager.h" #include "ui/aura/layout_manager.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/shared/compound_event_filter.h" #include "ui/aura/shared/input_method_event_filter.h" @@ -97,7 +97,7 @@ #endif #if defined(OS_CHROMEOS) -#include "chromeos/monitor/output_configurator.h" +#include "chromeos/display/output_configurator.h" #include "ui/aura/dispatcher_linux.h" #endif // defined(OS_CHROMEOS) @@ -223,7 +223,7 @@ Shell::~Shell() { app_list_controller_.reset(); // Destroy all child windows including widgets. - monitor_controller_->CloseChildWindows(); + display_controller_->CloseChildWindows(); // These need a valid Shell instance to clean up properly, so explicitly // delete them before invalidating the instance. @@ -241,7 +241,7 @@ Shell::~Shell() { visibility_controller_.reset(); // This also deletes all RootWindows. - monitor_controller_.reset(); + display_controller_.reset(); // Launcher widget has a InputMethodBridge that references to // input_method_filter_'s input_method_. So explicitly release launcher_ @@ -268,8 +268,8 @@ Shell::~Shell() { // static Shell* Shell::CreateInstance(ShellDelegate* delegate) { CHECK(!instance_); - aura::Env::GetInstance()->SetMonitorManager( - new internal::MultiMonitorManager()); + aura::Env::GetInstance()->SetDisplayManager( + new internal::MultiDisplayManager()); instance_ = new Shell(delegate); instance_->Init(); return instance_; @@ -299,13 +299,13 @@ internal::RootWindowController* Shell::GetPrimaryRootWindowController() { // static Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() { - return Shell::GetInstance()->monitor_controller()-> + return Shell::GetInstance()->display_controller()-> GetAllRootWindowControllers(); } // static aura::RootWindow* Shell::GetPrimaryRootWindow() { - return GetInstance()->monitor_controller()->GetPrimaryRootWindow(); + return GetInstance()->display_controller()->GetPrimaryRootWindow(); } // static @@ -315,7 +315,7 @@ aura::RootWindow* Shell::GetActiveRootWindow() { // static aura::RootWindow* Shell::GetRootWindowAt(const gfx::Point& point) { - if (!internal::MonitorController::IsVirtualScreenCoordinatesEnabled()) + if (!internal::DisplayController::IsVirtualScreenCoordinatesEnabled()) return GetPrimaryRootWindow(); RootWindowList root_windows = GetAllRootWindows(); for (RootWindowList::const_iterator iter = root_windows.begin(); @@ -331,7 +331,7 @@ aura::RootWindow* Shell::GetRootWindowAt(const gfx::Point& point) { // static aura::RootWindow* Shell::GetRootWindowMatching(const gfx::Rect& rect) { - if (!internal::MonitorController::IsVirtualScreenCoordinatesEnabled()) + if (!internal::DisplayController::IsVirtualScreenCoordinatesEnabled()) return GetPrimaryRootWindow(); if (rect.IsEmpty()) return GetRootWindowAt(rect.origin()); @@ -354,7 +354,7 @@ aura::RootWindow* Shell::GetRootWindowMatching(const gfx::Rect& rect) { // static Shell::RootWindowList Shell::GetAllRootWindows() { - return Shell::GetInstance()->monitor_controller()-> + return Shell::GetInstance()->display_controller()-> GetAllRootWindows(); } @@ -390,9 +390,9 @@ void Shell::Init() { activation_controller_.reset( new internal::ActivationController(focus_manager_.get())); - monitor_controller_.reset(new internal::MonitorController); - monitor_controller_->InitPrimaryDisplay(); - aura::RootWindow* root_window = monitor_controller_->GetPrimaryRootWindow(); + display_controller_.reset(new internal::DisplayController); + display_controller_->InitPrimaryDisplay(); + aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow(); active_root_window_ = root_window; #if !defined(OS_MACOSX) @@ -457,9 +457,9 @@ void Shell::Init() { magnification_controller_.reset( internal::MagnificationController::CreateInstance()); - if (internal::MonitorController::IsExtendedDesktopEnabled()) { + if (internal::DisplayController::IsExtendedDesktopEnabled()) { mouse_cursor_filter_.reset( - new internal::MouseCursorEventFilter(monitor_controller_.get())); + new internal::MouseCursorEventFilter(display_controller_.get())); AddEnvEventFilter(mouse_cursor_filter_.get()); } @@ -511,7 +511,7 @@ void Shell::Init() { power_button_controller_.reset(new PowerButtonController); AddShellObserver(power_button_controller_.get()); - monitor_controller_->InitSecondaryDisplays(); + display_controller_->InitSecondaryDisplays(); if (initially_hide_cursor_) aura::Env::GetInstance()->cursor_manager()->ShowCursor(false); @@ -580,15 +580,15 @@ void Shell::RotateFocus(Direction direction) { internal::FocusCycler::BACKWARD); } -void Shell::SetMonitorWorkAreaInsets(Window* contains, +void Shell::SetDisplayWorkAreaInsets(Window* contains, const gfx::Insets& insets) { - internal::MultiMonitorManager* monitor_manager = - static_cast( - aura::Env::GetInstance()->monitor_manager()); - if (!monitor_manager->UpdateWorkAreaOfMonitorNearestWindow(contains, insets)) + internal::MultiDisplayManager* display_manager = + static_cast( + aura::Env::GetInstance()->display_manager()); + if (!display_manager->UpdateWorkAreaOfDisplayNearestWindow(contains, insets)) return; FOR_EACH_OBSERVER(ShellObserver, observers_, - OnMonitorWorkAreaInsetsChanged()); + OnDisplayWorkAreaInsetsChanged()); } void Shell::OnLoginStateChanged(user::LoginStatus status) { @@ -671,9 +671,9 @@ int Shell::GetGridSize() const { workspace_manager()->grid_size(); } -void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) { +void Shell::InitRootWindowForSecondaryDisplay(aura::RootWindow* root) { root->set_focus_manager(focus_manager_.get()); - if (internal::MonitorController::IsExtendedDesktopEnabled()) { + if (internal::DisplayController::IsExtendedDesktopEnabled()) { internal::RootWindowController* controller = new internal::RootWindowController(root); controller->CreateContainers(); @@ -687,11 +687,11 @@ void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) { root->SetFocusWhenShown(false); root->SetLayoutManager(new internal::RootWindowLayoutManager(root)); aura::Window* container = new aura::Window(NULL); - container->SetName("SecondaryMonitorContainer"); + container->SetName("SecondaryDisplayContainer"); container->Init(ui::LAYER_NOT_DRAWN); root->AddChild(container); container->SetLayoutManager(new internal::BaseLayoutManager(root)); - CreateSecondaryMonitorWidget(container); + CreateSecondaryDisplayWidget(container); container->Show(); root->layout_manager()->OnWindowResized(); root->ShowRootWindow(); diff --git a/ash/shell.h b/ash/shell.h index b9e9bd2..107913b 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -83,7 +83,7 @@ class DragDropController; class FocusCycler; class KeyRewriterEventFilter; class MagnificationController; -class MonitorController; +class DisplayController; class MouseCursorEventFilter; class PanelLayoutManager; class PartialScreenshotEventFilter; @@ -219,11 +219,11 @@ class ASH_EXPORT Shell : aura::CursorDelegate { // Rotates focus through containers that can receive focus. void RotateFocus(Direction direction); - // Sets the work area insets of the monitor that contains |window|, + // Sets the work area insets of the display that contains |window|, // this notifies observers too. // TODO(sky): this no longer really replicates what happens and is unreliable. // Remove this. - void SetMonitorWorkAreaInsets(aura::Window* window, + void SetDisplayWorkAreaInsets(aura::Window* window, const gfx::Insets& insets); // Called when the user logs in. @@ -279,8 +279,8 @@ class ASH_EXPORT Shell : aura::CursorDelegate { internal::FocusCycler* focus_cycler() { return focus_cycler_.get(); } - internal::MonitorController* monitor_controller() { - return monitor_controller_.get(); + internal::DisplayController* display_controller() { + return display_controller_.get(); } ShellDelegate* delegate() { return delegate_.get(); } @@ -346,8 +346,8 @@ class ASH_EXPORT Shell : aura::CursorDelegate { browser_context_ = browser_context; } - // Initializes the root window to be used for a secondary monitor. - void InitRootWindowForSecondaryMonitor(aura::RootWindow* root); + // Initializes the root window to be used for a secondary display. + void InitRootWindowForSecondaryDisplay(aura::RootWindow* root); #if defined(OS_CHROMEOS) chromeos::OutputConfigurator* output_configurator() { @@ -429,7 +429,7 @@ class ASH_EXPORT Shell : aura::CursorDelegate { scoped_ptr video_detector_; scoped_ptr window_cycle_controller_; scoped_ptr focus_cycler_; - scoped_ptr monitor_controller_; + scoped_ptr display_controller_; scoped_ptr high_contrast_controller_; scoped_ptr magnification_controller_; scoped_ptr focus_manager_; diff --git a/ash/shell_observer.h b/ash/shell_observer.h index 4b73efb..3230bb3 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h @@ -14,7 +14,7 @@ namespace ash { class ASH_EXPORT ShellObserver { public: // Invoked after the screen's work area insets changes. - virtual void OnMonitorWorkAreaInsetsChanged() {} + virtual void OnDisplayWorkAreaInsetsChanged() {} // Invoked when the user logs in. virtual void OnLoginStateChanged(user::LoginStatus status) {} diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 5b92cd8..45996b2 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc @@ -12,7 +12,7 @@ #include "base/string_split.h" #include "content/public/test/web_contents_tester.h" #include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/base/ime/text_input_test_support.h" #include "ui/compositor/layer_animator.h" @@ -30,7 +30,7 @@ std::vector CreateDisplaysFromString( base::SplitString(specs, ',', &parts); for (std::vector::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { - displays.push_back(aura::MonitorManager::CreateMonitorFromSpec(*iter)); + displays.push_back(aura::DisplayManager::CreateDisplayFromSpec(*iter)); } return displays; } @@ -72,20 +72,20 @@ void AshTestBase::TearDown() { ui::TextInputTestSupport::Shutdown(); } -void AshTestBase::ChangeMonitorConfig(float scale, +void AshTestBase::ChangeDisplayConfig(float scale, const gfx::Rect& bounds_in_pixel) { gfx::Display display = gfx::Display(gfx::Screen::GetPrimaryDisplay().id()); display.SetScaleAndBounds(scale, bounds_in_pixel); std::vector displays; displays.push_back(display); - aura::Env::GetInstance()->monitor_manager()->OnNativeMonitorsChanged( + aura::Env::GetInstance()->display_manager()->OnNativeDisplaysChanged( displays); } -void AshTestBase::UpdateMonitor(const std::string& display_specs) { +void AshTestBase::UpdateDisplay(const std::string& display_specs) { std::vector displays = CreateDisplaysFromString(display_specs); - aura::Env::GetInstance()->monitor_manager()-> - OnNativeMonitorsChanged(displays); + aura::Env::GetInstance()->display_manager()-> + OnNativeDisplaysChanged(displays); } void AshTestBase::RunAllPendingInMessageLoop() { diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index 559b370..e26d2c3 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h @@ -36,16 +36,16 @@ class AshTestBase : public testing::Test { virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; - // Change the primary monitor's configuration to use |bounds| + // Change the primary display's configuration to use |bounds| // and |scale|. - void ChangeMonitorConfig(float scale, const gfx::Rect& bounds); + void ChangeDisplayConfig(float scale, const gfx::Rect& bounds); // Update the display configuration as given in |display_specs|. The // format of |display_spec| is a list of comma separated spec for // each displays. Please refer to the comment in - // | aura::MonitorManager::CreateMonitorFromSpec| for the format of + // | aura::DisplayManager::CreateDisplayFromSpec| for the format of // the display spec. - void UpdateMonitor(const std::string& display_specs); + void UpdateDisplay(const std::string& display_specs); protected: void RunAllPendingInMessageLoop(); diff --git a/ash/tooltips/tooltip_controller.cc b/ash/tooltips/tooltip_controller.cc index 64ca6f0..4798cd33 100644 --- a/ash/tooltips/tooltip_controller.cc +++ b/ash/tooltips/tooltip_controller.cc @@ -66,9 +66,9 @@ gfx::Font GetDefaultFont() { int GetMaxWidth(int x, int y) { // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure // out a way to merge. - gfx::Rect monitor_bounds = + gfx::Rect display_bounds = gfx::Screen::GetDisplayNearestPoint(gfx::Point(x, y)).bounds(); - return (monitor_bounds.width() + 1) / 2; + return (display_bounds.width() + 1) / 2; } // Creates a widget of type TYPE_TOOLTIP @@ -155,22 +155,22 @@ class TooltipController::Tooltip { tooltip_height); tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); - gfx::Rect monitor_bounds = + gfx::Rect display_bounds = gfx::Screen::GetDisplayNearestPoint(tooltip_rect.origin()).bounds(); // If tooltip is out of bounds on the x axis, we simply shift it // horizontally by the offset. - if (tooltip_rect.right() > monitor_bounds.right()) { - int h_offset = tooltip_rect.right() - monitor_bounds.right(); + if (tooltip_rect.right() > display_bounds.right()) { + int h_offset = tooltip_rect.right() - display_bounds.right(); tooltip_rect.Offset(-h_offset, 0); } // If tooltip is out of bounds on the y axis, we flip it to appear above the // mouse cursor instead of below. - if (tooltip_rect.bottom() > monitor_bounds.bottom()) + if (tooltip_rect.bottom() > display_bounds.bottom()) tooltip_rect.set_y(mouse_pos.y() - tooltip_height); - widget_->SetBounds(tooltip_rect.AdjustToFit(monitor_bounds)); + widget_->SetBounds(tooltip_rect.AdjustToFit(display_bounds)); } }; diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc index 4e39fff..29d39a0d 100644 --- a/ash/wm/base_layout_manager.cc +++ b/ash/wm/base_layout_manager.cc @@ -120,7 +120,7 @@ void BaseLayoutManager::OnRootWindowResized(const aura::RootWindow* root, ///////////////////////////////////////////////////////////////////////////// // BaseLayoutManager, ash::ShellObserver overrides: -void BaseLayoutManager::OnMonitorWorkAreaInsetsChanged() { +void BaseLayoutManager::OnDisplayWorkAreaInsetsChanged() { AdjustWindowSizesForScreenChange(); } @@ -222,8 +222,8 @@ void BaseLayoutManager::MaybeAnimateToBounds(aura::Window* window, } void BaseLayoutManager::AdjustWindowSizesForScreenChange() { - // If a user plugs an external monitor into a laptop running Aura the - // monitor size will change. Maximized windows need to resize to match. + // If a user plugs an external display into a laptop running Aura the + // display size will change. Maximized windows need to resize to match. // We also do this when developers running Aura on a desktop manually resize // the host window. // We also need to do this when the work area insets changes. @@ -238,10 +238,10 @@ void BaseLayoutManager::AdjustWindowSizesForScreenChange() { window, gfx::Screen::GetDisplayNearestWindow(window).bounds()); } else { // The work area may be smaller than the full screen. - gfx::Rect monitor_rect = + gfx::Rect display_rect = gfx::Screen::GetDisplayNearestWindow(window).work_area(); - // Put as much of the window as possible within the monitor area. - window->SetBounds(window->bounds().AdjustToFit(monitor_rect)); + // Put as much of the window as possible within the display area. + window->SetBounds(window->bounds().AdjustToFit(display_rect)); } } } diff --git a/ash/wm/base_layout_manager.h b/ash/wm/base_layout_manager.h index becf24a..8ba5f5c 100644 --- a/ash/wm/base_layout_manager.h +++ b/ash/wm/base_layout_manager.h @@ -57,7 +57,7 @@ class ASH_EXPORT BaseLayoutManager : public aura::LayoutManager, const gfx::Size& old_size) OVERRIDE; // ash::ShellObserver overrides: - virtual void OnMonitorWorkAreaInsetsChanged() OVERRIDE; + virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE; // WindowObserver overrides: virtual void OnWindowPropertyChanged(aura::Window* window, diff --git a/ash/wm/base_layout_manager_unittest.cc b/ash/wm/base_layout_manager_unittest.cc index 626aa66..2de08af 100644 --- a/ash/wm/base_layout_manager_unittest.cc +++ b/ash/wm/base_layout_manager_unittest.cc @@ -29,7 +29,7 @@ class BaseLayoutManagerTest : public test::AshTestBase { virtual void SetUp() OVERRIDE { test::AshTestBase::SetUp(); - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), gfx::Insets(1, 2, 3, 4)); Shell::GetPrimaryRootWindow()->SetHostSize(gfx::Size(800, 600)); @@ -53,7 +53,7 @@ TEST_F(BaseLayoutManagerTest, Maximize) { gfx::Rect bounds(100, 100, 200, 200); scoped_ptr window(CreateTestWindow(bounds)); window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); - // Maximized window fills the work area, not the whole monitor. + // Maximized window fills the work area, not the whole display. EXPECT_EQ(ScreenAsh::GetMaximizedWindowBounds(window.get()).ToString(), window->bounds().ToString()); window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); @@ -93,7 +93,7 @@ TEST_F(BaseLayoutManagerTest, Fullscreen) { gfx::Rect bounds(100, 100, 200, 200); scoped_ptr window(CreateTestWindow(bounds)); window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); - // Fullscreen window fills the whole monitor. + // Fullscreen window fills the whole display. EXPECT_EQ( gfx::Screen::GetDisplayNearestWindow(window.get()).bounds().ToString(), window->bounds().ToString()); @@ -105,12 +105,12 @@ TEST_F(BaseLayoutManagerTest, Fullscreen) { TEST_F(BaseLayoutManagerTest, FullscreenRootWindowResize) { gfx::Rect bounds(100, 100, 200, 200); scoped_ptr window(CreateTestWindow(bounds)); - // Fullscreen window fills the whole monitor. + // Fullscreen window fills the whole display. window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); EXPECT_EQ( gfx::Screen::GetDisplayNearestWindow(window.get()).bounds().ToString(), window->bounds().ToString()); - // Enlarge the root window. We should still match the monitor size. + // Enlarge the root window. We should still match the display size. Shell::GetPrimaryRootWindow()->SetHostSize(gfx::Size(800, 600)); EXPECT_EQ( gfx::Screen::GetDisplayNearestWindow(window.get()).bounds().ToString(), diff --git a/ash/wm/frame_painter.cc b/ash/wm/frame_painter.cc index 617b22ea..98e0007 100644 --- a/ash/wm/frame_painter.cc +++ b/ash/wm/frame_painter.cc @@ -376,8 +376,8 @@ void FramePainter::PaintHeader(views::NonClientFrameView* view, // We don't need the extra lightness in the edges when we're at the top edge // of the screen. - // TODO(oshima): This will not work under multi-monitor, need to add method - // like GetWindowBoundsInMonitor(). + // TODO(oshima): This will not work under multi-display, need to add method + // like GetWindowBoundsInDisplay(). if (frame_->GetWindowScreenBounds().y() == 0) return; diff --git a/ash/wm/screen_dimmer.h b/ash/wm/screen_dimmer.h index daa60ea0..46bed1f 100644 --- a/ash/wm/screen_dimmer.h +++ b/ash/wm/screen_dimmer.h @@ -24,7 +24,7 @@ namespace ash { namespace internal { // ScreenDimmer displays a partially-opaque layer above everything -// else in the root window to darken the monitor. It shouldn't be used +// else in the root window to darken the display. It shouldn't be used // for long-term brightness adjustments due to performance // considerations -- it's only intended for cases where we want to // briefly dim the screen (e.g. to indicate to the user that we're diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc index 3c3246f..156fad1 100644 --- a/ash/wm/shelf_layout_manager.cc +++ b/ash/wm/shelf_layout_manager.cc @@ -206,7 +206,7 @@ bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) { } gfx::Rect ShelfLayoutManager::GetIdealBounds() { - // TODO: this is wrong. Figure out what monitor shelf is on and everything + // TODO: this is wrong. Figure out what display shelf is on and everything // should be based on it. gfx::Rect bounds( gfx::Screen::GetDisplayNearestWindow(status_->GetNativeView()).bounds()); @@ -239,7 +239,7 @@ void ShelfLayoutManager::LayoutShelf() { } GetLayer(status_)->SetOpacity(target_bounds.opacity); status_->SetBounds(target_bounds.status_bounds); - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), target_bounds.work_area_insets); UpdateHitTestBounds(); @@ -384,7 +384,7 @@ void ShelfLayoutManager::SetState(VisibilityState visibility_state) { status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); GetLayer(status_)->SetBounds(target_bounds.status_bounds); GetLayer(status_)->SetOpacity(target_bounds.opacity); - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), target_bounds.work_area_insets); UpdateHitTestBounds(); diff --git a/ash/wm/shelf_layout_manager_unittest.cc b/ash/wm/shelf_layout_manager_unittest.cc index ff61d3f..898cc2a 100644 --- a/ash/wm/shelf_layout_manager_unittest.cc +++ b/ash/wm/shelf_layout_manager_unittest.cc @@ -14,7 +14,7 @@ #include "ash/test/ash_test_base.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/test/event_generator.h" #include "ui/aura/window.h" @@ -92,8 +92,8 @@ TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) { gfx::Rect launcher_bounds(shelf->launcher_widget()->GetWindowScreenBounds()); int shelf_height = shelf->GetIdealBounds().height(); - const aura::MonitorManager* manager = - aura::Env::GetInstance()->monitor_manager(); + const aura::DisplayManager* manager = + aura::Env::GetInstance()->display_manager(); const gfx::Display& display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); ASSERT_NE(-1, display.id()); @@ -144,8 +144,8 @@ TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) { shelf->LayoutShelf(); EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state()); - const aura::MonitorManager* manager = - aura::Env::GetInstance()->monitor_manager(); + const aura::DisplayManager* manager = + aura::Env::GetInstance()->display_manager(); const gfx::Display& display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); @@ -326,25 +326,25 @@ TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) { widget->Init(params); widget->Show(); aura::Window* window = widget->GetNativeWindow(); - gfx::Rect monitor_bounds( + gfx::Rect display_bounds( gfx::Screen::GetDisplayNearestWindow(window).bounds()); - EXPECT_EQ(monitor_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, + EXPECT_EQ(display_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, shelf->GetMaximizedWindowBounds(window).bottom()); EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state()); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state()); - EXPECT_EQ(monitor_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, + EXPECT_EQ(display_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, shelf->GetMaximizedWindowBounds(window).bottom()); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_DEFAULT); EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state()); - EXPECT_EQ(monitor_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, + EXPECT_EQ(display_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, shelf->GetMaximizedWindowBounds(window).bottom()); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state()); - EXPECT_GT(monitor_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, + EXPECT_GT(display_bounds.bottom() - ShelfLayoutManager::kAutoHideSize, shelf->GetMaximizedWindowBounds(window).bottom()); widget->Maximize(); @@ -498,8 +498,8 @@ TEST_F(ShelfLayoutManagerTest, SetAlignment) { shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); gfx::Rect launcher_bounds(shelf->launcher_widget()->GetWindowScreenBounds()); - const aura::MonitorManager* manager = - aura::Env::GetInstance()->monitor_manager(); + const aura::DisplayManager* manager = + aura::Env::GetInstance()->display_manager(); gfx::Display display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); ASSERT_NE(-1, display.id()); diff --git a/ash/wm/stacking_controller.cc b/ash/wm/stacking_controller.cc index 368c9b5..6d44525 100644 --- a/ash/wm/stacking_controller.cc +++ b/ash/wm/stacking_controller.cc @@ -4,7 +4,7 @@ #include "ash/wm/stacking_controller.h" -#include "ash/monitor/monitor_controller.h" +#include "ash/display/display_controller.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" #include "ash/wm/always_on_top_controller.h" @@ -23,7 +23,7 @@ namespace { // that matches the window's bound will be used. Otherwise, it'll // return the active root window. aura::RootWindow* FindContainerRoot(const gfx::Rect& bounds) { - if (!MonitorController::IsVirtualScreenCoordinatesEnabled() || + if (!DisplayController::IsVirtualScreenCoordinatesEnabled() || (bounds.origin().x() == 0 && bounds.origin().y() == 0 && bounds.IsEmpty())) { return Shell::GetActiveRootWindow(); diff --git a/ash/wm/toplevel_window_event_filter_unittest.cc b/ash/wm/toplevel_window_event_filter_unittest.cc index fc8984b..ca9aeeb 100644 --- a/ash/wm/toplevel_window_event_filter_unittest.cc +++ b/ash/wm/toplevel_window_event_filter_unittest.cc @@ -402,7 +402,7 @@ TEST_F(ToplevelWindowEventFilterTest, DontDragToNegativeY) { EXPECT_EQ(100, target->bounds().height()); } -// Verifies we don't let windows go bigger than the monitor width. +// Verifies we don't let windows go bigger than the display width. TEST_F(ToplevelWindowEventFilterTest, DontGotWiderThanScreen) { scoped_ptr target(CreateWindow(HTRIGHT)); gfx::Rect work_area = diff --git a/ash/wm/window_resizer.cc b/ash/wm/window_resizer.cc index 7e62d23..df28ec7 100644 --- a/ash/wm/window_resizer.cc +++ b/ash/wm/window_resizer.cc @@ -292,7 +292,7 @@ int WindowResizer::GetWidthForDrag(const Details& details, *delta_x = -x_multiplier * (details.initial_bounds.width() - min_width); } - // And don't let the window go bigger than the monitor. + // And don't let the window go bigger than the display. int max_width = gfx::Screen::GetDisplayNearestWindow(details.window).bounds().width(); if (width > max_width) { @@ -326,7 +326,7 @@ int WindowResizer::GetHeightForDrag(const Details& details, *delta_y = -y_multiplier * (details.initial_bounds.height() - min_height); } - // And don't let the window go bigger than the monitor. + // And don't let the window go bigger than the display. int max_height = gfx::Screen::GetDisplayNearestWindow(details.window).bounds().height(); if (height > max_height) { diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h index e0bd718..2f611b8 100644 --- a/ash/wm/window_util.h +++ b/ash/wm/window_util.h @@ -56,7 +56,7 @@ ASH_EXPORT void MinimizeWindow(aura::Window* window); // Restores |window|, which must not be NULL. ASH_EXPORT void RestoreWindow(aura::Window* window); -// Moves the window to the center of the monitor. +// Moves the window to the center of the display. ASH_EXPORT void CenterWindow(aura::Window* window); } // namespace wm diff --git a/ash/wm/workspace/snap_sizer.cc b/ash/wm/workspace/snap_sizer.cc index 092ba697..c303f1d 100644 --- a/ash/wm/workspace/snap_sizer.cc +++ b/ash/wm/workspace/snap_sizer.cc @@ -129,7 +129,7 @@ gfx::Rect SnapSizer::GetTargetBoundsForPercent(int percent_index) const { } bool SnapSizer::AlongEdge(int x) const { - // TODO: need to support multi-monitor. + // TODO: need to support multi-display. gfx::Rect area(gfx::Screen::GetDisplayNearestWindow(window_).bounds()); return (x <= area.x()) || (x >= area.right() - 1); } diff --git a/ash/wm/workspace/workspace_manager.cc b/ash/wm/workspace/workspace_manager.cc index 1eccfe6..016244a 100644 --- a/ash/wm/workspace/workspace_manager.cc +++ b/ash/wm/workspace/workspace_manager.cc @@ -141,7 +141,7 @@ WorkspaceManager::WindowState WorkspaceManager::GetWindowState() { if (!shelf_ || !active_workspace_) return WINDOW_STATE_DEFAULT; - // TODO: this code needs to be made multi-monitor aware. + // TODO: this code needs to be made multi-display aware. gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); const aura::Window::Windows& windows(contents_view_->children()); bool window_overlaps_launcher = false; diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 9b52030..26d957c 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc @@ -286,7 +286,7 @@ void WorkspaceWindowResizer::AdjustBoundsForMainWindow( if (bounds->y() > max_y) bounds->set_y(max_y); - // Don't allow dragging above the top of the monitor. + // Don't allow dragging above the top of the display. if (bounds->y() <= work_area.y()) bounds->set_y(work_area.y()); @@ -419,8 +419,8 @@ void WorkspaceWindowResizer::RestackWindows() { WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType( const gfx::Point& location) const { - // TODO: this likely only wants total monitor area, not the area of a single - // monitor. + // TODO: this likely only wants total display area, not the area of a single + // display. gfx::Rect area( gfx::Screen::GetDisplayNearestWindow(details_.window).bounds()); if (location.x() <= area.x()) diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc index d3654c0..eed78ae 100644 --- a/ash/wm/workspace/workspace_window_resizer_unittest.cc +++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc @@ -55,7 +55,7 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { gfx::Rect root_bounds(root->bounds()); EXPECT_EQ(kRootHeight, root_bounds.height()); - Shell::GetInstance()->SetMonitorWorkAreaInsets(root, gfx::Insets()); + Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets()); window_.reset(new aura::Window(&delegate_)); window_->Init(ui::LAYER_NOT_DRAWN); window_->SetParent(root); @@ -347,13 +347,13 @@ TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) { // Assertions around attached window resize dragging from the bottom with 3 // windows. // TODO(oshima): Host window doesn't get a resize event after -// SetHostSize on Windows trybot, which gives wrong work/monitor area. +// SetHostSize on Windows trybot, which gives wrong work/display area. TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3) { aura::RootWindow* root = Shell::GetPrimaryRootWindow(); root->SetHostSize(gfx::Size(600, 800)); LOG(ERROR) << "=== Calling OnHostResized, 600x800"; - Shell::GetInstance()->SetMonitorWorkAreaInsets(root, gfx::Insets()); + Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets()); window_->SetBounds(gfx::Rect( 300, 100, 300, 200)); window2_->SetBounds(gfx::Rect(300, 300, 200, 150)); @@ -496,7 +496,7 @@ TEST_F(WorkspaceWindowResizerTest, RestackAttached) { // Makes sure we don't allow dragging below the work area. TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) { - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0)); window_->SetBounds(gfx::Rect(100, 200, 300, 400)); @@ -513,7 +513,7 @@ TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) { // Makes sure we don't allow dragging off the top of the work area. TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) { - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0)); window_->SetBounds(gfx::Rect(100, 200, 300, 400)); @@ -526,7 +526,7 @@ TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) { } TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) { - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0)); window_->SetBounds(gfx::Rect(100, 200, 300, 380)); @@ -595,7 +595,7 @@ TEST_F(WorkspaceWindowResizerTest, SnapToEdge) { // the work area. TEST_F(WorkspaceWindowResizerTest, TallWindow) { aura::RootWindow* root = Shell::GetPrimaryRootWindow(); - Shell::GetInstance()->SetMonitorWorkAreaInsets( + Shell::GetInstance()->SetDisplayWorkAreaInsets( root, gfx::Insets(0, 0, 50, 0)); window_->SetBounds(gfx::Rect(0, 0, 320, 560)); SetGridSize(16); diff --git a/chrome/browser/chromeos/power/output_observer.cc b/chrome/browser/chromeos/power/output_observer.cc index 1896495..9b8c221 100644 --- a/chrome/browser/chromeos/power/output_observer.cc +++ b/chrome/browser/chromeos/power/output_observer.cc @@ -6,7 +6,7 @@ #include "ash/shell.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/monitor/output_configurator.h" +#include "chromeos/display/output_configurator.h" namespace chromeos { diff --git a/chrome/browser/ui/ash/ash_init.cc b/chrome/browser/ui/ash/ash_init.cc index 5bf0b0a..97f6f16 100644 --- a/chrome/browser/ui/ash/ash_init.cc +++ b/chrome/browser/ui/ash/ash_init.cc @@ -21,7 +21,7 @@ #include "chrome/common/chrome_switches.h" #include "ui/aura/aura_switches.h" #include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/compositor/compositor_setup.h" @@ -54,7 +54,7 @@ void OpenAsh() { #endif if (use_fullscreen) { - aura::MonitorManager::set_use_fullscreen_host_window(true); + aura::DisplayManager::set_use_fullscreen_host_window(true); #if defined(OS_CHROMEOS) aura::RootWindow::set_hide_host_cursor(true); // Hide the mouse cursor completely at boot. diff --git a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc index 056271d..3c9bea2 100644 --- a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc +++ b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc @@ -12,7 +12,7 @@ #include "ui/aura/desktop/desktop_screen.h" #include "ui/aura/desktop/desktop_stacking_client.h" #include "ui/aura/env.h" -#include "ui/aura/single_monitor_manager.h" +#include "ui/aura/single_display_manager.h" #include "ui/gfx/screen.h" #include "ui/views/widget/native_widget_aura.h" #if defined(OS_LINUX) @@ -30,7 +30,7 @@ ChromeBrowserMainExtraPartsAura::~ChromeBrowserMainExtraPartsAura() { void ChromeBrowserMainExtraPartsAura::PreProfileInit() { #if !defined(USE_ASH) gfx::Screen::SetInstance(aura::CreateDesktopScreen()); - aura::Env::GetInstance()->SetMonitorManager(new aura::SingleMonitorManager); + aura::Env::GetInstance()->SetDisplayManager(new aura::SingleDisplayManager); stacking_client_.reset(new aura::DesktopStackingClient); #endif // !USE_ASH diff --git a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc index 506a0ea..61acf54 100644 --- a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc @@ -10,7 +10,7 @@ #include "ui/aura/desktop/desktop_stacking_client.h" #include "ui/aura/desktop/desktop_screen.h" #include "ui/aura/env.h" -#include "ui/aura/single_monitor_manager.h" +#include "ui/aura/single_display_manager.h" #include "ui/gfx/screen.h" ChromeBrowserMainExtraPartsAsh::ChromeBrowserMainExtraPartsAsh() { @@ -23,7 +23,7 @@ void ChromeBrowserMainExtraPartsAsh::PreProfileInit() { if (browser::ShouldOpenAshOnStartup()) { browser::OpenAsh(); } else { - aura::Env::GetInstance()->SetMonitorManager(new aura::SingleMonitorManager); + aura::Env::GetInstance()->SetDisplayManager(new aura::SingleDisplayManager); stacking_client_.reset(new aura::DesktopStackingClient); gfx::Screen::SetInstance(aura::CreateDesktopScreen()); } diff --git a/chrome/browser/ui/webui/options2/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options2/chromeos/display_options_handler.cc index 835b742..d9bdd8c 100644 --- a/chrome/browser/ui/webui/options2/chromeos/display_options_handler.cc +++ b/chrome/browser/ui/webui/options2/chromeos/display_options_handler.cc @@ -6,16 +6,16 @@ #include -#include "ash/monitor/monitor_controller.h" +#include "ash/display/display_controller.h" #include "ash/shell.h" #include "base/logging.h" #include "base/json/json_value_converter.h" #include "base/values.h" -#include "chromeos/monitor/output_configurator.h" +#include "chromeos/display/output_configurator.h" #include "content/public/browser/web_ui.h" #include "grit/generated_resources.h" #include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/display.h" #include "ui/gfx/rect.h" @@ -23,14 +23,14 @@ namespace chromeos { namespace options2 { -using ash::internal::MonitorController; +using ash::internal::DisplayController; DisplayOptionsHandler::DisplayOptionsHandler() { - aura::Env::GetInstance()->monitor_manager()->AddObserver(this); + aura::Env::GetInstance()->display_manager()->AddObserver(this); } DisplayOptionsHandler::~DisplayOptionsHandler() { - aura::Env::GetInstance()->monitor_manager()->RemoveObserver(this); + aura::Env::GetInstance()->display_manager()->RemoveObserver(this); } void DisplayOptionsHandler::GetLocalizedValues( @@ -80,13 +80,13 @@ void DisplayOptionsHandler::OnDisplayRemoved(const gfx::Display& old_display) { } void DisplayOptionsHandler::UpdateDisplaySectionVisibility() { - aura::MonitorManager* monitor_manager = - aura::Env::GetInstance()->monitor_manager(); + aura::DisplayManager* display_manager = + aura::Env::GetInstance()->display_manager(); chromeos::State output_state = ash::Shell::GetInstance()->output_configurator()->output_state(); base::FundamentalValue show_options( - MonitorController::IsExtendedDesktopEnabled() && - monitor_manager->GetNumDisplays() > 1 && + DisplayController::IsExtendedDesktopEnabled() && + display_manager->GetNumDisplays() > 1 && output_state != chromeos::STATE_INVALID && output_state != chromeos::STATE_HEADLESS && output_state != chromeos::STATE_SINGLE); @@ -95,16 +95,16 @@ void DisplayOptionsHandler::UpdateDisplaySectionVisibility() { } void DisplayOptionsHandler::SendDisplayInfo() { - aura::MonitorManager* monitor_manager = - aura::Env::GetInstance()->monitor_manager(); + aura::DisplayManager* display_manager = + aura::Env::GetInstance()->display_manager(); chromeos::OutputConfigurator* output_configurator = ash::Shell::GetInstance()->output_configurator(); base::FundamentalValue mirroring( output_configurator->output_state() == chromeos::STATE_DUAL_MIRROR); base::ListValue displays; - for (size_t i = 0; i < monitor_manager->GetNumDisplays(); ++i) { - const gfx::Display& display = monitor_manager->GetDisplayAt(i); + for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { + const gfx::Display& display = display_manager->GetDisplayAt(i); const gfx::Rect& bounds = display.bounds(); base::DictionaryValue* js_display = new base::DictionaryValue(); js_display->SetDouble("id", display.id()); @@ -115,10 +115,10 @@ void DisplayOptionsHandler::SendDisplayInfo() { displays.Set(i, js_display); } - MonitorController* monitor_controller = - ash::Shell::GetInstance()->monitor_controller(); + DisplayController* display_controller = + ash::Shell::GetInstance()->display_controller(); base::FundamentalValue layout(static_cast( - monitor_controller->secondary_display_layout())); + display_controller->secondary_display_layout())); web_ui()->CallJavascriptFunction( "options.DisplayOptions.setDisplayInfo", @@ -148,11 +148,11 @@ void DisplayOptionsHandler::HandleDisplayLayout(const base::ListValue* args) { LOG(ERROR) << "Invalid parameter"; return; } - DCHECK_LE(MonitorController::TOP, layout); - DCHECK_GE(MonitorController::LEFT, layout); + DCHECK_LE(DisplayController::TOP, layout); + DCHECK_GE(DisplayController::LEFT, layout); - ash::Shell::GetInstance()->monitor_controller()->SetSecondaryDisplayLayout( - static_cast(layout)); + ash::Shell::GetInstance()->display_controller()->SetSecondaryDisplayLayout( + static_cast(layout)); SendDisplayInfo(); } diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index dff9498..9870c9e 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -103,8 +103,8 @@ 'dbus/sms_client.h', 'dbus/update_engine_client.cc', 'dbus/update_engine_client.h', - 'monitor/output_configurator.cc', - 'monitor/output_configurator.h', + 'display/output_configurator.cc', + 'display/output_configurator.h', 'network/network_sms_handler.cc', 'network/network_sms_handler.h', ], diff --git a/chromeos/display/DEPS b/chromeos/display/DEPS new file mode 100644 index 0000000..d6abdda --- /dev/null +++ b/chromeos/display/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+dbus", +] diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc new file mode 100644 index 0000000..4543a52 --- /dev/null +++ b/chromeos/display/output_configurator.cc @@ -0,0 +1,804 @@ +// 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 "chromeos/display/output_configurator.h" + +#include +#include +#include + +// Xlib defines Status as int which causes our include of dbus/bus.h to fail +// when it tries to name an enum Status. Thus, we need to undefine it (note +// that this will cause a problem if code needs to use the Status type). +// RootWindow causes similar problems in that there is a Chromium type with that +// name. +#undef Status +#undef RootWindow + +#include "base/chromeos/chromeos_version.h" +#include "base/logging.h" +#include "base/message_pump_aurax11.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "dbus/bus.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "dbus/object_path.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +namespace { +// DPI measurements. +const float kMmInInch = 25.4; +const float kDpi96 = 96.0; +const float kPixelsToMmScale = kMmInInch / kDpi96; + +// The DPI threshold to detech high density screen. +// Higher DPI than this will use device_scale_factor=2 +// Should be kept in sync with display_change_observer_x11.cc +const unsigned int kHighDensityDIPThreshold = 160; + +// Prefixes for the built-in displays. +const char kInternal_LVDS[] = "LVDS"; +const char kInternal_eDP[] = "eDP"; + +// Gap between screens so cursor at bottom of active display doesn't partially +// appear on top of inactive display. Higher numbers guard against larger +// cursors, but also waste more memory. We will double this gap for screens +// with a device_scale_factor of 2. While this gap will not guard against all +// possible cursors in X, it should handle the ones we actually use. See +// crbug.com/130188 +const int kVerticalGap = 30; + +// TODO: Determine if we need to organize modes in a way which provides better +// than O(n) lookup time. In many call sites, for example, the "next" mode is +// typically what we are looking for so using this helper might be too +// expensive. +static XRRModeInfo* ModeInfoForID(XRRScreenResources* screen, RRMode modeID) { + XRRModeInfo* result = NULL; + for (int i = 0; (i < screen->nmode) && (result == NULL); i++) + if (modeID == screen->modes[i].id) + result = &screen->modes[i]; + + // We can't fail to find a mode referenced from the same screen. + CHECK(result != NULL); + return result; +} + +// Identifies the modes which will be used by the respective outputs when in a +// mirror mode. This means that the two modes will have the same resolution. +// The RROutput IDs |one| and |two| are used to look up the modes and +// |out_one_mode| and |out_two_mode| are the out-parameters for the respective +// modes. +// Returns false if it fails to find a compatible set of modes. +static bool FindMirrorModeForOutputs(Display* display, + XRRScreenResources* screen, + RROutput one, + RROutput two, + RRMode* out_one_mode, + RRMode* out_two_mode) { + XRROutputInfo* primary = XRRGetOutputInfo(display, screen, one); + XRROutputInfo* secondary = XRRGetOutputInfo(display, screen, two); + + int one_index = 0; + int two_index = 0; + bool found = false; + while (!found && + (one_index < primary->nmode) && + (two_index < secondary->nmode)) { + RRMode one_id = primary->modes[one_index]; + RRMode two_id = secondary->modes[two_index]; + XRRModeInfo* one_mode = ModeInfoForID(screen, one_id); + XRRModeInfo* two_mode = ModeInfoForID(screen, two_id); + int one_width = one_mode->width; + int one_height = one_mode->height; + int two_width = two_mode->width; + int two_height = two_mode->height; + if ((one_width == two_width) && (one_height == two_height)) { + *out_one_mode = one_id; + *out_two_mode = two_id; + found = true; + } else { + // The sort order of the modes is NOT by mode area but is sorted by width, + // then by height within each like width. + if (one_width > two_width) { + one_index += 1; + } else if (one_width < two_width) { + two_index += 1; + } else { + if (one_height > two_height) { + one_index += 1; + } else { + two_index += 1; + } + } + } + } + XRRFreeOutputInfo(primary); + XRRFreeOutputInfo(secondary); + return found; +} + +// A helper to call XRRSetCrtcConfig with the given options but some of our +// default output count and rotation arguments. +static void ConfigureCrtc(Display *display, + XRRScreenResources* screen, + RRCrtc crtc, + int x, + int y, + RRMode mode, + RROutput output) { + const Rotation kRotate = RR_Rotate_0; + RROutput* outputs = NULL; + int num_outputs = 0; + + // Check the output and mode argument - if either are None, we should disable. + if ((output != None) && (mode != None)) { + outputs = &output; + num_outputs = 1; + } + + XRRSetCrtcConfig(display, + screen, + crtc, + CurrentTime, + x, + y, + mode, + kRotate, + outputs, + num_outputs); + if (num_outputs == 1) { + // We are enabling a display so make sure it is turned on. + CHECK(DPMSEnable(display)); + CHECK(DPMSForceLevel(display, DPMSModeOn)); + } +} + +// Called to set the frame buffer (underling XRR "screen") size. Has a +// side-effect of disabling all CRTCs. +static void CreateFrameBuffer(Display* display, + XRRScreenResources* screen, + Window window, + int width, + int height) { + // Note that setting the screen size fails if any CRTCs are currently + // pointing into it so disable them all. + for (int i = 0; i < screen->ncrtc; ++i) { + const int x = 0; + const int y = 0; + const RRMode kMode = None; + const RROutput kOutput = None; + + ConfigureCrtc(display, + screen, + screen->crtcs[i], + x, + y, + kMode, + kOutput); + } + int mm_width = width * kPixelsToMmScale; + int mm_height = height * kPixelsToMmScale; + XRRSetScreenSize(display, window, width, height, mm_width, mm_height); +} + +// A helper to get the current CRTC, Mode, and height for a given output. This +// is read from the XRandR configuration and not any of our caches. +static void GetOutputConfiguration(Display* display, + XRRScreenResources* screen, + RROutput output, + RRCrtc* crtc, + RRMode* mode, + int* height) { + XRROutputInfo* output_info = XRRGetOutputInfo(display, screen, output); + CHECK(output_info != NULL); + *crtc = output_info->crtc; + XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display, screen, *crtc); + if (crtc_info != NULL) { + *mode = crtc_info->mode; + *height = crtc_info->height; + XRRFreeCrtcInfo(crtc_info); + } + XRRFreeOutputInfo(output_info); +} + +// A helper to determine the device_scale_factor given pixel width and mm_width. +// This currently only reports two scale factors (1.0 and 2.0) +static float ComputeDeviceScaleFactor(unsigned int width, + unsigned long mm_width) { + float device_scale_factor = 1.0f; + if (mm_width > 0 && (kMmInInch * width / mm_width) > kHighDensityDIPThreshold) + device_scale_factor = 2.0f; + return device_scale_factor; +} + +} // namespace + +bool OutputConfigurator::TryRecacheOutputs(Display* display, + XRRScreenResources* screen) { + bool outputs_did_change = false; + int previous_connected_count = 0; + int new_connected_count = 0; + + if (output_count_ != screen->noutput) { + outputs_did_change = true; + } else { + // The outputs might have changed so compare the connected states in the + // screen to our existing cache. + for (int i = 0; (i < output_count_) && !outputs_did_change; ++i) { + RROutput thisID = screen->outputs[i]; + XRROutputInfo* output = XRRGetOutputInfo(display, screen, thisID); + bool now_connected = (RR_Connected == output->connection); + outputs_did_change = (now_connected != output_cache_[i].is_connected); + XRRFreeOutputInfo(output); + + if (output_cache_[i].is_connected) + previous_connected_count += 1; + if (now_connected) + new_connected_count += 1; + } + } + + if (outputs_did_change) { + // We now know that we need to recache so free and re-alloc the buffer. + output_count_ = screen->noutput; + if (output_count_ == 0) { + output_cache_.reset(NULL); + } else { + // Ideally, this would be allocated inline in the OutputConfigurator + // instance since we support at most 2 connected outputs but this dynamic + // allocation was specifically requested. + output_cache_.reset(new CachedOutputDescription[output_count_]); + } + + // TODO: This approach to finding CRTCs only supports two. Expand on this. + RRCrtc used_crtc = None; + primary_output_index_ = -1; + secondary_output_index_ = -1; + + for (int i = 0; i < output_count_; ++i) { + RROutput this_id = screen->outputs[i]; + XRROutputInfo* output = XRRGetOutputInfo(display, screen, this_id); + bool is_connected = (RR_Connected == output->connection); + RRCrtc crtc = None; + RRMode ideal_mode = None; + int x = 0; + int y = 0; + unsigned long mm_width = output->mm_width; + unsigned long mm_height = output->mm_height; + bool is_internal = false; + + if (is_connected) { + for (int j = 0; (j < output->ncrtc) && (None == crtc); ++j) { + RRCrtc possible = output->crtcs[j]; + if (possible != used_crtc) { + crtc = possible; + used_crtc = possible; + } + } + + const char* name = output->name; + is_internal = + (strncmp(kInternal_LVDS, + name, + arraysize(kInternal_LVDS) - 1) == 0) || + (strncmp(kInternal_eDP, + name, + arraysize(kInternal_eDP) - 1) == 0); + if (output->nmode > 0) + ideal_mode = output->modes[0]; + + if (crtc != None) { + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(display, screen, crtc); + x = crtcInfo->x; + y = crtcInfo->y; + XRRFreeCrtcInfo(crtcInfo); + } + + // Save this for later mirror mode detection. + if (primary_output_index_ == -1) + primary_output_index_ = i; + else if (secondary_output_index_ == -1) + secondary_output_index_ = i; + } + XRRFreeOutputInfo(output); + + // Now save the cached state for this output (we will default to mirror + // disabled and detect that after we have identified the first two + // connected outputs). + VLOG(1) << "Recache output index: " << i + << ", output id: " << this_id + << ", crtc id: " << crtc + << ", ideal mode id: " << ideal_mode + << ", x: " << x + << ", y: " << y + << ", is connected: " << is_connected + << ", is_internal: " << is_internal + << ", mm_width: " << mm_width + << ", mm_height: " << mm_height; + output_cache_[i].output = this_id; + output_cache_[i].crtc = crtc; + output_cache_[i].mirror_mode = None; + output_cache_[i].ideal_mode = ideal_mode; + output_cache_[i].x = x; + output_cache_[i].y = y; + output_cache_[i].is_connected = is_connected; + output_cache_[i].is_powered_on = true; + output_cache_[i].is_internal = is_internal; + output_cache_[i].mm_width = mm_width; + output_cache_[i].mm_height = mm_height; + } + + // Now, detect the mirror modes if we have two connected outputs. + if ((primary_output_index_ != -1) && (secondary_output_index_ != -1)) { + mirror_supported_ = FindMirrorModeForOutputs( + display, + screen, + output_cache_[primary_output_index_].output, + output_cache_[secondary_output_index_].output, + &output_cache_[primary_output_index_].mirror_mode, + &output_cache_[secondary_output_index_].mirror_mode); + + RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; + RRMode second_mode = output_cache_[secondary_output_index_].mirror_mode; + VLOG(1) << "Mirror mode supported " << mirror_supported_ + << " primary " << primary_mode + << " secondary " << second_mode; + } + } + return outputs_did_change; +} + +OutputConfigurator::OutputConfigurator() + : is_running_on_chrome_os_(base::chromeos::IsRunningOnChromeOS()), + output_count_(0), + output_cache_(NULL), + mirror_supported_(false), + primary_output_index_(-1), + secondary_output_index_(-1), + xrandr_event_base_(0), + output_state_(STATE_INVALID) { + if (is_running_on_chrome_os_) { + // Send the signal to powerd to tell it that we will take over output + // control. + // Note that this can be removed once the legacy powerd support is removed. + chromeos::DBusThreadManager* manager = chromeos::DBusThreadManager::Get(); + dbus::Bus* bus = manager->GetSystemBus(); + dbus::ExportedObject* remote_object = bus->GetExportedObject( + dbus::ObjectPath(power_manager::kPowerManagerServicePath)); + dbus::Signal signal(power_manager::kPowerManagerInterface, + power_manager::kUseNewMonitorConfigSignal); + CHECK(signal.raw_message() != NULL); + remote_object->SendSignal(&signal); + + // Cache the initial output state. + Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); + CHECK(display != NULL); + XGrabServer(display); + Window window = DefaultRootWindow(display); + XRRScreenResources* screen = XRRGetScreenResources(display, window); + CHECK(screen != NULL); + bool did_detect_outputs = TryRecacheOutputs(display, screen); + CHECK(did_detect_outputs); + State current_state = InferCurrentState(display, screen); + if (current_state == STATE_INVALID) { + // Unknown state. Transition into the default state. + State state = GetDefaultState(); + UpdateCacheAndXrandrToState(display, screen, window, state); + } else { + // This is a valid state so just save it to |output_state_|. + output_state_ = current_state; + } + // Find xrandr_event_base_ since we need it to interpret events, later. + int error_base_ignored = 0; + XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored); + // Relinquish X resources. + XRRFreeScreenResources(screen); + XUngrabServer(display); + CheckIsProjectingAndNotify(); + } +} + +OutputConfigurator::~OutputConfigurator() { +} + +void OutputConfigurator::UpdateCacheAndXrandrToState( + Display* display, + XRRScreenResources* screen, + Window window, + State new_state) { + // Default rules: + // - single display = rebuild framebuffer and set to ideal_mode. + // - multi display = rebuild framebuffer and set to mirror_mode. + + // First, calculate the width and height of the framebuffer (we could retain + // the existing buffer, if it isn't resizing, but that causes an odd display + // state where the CRTCs are repositioned over the root windows before Chrome + // can move them). It is a feature worth considering, though, and wouldn't + // be difficult to implement (just check the current framebuffer size before + // changing it). + int width = 0; + int height = 0; + int primary_height = 0; + int secondary_height = 0; + int vertical_gap = 0; + if (new_state == STATE_SINGLE) { + CHECK_NE(-1, primary_output_index_); + + XRRModeInfo* ideal_mode = ModeInfoForID( + screen, + output_cache_[primary_output_index_].ideal_mode); + width = ideal_mode->width; + height = ideal_mode->height; + } else if (new_state == STATE_DUAL_MIRROR) { + CHECK_NE(-1, primary_output_index_); + CHECK_NE(-1, secondary_output_index_); + + XRRModeInfo* mirror_mode = ModeInfoForID( + screen, + output_cache_[primary_output_index_].mirror_mode); + width = mirror_mode->width; + height = mirror_mode->height; + } else if ((new_state == STATE_DUAL_PRIMARY_ONLY) || + (new_state == STATE_DUAL_SECONDARY_ONLY)) { + CHECK_NE(-1, primary_output_index_); + CHECK_NE(-1, secondary_output_index_); + + XRRModeInfo* one_ideal = ModeInfoForID( + screen, + output_cache_[primary_output_index_].ideal_mode); + XRRModeInfo* two_ideal = ModeInfoForID( + screen, + output_cache_[secondary_output_index_].ideal_mode); + + // Compute the device scale factor for the topmost display. We only need + // to take this device's scale factor into account as we are creating a gap + // to avoid the cursor drawing onto the second (unused) display when the + // cursor is near the bottom of the topmost display. + float top_scale_factor; + if (new_state == STATE_DUAL_PRIMARY_ONLY) { + top_scale_factor = ComputeDeviceScaleFactor(one_ideal->width, + output_cache_[primary_output_index_].mm_width); + } else { + top_scale_factor = ComputeDeviceScaleFactor(two_ideal->width, + output_cache_[secondary_output_index_].mm_width); + } + vertical_gap = kVerticalGap * top_scale_factor; + + width = std::max(one_ideal->width, two_ideal->width); + height = one_ideal->height + two_ideal->height + vertical_gap; + primary_height = one_ideal->height; + secondary_height = two_ideal->height; + } + CreateFrameBuffer(display, screen, window, width, height); + + // Now, tile the outputs appropriately. + const int x = 0; + const int y = 0; + switch (new_state) { + case STATE_SINGLE: + ConfigureCrtc(display, + screen, + output_cache_[primary_output_index_].crtc, + x, + y, + output_cache_[primary_output_index_].ideal_mode, + output_cache_[primary_output_index_].output); + break; + case STATE_DUAL_MIRROR: + case STATE_DUAL_PRIMARY_ONLY: + case STATE_DUAL_SECONDARY_ONLY: { + RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; + RRMode secondary_mode = + output_cache_[secondary_output_index_].mirror_mode; + int primary_y = y; + int secondary_y = y; + + if (new_state != STATE_DUAL_MIRROR) { + primary_mode = output_cache_[primary_output_index_].ideal_mode; + secondary_mode = output_cache_[secondary_output_index_].ideal_mode; + } + if (new_state == STATE_DUAL_PRIMARY_ONLY) + secondary_y = y + primary_height + vertical_gap; + if (new_state == STATE_DUAL_SECONDARY_ONLY) + primary_y = y + secondary_height + vertical_gap; + + ConfigureCrtc(display, + screen, + output_cache_[primary_output_index_].crtc, + x, + primary_y, + primary_mode, + output_cache_[primary_output_index_].output); + ConfigureCrtc(display, + screen, + output_cache_[secondary_output_index_].crtc, + x, + secondary_y, + secondary_mode, + output_cache_[secondary_output_index_].output); + } + break; + case STATE_HEADLESS: + // Do nothing. + break; + default: + NOTREACHED() << "Unhandled state " << new_state; + } + output_state_ = new_state; +} + +bool OutputConfigurator::RecacheAndUseDefaultState() { + Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); + CHECK(display != NULL); + XGrabServer(display); + Window window = DefaultRootWindow(display); + XRRScreenResources* screen = XRRGetScreenResources(display, window); + CHECK(screen != NULL); + + bool did_detect_change = TryRecacheOutputs(display, screen); + if (did_detect_change) { + State state = GetDefaultState(); + UpdateCacheAndXrandrToState(display, screen, window, state); + } + XRRFreeScreenResources(screen); + XUngrabServer(display); + return did_detect_change; +} + +State OutputConfigurator::GetDefaultState() const { + State state = STATE_HEADLESS; + if (-1 != primary_output_index_) { + if (-1 != secondary_output_index_) + state = mirror_supported_ ? STATE_DUAL_MIRROR : STATE_DUAL_PRIMARY_ONLY; + else + state = STATE_SINGLE; + } + return state; +} + +State OutputConfigurator::InferCurrentState(Display* display, + XRRScreenResources* screen) const { + // STATE_INVALID will be our default or "unknown" state. + State state = STATE_INVALID; + // First step: count the number of connected outputs. + if (secondary_output_index_ == -1) { + // No secondary display. + if (primary_output_index_ == -1) { + // No primary display implies HEADLESS. + state = STATE_HEADLESS; + } else { + // The common case of primary-only. + // The only sanity check we require in this case is that the current mode + // of the output's CRTC is the ideal mode we determined for it. + RRCrtc primary_crtc = None; + RRMode primary_mode = None; + int primary_height = 0; + GetOutputConfiguration(display, + screen, + output_cache_[primary_output_index_].output, + &primary_crtc, + &primary_mode, + &primary_height); + if (primary_mode == output_cache_[primary_output_index_].ideal_mode) + state = STATE_SINGLE; + } + } else { + // We have two displays attached so we need to look at their configuration. + // Note that, for simplicity, we will only detect the states that we would + // have used and will assume anything unexpected is INVALID (which should + // not happen in any expected usage scenario). + RRCrtc primary_crtc = None; + RRMode primary_mode = None; + int primary_height = 0; + GetOutputConfiguration(display, + screen, + output_cache_[primary_output_index_].output, + &primary_crtc, + &primary_mode, + &primary_height); + RRCrtc secondary_crtc = None; + RRMode secondary_mode = None; + int secondary_height = 0; + GetOutputConfiguration(display, + screen, + output_cache_[secondary_output_index_].output, + &secondary_crtc, + &secondary_mode, + &secondary_height); + // Make sure the CRTCs are matched to the expected outputs. + if ((output_cache_[primary_output_index_].crtc == primary_crtc) && + (output_cache_[secondary_output_index_].crtc == secondary_crtc)) { + // Check the mode matching: either both mirror or both ideal. + if ((output_cache_[primary_output_index_].mirror_mode == primary_mode) && + (output_cache_[secondary_output_index_].mirror_mode == + secondary_mode)) { + // We are already in mirror mode. + state = STATE_DUAL_MIRROR; + } else if ((output_cache_[primary_output_index_].ideal_mode == + primary_mode) && + (output_cache_[secondary_output_index_].ideal_mode == + secondary_mode)) { + // Both outputs are in their "ideal" mode so check their Y-offsets to + // see which "ideal" configuration this is. + if (primary_height == output_cache_[secondary_output_index_].y) { + // Secondary is tiled first. + state = STATE_DUAL_SECONDARY_ONLY; + } else if (secondary_height == output_cache_[primary_output_index_].y) { + // Primary is tiled first. + state = STATE_DUAL_PRIMARY_ONLY; + } + } + } + } + + return state; +} + +bool OutputConfigurator::CycleDisplayMode() { + VLOG(1) << "CycleDisplayMode"; + bool did_change = false; + if (is_running_on_chrome_os_) { + // Rules: + // - if there are 0 or 1 displays, do nothing and return false. + // - use y-coord of CRTCs to determine if we are mirror, primary-first, or + // secondary-first. The cycle order is: + // mirror->primary->secondary->mirror. + State new_state = STATE_INVALID; + switch (output_state_) { + case STATE_DUAL_MIRROR: + new_state = STATE_DUAL_PRIMARY_ONLY; + break; + case STATE_DUAL_PRIMARY_ONLY: + new_state = STATE_DUAL_SECONDARY_ONLY; + break; + case STATE_DUAL_SECONDARY_ONLY: + new_state = mirror_supported_ ? + STATE_DUAL_MIRROR : + STATE_DUAL_PRIMARY_ONLY; + break; + default: + // Do nothing - we aren't in a mode which we can rotate. + break; + } + if (STATE_INVALID != new_state) + did_change = SetDisplayMode(new_state); + } + return did_change; +} + +bool OutputConfigurator::ScreenPowerSet(bool power_on, bool all_displays) { + VLOG(1) << "OutputConfigurator::SetScreensOn " << power_on + << " all displays " << all_displays; + bool success = false; + if (is_running_on_chrome_os_) { + Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); + CHECK(display != NULL); + XGrabServer(display); + Window window = DefaultRootWindow(display); + XRRScreenResources* screen = XRRGetScreenResources(display, window); + CHECK(screen != NULL); + + // Set the CRTCs based on whether we want to turn the power on or off and + // select the outputs to operate on by name or all_displays. + for (int i = 0; i < output_count_; ++i) { + if (all_displays || output_cache_[i].is_internal) { + const int x = output_cache_[i].x; + const int y = output_cache_[i].y; + RROutput output = output_cache_[i].output; + RRCrtc crtc = output_cache_[i].crtc; + RRMode mode = None; + if (power_on) { + mode = (STATE_DUAL_MIRROR == output_state_) ? + output_cache_[i].mirror_mode : + output_cache_[i].ideal_mode; + } + + VLOG(1) << "SET POWER crtc: " << crtc + << ", mode " << mode + << ", output " << output + << ", x " << x + << ", y " << y; + ConfigureCrtc(display, + screen, + crtc, + x, + y, + mode, + output); + output_cache_[i].is_powered_on = power_on; + success = true; + } + } + + // Force the DPMS on since the driver doesn't always detect that it should + // turn on. + if (power_on) { + CHECK(DPMSEnable(display)); + CHECK(DPMSForceLevel(display, DPMSModeOn)); + } + + XRRFreeScreenResources(screen); + XUngrabServer(display); + } + return success; +} + +bool OutputConfigurator::SetDisplayMode(State new_state) { + if (output_state_ == STATE_INVALID || + output_state_ == STATE_HEADLESS || + output_state_ == STATE_SINGLE) + return false; + + Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); + CHECK(display != NULL); + XGrabServer(display); + Window window = DefaultRootWindow(display); + XRRScreenResources* screen = XRRGetScreenResources(display, window); + CHECK(screen != NULL); + + UpdateCacheAndXrandrToState(display, + screen, + window, + new_state); + XRRFreeScreenResources(screen); + XUngrabServer(display); + return true; +} + +bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { + // Ignore this event if the Xrandr extension isn't supported. + if (is_running_on_chrome_os_ && + (event->type - xrandr_event_base_ == RRNotify)) { + XEvent* xevent = static_cast(event); + XRRNotifyEvent* notify_event = + reinterpret_cast(xevent); + if (notify_event->subtype == RRNotify_OutputChange) { + XRROutputChangeNotifyEvent* output_change_event = + reinterpret_cast(xevent); + if ((output_change_event->connection == RR_Connected) || + (output_change_event->connection == RR_Disconnected)) { + RecacheAndUseDefaultState(); + CheckIsProjectingAndNotify(); + } + // Ignore the case of RR_UnkownConnection. + } + } + return true; +} + +void OutputConfigurator::CheckIsProjectingAndNotify() { + // Determine if there is an "internal" output and how many outputs are + // connected. + bool has_internal_output = false; + int connected_output_count = 0; + for (int i = 0; i < output_count_; ++i) { + if (output_cache_[i].is_connected) { + connected_output_count += 1; + has_internal_output |= output_cache_[i].is_internal; + } + } + + // "Projecting" is defined as having more than 1 output connected while at + // least one of them is an internal output. + bool is_projecting = has_internal_output && (connected_output_count > 1); + chromeos::DBusThreadManager* manager = chromeos::DBusThreadManager::Get(); + dbus::Bus* bus = manager->GetSystemBus(); + dbus::ObjectProxy* power_manager_proxy = bus->GetObjectProxy( + power_manager::kPowerManagerServiceName, + dbus::ObjectPath(power_manager::kPowerManagerServicePath)); + dbus::MethodCall method_call( + power_manager::kPowerManagerInterface, + power_manager::kSetIsProjectingMethod); + dbus::MessageWriter writer(&method_call); + writer.AppendBool(is_projecting); + power_manager_proxy->CallMethod( + &method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + dbus::ObjectProxy::EmptyResponseCallback()); +} + +} // namespace chromeos diff --git a/chromeos/display/output_configurator.h b/chromeos/display/output_configurator.h new file mode 100644 index 0000000..2b6d2d4 --- /dev/null +++ b/chromeos/display/output_configurator.h @@ -0,0 +1,165 @@ +// 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 CHROMEOS_DISPLAY_OUTPUT_CONFIGURATOR_H_ +#define CHROMEOS_DISPLAY_OUTPUT_CONFIGURATOR_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/event_types.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "chromeos/chromeos_export.h" + +// Forward declarations for Xlib and Xrandr. +// This is so unused X definitions don't pollute the namespace. +typedef unsigned long XID; +typedef XID Window; +typedef XID RROutput; +typedef XID RRCrtc; +typedef XID RRMode; + +struct _XRRScreenResources; +typedef _XRRScreenResources XRRScreenResources; + +namespace chromeos { + +// The information we need to cache from an output to implement operations such +// as power state but also to eliminate duplicate operations within a given +// action (determining which CRTC to use for a given output, for example). +struct CachedOutputDescription { + RROutput output; + RRCrtc crtc; + RRMode mirror_mode; + RRMode ideal_mode; + int x; + int y; + bool is_connected; + bool is_powered_on; + bool is_internal; + unsigned long mm_width; + unsigned long mm_height; +}; + +// Used to describe the state of a multi-display configuration. +enum State { + STATE_INVALID, + STATE_HEADLESS, + STATE_SINGLE, + STATE_DUAL_MIRROR, + STATE_DUAL_PRIMARY_ONLY, + STATE_DUAL_SECONDARY_ONLY, +}; + +// This class interacts directly with the underlying Xrandr API to manipulate +// CTRCs and Outputs. It will likely grow more state, over time, or expose +// Output info in other ways as more of the Chrome display code grows up around +// it. +class CHROMEOS_EXPORT OutputConfigurator : public MessageLoop::Dispatcher { + public: + OutputConfigurator(); + virtual ~OutputConfigurator(); + + State output_state() const { return output_state_; } + + // Called when the user hits ctrl-F4 to request a display mode change. + // This method should only return false if it was called in a single-head or + // headless mode. + bool CycleDisplayMode(); + + // Called when powerd notifies us that some set of displays should be turned + // on or off. This requires enabling or disabling the CRTC associated with + // the display(s) in question so that the low power state is engaged. + bool ScreenPowerSet(bool power_on, bool all_displays); + + // Force switching the display mode to |new_state|. This method is used when + // the user explicitly changes the display mode in the options UI. Returns + // false if it was called in a single-head or headless mode. + bool SetDisplayMode(State new_state); + + // Called when an RRNotify event is received. The implementation is + // interested in the cases of RRNotify events which correspond to output + // add/remove events. Note that Output add/remove events are sent in response + // to our own reconfiguration operations so spurious events are common. + // Spurious events will have no effect. + virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; + + private: + // Updates |output_count_|, |output_cache_|, |mirror_supported_|, + // |primary_output_index_|, and |secondary_output_index_| with new data. + // Returns true if the update succeeded or false if it was skipped since no + // actual change was observed. + // Note that |output_state_| is not updated by this call. + bool TryRecacheOutputs(Display* display, XRRScreenResources* screen); + + // Uses the data stored in |output_cache_| and the given |new_state| to + // configure the Xrandr interface and then updates |output_state_| to reflect + // the new state. + void UpdateCacheAndXrandrToState(Display* display, + XRRScreenResources* screen, + Window window, + State new_state); + + // A helper to re-cache instance variable state and transition into the + // appropriate default state for the observed displays. + bool RecacheAndUseDefaultState(); + + // Checks the |primary_output_index_|, |secondary_output_index_|, and + // |mirror_supported_| to see how many displays are currently connected and + // returns the state which is most appropriate as a default state for those + // displays. + State GetDefaultState() const; + + // Called during start-up to determine what the current state of the displays + // appears to be, by investigating how the outputs compare to the data stored + // in |output_cache_|. Returns STATE_INVALID if the current display state + // doesn't match any supported state. |output_cache_| must be up-to-date with + // regards to the state of X or this method may return incorrect results. + State InferCurrentState(Display* display, XRRScreenResources* screen) const; + + // Scans the |output_cache_| to determine whether or not we are in a + // "projecting" state and then calls the DBus kSetIsProjectingMethod on powerd + // with the result. + void CheckIsProjectingAndNotify(); + + // This is detected by the constructor to determine whether or not we should + // be enabled. If we aren't running on ChromeOS, we can't assume that the + // Xrandr X11 extension is supported. + // If this flag is set to false, any attempts to change the output + // configuration to immediately fail without changing the state. + bool is_running_on_chrome_os_; + + // The number of outputs in the output_cache_ array. + int output_count_; + + // The list of cached output descriptions (|output_count_| elements long). + scoped_array output_cache_; + + // True if |output_cache_| describes a permutation of outputs which support a + // mirrored device mode. + bool mirror_supported_; + + // The index of the primary connected output in |output_cache_|. -1 if there + // is no primary output. This implies the machine currently has no outputs. + int primary_output_index_; + + // The index of the secondary connected output in |output_cache_|. -1 if + // there is no secondary output. This implies the machine currently has one + // output. + int secondary_output_index_; + + // The base of the event numbers used to represent XRandr events used in + // decoding events regarding output add/remove. + int xrandr_event_base_; + + // The display state as derived from the outputs observed in |output_cache_|. + // This is used for rotating display modes. + State output_state_; + + DISALLOW_COPY_AND_ASSIGN(OutputConfigurator); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DISPLAY_OUTPUT_CONFIGURATOR_H_ diff --git a/chromeos/monitor/DEPS b/chromeos/monitor/DEPS deleted file mode 100644 index d6abdda..0000000 --- a/chromeos/monitor/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+dbus", -] diff --git a/chromeos/monitor/output_configurator.cc b/chromeos/monitor/output_configurator.cc deleted file mode 100644 index 8e47f07..0000000 --- a/chromeos/monitor/output_configurator.cc +++ /dev/null @@ -1,804 +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 "chromeos/monitor/output_configurator.h" - -#include -#include -#include - -// Xlib defines Status as int which causes our include of dbus/bus.h to fail -// when it tries to name an enum Status. Thus, we need to undefine it (note -// that this will cause a problem if code needs to use the Status type). -// RootWindow causes similar problems in that there is a Chromium type with that -// name. -#undef Status -#undef RootWindow - -#include "base/chromeos/chromeos_version.h" -#include "base/logging.h" -#include "base/message_pump_aurax11.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "dbus/bus.h" -#include "dbus/exported_object.h" -#include "dbus/message.h" -#include "dbus/object_path.h" -#include "dbus/object_proxy.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { - -namespace { -// DPI measurements. -const float kMmInInch = 25.4; -const float kDpi96 = 96.0; -const float kPixelsToMmScale = kMmInInch / kDpi96; - -// The DPI threshold to detech high density screen. -// Higher DPI than this will use device_scale_factor=2 -// Should be kept in sync with monitor_change_observer_x11.cc -const unsigned int kHighDensityDIPThreshold = 160; - -// Prefixes for the built-in displays. -const char kInternal_LVDS[] = "LVDS"; -const char kInternal_eDP[] = "eDP"; - -// Gap between screens so cursor at bottom of active monitor doesn't partially -// appear on top of inactive monitor. Higher numbers guard against larger -// cursors, but also waste more memory. We will double this gap for screens -// with a device_scale_factor of 2. While this gap will not guard against all -// possible cursors in X, it should handle the ones we actually use. See -// crbug.com/130188 -const int kVerticalGap = 30; - -// TODO: Determine if we need to organize modes in a way which provides better -// than O(n) lookup time. In many call sites, for example, the "next" mode is -// typically what we are looking for so using this helper might be too -// expensive. -static XRRModeInfo* ModeInfoForID(XRRScreenResources* screen, RRMode modeID) { - XRRModeInfo* result = NULL; - for (int i = 0; (i < screen->nmode) && (result == NULL); i++) - if (modeID == screen->modes[i].id) - result = &screen->modes[i]; - - // We can't fail to find a mode referenced from the same screen. - CHECK(result != NULL); - return result; -} - -// Identifies the modes which will be used by the respective outputs when in a -// mirror mode. This means that the two modes will have the same resolution. -// The RROutput IDs |one| and |two| are used to look up the modes and -// |out_one_mode| and |out_two_mode| are the out-parameters for the respective -// modes. -// Returns false if it fails to find a compatible set of modes. -static bool FindMirrorModeForOutputs(Display* display, - XRRScreenResources* screen, - RROutput one, - RROutput two, - RRMode* out_one_mode, - RRMode* out_two_mode) { - XRROutputInfo* primary = XRRGetOutputInfo(display, screen, one); - XRROutputInfo* secondary = XRRGetOutputInfo(display, screen, two); - - int one_index = 0; - int two_index = 0; - bool found = false; - while (!found && - (one_index < primary->nmode) && - (two_index < secondary->nmode)) { - RRMode one_id = primary->modes[one_index]; - RRMode two_id = secondary->modes[two_index]; - XRRModeInfo* one_mode = ModeInfoForID(screen, one_id); - XRRModeInfo* two_mode = ModeInfoForID(screen, two_id); - int one_width = one_mode->width; - int one_height = one_mode->height; - int two_width = two_mode->width; - int two_height = two_mode->height; - if ((one_width == two_width) && (one_height == two_height)) { - *out_one_mode = one_id; - *out_two_mode = two_id; - found = true; - } else { - // The sort order of the modes is NOT by mode area but is sorted by width, - // then by height within each like width. - if (one_width > two_width) { - one_index += 1; - } else if (one_width < two_width) { - two_index += 1; - } else { - if (one_height > two_height) { - one_index += 1; - } else { - two_index += 1; - } - } - } - } - XRRFreeOutputInfo(primary); - XRRFreeOutputInfo(secondary); - return found; -} - -// A helper to call XRRSetCrtcConfig with the given options but some of our -// default output count and rotation arguments. -static void ConfigureCrtc(Display *display, - XRRScreenResources* screen, - RRCrtc crtc, - int x, - int y, - RRMode mode, - RROutput output) { - const Rotation kRotate = RR_Rotate_0; - RROutput* outputs = NULL; - int num_outputs = 0; - - // Check the output and mode argument - if either are None, we should disable. - if ((output != None) && (mode != None)) { - outputs = &output; - num_outputs = 1; - } - - XRRSetCrtcConfig(display, - screen, - crtc, - CurrentTime, - x, - y, - mode, - kRotate, - outputs, - num_outputs); - if (num_outputs == 1) { - // We are enabling a display so make sure it is turned on. - CHECK(DPMSEnable(display)); - CHECK(DPMSForceLevel(display, DPMSModeOn)); - } -} - -// Called to set the frame buffer (underling XRR "screen") size. Has a -// side-effect of disabling all CRTCs. -static void CreateFrameBuffer(Display* display, - XRRScreenResources* screen, - Window window, - int width, - int height) { - // Note that setting the screen size fails if any CRTCs are currently - // pointing into it so disable them all. - for (int i = 0; i < screen->ncrtc; ++i) { - const int x = 0; - const int y = 0; - const RRMode kMode = None; - const RROutput kOutput = None; - - ConfigureCrtc(display, - screen, - screen->crtcs[i], - x, - y, - kMode, - kOutput); - } - int mm_width = width * kPixelsToMmScale; - int mm_height = height * kPixelsToMmScale; - XRRSetScreenSize(display, window, width, height, mm_width, mm_height); -} - -// A helper to get the current CRTC, Mode, and height for a given output. This -// is read from the XRandR configuration and not any of our caches. -static void GetOutputConfiguration(Display* display, - XRRScreenResources* screen, - RROutput output, - RRCrtc* crtc, - RRMode* mode, - int* height) { - XRROutputInfo* output_info = XRRGetOutputInfo(display, screen, output); - CHECK(output_info != NULL); - *crtc = output_info->crtc; - XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display, screen, *crtc); - if (crtc_info != NULL) { - *mode = crtc_info->mode; - *height = crtc_info->height; - XRRFreeCrtcInfo(crtc_info); - } - XRRFreeOutputInfo(output_info); -} - -// A helper to determine the device_scale_factor given pixel width and mm_width. -// This currently only reports two scale factors (1.0 and 2.0) -static float ComputeDeviceScaleFactor(unsigned int width, - unsigned long mm_width) { - float device_scale_factor = 1.0f; - if (mm_width > 0 && (kMmInInch * width / mm_width) > kHighDensityDIPThreshold) - device_scale_factor = 2.0f; - return device_scale_factor; -} - -} // namespace - -bool OutputConfigurator::TryRecacheOutputs(Display* display, - XRRScreenResources* screen) { - bool outputs_did_change = false; - int previous_connected_count = 0; - int new_connected_count = 0; - - if (output_count_ != screen->noutput) { - outputs_did_change = true; - } else { - // The outputs might have changed so compare the connected states in the - // screen to our existing cache. - for (int i = 0; (i < output_count_) && !outputs_did_change; ++i) { - RROutput thisID = screen->outputs[i]; - XRROutputInfo* output = XRRGetOutputInfo(display, screen, thisID); - bool now_connected = (RR_Connected == output->connection); - outputs_did_change = (now_connected != output_cache_[i].is_connected); - XRRFreeOutputInfo(output); - - if (output_cache_[i].is_connected) - previous_connected_count += 1; - if (now_connected) - new_connected_count += 1; - } - } - - if (outputs_did_change) { - // We now know that we need to recache so free and re-alloc the buffer. - output_count_ = screen->noutput; - if (output_count_ == 0) { - output_cache_.reset(NULL); - } else { - // Ideally, this would be allocated inline in the OutputConfigurator - // instance since we support at most 2 connected outputs but this dynamic - // allocation was specifically requested. - output_cache_.reset(new CachedOutputDescription[output_count_]); - } - - // TODO: This approach to finding CRTCs only supports two. Expand on this. - RRCrtc used_crtc = None; - primary_output_index_ = -1; - secondary_output_index_ = -1; - - for (int i = 0; i < output_count_; ++i) { - RROutput this_id = screen->outputs[i]; - XRROutputInfo* output = XRRGetOutputInfo(display, screen, this_id); - bool is_connected = (RR_Connected == output->connection); - RRCrtc crtc = None; - RRMode ideal_mode = None; - int x = 0; - int y = 0; - unsigned long mm_width = output->mm_width; - unsigned long mm_height = output->mm_height; - bool is_internal = false; - - if (is_connected) { - for (int j = 0; (j < output->ncrtc) && (None == crtc); ++j) { - RRCrtc possible = output->crtcs[j]; - if (possible != used_crtc) { - crtc = possible; - used_crtc = possible; - } - } - - const char* name = output->name; - is_internal = - (strncmp(kInternal_LVDS, - name, - arraysize(kInternal_LVDS) - 1) == 0) || - (strncmp(kInternal_eDP, - name, - arraysize(kInternal_eDP) - 1) == 0); - if (output->nmode > 0) - ideal_mode = output->modes[0]; - - if (crtc != None) { - XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(display, screen, crtc); - x = crtcInfo->x; - y = crtcInfo->y; - XRRFreeCrtcInfo(crtcInfo); - } - - // Save this for later mirror mode detection. - if (primary_output_index_ == -1) - primary_output_index_ = i; - else if (secondary_output_index_ == -1) - secondary_output_index_ = i; - } - XRRFreeOutputInfo(output); - - // Now save the cached state for this output (we will default to mirror - // disabled and detect that after we have identified the first two - // connected outputs). - VLOG(1) << "Recache output index: " << i - << ", output id: " << this_id - << ", crtc id: " << crtc - << ", ideal mode id: " << ideal_mode - << ", x: " << x - << ", y: " << y - << ", is connected: " << is_connected - << ", is_internal: " << is_internal - << ", mm_width: " << mm_width - << ", mm_height: " << mm_height; - output_cache_[i].output = this_id; - output_cache_[i].crtc = crtc; - output_cache_[i].mirror_mode = None; - output_cache_[i].ideal_mode = ideal_mode; - output_cache_[i].x = x; - output_cache_[i].y = y; - output_cache_[i].is_connected = is_connected; - output_cache_[i].is_powered_on = true; - output_cache_[i].is_internal = is_internal; - output_cache_[i].mm_width = mm_width; - output_cache_[i].mm_height = mm_height; - } - - // Now, detect the mirror modes if we have two connected outputs. - if ((primary_output_index_ != -1) && (secondary_output_index_ != -1)) { - mirror_supported_ = FindMirrorModeForOutputs( - display, - screen, - output_cache_[primary_output_index_].output, - output_cache_[secondary_output_index_].output, - &output_cache_[primary_output_index_].mirror_mode, - &output_cache_[secondary_output_index_].mirror_mode); - - RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; - RRMode second_mode = output_cache_[secondary_output_index_].mirror_mode; - VLOG(1) << "Mirror mode supported " << mirror_supported_ - << " primary " << primary_mode - << " secondary " << second_mode; - } - } - return outputs_did_change; -} - -OutputConfigurator::OutputConfigurator() - : is_running_on_chrome_os_(base::chromeos::IsRunningOnChromeOS()), - output_count_(0), - output_cache_(NULL), - mirror_supported_(false), - primary_output_index_(-1), - secondary_output_index_(-1), - xrandr_event_base_(0), - output_state_(STATE_INVALID) { - if (is_running_on_chrome_os_) { - // Send the signal to powerd to tell it that we will take over output - // control. - // Note that this can be removed once the legacy powerd support is removed. - chromeos::DBusThreadManager* manager = chromeos::DBusThreadManager::Get(); - dbus::Bus* bus = manager->GetSystemBus(); - dbus::ExportedObject* remote_object = bus->GetExportedObject( - dbus::ObjectPath(power_manager::kPowerManagerServicePath)); - dbus::Signal signal(power_manager::kPowerManagerInterface, - power_manager::kUseNewMonitorConfigSignal); - CHECK(signal.raw_message() != NULL); - remote_object->SendSignal(&signal); - - // Cache the initial output state. - Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); - CHECK(display != NULL); - XGrabServer(display); - Window window = DefaultRootWindow(display); - XRRScreenResources* screen = XRRGetScreenResources(display, window); - CHECK(screen != NULL); - bool did_detect_outputs = TryRecacheOutputs(display, screen); - CHECK(did_detect_outputs); - State current_state = InferCurrentState(display, screen); - if (current_state == STATE_INVALID) { - // Unknown state. Transition into the default state. - State state = GetDefaultState(); - UpdateCacheAndXrandrToState(display, screen, window, state); - } else { - // This is a valid state so just save it to |output_state_|. - output_state_ = current_state; - } - // Find xrandr_event_base_ since we need it to interpret events, later. - int error_base_ignored = 0; - XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored); - // Relinquish X resources. - XRRFreeScreenResources(screen); - XUngrabServer(display); - CheckIsProjectingAndNotify(); - } -} - -OutputConfigurator::~OutputConfigurator() { -} - -void OutputConfigurator::UpdateCacheAndXrandrToState( - Display* display, - XRRScreenResources* screen, - Window window, - State new_state) { - // Default rules: - // - single display = rebuild framebuffer and set to ideal_mode. - // - multi display = rebuild framebuffer and set to mirror_mode. - - // First, calculate the width and height of the framebuffer (we could retain - // the existing buffer, if it isn't resizing, but that causes an odd display - // state where the CRTCs are repositioned over the root windows before Chrome - // can move them). It is a feature worth considering, though, and wouldn't - // be difficult to implement (just check the current framebuffer size before - // changing it). - int width = 0; - int height = 0; - int primary_height = 0; - int secondary_height = 0; - int vertical_gap = 0; - if (new_state == STATE_SINGLE) { - CHECK_NE(-1, primary_output_index_); - - XRRModeInfo* ideal_mode = ModeInfoForID( - screen, - output_cache_[primary_output_index_].ideal_mode); - width = ideal_mode->width; - height = ideal_mode->height; - } else if (new_state == STATE_DUAL_MIRROR) { - CHECK_NE(-1, primary_output_index_); - CHECK_NE(-1, secondary_output_index_); - - XRRModeInfo* mirror_mode = ModeInfoForID( - screen, - output_cache_[primary_output_index_].mirror_mode); - width = mirror_mode->width; - height = mirror_mode->height; - } else if ((new_state == STATE_DUAL_PRIMARY_ONLY) || - (new_state == STATE_DUAL_SECONDARY_ONLY)) { - CHECK_NE(-1, primary_output_index_); - CHECK_NE(-1, secondary_output_index_); - - XRRModeInfo* one_ideal = ModeInfoForID( - screen, - output_cache_[primary_output_index_].ideal_mode); - XRRModeInfo* two_ideal = ModeInfoForID( - screen, - output_cache_[secondary_output_index_].ideal_mode); - - // Compute the device scale factor for the topmost display. We only need - // to take this device's scale factor into account as we are creating a gap - // to avoid the cursor drawing onto the second (unused) display when the - // cursor is near the bottom of the topmost display. - float top_scale_factor; - if (new_state == STATE_DUAL_PRIMARY_ONLY) { - top_scale_factor = ComputeDeviceScaleFactor(one_ideal->width, - output_cache_[primary_output_index_].mm_width); - } else { - top_scale_factor = ComputeDeviceScaleFactor(two_ideal->width, - output_cache_[secondary_output_index_].mm_width); - } - vertical_gap = kVerticalGap * top_scale_factor; - - width = std::max(one_ideal->width, two_ideal->width); - height = one_ideal->height + two_ideal->height + vertical_gap; - primary_height = one_ideal->height; - secondary_height = two_ideal->height; - } - CreateFrameBuffer(display, screen, window, width, height); - - // Now, tile the outputs appropriately. - const int x = 0; - const int y = 0; - switch (new_state) { - case STATE_SINGLE: - ConfigureCrtc(display, - screen, - output_cache_[primary_output_index_].crtc, - x, - y, - output_cache_[primary_output_index_].ideal_mode, - output_cache_[primary_output_index_].output); - break; - case STATE_DUAL_MIRROR: - case STATE_DUAL_PRIMARY_ONLY: - case STATE_DUAL_SECONDARY_ONLY: { - RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; - RRMode secondary_mode = - output_cache_[secondary_output_index_].mirror_mode; - int primary_y = y; - int secondary_y = y; - - if (new_state != STATE_DUAL_MIRROR) { - primary_mode = output_cache_[primary_output_index_].ideal_mode; - secondary_mode = output_cache_[secondary_output_index_].ideal_mode; - } - if (new_state == STATE_DUAL_PRIMARY_ONLY) - secondary_y = y + primary_height + vertical_gap; - if (new_state == STATE_DUAL_SECONDARY_ONLY) - primary_y = y + secondary_height + vertical_gap; - - ConfigureCrtc(display, - screen, - output_cache_[primary_output_index_].crtc, - x, - primary_y, - primary_mode, - output_cache_[primary_output_index_].output); - ConfigureCrtc(display, - screen, - output_cache_[secondary_output_index_].crtc, - x, - secondary_y, - secondary_mode, - output_cache_[secondary_output_index_].output); - } - break; - case STATE_HEADLESS: - // Do nothing. - break; - default: - NOTREACHED() << "Unhandled state " << new_state; - } - output_state_ = new_state; -} - -bool OutputConfigurator::RecacheAndUseDefaultState() { - Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); - CHECK(display != NULL); - XGrabServer(display); - Window window = DefaultRootWindow(display); - XRRScreenResources* screen = XRRGetScreenResources(display, window); - CHECK(screen != NULL); - - bool did_detect_change = TryRecacheOutputs(display, screen); - if (did_detect_change) { - State state = GetDefaultState(); - UpdateCacheAndXrandrToState(display, screen, window, state); - } - XRRFreeScreenResources(screen); - XUngrabServer(display); - return did_detect_change; -} - -State OutputConfigurator::GetDefaultState() const { - State state = STATE_HEADLESS; - if (-1 != primary_output_index_) { - if (-1 != secondary_output_index_) - state = mirror_supported_ ? STATE_DUAL_MIRROR : STATE_DUAL_PRIMARY_ONLY; - else - state = STATE_SINGLE; - } - return state; -} - -State OutputConfigurator::InferCurrentState(Display* display, - XRRScreenResources* screen) const { - // STATE_INVALID will be our default or "unknown" state. - State state = STATE_INVALID; - // First step: count the number of connected outputs. - if (secondary_output_index_ == -1) { - // No secondary display. - if (primary_output_index_ == -1) { - // No primary display implies HEADLESS. - state = STATE_HEADLESS; - } else { - // The common case of primary-only. - // The only sanity check we require in this case is that the current mode - // of the output's CRTC is the ideal mode we determined for it. - RRCrtc primary_crtc = None; - RRMode primary_mode = None; - int primary_height = 0; - GetOutputConfiguration(display, - screen, - output_cache_[primary_output_index_].output, - &primary_crtc, - &primary_mode, - &primary_height); - if (primary_mode == output_cache_[primary_output_index_].ideal_mode) - state = STATE_SINGLE; - } - } else { - // We have two displays attached so we need to look at their configuration. - // Note that, for simplicity, we will only detect the states that we would - // have used and will assume anything unexpected is INVALID (which should - // not happen in any expected usage scenario). - RRCrtc primary_crtc = None; - RRMode primary_mode = None; - int primary_height = 0; - GetOutputConfiguration(display, - screen, - output_cache_[primary_output_index_].output, - &primary_crtc, - &primary_mode, - &primary_height); - RRCrtc secondary_crtc = None; - RRMode secondary_mode = None; - int secondary_height = 0; - GetOutputConfiguration(display, - screen, - output_cache_[secondary_output_index_].output, - &secondary_crtc, - &secondary_mode, - &secondary_height); - // Make sure the CRTCs are matched to the expected outputs. - if ((output_cache_[primary_output_index_].crtc == primary_crtc) && - (output_cache_[secondary_output_index_].crtc == secondary_crtc)) { - // Check the mode matching: either both mirror or both ideal. - if ((output_cache_[primary_output_index_].mirror_mode == primary_mode) && - (output_cache_[secondary_output_index_].mirror_mode == - secondary_mode)) { - // We are already in mirror mode. - state = STATE_DUAL_MIRROR; - } else if ((output_cache_[primary_output_index_].ideal_mode == - primary_mode) && - (output_cache_[secondary_output_index_].ideal_mode == - secondary_mode)) { - // Both outputs are in their "ideal" mode so check their Y-offsets to - // see which "ideal" configuration this is. - if (primary_height == output_cache_[secondary_output_index_].y) { - // Secondary is tiled first. - state = STATE_DUAL_SECONDARY_ONLY; - } else if (secondary_height == output_cache_[primary_output_index_].y) { - // Primary is tiled first. - state = STATE_DUAL_PRIMARY_ONLY; - } - } - } - } - - return state; -} - -bool OutputConfigurator::CycleDisplayMode() { - VLOG(1) << "CycleDisplayMode"; - bool did_change = false; - if (is_running_on_chrome_os_) { - // Rules: - // - if there are 0 or 1 displays, do nothing and return false. - // - use y-coord of CRTCs to determine if we are mirror, primary-first, or - // secondary-first. The cycle order is: - // mirror->primary->secondary->mirror. - State new_state = STATE_INVALID; - switch (output_state_) { - case STATE_DUAL_MIRROR: - new_state = STATE_DUAL_PRIMARY_ONLY; - break; - case STATE_DUAL_PRIMARY_ONLY: - new_state = STATE_DUAL_SECONDARY_ONLY; - break; - case STATE_DUAL_SECONDARY_ONLY: - new_state = mirror_supported_ ? - STATE_DUAL_MIRROR : - STATE_DUAL_PRIMARY_ONLY; - break; - default: - // Do nothing - we aren't in a mode which we can rotate. - break; - } - if (STATE_INVALID != new_state) - did_change = SetDisplayMode(new_state); - } - return did_change; -} - -bool OutputConfigurator::ScreenPowerSet(bool power_on, bool all_displays) { - VLOG(1) << "OutputConfigurator::SetScreensOn " << power_on - << " all displays " << all_displays; - bool success = false; - if (is_running_on_chrome_os_) { - Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); - CHECK(display != NULL); - XGrabServer(display); - Window window = DefaultRootWindow(display); - XRRScreenResources* screen = XRRGetScreenResources(display, window); - CHECK(screen != NULL); - - // Set the CRTCs based on whether we want to turn the power on or off and - // select the outputs to operate on by name or all_displays. - for (int i = 0; i < output_count_; ++i) { - if (all_displays || output_cache_[i].is_internal) { - const int x = output_cache_[i].x; - const int y = output_cache_[i].y; - RROutput output = output_cache_[i].output; - RRCrtc crtc = output_cache_[i].crtc; - RRMode mode = None; - if (power_on) { - mode = (STATE_DUAL_MIRROR == output_state_) ? - output_cache_[i].mirror_mode : - output_cache_[i].ideal_mode; - } - - VLOG(1) << "SET POWER crtc: " << crtc - << ", mode " << mode - << ", output " << output - << ", x " << x - << ", y " << y; - ConfigureCrtc(display, - screen, - crtc, - x, - y, - mode, - output); - output_cache_[i].is_powered_on = power_on; - success = true; - } - } - - // Force the DPMS on since the driver doesn't always detect that it should - // turn on. - if (power_on) { - CHECK(DPMSEnable(display)); - CHECK(DPMSForceLevel(display, DPMSModeOn)); - } - - XRRFreeScreenResources(screen); - XUngrabServer(display); - } - return success; -} - -bool OutputConfigurator::SetDisplayMode(State new_state) { - if (output_state_ == STATE_INVALID || - output_state_ == STATE_HEADLESS || - output_state_ == STATE_SINGLE) - return false; - - Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); - CHECK(display != NULL); - XGrabServer(display); - Window window = DefaultRootWindow(display); - XRRScreenResources* screen = XRRGetScreenResources(display, window); - CHECK(screen != NULL); - - UpdateCacheAndXrandrToState(display, - screen, - window, - new_state); - XRRFreeScreenResources(screen); - XUngrabServer(display); - return true; -} - -bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { - // Ignore this event if the Xrandr extension isn't supported. - if (is_running_on_chrome_os_ && - (event->type - xrandr_event_base_ == RRNotify)) { - XEvent* xevent = static_cast(event); - XRRNotifyEvent* notify_event = - reinterpret_cast(xevent); - if (notify_event->subtype == RRNotify_OutputChange) { - XRROutputChangeNotifyEvent* output_change_event = - reinterpret_cast(xevent); - if ((output_change_event->connection == RR_Connected) || - (output_change_event->connection == RR_Disconnected)) { - RecacheAndUseDefaultState(); - CheckIsProjectingAndNotify(); - } - // Ignore the case of RR_UnkownConnection. - } - } - return true; -} - -void OutputConfigurator::CheckIsProjectingAndNotify() { - // Determine if there is an "internal" output and how many outputs are - // connected. - bool has_internal_output = false; - int connected_output_count = 0; - for (int i = 0; i < output_count_; ++i) { - if (output_cache_[i].is_connected) { - connected_output_count += 1; - has_internal_output |= output_cache_[i].is_internal; - } - } - - // "Projecting" is defined as having more than 1 output connected while at - // least one of them is an internal output. - bool is_projecting = has_internal_output && (connected_output_count > 1); - chromeos::DBusThreadManager* manager = chromeos::DBusThreadManager::Get(); - dbus::Bus* bus = manager->GetSystemBus(); - dbus::ObjectProxy* power_manager_proxy = bus->GetObjectProxy( - power_manager::kPowerManagerServiceName, - dbus::ObjectPath(power_manager::kPowerManagerServicePath)); - dbus::MethodCall method_call( - power_manager::kPowerManagerInterface, - power_manager::kSetIsProjectingMethod); - dbus::MessageWriter writer(&method_call); - writer.AppendBool(is_projecting); - power_manager_proxy->CallMethod( - &method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - dbus::ObjectProxy::EmptyResponseCallback()); -} - -} // namespace chromeos diff --git a/chromeos/monitor/output_configurator.h b/chromeos/monitor/output_configurator.h deleted file mode 100644 index b98bcb4..0000000 --- a/chromeos/monitor/output_configurator.h +++ /dev/null @@ -1,165 +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 CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ -#define CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/event_types.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "chromeos/chromeos_export.h" - -// Forward declarations for Xlib and Xrandr. -// This is so unused X definitions don't pollute the namespace. -typedef unsigned long XID; -typedef XID Window; -typedef XID RROutput; -typedef XID RRCrtc; -typedef XID RRMode; - -struct _XRRScreenResources; -typedef _XRRScreenResources XRRScreenResources; - -namespace chromeos { - -// The information we need to cache from an output to implement operations such -// as power state but also to eliminate duplicate operations within a given -// action (determining which CRTC to use for a given output, for example). -struct CachedOutputDescription { - RROutput output; - RRCrtc crtc; - RRMode mirror_mode; - RRMode ideal_mode; - int x; - int y; - bool is_connected; - bool is_powered_on; - bool is_internal; - unsigned long mm_width; - unsigned long mm_height; -}; - -// Used to describe the state of a multi-monitor configuration. -enum State { - STATE_INVALID, - STATE_HEADLESS, - STATE_SINGLE, - STATE_DUAL_MIRROR, - STATE_DUAL_PRIMARY_ONLY, - STATE_DUAL_SECONDARY_ONLY, -}; - -// This class interacts directly with the underlying Xrandr API to manipulate -// CTRCs and Outputs. It will likely grow more state, over time, or expose -// Output info in other ways as more of the Chrome display code grows up around -// it. -class CHROMEOS_EXPORT OutputConfigurator : public MessageLoop::Dispatcher { - public: - OutputConfigurator(); - virtual ~OutputConfigurator(); - - State output_state() const { return output_state_; } - - // Called when the user hits ctrl-F4 to request a display mode change. - // This method should only return false if it was called in a single-head or - // headless mode. - bool CycleDisplayMode(); - - // Called when powerd notifies us that some set of displays should be turned - // on or off. This requires enabling or disabling the CRTC associated with - // the display(s) in question so that the low power state is engaged. - bool ScreenPowerSet(bool power_on, bool all_displays); - - // Force switching the display mode to |new_state|. This method is used when - // the user explicitly changes the display mode in the options UI. Returns - // false if it was called in a single-head or headless mode. - bool SetDisplayMode(State new_state); - - // Called when an RRNotify event is received. The implementation is - // interested in the cases of RRNotify events which correspond to output - // add/remove events. Note that Output add/remove events are sent in response - // to our own reconfiguration operations so spurious events are common. - // Spurious events will have no effect. - virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; - - private: - // Updates |output_count_|, |output_cache_|, |mirror_supported_|, - // |primary_output_index_|, and |secondary_output_index_| with new data. - // Returns true if the update succeeded or false if it was skipped since no - // actual change was observed. - // Note that |output_state_| is not updated by this call. - bool TryRecacheOutputs(Display* display, XRRScreenResources* screen); - - // Uses the data stored in |output_cache_| and the given |new_state| to - // configure the Xrandr interface and then updates |output_state_| to reflect - // the new state. - void UpdateCacheAndXrandrToState(Display* display, - XRRScreenResources* screen, - Window window, - State new_state); - - // A helper to re-cache instance variable state and transition into the - // appropriate default state for the observed displays. - bool RecacheAndUseDefaultState(); - - // Checks the |primary_output_index_|, |secondary_output_index_|, and - // |mirror_supported_| to see how many displays are currently connected and - // returns the state which is most appropriate as a default state for those - // displays. - State GetDefaultState() const; - - // Called during start-up to determine what the current state of the displays - // appears to be, by investigating how the outputs compare to the data stored - // in |output_cache_|. Returns STATE_INVALID if the current display state - // doesn't match any supported state. |output_cache_| must be up-to-date with - // regards to the state of X or this method may return incorrect results. - State InferCurrentState(Display* display, XRRScreenResources* screen) const; - - // Scans the |output_cache_| to determine whether or not we are in a - // "projecting" state and then calls the DBus kSetIsProjectingMethod on powerd - // with the result. - void CheckIsProjectingAndNotify(); - - // This is detected by the constructor to determine whether or not we should - // be enabled. If we aren't running on ChromeOS, we can't assume that the - // Xrandr X11 extension is supported. - // If this flag is set to false, any attempts to change the output - // configuration to immediately fail without changing the state. - bool is_running_on_chrome_os_; - - // The number of outputs in the output_cache_ array. - int output_count_; - - // The list of cached output descriptions (|output_count_| elements long). - scoped_array output_cache_; - - // True if |output_cache_| describes a permutation of outputs which support a - // mirrored device mode. - bool mirror_supported_; - - // The index of the primary connected output in |output_cache_|. -1 if there - // is no primary output. This implies the machine currently has no outputs. - int primary_output_index_; - - // The index of the secondary connected output in |output_cache_|. -1 if - // there is no secondary output. This implies the machine currently has one - // output. - int secondary_output_index_; - - // The base of the event numbers used to represent XRandr events used in - // decoding events regarding output add/remove. - int xrandr_event_base_; - - // The display state as derived from the outputs observed in |output_cache_|. - // This is used for rotating display modes. - State output_state_; - - DISALLOW_COPY_AND_ASSIGN(OutputConfigurator); -}; - -} // namespace chromeos - -#endif // CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index ff85629..8befbdd 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -87,10 +87,10 @@ 'focus_manager.h', 'layout_manager.cc', 'layout_manager.h', - 'monitor_change_observer_x11.cc', - 'monitor_change_observer_x11.h', - 'monitor_manager.cc', - 'monitor_manager.h', + 'display_change_observer_x11.cc', + 'display_change_observer_x11.h', + 'display_manager.cc', + 'display_manager.h', 'root_window_host.h', 'root_window_host_linux.cc', 'root_window_host_linux.h', @@ -110,8 +110,8 @@ 'shared/input_method_event_filter.h', 'shared/root_window_capture_client.cc', 'shared/root_window_capture_client.h', - 'single_monitor_manager.cc', - 'single_monitor_manager.h', + 'single_display_manager.cc', + 'single_display_manager.h', 'ui_controls_win.cc', 'ui_controls_x11.cc', 'window.cc', diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc index 92a837e..be3465b 100644 --- a/ui/aura/bench/bench_main.cc +++ b/ui/aura/bench/bench_main.cc @@ -14,7 +14,7 @@ #include "ui/aura/env.h" #include "ui/aura/event.h" #include "ui/aura/root_window.h" -#include "ui/aura/single_monitor_manager.h" +#include "ui/aura/single_display_manager.h" #include "ui/aura/window.h" #include "ui/base/hit_test.h" #include "ui/base/resource/resource_bundle.h" @@ -282,11 +282,11 @@ int main(int argc, char** argv) { MessageLoop message_loop(MessageLoop::TYPE_UI); ui::CompositorTestSupport::Initialize(); - aura::SingleMonitorManager* manager = new aura::SingleMonitorManager; + aura::SingleDisplayManager* manager = new aura::SingleDisplayManager; manager->set_use_fullscreen_host_window(true); - aura::Env::GetInstance()->SetMonitorManager(manager); + aura::Env::GetInstance()->SetDisplayManager(manager); scoped_ptr root_window( - aura::MonitorManager::CreateRootWindowForPrimaryMonitor()); + aura::DisplayManager::CreateRootWindowForPrimaryDisplay()); // add layers ColoredLayer background(SK_ColorRED); diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc index 050acb0..b1908e8 100644 --- a/ui/aura/demo/demo_main.cc +++ b/ui/aura/demo/demo_main.cc @@ -12,7 +12,7 @@ #include "ui/aura/env.h" #include "ui/aura/event.h" #include "ui/aura/root_window.h" -#include "ui/aura/single_monitor_manager.h" +#include "ui/aura/single_display_manager.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/base/hit_test.h" @@ -120,9 +120,9 @@ int main(int argc, char** argv) { // Create the message-loop here before creating the root window. MessageLoop message_loop(MessageLoop::TYPE_UI); ui::CompositorTestSupport::Initialize(); - aura::Env::GetInstance()->SetMonitorManager(new aura::SingleMonitorManager); + aura::Env::GetInstance()->SetDisplayManager(new aura::SingleDisplayManager); scoped_ptr root_window( - aura::MonitorManager::CreateRootWindowForPrimaryMonitor()); + aura::DisplayManager::CreateRootWindowForPrimaryDisplay()); scoped_ptr stacking_client(new DemoStackingClient( root_window.get())); diff --git a/ui/aura/display_change_observer_x11.cc b/ui/aura/display_change_observer_x11.cc new file mode 100644 index 0000000..85b4aec --- /dev/null +++ b/ui/aura/display_change_observer_x11.cc @@ -0,0 +1,148 @@ +// 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 "ui/aura/display_change_observer_x11.h" + +#include +#include +#include +#include + +#include + +#include "base/message_pump_aurax11.h" +#include "ui/aura/dispatcher_linux.h" +#include "ui/aura/env.h" +#include "ui/aura/display_manager.h" +#include "ui/compositor/dip_util.h" +#include "ui/gfx/display.h" + +namespace aura { +namespace internal { + +namespace { + +// The DPI threshold to detect high density screen. +// Higher DPI than this will use device_scale_factor=2. +// Note: This value has to be kept in sync with the mouse/touchpad driver +// which controls mouse pointer acceleration. If you need to update this value, +// please update the bug (crosbug.com/31628) first and make sure that the +// driver will use the same value. +// This value also has to be kept in sync with the value in +// chromeos/display/output_configurator.cc. See crbug.com/130188 +const unsigned int kHighDensityDIPThreshold = 160; + +// 1 inch in mm. +const float kInchInMm = 25.4f; + +XRRModeInfo* FindMode(XRRScreenResources* screen_resources, XID current_mode) { + for (int m = 0; m < screen_resources->nmode; m++) { + XRRModeInfo *mode = &screen_resources->modes[m]; + if (mode->id == current_mode) + return mode; + } + return NULL; +} + +bool CompareDisplayY(const gfx::Display& lhs, const gfx::Display& rhs) { + return lhs.bounds_in_pixel().y() < rhs.bounds_in_pixel().y(); +} + +} // namespace + +DisplayChangeObserverX11::DisplayChangeObserverX11() + : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), + x_root_window_(DefaultRootWindow(xdisplay_)), + xrandr_event_base_(0) { + int error_base_ignored; + XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); + static_cast(Env::GetInstance()->GetDispatcher())-> + AddDispatcherForRootWindow(this); +} + +DisplayChangeObserverX11::~DisplayChangeObserverX11() { + static_cast(Env::GetInstance()->GetDispatcher())-> + RemoveDispatcherForRootWindow(this); +} + +bool DisplayChangeObserverX11::Dispatch(const base::NativeEvent& event) { + if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { + NotifyDisplayChange(); + } + return true; +} + +void DisplayChangeObserverX11::NotifyDisplayChange() { + if (!DisplayManager::use_fullscreen_host_window()) + return; // Use the default display that display manager determined. + + XRRScreenResources* screen_resources = + XRRGetScreenResources(xdisplay_, x_root_window_); + std::map crtc_info_map; + + for (int c = 0; c < screen_resources->ncrtc; c++) { + XID crtc_id = screen_resources->crtcs[c]; + XRRCrtcInfo *crtc_info = + XRRGetCrtcInfo(xdisplay_, screen_resources, crtc_id); + crtc_info_map[crtc_id] = crtc_info; + } + + std::vector displays; + std::set y_coords; + for (int o = 0; o < screen_resources->noutput; o++) { + XRROutputInfo *output_info = + XRRGetOutputInfo(xdisplay_, + screen_resources, + screen_resources->outputs[o]); + if (output_info->connection != RR_Connected) { + XRRFreeOutputInfo(output_info); + continue; + } + XRRCrtcInfo* crtc_info = crtc_info_map[output_info->crtc]; + if (!crtc_info) { + LOG(WARNING) << "Crtc not found for output"; + continue; + } + XRRModeInfo* mode = FindMode(screen_resources, crtc_info->mode); + CHECK(mode); + // Mirrored displays have the same y coordinates. + if (y_coords.find(crtc_info->y) != y_coords.end()) + continue; + // TODO(oshima): Create unique ID for the display. + displays.push_back(gfx::Display( + 0, + gfx::Rect(crtc_info->x, crtc_info->y, mode->width, mode->height))); + + float device_scale_factor = 1.0f; + if (output_info->mm_width > 0 && + (kInchInMm * mode->width / output_info->mm_width) > + kHighDensityDIPThreshold) { + device_scale_factor = 2.0f; + } + displays.back().set_device_scale_factor(device_scale_factor); + y_coords.insert(crtc_info->y); + XRRFreeOutputInfo(output_info); + } + + // Free all allocated resources. + for (std::map::const_iterator iter = crtc_info_map.begin(); + iter != crtc_info_map.end(); ++iter) { + XRRFreeCrtcInfo(iter->second); + } + XRRFreeScreenResources(screen_resources); + + // PowerManager lays out the outputs vertically. Sort them by Y + // coordinates. + std::sort(displays.begin(), displays.end(), CompareDisplayY); + // TODO(oshima): Assisgn index as ID for now. Use unique ID. + int id = 0; + for (std::vector::iterator iter = displays.begin(); + iter != displays.end(); ++iter, ++id) + (*iter).set_id(id); + + Env::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays); +} + +} // namespace internal +} // namespace aura diff --git a/ui/aura/display_change_observer_x11.h b/ui/aura/display_change_observer_x11.h new file mode 100644 index 0000000..caf3be7 --- /dev/null +++ b/ui/aura/display_change_observer_x11.h @@ -0,0 +1,47 @@ +// 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 UI_AURA_DISPLAY_CHANGE_OBSERVER_X11_H +#define UI_AURA_DISPLAY_CHANGE_OBSERVER_X11_H +#pragma once + +#include + +// Xlib.h defines RootWindow. +#undef RootWindow + +#include "base/basictypes.h" +#include "base/message_loop.h" + +namespace aura { +namespace internal { + +// An object that observes changes in display configuration and +// update DisplayManagers. +class DisplayChangeObserverX11 : public MessageLoop::Dispatcher { + public: + DisplayChangeObserverX11(); + virtual ~DisplayChangeObserverX11(); + + // Overridden from Dispatcher overrides: + virtual bool Dispatch(const base::NativeEvent& xev) OVERRIDE; + + // Reads display configurations from the system and notifies + // |display_manager_| about the change. + void NotifyDisplayChange(); + + private: + Display* xdisplay_; + + ::Window x_root_window_; + + int xrandr_event_base_; + + DISALLOW_COPY_AND_ASSIGN(DisplayChangeObserverX11); +}; + +} // namespace internal +} // namespace aura + +#endif // UI_AURA_DISPLAY_CHANGE_OBSERVER_X11_H diff --git a/ui/aura/display_manager.cc b/ui/aura/display_manager.cc new file mode 100644 index 0000000..af1e848 --- /dev/null +++ b/ui/aura/display_manager.cc @@ -0,0 +1,87 @@ +// 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 "ui/aura/display_manager.h" + +#include + +#include "base/logging.h" +#include "ui/aura/display_observer.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/aura/root_window_host.h" +#include "ui/gfx/display.h" +#include "ui/gfx/rect.h" + +namespace aura { +namespace { +// Default bounds for a display. +const int kDefaultHostWindowX = 200; +const int kDefaultHostWindowY = 200; +const int kDefaultHostWindowWidth = 1280; +const int kDefaultHostWindowHeight = 1024; +} // namespace + +// static +bool DisplayManager::use_fullscreen_host_window_ = false; + +// static +gfx::Display DisplayManager::CreateDisplayFromSpec(const std::string& spec) { + static int synthesized_display_id = 1000; + gfx::Rect bounds(kDefaultHostWindowX, kDefaultHostWindowY, + kDefaultHostWindowWidth, kDefaultHostWindowHeight); + int x = 0, y = 0, width, height; + float scale = 1.0f; + if (sscanf(spec.c_str(), "%dx%d*%f", &width, &height, &scale) >= 2) { + bounds.set_size(gfx::Size(width, height)); + } else if (sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height, + &scale) >= 4 ) { + bounds = gfx::Rect(x, y, width, height); + } else if (use_fullscreen_host_window_) { + bounds = gfx::Rect(aura::RootWindowHost::GetNativeScreenSize()); + } + gfx::Display display(synthesized_display_id++); + display.SetScaleAndBounds(scale, bounds); + DVLOG(1) << "Display bounds=" << bounds.ToString() << ", scale=" << scale; + return display; +} + +// static +RootWindow* DisplayManager::CreateRootWindowForPrimaryDisplay() { + DisplayManager* manager = aura::Env::GetInstance()->display_manager(); + RootWindow* root = + manager->CreateRootWindowForDisplay(manager->GetDisplayAt(0)); + if (use_fullscreen_host_window_) + root->ConfineCursorToWindow(); + return root; +} + +DisplayManager::DisplayManager() { +} + +DisplayManager::~DisplayManager() { +} + +void DisplayManager::AddObserver(DisplayObserver* observer) { + observers_.AddObserver(observer); +} + +void DisplayManager::RemoveObserver(DisplayObserver* observer) { + observers_.RemoveObserver(observer); +} + +void DisplayManager::NotifyBoundsChanged(const gfx::Display& display) { + FOR_EACH_OBSERVER(DisplayObserver, observers_, + OnDisplayBoundsChanged(display)); +} + +void DisplayManager::NotifyDisplayAdded(const gfx::Display& display) { + FOR_EACH_OBSERVER(DisplayObserver, observers_, OnDisplayAdded(display)); +} + +void DisplayManager::NotifyDisplayRemoved(const gfx::Display& display) { + FOR_EACH_OBSERVER(DisplayObserver, observers_, OnDisplayRemoved(display)); +} + +} // namespace aura diff --git a/ui/aura/display_manager.h b/ui/aura/display_manager.h new file mode 100644 index 0000000..1d889c4 --- /dev/null +++ b/ui/aura/display_manager.h @@ -0,0 +1,101 @@ +// 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 UI_AURA_DISPLAY_MANAGER_H_ +#define UI_AURA_DISPLAY_MANAGER_H_ +#pragma once + +#include +#include + +#include "base/basictypes.h" +#include "base/observer_list.h" +#include "ui/aura/aura_export.h" + +namespace gfx { +class Display; +class Point; +class Size; +} + +namespace aura { +class DisplayObserver; +class RootWindow; +class Window; + +// DisplayManager creates, deletes and updates Display objects when +// display configuration changes, and notifies DisplayObservers about +// the change. This is owned by Env and its lifetime is longer than +// any windows. +class AURA_EXPORT DisplayManager { + public: + static void set_use_fullscreen_host_window(bool use_fullscreen) { + use_fullscreen_host_window_ = use_fullscreen; + } + static bool use_fullscreen_host_window() { + return use_fullscreen_host_window_; + } + + // Creates a display from string spec. 100+200-1440x800 creates display + // whose size is 1440x800 at the location (100, 200) in screen's coordinates. + // The location can be omitted and be just "1440x800", which creates + // display at the origin of the screen. An empty string creates + // the display with default size. + // The device scale factor can be specified by "*", like "1280x780*2", + // or will use the value of |gfx::Display::GetForcedDeviceScaleFactor()| if + // --force-device-scale-factor is specified. + static gfx::Display CreateDisplayFromSpec(const std::string& spec); + + // A utility function to create a root window for primary display. + static RootWindow* CreateRootWindowForPrimaryDisplay(); + + DisplayManager(); + virtual ~DisplayManager(); + + // Adds/removes DisplayObservers. + void AddObserver(DisplayObserver* observer); + void RemoveObserver(DisplayObserver* observer); + + // 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. + virtual void OnNativeDisplaysChanged( + const std::vector& display) = 0; + + // Create a root window for given |display|. + virtual RootWindow* CreateRootWindowForDisplay( + const gfx::Display& display) = 0; + + // Returns the display at |index|. The display at 0 is considered "primary". + virtual const gfx::Display& GetDisplayAt(size_t index) = 0; + + virtual size_t GetNumDisplays() const = 0; + + // Returns the display object nearest given |window|. + virtual const gfx::Display& GetDisplayNearestWindow( + const Window* window) const = 0; + + // Returns the display object nearest given |pint|. + virtual const gfx::Display& GetDisplayNearestPoint( + const gfx::Point& point) const = 0; + + protected: + // Calls observers' OnDisplayBoundsChanged methods. + void NotifyBoundsChanged(const gfx::Display& display); + void NotifyDisplayAdded(const gfx::Display& display); + void NotifyDisplayRemoved(const gfx::Display& display); + + private: + // If set before the RootWindow is created, the host window will cover the + // entire display. Note that this can still be overridden via the + // switches::kAuraHostWindowSize flag. + static bool use_fullscreen_host_window_; + + ObserverList observers_; + DISALLOW_COPY_AND_ASSIGN(DisplayManager); +}; + +} // namespace aura + +#endif // UI_AURA_DISPLAY_MANAGER_H_ diff --git a/ui/aura/display_observer.h b/ui/aura/display_observer.h index 282241d..0399ae6 100644 --- a/ui/aura/display_observer.h +++ b/ui/aura/display_observer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_AURA_MONITOR_OBSERVER_H_ -#define UI_AURA_MONITOR_OBSERVER_H_ +#ifndef UI_AURA_DISPLAY_OBSERVER_H_ +#define UI_AURA_DISPLAY_OBSERVER_H_ #pragma once #include "ui/aura/aura_export.h" @@ -20,7 +20,7 @@ class AURA_EXPORT DisplayObserver { // Called when the |display|'s bound has changed. virtual void OnDisplayBoundsChanged(const gfx::Display& display) = 0; - // Called when |new_monitor| has been added. + // Called when |new_display| has been added. virtual void OnDisplayAdded(const gfx::Display& new_display) = 0; // Called when |old_display| has been removed. @@ -32,4 +32,4 @@ class AURA_EXPORT DisplayObserver { } // namespace aura -#endif // UI_AURA_MONITOR_OBSERVER_H_ +#endif // UI_AURA_DISPLAY_OBSERVER_H_ diff --git a/ui/aura/env.cc b/ui/aura/env.cc index 18aac53..d65a318 100644 --- a/ui/aura/env.cc +++ b/ui/aura/env.cc @@ -7,13 +7,13 @@ #include "ui/aura/cursor_manager.h" #include "ui/aura/env_observer.h" #include "ui/aura/event_filter.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window_host.h" #include "ui/aura/window.h" #include "ui/compositor/compositor.h" #if defined(USE_X11) -#include "ui/aura/monitor_change_observer_x11.h" +#include "ui/aura/display_change_observer_x11.h" #endif namespace aura { @@ -57,11 +57,11 @@ void Env::RemoveObserver(EnvObserver* observer) { observers_.RemoveObserver(observer); } -void Env::SetMonitorManager(MonitorManager* monitor_manager) { - monitor_manager_.reset(monitor_manager); +void Env::SetDisplayManager(DisplayManager* display_manager) { + display_manager_.reset(display_manager); #if defined(USE_X11) - // Update the monitor manager with latest info. - monitor_change_observer_->NotifyDisplayChange(); + // Update the display manager with latest info. + display_change_observer_->NotifyDisplayChange(); #endif } @@ -83,7 +83,7 @@ void Env::Init() { dispatcher_.reset(CreateDispatcher()); #endif #if defined(USE_X11) - monitor_change_observer_.reset(new internal::MonitorChangeObserverX11); + display_change_observer_.reset(new internal::DisplayChangeObserverX11); #endif ui::Compositor::Initialize(false); } diff --git a/ui/aura/env.h b/ui/aura/env.h index e8e787d8..bef9483 100644 --- a/ui/aura/env.h +++ b/ui/aura/env.h @@ -17,11 +17,11 @@ namespace aura { class CursorManager; class EnvObserver; class EventFilter; -class MonitorManager; +class DisplayManager; class Window; namespace internal { -class MonitorChangeObserverX11; +class DisplayChangeObserverX11; } #if !defined(OS_MACOSX) @@ -56,10 +56,10 @@ class AURA_EXPORT Env { stacking_client_ = stacking_client; } - // Gets/sets MonitorManager. The MonitorManager's ownership is + // Gets/sets DisplayManager. The DisplayManager's ownership is // transfered. - MonitorManager* monitor_manager() { return monitor_manager_.get(); } - void SetMonitorManager(MonitorManager* monitor_manager); + DisplayManager* display_manager() { return display_manager_.get(); } + void SetDisplayManager(DisplayManager* display_manager); // Env takes ownership of the EventFilter. EventFilter* event_filter() { return event_filter_.get(); } @@ -92,12 +92,12 @@ class AURA_EXPORT Env { int mouse_button_flags_; bool is_touch_down_; client::StackingClient* stacking_client_; - scoped_ptr monitor_manager_; + scoped_ptr display_manager_; scoped_ptr event_filter_; CursorManager cursor_manager_; #if defined(USE_X11) - scoped_ptr monitor_change_observer_; + scoped_ptr display_change_observer_; #endif DISALLOW_COPY_AND_ASSIGN(Env); diff --git a/ui/aura/monitor_change_observer_x11.cc b/ui/aura/monitor_change_observer_x11.cc deleted file mode 100644 index 5afe527..0000000 --- a/ui/aura/monitor_change_observer_x11.cc +++ /dev/null @@ -1,148 +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 "ui/aura/monitor_change_observer_x11.h" - -#include -#include -#include -#include - -#include - -#include "base/message_pump_aurax11.h" -#include "ui/aura/dispatcher_linux.h" -#include "ui/aura/env.h" -#include "ui/aura/monitor_manager.h" -#include "ui/compositor/dip_util.h" -#include "ui/gfx/display.h" - -namespace aura { -namespace internal { - -namespace { - -// The DPI threshold to detect high density screen. -// Higher DPI than this will use device_scale_factor=2. -// Note: This value has to be kept in sync with the mouse/touchpad driver -// which controls mouse pointer acceleration. If you need to update this value, -// please update the bug (crosbug.com/31628) first and make sure that the -// driver will use the same value. -// This value also has to be kept in sync with the value in -// chromeos/monitor/output_configurator.cc. See crbug.com/130188 -const unsigned int kHighDensityDIPThreshold = 160; - -// 1 inch in mm. -const float kInchInMm = 25.4f; - -XRRModeInfo* FindMode(XRRScreenResources* screen_resources, XID current_mode) { - for (int m = 0; m < screen_resources->nmode; m++) { - XRRModeInfo *mode = &screen_resources->modes[m]; - if (mode->id == current_mode) - return mode; - } - return NULL; -} - -bool CompareDisplayY(const gfx::Display& lhs, const gfx::Display& rhs) { - return lhs.bounds_in_pixel().y() < rhs.bounds_in_pixel().y(); -} - -} // namespace - -MonitorChangeObserverX11::MonitorChangeObserverX11() - : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), - x_root_window_(DefaultRootWindow(xdisplay_)), - xrandr_event_base_(0) { - int error_base_ignored; - XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); - static_cast(Env::GetInstance()->GetDispatcher())-> - AddDispatcherForRootWindow(this); -} - -MonitorChangeObserverX11::~MonitorChangeObserverX11() { - static_cast(Env::GetInstance()->GetDispatcher())-> - RemoveDispatcherForRootWindow(this); -} - -bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) { - if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { - NotifyDisplayChange(); - } - return true; -} - -void MonitorChangeObserverX11::NotifyDisplayChange() { - if (!MonitorManager::use_fullscreen_host_window()) - return; // Use the default monitor that monitor manager determined. - - XRRScreenResources* screen_resources = - XRRGetScreenResources(xdisplay_, x_root_window_); - std::map crtc_info_map; - - for (int c = 0; c < screen_resources->ncrtc; c++) { - XID crtc_id = screen_resources->crtcs[c]; - XRRCrtcInfo *crtc_info = - XRRGetCrtcInfo(xdisplay_, screen_resources, crtc_id); - crtc_info_map[crtc_id] = crtc_info; - } - - std::vector displays; - std::set y_coords; - for (int o = 0; o < screen_resources->noutput; o++) { - XRROutputInfo *output_info = - XRRGetOutputInfo(xdisplay_, - screen_resources, - screen_resources->outputs[o]); - if (output_info->connection != RR_Connected) { - XRRFreeOutputInfo(output_info); - continue; - } - XRRCrtcInfo* crtc_info = crtc_info_map[output_info->crtc]; - if (!crtc_info) { - LOG(WARNING) << "Crtc not found for output"; - continue; - } - XRRModeInfo* mode = FindMode(screen_resources, crtc_info->mode); - CHECK(mode); - // Mirrored monitors have the same y coordinates. - if (y_coords.find(crtc_info->y) != y_coords.end()) - continue; - // TODO(oshima): Create unique ID for the monitor. - displays.push_back(gfx::Display( - 0, - gfx::Rect(crtc_info->x, crtc_info->y, mode->width, mode->height))); - - float device_scale_factor = 1.0f; - if (output_info->mm_width > 0 && - (kInchInMm * mode->width / output_info->mm_width) > - kHighDensityDIPThreshold) { - device_scale_factor = 2.0f; - } - displays.back().set_device_scale_factor(device_scale_factor); - y_coords.insert(crtc_info->y); - XRRFreeOutputInfo(output_info); - } - - // Free all allocated resources. - for (std::map::const_iterator iter = crtc_info_map.begin(); - iter != crtc_info_map.end(); ++iter) { - XRRFreeCrtcInfo(iter->second); - } - XRRFreeScreenResources(screen_resources); - - // PowerManager lays out the outputs vertically. Sort them by Y - // coordinates. - std::sort(displays.begin(), displays.end(), CompareDisplayY); - // TODO(oshima): Assisgn index as ID for now. Use unique ID. - int id = 0; - for (std::vector::iterator iter = displays.begin(); - iter != displays.end(); ++iter, ++id) - (*iter).set_id(id); - - Env::GetInstance()->monitor_manager()->OnNativeMonitorsChanged(displays); -} - -} // namespace internal -} // namespace aura diff --git a/ui/aura/monitor_change_observer_x11.h b/ui/aura/monitor_change_observer_x11.h deleted file mode 100644 index 4160860..0000000 --- a/ui/aura/monitor_change_observer_x11.h +++ /dev/null @@ -1,47 +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 UI_AURA_MONITOR_CHANGE_OBSERVER_X11_H -#define UI_AURA_MONITOR_CHANGE_OBSERVER_X11_H -#pragma once - -#include - -// Xlib.h defines RootWindow. -#undef RootWindow - -#include "base/basictypes.h" -#include "base/message_loop.h" - -namespace aura { -namespace internal { - -// An object that observes changes in monitor configuration and -// update MonitorManagers. -class MonitorChangeObserverX11 : public MessageLoop::Dispatcher { - public: - MonitorChangeObserverX11(); - virtual ~MonitorChangeObserverX11(); - - // Overridden from Dispatcher overrides: - virtual bool Dispatch(const base::NativeEvent& xev) OVERRIDE; - - // Reads display configurations from the system and notifies - // |monitor_manager_| about the change. - void NotifyDisplayChange(); - - private: - Display* xdisplay_; - - ::Window x_root_window_; - - int xrandr_event_base_; - - DISALLOW_COPY_AND_ASSIGN(MonitorChangeObserverX11); -}; - -} // namespace internal -} // namespace aura - -#endif // UI_AURA_MONITOR_CHANGE_OBSERVER_X11_H diff --git a/ui/aura/monitor_manager.cc b/ui/aura/monitor_manager.cc deleted file mode 100644 index aba7bcc..0000000 --- a/ui/aura/monitor_manager.cc +++ /dev/null @@ -1,87 +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 "ui/aura/monitor_manager.h" - -#include - -#include "base/logging.h" -#include "ui/aura/display_observer.h" -#include "ui/aura/env.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_host.h" -#include "ui/gfx/display.h" -#include "ui/gfx/rect.h" - -namespace aura { -namespace { -// Default bounds for a monitor. -const int kDefaultHostWindowX = 200; -const int kDefaultHostWindowY = 200; -const int kDefaultHostWindowWidth = 1280; -const int kDefaultHostWindowHeight = 1024; -} // namespace - -// static -bool MonitorManager::use_fullscreen_host_window_ = false; - -// static -gfx::Display MonitorManager::CreateMonitorFromSpec(const std::string& spec) { - static int synthesized_monitor_id = 1000; - gfx::Rect bounds(kDefaultHostWindowX, kDefaultHostWindowY, - kDefaultHostWindowWidth, kDefaultHostWindowHeight); - int x = 0, y = 0, width, height; - float scale = 1.0f; - if (sscanf(spec.c_str(), "%dx%d*%f", &width, &height, &scale) >= 2) { - bounds.set_size(gfx::Size(width, height)); - } else if (sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height, - &scale) >= 4 ) { - bounds = gfx::Rect(x, y, width, height); - } else if (use_fullscreen_host_window_) { - bounds = gfx::Rect(aura::RootWindowHost::GetNativeScreenSize()); - } - gfx::Display display(synthesized_monitor_id++); - display.SetScaleAndBounds(scale, bounds); - DVLOG(1) << "Display bounds=" << bounds.ToString() << ", scale=" << scale; - return display; -} - -// static -RootWindow* MonitorManager::CreateRootWindowForPrimaryMonitor() { - MonitorManager* manager = aura::Env::GetInstance()->monitor_manager(); - RootWindow* root = - manager->CreateRootWindowForMonitor(manager->GetDisplayAt(0)); - if (use_fullscreen_host_window_) - root->ConfineCursorToWindow(); - return root; -} - -MonitorManager::MonitorManager() { -} - -MonitorManager::~MonitorManager() { -} - -void MonitorManager::AddObserver(DisplayObserver* observer) { - observers_.AddObserver(observer); -} - -void MonitorManager::RemoveObserver(DisplayObserver* observer) { - observers_.RemoveObserver(observer); -} - -void MonitorManager::NotifyBoundsChanged(const gfx::Display& display) { - FOR_EACH_OBSERVER(DisplayObserver, observers_, - OnDisplayBoundsChanged(display)); -} - -void MonitorManager::NotifyDisplayAdded(const gfx::Display& display) { - FOR_EACH_OBSERVER(DisplayObserver, observers_, OnDisplayAdded(display)); -} - -void MonitorManager::NotifyDisplayRemoved(const gfx::Display& display) { - FOR_EACH_OBSERVER(DisplayObserver, observers_, OnDisplayRemoved(display)); -} - -} // namespace aura diff --git a/ui/aura/monitor_manager.h b/ui/aura/monitor_manager.h deleted file mode 100644 index 40e6bbf..0000000 --- a/ui/aura/monitor_manager.h +++ /dev/null @@ -1,101 +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 UI_AURA_MONITOR_MANAGER_H_ -#define UI_AURA_MONITOR_MANAGER_H_ -#pragma once - -#include -#include - -#include "base/basictypes.h" -#include "base/observer_list.h" -#include "ui/aura/aura_export.h" - -namespace gfx { -class Display; -class Point; -class Size; -} - -namespace aura { -class DisplayObserver; -class RootWindow; -class Window; - -// MonitorManager creates, deletes and updates Monitor objects when -// monitor configuration changes, and notifies DisplayObservers about -// the change. This is owned by Env and its lifetime is longer than -// any windows. -class AURA_EXPORT MonitorManager { - public: - static void set_use_fullscreen_host_window(bool use_fullscreen) { - use_fullscreen_host_window_ = use_fullscreen; - } - static bool use_fullscreen_host_window() { - return use_fullscreen_host_window_; - } - - // Creates a monitor from string spec. 100+200-1440x800 creates monitor - // whose size is 1440x800 at the location (100, 200) in screen's coordinates. - // The location can be omitted and be just "1440x800", which creates - // monitor at the origin of the screen. An empty string creates - // the monitor with default size. - // The device scale factor can be specified by "*", like "1280x780*2", - // or will use the value of |gfx::Display::GetForcedDeviceScaleFactor()| if - // --force-device-scale-factor is specified. - static gfx::Display CreateMonitorFromSpec(const std::string& spec); - - // A utility function to create a root window for primary monitor. - static RootWindow* CreateRootWindowForPrimaryMonitor(); - - MonitorManager(); - virtual ~MonitorManager(); - - // Adds/removes DisplayObservers. - void AddObserver(DisplayObserver* observer); - void RemoveObserver(DisplayObserver* observer); - - // Called when monitor configuration has changed. The new monitor - // configurations is passed as a vector of Monitor object, which - // contains each monitor's new infomration. - virtual void OnNativeMonitorsChanged( - const std::vector& display) = 0; - - // Create a root window for given |monitor|. - virtual RootWindow* CreateRootWindowForMonitor( - const gfx::Display& display) = 0; - - // Returns the display at |index|. The display at 0 is considered "primary". - virtual const gfx::Display& GetDisplayAt(size_t index) = 0; - - virtual size_t GetNumDisplays() const = 0; - - // Returns the display object nearest given |window|. - virtual const gfx::Display& GetDisplayNearestWindow( - const Window* window) const = 0; - - // Returns the monitor object nearest given |pint|. - virtual const gfx::Display& GetDisplayNearestPoint( - const gfx::Point& point) const = 0; - - protected: - // Calls observers' OnDisplayBoundsChanged methods. - void NotifyBoundsChanged(const gfx::Display& display); - void NotifyDisplayAdded(const gfx::Display& display); - void NotifyDisplayRemoved(const gfx::Display& display); - - private: - // If set before the RootWindow is created, the host window will cover the - // entire monitor. Note that this can still be overridden via the - // switches::kAuraHostWindowSize flag. - static bool use_fullscreen_host_window_; - - ObserverList observers_; - DISALLOW_COPY_AND_ASSIGN(MonitorManager); -}; - -} // namespace aura - -#endif // UI_AURA_MONITOR_MANAGER_H_ diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 6728fa4..85a1247 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -19,7 +19,7 @@ #include "ui/aura/event.h" #include "ui/aura/event_filter.h" #include "ui/aura/focus_manager.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window_host.h" #include "ui/aura/root_window_observer.h" #include "ui/aura/window.h" @@ -64,9 +64,9 @@ void GetEventFiltersToNotify(Window* target, EventFilters* filters) { filters->push_back(Env::GetInstance()->event_filter()); } -float GetDeviceScaleFactorFromMonitor(const aura::Window* window) { - MonitorManager* monitor_manager = Env::GetInstance()->monitor_manager(); - return monitor_manager->GetDisplayNearestWindow(window).device_scale_factor(); +float GetDeviceScaleFactorFromDisplay(const aura::Window* window) { + DisplayManager* display_manager = Env::GetInstance()->display_manager(); + return display_manager->GetDisplayNearestWindow(window).device_scale_factor(); } Window* ConsumerToWindow(ui::GestureConsumer* consumer) { @@ -154,7 +154,7 @@ RootWindow* RootWindow::GetForAcceleratedWidget( } void RootWindow::Init() { - compositor()->SetScaleAndSize(GetDeviceScaleFactorFromMonitor(this), + compositor()->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this), host_->GetBounds().size()); Window::Init(ui::LAYER_NOT_DRAWN); last_mouse_location_ = @@ -390,8 +390,8 @@ bool RootWindow::DispatchGestureEvent(GestureEvent* event) { void RootWindow::OnHostResized(const gfx::Size& size_in_pixel) { DispatchHeldMouseMove(); // The compositor should have the same size as the native root window host. - // Get the latest scale from monitor because it might have been changed. - compositor_->SetScaleAndSize(GetDeviceScaleFactorFromMonitor(this), + // Get the latest scale from display because it might have been changed. + compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this), size_in_pixel); gfx::Size old(bounds().size()); // The layer, and all the observers should be notified of the diff --git a/ui/aura/single_display_manager.cc b/ui/aura/single_display_manager.cc new file mode 100644 index 0000000..3ffc80b --- /dev/null +++ b/ui/aura/single_display_manager.cc @@ -0,0 +1,98 @@ +// 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 "ui/aura/single_display_manager.h" + +#include + +#include "base/command_line.h" +#include "ui/aura/aura_switches.h" +#include "ui/aura/root_window.h" +#include "ui/aura/root_window_host.h" +#include "ui/gfx/display.h" +#include "ui/gfx/rect.h" + +namespace aura { + +using std::string; + +namespace { +// Default bounds for the primary display. +const int kDefaultHostWindowX = 200; +const int kDefaultHostWindowY = 200; +const int kDefaultHostWindowWidth = 1280; +const int kDefaultHostWindowHeight = 1024; +} // namespace + +SingleDisplayManager::SingleDisplayManager() + : root_window_(NULL) { + Init(); +} + +SingleDisplayManager::~SingleDisplayManager() { + // All displays must have been deleted when display manager is deleted. + CHECK(!root_window_); +} + +void SingleDisplayManager::OnNativeDisplaysChanged( + const std::vector& displays) { + DCHECK(displays.size() > 0); + if (use_fullscreen_host_window()) { + display_.SetSize(displays[0].bounds().size()); + NotifyBoundsChanged(display_); + } +} + +RootWindow* SingleDisplayManager::CreateRootWindowForDisplay( + const gfx::Display& display) { + DCHECK(!root_window_); + DCHECK_EQ(display_.id(), display.id()); + root_window_ = new RootWindow(display.bounds()); + root_window_->AddObserver(this); + root_window_->Init(); + return root_window_; +} + +const gfx::Display& SingleDisplayManager::GetDisplayAt(size_t index) { + return display_; +} + +size_t SingleDisplayManager::GetNumDisplays() const { + return 1; +} + +const gfx::Display& SingleDisplayManager::GetDisplayNearestWindow( + const Window* window) const { + return display_; +} + +const gfx::Display& SingleDisplayManager::GetDisplayNearestPoint( + const gfx::Point& point) const { + return display_; +} + +void SingleDisplayManager::OnWindowBoundsChanged( + Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { + if (!use_fullscreen_host_window()) { + Update(new_bounds.size()); + NotifyBoundsChanged(display_); + } +} + +void SingleDisplayManager::OnWindowDestroying(Window* window) { + if (root_window_ == window) + root_window_ = NULL; +} + +void SingleDisplayManager::Init() { + const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kAuraHostWindowSize); + display_ = CreateDisplayFromSpec(size_str); +} + +void SingleDisplayManager::Update(const gfx::Size size) { + display_.SetSize(size); +} + +} // namespace aura diff --git a/ui/aura/single_display_manager.h b/ui/aura/single_display_manager.h new file mode 100644 index 0000000..d7b8265 --- /dev/null +++ b/ui/aura/single_display_manager.h @@ -0,0 +1,60 @@ +// 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 UI_AURA_SINGLE_DISPLAY_MANAGER_H_ +#define UI_AURA_SINGLE_DISPLAY_MANAGER_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "ui/aura/aura_export.h" +#include "ui/aura/display_manager.h" +#include "ui/aura/window_observer.h" +#include "ui/gfx/display.h" + +namespace gfx { +class Rect; +} + +namespace aura { + +// A display manager assuming there is one display. +class AURA_EXPORT SingleDisplayManager : public DisplayManager, + public WindowObserver { + public: + SingleDisplayManager(); + virtual ~SingleDisplayManager(); + + // DisplayManager overrides: + virtual void OnNativeDisplaysChanged( + const std::vector& display) OVERRIDE; + virtual RootWindow* CreateRootWindowForDisplay( + const gfx::Display& display) OVERRIDE; + virtual const gfx::Display& GetDisplayAt(size_t index) OVERRIDE; + + virtual size_t GetNumDisplays() const OVERRIDE; + + virtual const gfx::Display& GetDisplayNearestWindow( + const Window* window) const OVERRIDE; + virtual const gfx::Display& GetDisplayNearestPoint( + const gfx::Point& point) const OVERRIDE; + + // WindowObserver overrides: + virtual void OnWindowBoundsChanged(Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) OVERRIDE; + virtual void OnWindowDestroying(Window* window) OVERRIDE; + + private: + void Init(); + void Update(const gfx::Size size); + + RootWindow* root_window_; + gfx::Display display_; + + DISALLOW_COPY_AND_ASSIGN(SingleDisplayManager); +}; + +} // namespace aura + +#endif // UI_AURA_SINGLE_DISPLAY_MANAGER_H_ diff --git a/ui/aura/single_monitor_manager.cc b/ui/aura/single_monitor_manager.cc deleted file mode 100644 index e099341..0000000 --- a/ui/aura/single_monitor_manager.cc +++ /dev/null @@ -1,98 +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 "ui/aura/single_monitor_manager.h" - -#include - -#include "base/command_line.h" -#include "ui/aura/aura_switches.h" -#include "ui/aura/root_window.h" -#include "ui/aura/root_window_host.h" -#include "ui/gfx/display.h" -#include "ui/gfx/rect.h" - -namespace aura { - -using std::string; - -namespace { -// Default bounds for the primary monitor. -const int kDefaultHostWindowX = 200; -const int kDefaultHostWindowY = 200; -const int kDefaultHostWindowWidth = 1280; -const int kDefaultHostWindowHeight = 1024; -} // namespace - -SingleMonitorManager::SingleMonitorManager() - : root_window_(NULL) { - Init(); -} - -SingleMonitorManager::~SingleMonitorManager() { - // All monitors must have been deleted when monitor manager is deleted. - CHECK(!root_window_); -} - -void SingleMonitorManager::OnNativeMonitorsChanged( - const std::vector& displays) { - DCHECK(displays.size() > 0); - if (use_fullscreen_host_window()) { - display_.SetSize(displays[0].bounds().size()); - NotifyBoundsChanged(display_); - } -} - -RootWindow* SingleMonitorManager::CreateRootWindowForMonitor( - const gfx::Display& display) { - DCHECK(!root_window_); - DCHECK_EQ(display_.id(), display.id()); - root_window_ = new RootWindow(display.bounds()); - root_window_->AddObserver(this); - root_window_->Init(); - return root_window_; -} - -const gfx::Display& SingleMonitorManager::GetDisplayAt(size_t index) { - return display_; -} - -size_t SingleMonitorManager::GetNumDisplays() const { - return 1; -} - -const gfx::Display& SingleMonitorManager::GetDisplayNearestWindow( - const Window* window) const { - return display_; -} - -const gfx::Display& SingleMonitorManager::GetDisplayNearestPoint( - const gfx::Point& point) const { - return display_; -} - -void SingleMonitorManager::OnWindowBoundsChanged( - Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { - if (!use_fullscreen_host_window()) { - Update(new_bounds.size()); - NotifyBoundsChanged(display_); - } -} - -void SingleMonitorManager::OnWindowDestroying(Window* window) { - if (root_window_ == window) - root_window_ = NULL; -} - -void SingleMonitorManager::Init() { - const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kAuraHostWindowSize); - display_ = CreateMonitorFromSpec(size_str); -} - -void SingleMonitorManager::Update(const gfx::Size size) { - display_.SetSize(size); -} - -} // namespace aura diff --git a/ui/aura/single_monitor_manager.h b/ui/aura/single_monitor_manager.h deleted file mode 100644 index 46ef34c..0000000 --- a/ui/aura/single_monitor_manager.h +++ /dev/null @@ -1,60 +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 UI_AURA_SINGLE_MONITOR_MANAGER_H_ -#define UI_AURA_SINGLE_MONITOR_MANAGER_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "ui/aura/aura_export.h" -#include "ui/aura/monitor_manager.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/display.h" - -namespace gfx { -class Rect; -} - -namespace aura { - -// A monitor manager assuming there is one monitor. -class AURA_EXPORT SingleMonitorManager : public MonitorManager, - public WindowObserver { - public: - SingleMonitorManager(); - virtual ~SingleMonitorManager(); - - // MonitorManager overrides: - virtual void OnNativeMonitorsChanged( - const std::vector& display) OVERRIDE; - virtual RootWindow* CreateRootWindowForMonitor( - const gfx::Display& display) OVERRIDE; - virtual const gfx::Display& GetDisplayAt(size_t index) OVERRIDE; - - virtual size_t GetNumDisplays() const OVERRIDE; - - virtual const gfx::Display& GetDisplayNearestWindow( - const Window* window) const OVERRIDE; - virtual const gfx::Display& GetDisplayNearestPoint( - const gfx::Point& point) const OVERRIDE; - - // WindowObserver overrides: - virtual void OnWindowBoundsChanged(Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) OVERRIDE; - virtual void OnWindowDestroying(Window* window) OVERRIDE; - - private: - void Init(); - void Update(const gfx::Size size); - - RootWindow* root_window_; - gfx::Display display_; - - DISALLOW_COPY_AND_ASSIGN(SingleMonitorManager); -}; - -} // namespace aura - -#endif // UI_AURA_SINGLE_MONITOR_MANAGER_H_ diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc index c8549ba..1dabfd4 100644 --- a/ui/aura/test/aura_test_helper.cc +++ b/ui/aura/test/aura_test_helper.cc @@ -8,10 +8,10 @@ #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" #include "ui/aura/focus_manager.h" -#include "ui/aura/monitor_manager.h" +#include "ui/aura/display_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/shared/root_window_capture_client.h" -#include "ui/aura/single_monitor_manager.h" +#include "ui/aura/single_display_manager.h" #include "ui/aura/test/test_activation_client.h" #include "ui/aura/test/test_screen.h" #include "ui/aura/test/test_stacking_client.h" @@ -43,8 +43,8 @@ AuraTestHelper::~AuraTestHelper() { void AuraTestHelper::SetUp() { setup_called_ = true; - Env::GetInstance()->SetMonitorManager(new SingleMonitorManager); - root_window_.reset(aura::MonitorManager::CreateRootWindowForPrimaryMonitor()); + Env::GetInstance()->SetDisplayManager(new SingleDisplayManager); + root_window_.reset(aura::DisplayManager::CreateRootWindowForPrimaryDisplay()); gfx::Screen::SetInstance(new aura::TestScreen(root_window_.get())); ui_controls::InstallUIControlsAura(CreateUIControlsAura(root_window_.get())); diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 6a9c3ee0..437b75d 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -233,7 +233,7 @@ bool Window::IsVisible() const { gfx::Rect Window::GetBoundsInRootWindow() const { // TODO(beng): There may be a better way to handle this, and the existing code - // is likely wrong anyway in a multi-monitor world, but this will + // is likely wrong anyway in a multi-display world, but this will // do for now. if (!GetRootWindow()) return bounds(); diff --git a/ui/aura/window.h b/ui/aura/window.h index 34a5702..a8c0d72 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h @@ -135,7 +135,7 @@ class AURA_EXPORT Window : public ui::LayerDelegate, // Returns the window's bounds in screen coordinates. In ash, this is // effectively screen bounds. // - // TODO(oshima): Fix this to return screen's coordinate for multi-monitor + // TODO(oshima): Fix this to return screen's coordinate for multi-display // support. gfx::Rect GetBoundsInRootWindow() const; diff --git a/ui/views/widget/native_widget_aura_unittest.cc b/ui/views/widget/native_widget_aura_unittest.cc index 87672ad..cef5a85 100644 --- a/ui/views/widget/native_widget_aura_unittest.cc +++ b/ui/views/widget/native_widget_aura_unittest.cc @@ -13,9 +13,7 @@ #include "ui/aura/env.h" #include "ui/aura/event.h" #include "ui/aura/layout_manager.h" -#include "ui/aura/monitor_manager.h" #include "ui/aura/root_window.h" -#include "ui/aura/single_monitor_manager.h" #include "ui/aura/test/aura_test_helper.h" #include "ui/aura/window.h" #include "ui/gfx/screen.h" -- cgit v1.1