Index: ui/gfx/screen_win.h |
diff --git a/ui/gfx/screen_win.h b/ui/gfx/screen_win.h |
index b1488ae05bb850b9cfc4cfa762219b56d47ff5d0..715f434c0e987243ccaac6c429cc3325bebdc183 100644 |
--- a/ui/gfx/screen_win.h |
+++ b/ui/gfx/screen_win.h |
@@ -5,21 +5,108 @@ |
#ifndef UI_GFX_SCREEN_WIN_H_ |
#define UI_GFX_SCREEN_WIN_H_ |
-#include "base/compiler_specific.h" |
-#include "base/gtest_prod_util.h" |
+#include <vector> |
+ |
#include "base/macros.h" |
-#include "base/memory/scoped_ptr.h" |
#include "ui/gfx/display_change_notifier.h" |
#include "ui/gfx/gfx_export.h" |
#include "ui/gfx/screen.h" |
-#include "ui/gfx/win/singleton_hwnd_observer.h" |
+#include "ui/gfx/win/display_manager_observer.h" |
namespace gfx { |
-class GFX_EXPORT ScreenWin : public Screen { |
+class Point; |
+class Rect; |
+class Size; |
+ |
+namespace win { |
+ |
+class DisplayInfo; |
+class DisplayManager; |
+class ScreenWinDisplay; |
+ |
+} // namespace win |
+ |
+// 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. |
+// |
+// To do this, ScreenWin reasons over monitors as a tree using the primary |
+// monitor as the root. Any monitor touching this root is considered a child. |
+// Subsequent generations are formed similarly, having preferring parents that |
+// are discovered earlier. As a result, if there is a monitor that touches two |
+// other monitors, the earliest discovered monitor is the parent. |
+// |
+// This also presumes that all monitors are connected components. Windows, by UI |
+// construction restricts the layout of monitors to connected components. |
+// |
+// All scaling transformations are performed with respect to this physical-DIP |
+// mapping. |
+// |
+// Note that this does not handle cases where a scaled display may have |
+// insufficent room to lay out its children. In these cases, a DIP point could |
+// map to multiple screen points due to overlap. The first discovered screen |
+// will take precedence. |
+class GFX_EXPORT ScreenWin : public Screen, |
+ public gfx::win::DisplayManagerObserver { |
public: |
ScreenWin(); |
- ~ScreenWin() override; |
+ virtual ~ScreenWin() override; |
+ |
+ // Converts a screen pixel point to a DIP point. |
+ // The DPI scale is performed relative to the display containing the screen |
+ // pixel point maintaining a constant origin on both Screen and DIP (same as |
+ // Windows). |
+ static Point ScreenToDIPPoint(const Point& pixel_point); |
+ |
+ // Converts a DIP point to a screen pixel point. |
+ // The DPI scale is performed relative to the display containing the DIP point |
+ // maintaining a constant origin on both Screen and DIP (same as Windows). |
+ static Point DIPToScreenPoint(const Point& dip_point); |
+ |
+ // Converts a client pixel point relative to |hwnd| to a DIP point. |
+ // The DPI scale is performed relative to |hwnd| using an origin of (0, 0). |
+ static Point ClientToDIPPoint(HWND hwnd, const Point& client_point); |
+ |
+ // Converts a client DIP point relative to |hwnd| to a client pixel point. |
+ // The DPI scale is performed relative to |hwnd| using an origin of (0, 0). |
+ static Point DIPToClientPoint(HWND hwnd, const Point& dip_point); |
+ |
+ // WARNING: there is no right way to scale sizes and rects. The implementation |
+ // of these strives to maintain a constant size by scaling the size |
+ // independent of the origin. An alternative is to get the enclosing rect, |
+ // which is the right way for some situations. Understand which you need |
+ // before blindly assuming this is the right way. |
+ |
+ // Converts a screen rect to a DIP rect. |
+ // The DPI scale is performed relative to the display nearest to |hwnd| |
+ // maintaining a constant origin on both Screen and DIP (same as Windows). |
+ // If |hwnd| is null, scaling will be performed to the display nearest to |
+ // |pixel_bounds|. |
+ static Rect ScreenToDIPRect(HWND hwnd, const Rect& pixel_bounds); |
+ |
+ // Converts a DIP rect to a screen rect. |
+ // The DPI scale is performed relative to the display nearest to |hwnd| |
+ // maintaining a constant origin on both Screen and DIP (same as Windows). |
+ // If |hwnd| is null, scaling will be performed to the display nearest to |
+ // |dip_bounds|. |
+ static Rect DIPToScreenRect(HWND hwnd, const Rect& dip_bounds); |
+ |
+ // Converts a client rect to a DIP rect. |
+ // The DPI scale is performed relative to |hwnd| using an origin of (0, 0). |
+ static Rect ClientToDIPRect(HWND hwnd, const Rect& pixel_bounds); |
+ |
+ // Converts a DIP rect to a client rect. |
+ // The DPI scale is performed relative to |hwnd| using an origin of (0, 0). |
+ static Rect DIPToClientRect(HWND hwnd, const Rect& dip_bounds); |
+ |
+ // Converts a screen size to a DIP size. |
+ // The DPI scale is performed relative to the display nearest to |hwnd|. |
+ static Size ScreenToDIPSize(HWND hwnd, const Size& size_in_pixels); |
+ |
+ // Converts a DIP size to a screen size. |
+ // The DPI scale is performed relative to the display nearest to |hwnd|. |
+ static Size DIPToScreenSize(HWND hwnd, const Size& dip_size); |
// Returns the HWND associated with the NativeView. |
virtual HWND GetHWNDFromNativeView(NativeView window) const; |
@@ -40,23 +127,22 @@ class GFX_EXPORT ScreenWin : public Screen { |
gfx::Display GetPrimaryDisplay() const override; |
void AddObserver(DisplayObserver* observer) override; |
void RemoveObserver(DisplayObserver* observer) override; |
+ gfx::Rect ScreenToDIPRectInWindow( |
+ NativeView view, const gfx::Rect& screen_rect) const override; |
+ gfx::Rect DIPToScreenRectInWindow( |
+ NativeView view, const gfx::Rect& dip_rect) const override; |
- private: |
- FRIEND_TEST_ALL_PREFIXES(ScreenWinTest, SingleDisplay1x); |
- FRIEND_TEST_ALL_PREFIXES(ScreenWinTest, SingleDisplay2x); |
- |
- void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); |
- |
- static std::vector<gfx::Display> GetDisplaysForMonitorInfos( |
- const std::vector<MONITORINFOEX>& monitor_infos); |
+ // Overridden from gfx::win::DisplayManagerObserver: |
+ void OnDisplaysChanged( |
+ const std::vector<gfx::win::ScreenWinDisplay> old_screen_win_displays, |
+ const std::vector<gfx::win::ScreenWinDisplay> new_screen_win_displays) |
+ override; |
+ private: |
// Helper implementing the DisplayObserver handling. |
gfx::DisplayChangeNotifier change_notifier_; |
- scoped_ptr<SingletonHwndObserver> singleton_hwnd_observer_; |
- |
- // Current list of displays. |
- std::vector<gfx::Display> displays_; |
+ gfx::win::DisplayManager* display_manager_; |
DISALLOW_COPY_AND_ASSIGN(ScreenWin); |
}; |