Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: ui/gfx/screen_win.cc

Issue 1679393002: Multiple DPI Tracking for ScreenWin (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add rect_util_unittests to GN Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/screen_win.h" 5 #include "ui/gfx/screen_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "ui/gfx/display.h" 11 #include "ui/gfx/display.h"
12 #include "ui/gfx/geometry/point.h" 12 #include "ui/gfx/geometry/point.h"
13 #include "ui/gfx/geometry/point_conversions.h"
13 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/geometry/size.h"
16 #include "ui/gfx/geometry/vector2d.h"
14 #include "ui/gfx/win/display_info.h" 17 #include "ui/gfx/win/display_info.h"
15 #include "ui/gfx/win/dpi.h" 18 #include "ui/gfx/win/dpi.h"
19 #include "ui/gfx/win/rect_util.h"
16 #include "ui/gfx/win/screen_win_display.h" 20 #include "ui/gfx/win/screen_win_display.h"
17 21
18 namespace { 22 namespace {
19 23
24 gfx::ScreenWin* g_screen_win_instance = nullptr;
25
26 std::vector<gfx::win::DisplayInfo>::const_iterator FindTouchingDisplayInfo(
27 const gfx::win::ScreenWinDisplay& screen_win_display,
28 const std::vector<gfx::win::DisplayInfo>& display_infos) {
29 auto end = display_infos.end();
30 for (auto display_info_iter = display_infos.begin();
31 display_info_iter != end;
32 display_info_iter++) {
33 gfx::win::RectEdge edge =
34 gfx::win::FindTouchingRectEdge(screen_win_display.pixel_bounds(),
35 display_info_iter->screen_rect());
36 if (edge != gfx::win::RectEdge::NONE)
37 return display_info_iter;
38 }
39 return end;
40 }
41
42 // Windows historically has had a hard time handling displays of DPIs higher
43 // than 96. Handling multiple DPI displays means we have to deal with Windows'
44 // monitor physical coordinates and map into Chrome's DIP coordinates.
45 //
46 // To do this, DisplayInfosToScreenWinDisplays reasons over monitors as a tree
47 // using the primary monitor as the root. Any monitor touching this root is
48 // considered a child. Subsequent generations are formed similarly, having
49 // preferring parents that are discovered earlier. As a result, if there is a
50 // monitor that touches two other monitors, the earliest discovered monitor is
51 // the parent.
52 //
53 // This also presumes that all monitors are connected components. Windows, by UI
54 // construction restricts the layout of monitors to connected components except
55 // when DPI virtualization is happening. When this happens, we scale relative
56 // to (0, 0) like before.
57 //
58 // All subsequent scaling transformations are performed with respect to the
59 // calculated physical-DIP mapping on ScreenWinDisplay.
60 //
61 // Note that this does not handle cases where a scaled display may have
62 // insufficient room to lay out its children. In these cases, a DIP point could
63 // map to multiple screen points due to overlap. The first discovered screen
64 // will take precedence.
20 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays( 65 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays(
21 const std::vector<gfx::win::DisplayInfo>& display_infos) { 66 const std::vector<gfx::win::DisplayInfo>& display_infos) {
67 std::vector<gfx::win::DisplayInfo> display_infos_remaining = display_infos;
68
69 // Seed the primary display to layout all the other displays.
22 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays; 70 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
23 for (const auto& display_info : display_infos) 71 for (auto current = display_infos_remaining.begin();
72 current != display_infos_remaining.end();
73 current++) {
74 if (current->screen_rect().origin().IsOrigin()) {
75 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(*current));
76 display_infos_remaining.erase(current);
77 break;
78 }
79 }
80
81 // Scale touching display_infos relative to each other.
82 // If the DisplayInfo count doesn't change through one cycle of the loop, it
83 // either means we're done or we have non-touching DisplayInfos in the vector.
84 size_t display_infos_at_cycle_start = 0;
85 while ((display_infos_remaining.size() > 0) &&
86 (display_infos_remaining.size() != display_infos_at_cycle_start)) {
87 display_infos_at_cycle_start = display_infos_remaining.size();
88 for (const auto& screen_win_display : screen_win_displays) {
89 auto display_info = FindTouchingDisplayInfo(screen_win_display,
90 display_infos_remaining);
91 if (display_info != display_infos_remaining.end()) {
92 screen_win_displays.push_back(
93 gfx::win::ScreenWinDisplay(screen_win_display, *display_info));
94 display_infos_remaining.erase(display_info);
95 break;
96 }
97 }
98 }
99
100 // Under Windows DPI virtualization, not all display_infos touch, so scale
101 // the remaining display infos relative to the origin.
102 for (const auto& display_info : display_infos_remaining)
24 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info)); 103 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info));
25 104
26 return screen_win_displays; 105 return screen_win_displays;
27 } 106 }
28 107
29 std::vector<gfx::Display> ScreenWinDisplaysToDisplays( 108 std::vector<gfx::Display> ScreenWinDisplaysToDisplays(
30 const std::vector<gfx::win::ScreenWinDisplay>& screen_win_displays) { 109 const std::vector<gfx::win::ScreenWinDisplay>& screen_win_displays) {
31 std::vector<gfx::Display> displays; 110 std::vector<gfx::Display> displays;
32 for (const auto& screen_win_display : screen_win_displays) 111 for (const auto& screen_win_display : screen_win_displays)
33 displays.push_back(screen_win_display.display()); 112 displays.push_back(screen_win_display.display());
(...skipping 24 matching lines...) Expand all
58 137
59 std::vector<gfx::win::DisplayInfo> GetDisplayInfosFromSystem() { 138 std::vector<gfx::win::DisplayInfo> GetDisplayInfosFromSystem() {
60 std::vector<gfx::win::DisplayInfo> display_infos; 139 std::vector<gfx::win::DisplayInfo> display_infos;
61 EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback, 140 EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback,
62 reinterpret_cast<LPARAM>(&display_infos)); 141 reinterpret_cast<LPARAM>(&display_infos));
63 DCHECK_EQ(static_cast<size_t>(::GetSystemMetrics(SM_CMONITORS)), 142 DCHECK_EQ(static_cast<size_t>(::GetSystemMetrics(SM_CMONITORS)),
64 display_infos.size()); 143 display_infos.size());
65 return display_infos; 144 return display_infos;
66 } 145 }
67 146
147 // Returns a point in |to_origin|'s coordinates and position scaled by
148 // |scale_factor|.
149 gfx::Point ScalePointRelative(const gfx::Point& from_origin,
150 const gfx::Point& to_origin,
151 const float scale_factor,
152 const gfx::Point& point) {
153 gfx::Vector2d from_origin_vector(from_origin.x(), from_origin.y());
154 gfx::Vector2d to_origin_vector(to_origin.x(), to_origin.y());
155 gfx::Point scaled_relative_point(
156 gfx::ScaleToFlooredPoint(point - from_origin_vector, scale_factor));
157 return scaled_relative_point + to_origin_vector;
158 }
159
68 } // namespace 160 } // namespace
69 161
70 namespace gfx { 162 namespace gfx {
71 163
72 ScreenWin::ScreenWin() { 164 ScreenWin::ScreenWin() {
165 DCHECK(g_screen_win_instance == nullptr);
oshima 2016/02/11 22:59:58 DCHECK(!g_screen_win_instance) is more common
robliao 2016/02/12 01:52:53 Done.
166 g_screen_win_instance = this;
73 Initialize(); 167 Initialize();
74 } 168 }
75 169
76 ScreenWin::~ScreenWin() = default; 170 ScreenWin::~ScreenWin() {
171 DCHECK(g_screen_win_instance == this);
172 g_screen_win_instance = nullptr;
173 }
174
175 // static
176 Point ScreenWin::ScreenToDIPPoint(const Point& pixel_point) {
177 const gfx::win::ScreenWinDisplay screen_win_display =
178 ScreenWin::GetScreenWinDisplayVia(
179 &ScreenWin::GetScreenWinDisplayNearestScreenPoint, pixel_point);
180 const Display display = screen_win_display.display();
181 return ScalePointRelative(screen_win_display.pixel_bounds().origin(),
182 display.bounds().origin(),
183 1.0f / display.device_scale_factor(),
184 pixel_point);
185 }
186
187 // static
188 Point ScreenWin::DIPToScreenPoint(const Point& dip_point) {
189 const gfx::win::ScreenWinDisplay screen_win_display =
190 ScreenWin::GetScreenWinDisplayVia(
191 &ScreenWin::GetScreenWinDisplayNearestDIPPoint, dip_point);
192 const Display display = screen_win_display.display();
193 return ScalePointRelative(display.bounds().origin(),
194 screen_win_display.pixel_bounds().origin(),
195 display.device_scale_factor(),
196 dip_point);
197 }
198
199 // static
200 Point ScreenWin::ClientToDIPPoint(HWND hwnd, const Point& client_point) {
201 const float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
202 return ScaleToFlooredPoint(client_point, 1.0f / scale_factor);
203 }
204
205 // static
206 Point ScreenWin::DIPToClientPoint(HWND hwnd, const Point& dip_point) {
207 float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
208 return ScaleToFlooredPoint(dip_point, scale_factor);
209 }
210
211 // static
212 Rect ScreenWin::ScreenToDIPRect(HWND hwnd, const Rect& pixel_bounds) {
213 float scale_factor = hwnd ?
214 ScreenWin::GetScaleFactorForHWND(hwnd) :
215 ScreenWin::GetScreenWinDisplayVia(
216 &ScreenWin::GetScreenWinDisplayNearestScreenRect, pixel_bounds).
217 display().device_scale_factor();
218 gfx::Rect dip_rect = ScaleToEnclosingRect(pixel_bounds, 1.0f / scale_factor);
219 dip_rect.set_origin(ScreenWin::ScreenToDIPPoint(pixel_bounds.origin()));
220 return dip_rect;
221 }
222
223 // static
224 Rect ScreenWin::DIPToScreenRect(HWND hwnd, const Rect& dip_bounds) {
225 float scale_factor = hwnd ?
226 ScreenWin::GetScaleFactorForHWND(hwnd) :
227 ScreenWin::GetScreenWinDisplayVia(
228 &ScreenWin::GetScreenWinDisplayNearestDIPRect, dip_bounds).
229 display().device_scale_factor();
230 gfx::Rect screen_rect = ScaleToEnclosingRect(dip_bounds, scale_factor);
231 screen_rect.set_origin(ScreenWin::DIPToScreenPoint(dip_bounds.origin()));
232 return screen_rect;
233 }
234
235 // static
236 Rect ScreenWin::ClientToDIPRect(HWND hwnd, const Rect& pixel_bounds) {
237 float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
238 return ScaleToEnclosingRect(pixel_bounds, 1.0f / scale_factor);
239 }
240
241 // static
242 Rect ScreenWin::DIPToClientRect(HWND hwnd, const Rect& dip_bounds) {
243 float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
244 return ScaleToEnclosingRect(dip_bounds, scale_factor);
245 }
246
247 // static
248 Size ScreenWin::ScreenToDIPSize(HWND hwnd, const Size& size_in_pixels) {
249 float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
250 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
251 return ScaleToCeiledSize(size_in_pixels, 1.0f / scale_factor);
252 }
253
254 // static
255 Size ScreenWin::DIPToScreenSize(HWND hwnd, const Size& dip_size) {
256 float scale_factor = ScreenWin::GetScaleFactorForHWND(hwnd);
257 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
258 return ScaleToCeiledSize(dip_size, scale_factor);
259 }
77 260
78 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { 261 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const {
79 NOTREACHED(); 262 NOTREACHED();
80 return nullptr; 263 return nullptr;
81 } 264 }
82 265
83 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { 266 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const {
84 NOTREACHED(); 267 NOTREACHED();
85 return nullptr; 268 return nullptr;
86 } 269 }
87 270
88 gfx::Point ScreenWin::GetCursorScreenPoint() { 271 gfx::Point ScreenWin::GetCursorScreenPoint() {
89 POINT pt; 272 POINT pt;
90 ::GetCursorPos(&pt); 273 ::GetCursorPos(&pt);
91 gfx::Point cursor_pos_pixels(pt); 274 gfx::Point cursor_pos_pixels(pt);
92 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels); 275 return ScreenWin::ScreenToDIPPoint(cursor_pos_pixels);
93 } 276 }
94 277
95 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() { 278 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() {
96 POINT cursor_loc; 279 POINT cursor_loc;
97 HWND hwnd = 280 HWND hwnd =
98 ::GetCursorPos(&cursor_loc) ? ::WindowFromPoint(cursor_loc) : nullptr; 281 ::GetCursorPos(&cursor_loc) ? ::WindowFromPoint(cursor_loc) : nullptr;
99 return GetNativeWindowFromHWND(hwnd); 282 return GetNativeWindowFromHWND(hwnd);
100 } 283 }
101 284
102 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) { 285 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) {
103 gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point); 286 gfx::Point point_in_pixels = ScreenWin::DIPToScreenPoint(point);
104 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT())); 287 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT()));
105 } 288 }
106 289
107 int ScreenWin::GetNumDisplays() const { 290 int ScreenWin::GetNumDisplays() const {
108 return static_cast<int>(screen_win_displays_.size()); 291 return static_cast<int>(screen_win_displays_.size());
109 } 292 }
110 293
111 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { 294 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const {
112 return ScreenWinDisplaysToDisplays(screen_win_displays_); 295 return ScreenWinDisplaysToDisplays(screen_win_displays_);
113 } 296 }
114 297
115 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { 298 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const {
116 HWND window_hwnd = GetHWNDFromNativeView(window); 299 HWND window_hwnd = GetHWNDFromNativeView(window);
117 if (!window_hwnd) { 300 if (!window_hwnd) {
118 // When |window| isn't rooted to a display, we should just return the 301 // When |window| isn't rooted to a display, we should just return the
119 // default display so we get some correct display information like the 302 // default display so we get some correct display information like the
120 // scaling factor. 303 // scaling factor.
121 return GetPrimaryDisplay(); 304 return GetPrimaryDisplay();
122 } 305 }
123 gfx::win::ScreenWinDisplay screen_win_display = 306 gfx::win::ScreenWinDisplay screen_win_display =
124 GetScreenWinDisplayNearestHWND(window_hwnd); 307 GetScreenWinDisplayNearestHWND(window_hwnd);
125 return screen_win_display.display(); 308 return screen_win_display.display();
126 } 309 }
127 310
128 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { 311 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const {
129 gfx::Point screen_point(gfx::win::DIPToScreenPoint(point)); 312 gfx::Point screen_point(ScreenWin::DIPToScreenPoint(point));
130 gfx::win::ScreenWinDisplay screen_win_display = 313 gfx::win::ScreenWinDisplay screen_win_display =
131 GetScreenWinDisplayNearestScreenPoint(screen_point); 314 GetScreenWinDisplayNearestScreenPoint(screen_point);
132 return screen_win_display.display(); 315 return screen_win_display.display();
133 } 316 }
134 317
135 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const { 318 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const {
136 gfx::win::ScreenWinDisplay screen_win_display = 319 gfx::win::ScreenWinDisplay screen_win_display =
137 GetScreenWinDisplayNearestScreenRect(match_rect); 320 GetScreenWinDisplayNearestScreenRect(match_rect);
138 return screen_win_display.display(); 321 return screen_win_display.display();
139 } 322 }
140 323
141 gfx::Display ScreenWin::GetPrimaryDisplay() const { 324 gfx::Display ScreenWin::GetPrimaryDisplay() const {
142 return GetPrimaryScreenWinDisplay().display(); 325 return GetPrimaryScreenWinDisplay().display();
143 } 326 }
144 327
145 void ScreenWin::AddObserver(DisplayObserver* observer) { 328 void ScreenWin::AddObserver(DisplayObserver* observer) {
146 change_notifier_.AddObserver(observer); 329 change_notifier_.AddObserver(observer);
147 } 330 }
148 331
149 void ScreenWin::RemoveObserver(DisplayObserver* observer) { 332 void ScreenWin::RemoveObserver(DisplayObserver* observer) {
150 change_notifier_.RemoveObserver(observer); 333 change_notifier_.RemoveObserver(observer);
151 } 334 }
152 335
336 gfx::Rect ScreenWin::ScreenToDIPRectInWindow(
337 NativeView view, const gfx::Rect& screen_rect) const {
338 HWND hwnd = view ? GetHWNDFromNativeView(view) : NULL;
oshima 2016/02/11 22:59:58 nit: nullptr throughout the CL
robliao 2016/02/12 01:52:53 Done.
339 return ScreenWin::ScreenToDIPRect(hwnd, screen_rect);
340 }
341
342 gfx::Rect ScreenWin::DIPToScreenRectInWindow(NativeView view,
343 const gfx::Rect& dip_rect) const {
344 HWND hwnd = view ? GetHWNDFromNativeView(view) : NULL;
345 return ScreenWin::DIPToScreenRect(hwnd, dip_rect);
346 }
347
153 void ScreenWin::UpdateFromDisplayInfos( 348 void ScreenWin::UpdateFromDisplayInfos(
154 const std::vector<gfx::win::DisplayInfo>& display_infos) { 349 const std::vector<gfx::win::DisplayInfo>& display_infos) {
155 screen_win_displays_ = DisplayInfosToScreenWinDisplays(display_infos); 350 screen_win_displays_ = DisplayInfosToScreenWinDisplays(display_infos);
156 } 351 }
157 352
158 void ScreenWin::Initialize() { 353 void ScreenWin::Initialize() {
159 singleton_hwnd_observer_.reset( 354 singleton_hwnd_observer_.reset(
160 new gfx::SingletonHwndObserver( 355 new gfx::SingletonHwndObserver(
161 base::Bind(&ScreenWin::OnWndProc, base::Unretained(this)))); 356 base::Bind(&ScreenWin::OnWndProc, base::Unretained(this))));
162 UpdateFromDisplayInfos(GetDisplayInfosFromSystem()); 357 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenRect( 401 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenRect(
207 const Rect& screen_rect) const { 402 const Rect& screen_rect) const {
208 return GetScreenWinDisplay(MonitorInfoFromScreenRect(screen_rect)); 403 return GetScreenWinDisplay(MonitorInfoFromScreenRect(screen_rect));
209 } 404 }
210 405
211 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenPoint( 406 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenPoint(
212 const Point& screen_point) const { 407 const Point& screen_point) const {
213 return GetScreenWinDisplay(MonitorInfoFromScreenPoint(screen_point)); 408 return GetScreenWinDisplay(MonitorInfoFromScreenPoint(screen_point));
214 } 409 }
215 410
411 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestDIPPoint(
412 const Point& dip_point) const {
413 gfx::win::ScreenWinDisplay primary_screen_win_display;
414 for (const auto& screen_win_display : screen_win_displays_) {
415 Display display = screen_win_display.display();
416 const gfx::Rect dip_bounds = display.bounds();
417 if (dip_bounds.Contains(dip_point))
418 return screen_win_display;
419 else if (dip_bounds.origin().IsOrigin())
420 primary_screen_win_display = screen_win_display;
421 }
422 return primary_screen_win_display;
423 }
424
425 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestDIPRect(
426 const Rect& dip_rect) const {
427 gfx::win::ScreenWinDisplay closest_screen_win_display;
428 int64_t closest_distance_squared = INT64_MAX;
429 for (const auto& screen_win_display : screen_win_displays_) {
430 Display display = screen_win_display.display();
431 gfx::Rect dip_bounds = display.bounds();
432 int64_t distance_squared =
433 gfx::win::SquaredDistanceBetweenRects(dip_rect, dip_bounds);
oshima 2016/02/11 22:59:58 can this be manhattan distance? you can also move
robliao 2016/02/12 01:52:53 Using Manhattan distance seems like it would retur
434 if (distance_squared == 0) {
435 return screen_win_display;
436 } else if (distance_squared < closest_distance_squared) {
437 closest_distance_squared = distance_squared;
438 closest_screen_win_display = screen_win_display;
439 }
440 }
441 return closest_screen_win_display;
442 }
443
216 gfx::win::ScreenWinDisplay ScreenWin::GetPrimaryScreenWinDisplay() const { 444 gfx::win::ScreenWinDisplay ScreenWin::GetPrimaryScreenWinDisplay() const {
217 MONITORINFOEX monitor_info = MonitorInfoFromWindow(nullptr, 445 MONITORINFOEX monitor_info = MonitorInfoFromWindow(nullptr,
218 MONITOR_DEFAULTTOPRIMARY); 446 MONITOR_DEFAULTTOPRIMARY);
219 gfx::win::ScreenWinDisplay screen_win_display = 447 gfx::win::ScreenWinDisplay screen_win_display =
220 GetScreenWinDisplay(monitor_info); 448 GetScreenWinDisplay(monitor_info);
221 gfx::Display display = screen_win_display.display(); 449 gfx::Display display = screen_win_display.display();
222 // The Windows primary monitor is defined to have an origin of (0, 0). 450 // The Windows primary monitor is defined to have an origin of (0, 0).
223 DCHECK_EQ(0, display.bounds().origin().x()); 451 DCHECK_EQ(0, display.bounds().origin().x());
224 DCHECK_EQ(0, display.bounds().origin().y()); 452 DCHECK_EQ(0, display.bounds().origin().y());
225 return screen_win_display; 453 return screen_win_display;
226 } 454 }
227 455
228 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplay( 456 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplay(
229 const MONITORINFOEX& monitor_info) const { 457 const MONITORINFOEX& monitor_info) const {
230 int64_t id = 458 int64_t id =
231 gfx::win::DisplayInfo::DeviceIdFromDeviceName(monitor_info.szDevice); 459 gfx::win::DisplayInfo::DeviceIdFromDeviceName(monitor_info.szDevice);
232 for (const auto& screen_win_display : screen_win_displays_) { 460 for (const auto& screen_win_display : screen_win_displays_) {
233 if (screen_win_display.display().id() == id) 461 if (screen_win_display.display().id() == id)
234 return screen_win_display; 462 return screen_win_display;
235 } 463 }
236 // There is 1:1 correspondence between MONITORINFOEX and ScreenWinDisplay. 464 // There is 1:1 correspondence between MONITORINFOEX and ScreenWinDisplay.
237 // If we make it here, it means we have no displays and we should hand out the 465 // If we make it here, it means we have no displays and we should hand out the
238 // default display. 466 // default display.
239 DCHECK_EQ(screen_win_displays_.size(), 0u); 467 DCHECK_EQ(screen_win_displays_.size(), 0u);
240 return gfx::win::ScreenWinDisplay(); 468 return gfx::win::ScreenWinDisplay();
241 } 469 }
242 470
471 // static
472 float ScreenWin::GetScaleFactorForHWND(HWND hwnd) {
473 if (!g_screen_win_instance)
474 return gfx::win::ScreenWinDisplay().display().device_scale_factor();
475
476 DCHECK(hwnd);
477 HWND rootHwnd = g_screen_win_instance->GetRootWindow(hwnd);
478 gfx::win::ScreenWinDisplay screen_win_display =
479 g_screen_win_instance->GetScreenWinDisplayNearestHWND(rootHwnd);
480 return screen_win_display.display().device_scale_factor();
481 }
482
483 // static
484 template <typename Getter, typename GetterType>
485 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayVia(Getter getter,
486 GetterType value) {
487 if (!g_screen_win_instance)
488 return gfx::win::ScreenWinDisplay();
489
490 return (g_screen_win_instance->*getter)(value);
491 }
492
243 } // namespace gfx 493 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698