Index: ui/gfx/screen_win.cc |
diff --git a/ui/gfx/screen_win.cc b/ui/gfx/screen_win.cc |
index 7dff9e90d8c686a899b75dfc1df303eb4f85d53b..7b2fcc3aa3f8569aadda44bef0fd6d74d3b03ace 100644 |
--- a/ui/gfx/screen_win.cc |
+++ b/ui/gfx/screen_win.cc |
@@ -15,6 +15,10 @@ |
namespace { |
+// The delay to handle the display changes notifications. |
+// See comments in ScreenWin::OnDisplayChanged. |
+const int64 kConfigureDelayMs = 500; |
+ |
MONITORINFOEX GetMonitorInfoForMonitor(HMONITOR monitor) { |
MONITORINFOEX monitor_info; |
ZeroMemory(&monitor_info, sizeof(MONITORINFOEX)); |
@@ -24,7 +28,6 @@ MONITORINFOEX GetMonitorInfoForMonitor(HMONITOR monitor) { |
} |
gfx::Display GetDisplay(MONITORINFOEX& monitor_info) { |
- // TODO(oshima): Implement Observer. |
int64 id = static_cast<int64>( |
base::Hash(base::WideToUTF8(monitor_info.szDevice))); |
gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor); |
@@ -79,6 +82,7 @@ BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, |
namespace gfx { |
ScreenWin::ScreenWin() { |
+ displays_ = BuildDisplays(); |
} |
ScreenWin::~ScreenWin() { |
@@ -111,10 +115,7 @@ int ScreenWin::GetNumDisplays() const { |
} |
std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { |
- std::vector<gfx::Display> all_displays; |
- EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, |
- reinterpret_cast<LPARAM>(&all_displays)); |
- return all_displays; |
+ return displays_; |
} |
gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { |
@@ -166,11 +167,11 @@ gfx::Display ScreenWin::GetPrimaryDisplay() const { |
} |
void ScreenWin::AddObserver(DisplayObserver* observer) { |
- // TODO(oshima): crbug.com/122863. |
+ change_notifier_.AddObserver(observer); |
} |
void ScreenWin::RemoveObserver(DisplayObserver* observer) { |
- // TODO(oshima): crbug.com/122863. |
+ change_notifier_.RemoveObserver(observer); |
} |
HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { |
@@ -183,4 +184,37 @@ NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { |
return NULL; |
} |
+std::vector<gfx::Display> ScreenWin::BuildDisplays() const { |
+ std::vector<gfx::Display> all_displays; |
+ EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, |
+ reinterpret_cast<LPARAM>(&all_displays)); |
+ return all_displays; |
+} |
+ |
+void ScreenWin::OnDisplayChanged() { |
+ // Windows send a WM_DISPLAYCHANGE message to all windows when the displays |
+ // change. This method will be called when this happen. In order to prevent |
+ // doing expensive work multiple time, we use a timer that will be reset |
+ // every time we get a new call and will be fulfilled kConfigureDelayMs after |
+ // the latest. |
+ if (configure_timer_.get() && configure_timer_->IsRunning()) { |
+ configure_timer_->Reset(); |
+ return; |
+ } |
+ |
+ configure_timer_.reset(new base::OneShotTimer<ScreenWin>()); |
+ configure_timer_->Start( |
+ FROM_HERE, |
+ base::TimeDelta::FromMilliseconds(kConfigureDelayMs), |
+ this, |
+ &ScreenWin::ConfigureTimerFired); |
+} |
+ |
+void ScreenWin::ConfigureTimerFired() { |
+ std::vector<gfx::Display> old_displays = displays_; |
+ displays_ = BuildDisplays(); |
+ |
+ change_notifier_.NotifyDisplaysChanged(old_displays, displays_); |
+} |
+ |
} // namespace gfx |