summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-21 04:08:57 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-21 04:08:57 +0000
commita11f03342dbb57db2a186e0211b71e8ead645397 (patch)
tree7a78907d017e5ddf86c443967dc9cc65c16c5270 /ash
parentb98e61c3c42d6c24e7de3b49f9bec8bec38d1f5f (diff)
downloadchromium_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.cc64
-rw-r--r--ash/display/display_controller.h6
-rw-r--r--ash/display/display_controller_unittest.cc2
-rw-r--r--ash/display/display_manager.cc113
-rw-r--r--ash/display/display_manager.h17
-rw-r--r--ash/display/display_manager_unittest.cc25
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();