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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/panels/display_settings_provider.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "chrome/browser/fullscreen.h" 10 #include "ui/gfx/screen.h" 11 12 namespace { 13 // The polling interval to check any display settings change, like full-screen 14 // mode changes. 15 const int kFullScreenModeCheckIntervalMs = 1000; 16 } // namespace 17 18 DisplaySettingsProvider::DisplaySettingsProvider() 19 : is_full_screen_(false) { 20 } 21 22 DisplaySettingsProvider::~DisplaySettingsProvider() { 23 } 24 25 void DisplaySettingsProvider::AddDisplayObserver(DisplayObserver* observer) { 26 display_observers_.AddObserver(observer); 27 } 28 29 void DisplaySettingsProvider::RemoveDisplayObserver(DisplayObserver* observer) { 30 display_observers_.RemoveObserver(observer); 31 } 32 33 void DisplaySettingsProvider::AddDesktopBarObserver( 34 DesktopBarObserver* observer) { 35 desktop_bar_observers_.AddObserver(observer); 36 } 37 38 void DisplaySettingsProvider::RemoveDesktopBarObserver( 39 DesktopBarObserver* observer) { 40 desktop_bar_observers_.RemoveObserver(observer); 41 } 42 43 void DisplaySettingsProvider::AddFullScreenObserver( 44 FullScreenObserver* observer) { 45 is_full_screen_ = IsFullScreen(); 46 full_screen_observers_.AddObserver(observer); 47 48 if (full_screen_observers_.size() == 1 && NeedsPeriodicFullScreenCheck()) { 49 full_screen_mode_timer_.Start(FROM_HERE, 50 base::TimeDelta::FromMilliseconds(kFullScreenModeCheckIntervalMs), 51 base::Bind(&DisplaySettingsProvider::CheckFullScreenMode, 52 base::Unretained(this), 53 PERFORM_FULLSCREEN_CHECK)); 54 } 55 } 56 57 void DisplaySettingsProvider::RemoveFullScreenObserver( 58 FullScreenObserver* observer) { 59 full_screen_observers_.RemoveObserver(observer); 60 61 if (full_screen_observers_.size() == 0) 62 full_screen_mode_timer_.Stop(); 63 } 64 65 // TODO(scottmg): This should be moved to ui/. 66 gfx::Rect DisplaySettingsProvider::GetPrimaryDisplayArea() const { 67 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 68 return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds(); 69 } 70 71 gfx::Rect DisplaySettingsProvider::GetPrimaryWorkArea() const { 72 #if defined(OS_MACOSX) 73 // On OSX, panels should be dropped all the way to the bottom edge of the 74 // screen (and overlap Dock). And we also want to exclude the system menu 75 // area. Note that the rect returned from gfx::Screen util functions is in 76 // platform-independent screen coordinates with (0, 0) as the top-left corner. 77 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 78 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 79 gfx::Rect display_area = display.bounds(); 80 gfx::Rect work_area = display.work_area(); 81 int system_menu_height = work_area.y() - display_area.y(); 82 if (system_menu_height > 0) { 83 display_area.set_y(display_area.y() + system_menu_height); 84 display_area.set_height(display_area.height() - system_menu_height); 85 } 86 return display_area; 87 #else 88 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 89 return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area(); 90 #endif 91 } 92 93 gfx::Rect DisplaySettingsProvider::GetDisplayAreaMatching( 94 const gfx::Rect& bounds) const { 95 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 96 return gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).bounds(); 97 } 98 99 gfx::Rect DisplaySettingsProvider::GetWorkAreaMatching( 100 const gfx::Rect& bounds) const { 101 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 102 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); 103 gfx::Display display = screen->GetDisplayMatching(bounds); 104 if (display.bounds() == screen->GetPrimaryDisplay().bounds()) 105 return GetPrimaryWorkArea(); 106 return display.work_area(); 107 } 108 109 void DisplaySettingsProvider::OnDisplaySettingsChanged() { 110 FOR_EACH_OBSERVER(DisplayObserver, display_observers_, OnDisplayChanged()); 111 } 112 113 bool DisplaySettingsProvider::IsAutoHidingDesktopBarEnabled( 114 DesktopBarAlignment alignment) { 115 return false; 116 } 117 118 int DisplaySettingsProvider::GetDesktopBarThickness( 119 DesktopBarAlignment alignment) const { 120 return 0; 121 } 122 123 DisplaySettingsProvider::DesktopBarVisibility 124 DisplaySettingsProvider::GetDesktopBarVisibility( 125 DesktopBarAlignment alignment) const { 126 return DESKTOP_BAR_VISIBLE; 127 } 128 129 bool DisplaySettingsProvider::NeedsPeriodicFullScreenCheck() const { 130 return true; 131 } 132 133 void DisplaySettingsProvider::CheckFullScreenMode( 134 FullScreenCheckMode check_mode) { 135 bool is_full_screen = false; 136 switch (check_mode) { 137 case ASSUME_FULLSCREEN_ON: 138 is_full_screen = true; 139 break; 140 case ASSUME_FULLSCREEN_OFF: 141 is_full_screen = false; 142 break; 143 case PERFORM_FULLSCREEN_CHECK: 144 is_full_screen = IsFullScreen(); 145 break; 146 default: 147 NOTREACHED(); 148 break; 149 } 150 if (is_full_screen == is_full_screen_) 151 return; 152 is_full_screen_ = is_full_screen; 153 154 FOR_EACH_OBSERVER(FullScreenObserver, 155 full_screen_observers_, 156 OnFullScreenModeChanged(is_full_screen_)); 157 } 158 159 bool DisplaySettingsProvider::IsFullScreen() { 160 return IsFullScreenMode(); 161 } 162 163 #if defined(USE_AURA) 164 // static 165 DisplaySettingsProvider* DisplaySettingsProvider::Create() { 166 return new DisplaySettingsProvider(); 167 } 168 #endif 169