| Index: ui/gfx/screen_win.cc
|
| diff --git a/ui/gfx/screen_win.cc b/ui/gfx/screen_win.cc
|
| index 32326a45f8afd88b150f283efb8e8079f60395f4..d68ee725c45b21cdb7e9ceab5617227309f32e54 100644
|
| --- a/ui/gfx/screen_win.cc
|
| +++ b/ui/gfx/screen_win.cc
|
| @@ -9,6 +9,8 @@
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| #include "ui/gfx/display.h"
|
| +#include "ui/gfx/display_layout.h"
|
| +#include "ui/gfx/display_layout_builder.h"
|
| #include "ui/gfx/geometry/point.h"
|
| #include "ui/gfx/geometry/point_conversions.h"
|
| #include "ui/gfx/geometry/rect.h"
|
| @@ -16,7 +18,7 @@
|
| #include "ui/gfx/geometry/vector2d.h"
|
| #include "ui/gfx/win/display_info.h"
|
| #include "ui/gfx/win/dpi.h"
|
| -#include "ui/gfx/win/rect_util.h"
|
| +#include "ui/gfx/win/scaling_util.h"
|
| #include "ui/gfx/win/screen_win_display.h"
|
|
|
| namespace {
|
| @@ -24,21 +26,32 @@ namespace {
|
| gfx::ScreenWin* g_screen_win_instance = nullptr;
|
|
|
| std::vector<gfx::win::DisplayInfo>::const_iterator FindTouchingDisplayInfo(
|
| - const gfx::win::ScreenWinDisplay& screen_win_display,
|
| + const gfx::win::DisplayInfo& display_info,
|
| const std::vector<gfx::win::DisplayInfo>& display_infos) {
|
| auto end = display_infos.end();
|
| for (auto display_info_iter = display_infos.begin();
|
| display_info_iter != end;
|
| display_info_iter++) {
|
| - gfx::win::RectEdge edge =
|
| - gfx::win::FindTouchingRectEdge(screen_win_display.pixel_bounds(),
|
| - display_info_iter->screen_rect());
|
| - if (edge != gfx::win::RectEdge::NONE)
|
| + if (gfx::win::DisplayInfosTouch(display_info, *display_info_iter))
|
| return display_info_iter;
|
| }
|
| return end;
|
| }
|
|
|
| +gfx::Display CreateDisplayFromDisplayInfo(
|
| + const gfx::win::DisplayInfo& display_info) {
|
| + gfx::Display display(display_info.id());
|
| + float scale_factor = display_info.device_scale_factor();
|
| + display.set_device_scale_factor(scale_factor);
|
| + display.set_work_area(
|
| + gfx::ScaleToEnclosingRect(display_info.screen_work_rect(),
|
| + 1.0f / scale_factor));
|
| + display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(),
|
| + 1.0f / scale_factor));
|
| + display.set_rotation(display_info.rotation());
|
| + return display;
|
| +}
|
| +
|
| // Windows historically has had a hard time handling displays of DPIs higher
|
| // than 96. Handling multiple DPI displays means we have to deal with Windows'
|
| // monitor physical coordinates and map into Chrome's DIP coordinates.
|
| @@ -64,43 +77,62 @@ std::vector<gfx::win::DisplayInfo>::const_iterator FindTouchingDisplayInfo(
|
| // will take precedence.
|
| std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays(
|
| const std::vector<gfx::win::DisplayInfo>& display_infos) {
|
| - std::vector<gfx::win::DisplayInfo> display_infos_remaining = display_infos;
|
|
|
| - // Seed the primary display to layout all the other displays.
|
| - std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
|
| - for (auto current = display_infos_remaining.begin();
|
| - current != display_infos_remaining.end();
|
| - current++) {
|
| - if (current->screen_rect().origin().IsOrigin()) {
|
| - screen_win_displays.push_back(gfx::win::ScreenWinDisplay(*current));
|
| - display_infos_remaining.erase(current);
|
| + // DisplayLayout reasons over gfx::Displays and we need to add on pixel info
|
| + // after it finishes its layout. As a result, create a vector of displays now
|
| + // for mutation to maintain this gfx::Display - gfx::win::DisplayInfo
|
| + // correspondence to construct a ScreenWinDisplay.
|
| +
|
| + // Stage 1: display_infos <--> displays
|
| + // Stage 2: Layout
|
| + // Stage 3: display_infos + displays -> ScreenWinDisplay
|
| +
|
| + // Find and extract the primary display.
|
| + size_t primary_display_index = 0;
|
| + int64_t primary_display_id = 0;
|
| + const size_t num_displays = display_infos.size();
|
| + for (size_t i = 0; i < num_displays; ++i) {
|
| + if (display_infos[i].screen_rect().origin().IsOrigin()) {
|
| + primary_display_index = i;
|
| break;
|
| }
|
| }
|
|
|
| - // Scale touching display_infos relative to each other.
|
| - // If the DisplayInfo count doesn't change through one cycle of the loop, it
|
| - // either means we're done or we have non-touching DisplayInfos in the vector.
|
| + std::vector<gfx::win::DisplayInfo> display_infos_remaining = display_infos;
|
| + display_infos_remaining.erase(
|
| + display_infos_remaining.begin() + primary_display_id);
|
| + std::vector<gfx::win::DisplayInfo> rooted_display_infos;
|
| + rooted_display_infos.push_back(display_infos[primary_display_index]);
|
| + gfx::DisplayLayoutBuilder builder(display_infos[primary_display_id].id());
|
| +
|
| size_t display_infos_at_cycle_start = 0;
|
| while ((display_infos_remaining.size() > 0) &&
|
| (display_infos_remaining.size() != display_infos_at_cycle_start)) {
|
| display_infos_at_cycle_start = display_infos_remaining.size();
|
| - for (const auto& screen_win_display : screen_win_displays) {
|
| - auto display_info = FindTouchingDisplayInfo(screen_win_display,
|
| - display_infos_remaining);
|
| - if (display_info != display_infos_remaining.end()) {
|
| - screen_win_displays.push_back(
|
| - gfx::win::ScreenWinDisplay(screen_win_display, *display_info));
|
| - display_infos_remaining.erase(display_info);
|
| + for (const auto& rooted_display_info : rooted_display_infos) {
|
| + auto display_info_iter = FindTouchingDisplayInfo(rooted_display_info,
|
| + display_infos_remaining);
|
| + if (display_info_iter != display_infos_remaining.end()) {
|
| + builder.AddDisplayPlacement(
|
| + gfx::win::CalculateDisplayPlacement(rooted_display_info,
|
| + *display_info_iter));
|
| + rooted_display_infos.push_back(*display_info_iter);
|
| + display_infos_remaining.erase(display_info_iter);
|
| break;
|
| }
|
| }
|
| }
|
|
|
| - // Under Windows DPI virtualization, not all display_infos touch, so scale
|
| - // the remaining display infos relative to the origin.
|
| - for (const auto& display_info : display_infos_remaining)
|
| - screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info));
|
| + std::vector<gfx::Display> displays;
|
| + for (const auto& display_info : display_infos)
|
| + displays.push_back(CreateDisplayFromDisplayInfo(display_info));
|
| +
|
| + scoped_ptr<gfx::DisplayLayout> layout(builder.Build());
|
| + layout->ApplyToDisplayList(&displays, nullptr, 0);
|
| +
|
| + std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
|
| + for (size_t i = 0; i < num_displays; ++i)
|
| + screen_win_displays.emplace_back(displays[i], display_infos[i]);
|
|
|
| return screen_win_displays;
|
| }
|
|
|