diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-21 04:08:57 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-21 04:08:57 +0000 |
commit | a11f03342dbb57db2a186e0211b71e8ead645397 (patch) | |
tree | 7a78907d017e5ddf86c443967dc9cc65c16c5270 /ash | |
parent | b98e61c3c42d6c24e7de3b49f9bec8bec38d1f5f (diff) | |
download | chromium_src-a11f03342dbb57db2a186e0211b71e8ead645397.zip chromium_src-a11f03342dbb57db2a186e0211b71e8ead645397.tar.gz chromium_src-a11f03342dbb57db2a186e0211b71e8ead645397.tar.bz2 |
Call OnDisplayBoundsChanged when bounds are changed due to layout.
BUG=247059
TEST=covered by test
Review URL: https://chromiumcodereview.appspot.com/17379003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207694 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/display/display_controller.cc | 64 | ||||
-rw-r--r-- | ash/display/display_controller.h | 6 | ||||
-rw-r--r-- | ash/display/display_controller_unittest.cc | 2 | ||||
-rw-r--r-- | ash/display/display_manager.cc | 113 | ||||
-rw-r--r-- | ash/display/display_manager.h | 17 | ||||
-rw-r--r-- | ash/display/display_manager_unittest.cc | 25 |
6 files changed, 167 insertions, 60 deletions
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc index 0754286..adad32f3 100644 --- a/ash/display/display_controller.cc +++ b/ash/display/display_controller.cc @@ -74,10 +74,6 @@ int num_displays_for_shutdown = -1; // to change this value in case to support even larger displays. const int kMaxValidOffset = 10000; -// The number of pixels to overlap between the primary and secondary displays, -// in case that the offset value is too large. -const int kMinimumOverlapForInvalidOffset = 100; - // Specifies how long the display change should have been disabled // after each display change operations. // |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid @@ -589,11 +585,7 @@ DisplayLayout DisplayController::GetCurrentDisplayLayout() const { // Invert if the primary was swapped. if (GetDisplayManager()->num_connected_displays() > 1) { DisplayIdPair pair = GetCurrentDisplayIdPair(); - DisplayLayout layout = GetRegisteredDisplayLayout(pair); - const gfx::Display& primary = GetPrimaryDisplay(); - // Invert if the primary was swapped. If mirrored, first is always - // primary. - return pair.first == primary.id() ? layout : layout.Invert(); + return ComputeDisplayLayoutForDisplayIdPair(pair); } // On release build, just fallback to default instead of blowing up. return default_display_layout_; @@ -942,49 +934,11 @@ void DisplayController::UpdateDisplayBoundsForLayout() { GetDisplayManager()->num_connected_displays() < 2) { return; } - DCHECK_EQ(2, Shell::GetScreen()->GetNumDisplays()); - const gfx::Rect& primary_bounds = GetPrimaryDisplay().bounds(); - - gfx::Display* secondary_display = GetSecondaryDisplay(); - const gfx::Rect& secondary_bounds = secondary_display->bounds(); - gfx::Point new_secondary_origin = primary_bounds.origin(); const DisplayLayout layout = GetCurrentDisplayLayout(); - DisplayLayout::Position position = layout.position; - - // Ignore the offset in case the secondary display doesn't share edges with - // the primary display. - int offset = layout.offset; - if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { - offset = std::min( - offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); - offset = std::max( - offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); - } else { - offset = std::min( - offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); - offset = std::max( - offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); - } - switch (position) { - case DisplayLayout::TOP: - new_secondary_origin.Offset(offset, -secondary_bounds.height()); - break; - case DisplayLayout::RIGHT: - new_secondary_origin.Offset(primary_bounds.width(), offset); - break; - case DisplayLayout::BOTTOM: - new_secondary_origin.Offset(offset, primary_bounds.height()); - break; - case DisplayLayout::LEFT: - new_secondary_origin.Offset(-secondary_bounds.width(), offset); - break; - } - gfx::Insets insets = secondary_display->GetWorkAreaInsets(); - secondary_display->set_bounds( - gfx::Rect(new_secondary_origin, secondary_bounds.size())); - secondary_display->UpdateWorkAreaFromInsets(insets); + Shell::GetInstance()->display_manager()->UpdateDisplayBoundsForLayout( + layout, GetPrimaryDisplay(), GetSecondaryDisplay()); } void DisplayController::NotifyDisplayConfigurationChanging() { @@ -1038,6 +992,18 @@ void DisplayController::OnFadeOutForSwapDisplayFinished() { #endif } +DisplayLayout DisplayController::ComputeDisplayLayoutForDisplayIdPair( + const DisplayIdPair& pair) const { + DisplayLayout layout = GetRegisteredDisplayLayout(pair); + int64 primary_id = layout.primary_id; + // TODO(oshima): replace this with DCHECK. + if (primary_id == gfx::Display::kInvalidDisplayID) + primary_id = GetPrimaryDisplay().id(); + // Invert if the primary was swapped. If mirrored, first is always + // primary. + return pair.first == primary_id ? layout : layout.Invert(); +} + void DisplayController::UpdateHostWindowNames() { #if defined(USE_X11) // crbug.com/120229 - set the window title for the primary dislpay diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h index 5133c73..e895421 100644 --- a/ash/display/display_controller.h +++ b/ash/display/display_controller.h @@ -231,6 +231,12 @@ class ASH_EXPORT DisplayController : public gfx::DisplayObserver { void OnFadeOutForSwapDisplayFinished(); + // Returns the display layout for the display id pair + // with display swapping applied. That is, this returns + // flipped layout if the displays are swapped. + DisplayLayout ComputeDisplayLayoutForDisplayIdPair( + const DisplayIdPair& display_pair) const; + void UpdateHostWindowNames(); bool in_bootstrap() const { return in_bootstrap_; } diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc index 79be192..06168da 100644 --- a/ash/display/display_controller_unittest.cc +++ b/ash/display/display_controller_unittest.cc @@ -807,6 +807,7 @@ TEST_F(DisplayControllerTest, Rotate) { EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); +#if !defined(OS_WIN) aura::test::EventGenerator generator2(root_windows[1]); generator2.MoveMouseToInHost(50, 40); EXPECT_EQ("179,25", event_handler.GetLocationAndReset()); @@ -823,6 +824,7 @@ TEST_F(DisplayControllerTest, Rotate) { generator1.MoveMouseToInHost(50, 40); EXPECT_EQ("69,159", event_handler.GetLocationAndReset()); +#endif Shell::GetInstance()->RemovePreTargetHandler(&event_handler); } diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc index eceb643..5a24505 100644 --- a/ash/display/display_manager.cc +++ b/ash/display/display_manager.cc @@ -58,6 +58,10 @@ typedef std::vector<DisplayInfo> DisplayInfoList; namespace { +// The number of pixels to overlap between the primary and secondary displays, +// in case that the offset value is too large. +const int kMinimumOverlapForInvalidOffset = 100; + // List of value UI Scale values. Scales for 2x are equivalent to 640, // 800, 1024, 1280, 1440, 1600 and 1920 pixel width respectively on // 2560 pixel width 2x density display. Please see crbug.com/233375 @@ -192,6 +196,53 @@ float DisplayManager::GetNextUIScale(const DisplayInfo& info, bool up) { return 1.0f; } +void DisplayManager::UpdateDisplayBoundsForLayout( + const DisplayLayout& layout, + const gfx::Display& primary_display, + gfx::Display* secondary_display) { + + const gfx::Rect& primary_bounds = primary_display.bounds(); + DisplayController::GetPrimaryDisplay().bounds(); + + const gfx::Rect& secondary_bounds = secondary_display->bounds(); + gfx::Point new_secondary_origin = primary_bounds.origin(); + + DisplayLayout::Position position = layout.position; + + // Ignore the offset in case the secondary display doesn't share edges with + // the primary display. + int offset = layout.offset; + if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { + offset = std::min( + offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); + offset = std::max( + offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); + } else { + offset = std::min( + offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); + offset = std::max( + offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); + } + switch (position) { + case DisplayLayout::TOP: + new_secondary_origin.Offset(offset, -secondary_bounds.height()); + break; + case DisplayLayout::RIGHT: + new_secondary_origin.Offset(primary_bounds.width(), offset); + break; + case DisplayLayout::BOTTOM: + new_secondary_origin.Offset(offset, primary_bounds.height()); + break; + case DisplayLayout::LEFT: + new_secondary_origin.Offset(-secondary_bounds.width(), offset); + break; + } + gfx::Insets insets = secondary_display->GetWorkAreaInsets(); + secondary_display->set_bounds( + gfx::Rect(new_secondary_origin, secondary_bounds.size())); + secondary_display->UpdateWorkAreaFromInsets(insets); +} + bool DisplayManager::IsActiveDisplay(const gfx::Display& display) const { for (DisplayList::const_iterator iter = displays_.begin(); iter != displays_.end(); ++iter) { @@ -550,6 +601,17 @@ void DisplayManager::UpdateDisplays( display_controller->NotifyDisplayConfigurationChanging(); mouse_location_in_native = display_controller->GetNativeMouseCursorLocation(); + size_t updated_index; + if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) && + std::find(added_display_indices.begin(), + added_display_indices.end(), + updated_index) == added_display_indices.end() && + std::find(changed_display_indices.begin(), + changed_display_indices.end(), + updated_index) == changed_display_indices.end()) { + changed_display_indices.push_back(updated_index); + } + displays_ = new_displays; base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); @@ -685,6 +747,15 @@ std::string DisplayManager::GetDisplayNameForId(int64 id) { return base::StringPrintf("Display %d", static_cast<int>(id)); } +int64 DisplayManager::GetDisplayIdForUIScaling() const { + // UI Scaling is effective only on internal display. + int64 display_id = gfx::Display::InternalDisplayId(); +#if defined(OS_WIN) + display_id = first_display_id(); +#endif + return display_id; +} + void DisplayManager::SetMirrorMode(bool mirrored) { if (num_connected_displays() <= 1) return; @@ -768,15 +839,6 @@ void DisplayManager::SetSoftwareMirroring(bool enabled) { mirrored_display_ = gfx::Display(); } -int64 DisplayManager::GetDisplayIdForUIScaling() const { - // UI Scaling is effective only on internal display. - int64 display_id = gfx::Display::InternalDisplayId(); -#if defined(OS_WIN) - display_id = first_display_id(); -#endif - return display_id; -} - void DisplayManager::Init() { // TODO(oshima): Move this logic to DisplayChangeObserver. const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( @@ -863,5 +925,38 @@ gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { return new_display; } +bool DisplayManager::UpdateSecondaryDisplayBoundsForLayout( + DisplayList* displays, + size_t* updated_index) const { + if (displays->size() != 2U) + return false; + + DisplayController* controller = Shell::GetInstance()->display_controller(); + DisplayIdPair pair = + std::make_pair(displays->at(0).id(), displays->at(1).id()); + DisplayLayout layout = + controller->ComputeDisplayLayoutForDisplayIdPair(pair); + + // Ignore if a user has a old format (should be extremely rare) + // and this will be replaced with DCHECK. + if (layout.primary_id != gfx::Display::kInvalidDisplayID) { + size_t primary_index, secondary_index; + if (displays->at(0).id() == layout.primary_id) { + primary_index = 0; + secondary_index = 1; + } else { + primary_index = 1; + secondary_index = 0; + } + gfx::Rect bounds = + GetDisplayForId(displays->at(secondary_index).id()).bounds(); + UpdateDisplayBoundsForLayout( + layout, displays->at(primary_index), &displays->at(secondary_index)); + *updated_index = secondary_index; + return bounds != displays->at(secondary_index).bounds(); + } + return false; +} + } // namespace internal } // namespace ash diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h index f1e52f9..916b8ba 100644 --- a/ash/display/display_manager.h +++ b/ash/display/display_manager.h @@ -9,6 +9,7 @@ #include <vector> #include "ash/ash_export.h" +#include "ash/display/display_controller.h" #include "ash/display/display_info.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" @@ -54,6 +55,12 @@ class ASH_EXPORT DisplayManager : // Returns next valid UI scale. static float GetNextUIScale(const DisplayInfo& info, bool up); + // Updates the bounds of |secondary_display| according to |layout|. + static void UpdateDisplayBoundsForLayout( + const DisplayLayout& layout, + const gfx::Display& primary_display, + gfx::Display* secondary_display); + // When set to true, the MonitorManager calls OnDisplayBoundsChanged // even if the display's bounds didn't change. Used to swap primary // display. @@ -187,7 +194,7 @@ class ASH_EXPORT DisplayManager : void SetSoftwareMirroring(bool enabled); #endif - private: +private: FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint); FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged); FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, @@ -226,6 +233,14 @@ class ASH_EXPORT DisplayManager : // Creates a display object from the DisplayInfo for |display_id|. gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id); + // Updates the bounds of the secondary display in |display_list| + // using the layout registered for the display pair and set the + // index of display updated to |updated_index|. Returns true + // if the secondary display's bounds has been changed from current + // value, or false otherwise. + bool UpdateSecondaryDisplayBoundsForLayout(DisplayList* display_list, + size_t* updated_index) const; + int64 first_display_id_; gfx::Display mirrored_display_; diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 062a0e7..f1fc5de 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc @@ -118,7 +118,7 @@ class DisplayManagerTest : public test::AshTestBase, DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest); }; -TEST_F(DisplayManagerTest, NativeDisplayTest) { +TEST_F(DisplayManagerTest, UpdateDisplayTest) { if (!SupportsMultipleDisplays()) return; @@ -209,6 +209,15 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) { EXPECT_EQ("1000,1000 600x400", GetDisplayInfoAt(1).bounds_in_pixel().ToString()); reset(); + + // Changing primary will update secondary as well. + UpdateDisplay("0+0-800x600,1000+1000-600x400"); + EXPECT_EQ("2 0 0", GetCountSummary()); + reset(); + EXPECT_EQ("0,0 800x600", + display_manager()->GetDisplayAt(0)->bounds().ToString()); + EXPECT_EQ("800,0 600x400", + display_manager()->GetDisplayAt(1)->bounds().ToString()); } // Test in emulation mode (use_fullscreen_host_window=false) @@ -756,6 +765,20 @@ TEST_F(DisplayManagerTest, Rotate) { EXPECT_EQ("300x400", GetDisplayInfoAt(1).size_in_pixel().ToString()); + // Just Rotating display will change the bounds on both display. + UpdateDisplay("100x200/l,300x400"); + EXPECT_EQ("2 0 0", GetCountSummary()); + reset(); + + // Updating tothe same configuration should report no changes. + UpdateDisplay("100x200/l,300x400"); + EXPECT_EQ("0 0 0", GetCountSummary()); + reset(); + + UpdateDisplay("100x200/l,300x400"); + EXPECT_EQ("0 0 0", GetCountSummary()); + reset(); + UpdateDisplay("200x200"); EXPECT_EQ("1 0 1", GetCountSummary()); reset(); |