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 bool already_started = full_screen_observers_.might_have_observers(); 47 full_screen_observers_.AddObserver(observer); 48 49 if (!already_started && NeedsPeriodicFullScreenCheck()) { 50 full_screen_mode_timer_.Start(FROM_HERE, 51 base::TimeDelta::FromMilliseconds(kFullScreenModeCheckIntervalMs), 52 base::Bind(&DisplaySettingsProvider::CheckFullScreenMode, 53 base::Unretained(this), 54 PERFORM_FULLSCREEN_CHECK)); 55 } 56 } 57 58 void DisplaySettingsProvider::RemoveFullScreenObserver( 59 FullScreenObserver* observer) { 60 full_screen_observers_.RemoveObserver(observer); 61 62 if (!full_screen_observers_.might_have_observers()) 63 full_screen_mode_timer_.Stop(); 64 } 65 66 // TODO(scottmg): This should be moved to ui/. 67 gfx::Rect DisplaySettingsProvider::GetPrimaryDisplayArea() const { 68 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 69 return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds(); 70 } 71 72 gfx::Rect DisplaySettingsProvider::GetPrimaryWorkArea() const { 73 #if defined(OS_MACOSX) 74 // On OSX, panels should be dropped all the way to the bottom edge of the 75 // screen (and overlap Dock). And we also want to exclude the system menu 76 // area. Note that the rect returned from gfx::Screen util functions is in 77 // platform-independent screen coordinates with (0, 0) as the top-left corner. 78 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 79 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 80 gfx::Rect display_area = display.bounds(); 81 gfx::Rect work_area = display.work_area(); 82 int system_menu_height = work_area.y() - display_area.y(); 83 if (system_menu_height > 0) { 84 display_area.set_y(display_area.y() + system_menu_height); 85 display_area.set_height(display_area.height() - system_menu_height); 86 } 87 return display_area; 88 #else 89 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 90 return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area(); 91 #endif 92 } 93 94 gfx::Rect DisplaySettingsProvider::GetDisplayAreaMatching( 95 const gfx::Rect& bounds) const { 96 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 97 return gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).bounds(); 98 } 99 100 gfx::Rect DisplaySettingsProvider::GetWorkAreaMatching( 101 const gfx::Rect& bounds) const { 102 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 103 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); 104 gfx::Display display = screen->GetDisplayMatching(bounds); 105 if (display.bounds() == screen->GetPrimaryDisplay().bounds()) 106 return GetPrimaryWorkArea(); 107 return display.work_area(); 108 } 109 110 void DisplaySettingsProvider::OnDisplaySettingsChanged() { 111 FOR_EACH_OBSERVER(DisplayObserver, display_observers_, OnDisplayChanged()); 112 } 113 114 bool DisplaySettingsProvider::IsAutoHidingDesktopBarEnabled( 115 DesktopBarAlignment alignment) { 116 return false; 117 } 118 119 int DisplaySettingsProvider::GetDesktopBarThickness( 120 DesktopBarAlignment alignment) const { 121 return 0; 122 } 123 124 DisplaySettingsProvider::DesktopBarVisibility 125 DisplaySettingsProvider::GetDesktopBarVisibility( 126 DesktopBarAlignment alignment) const { 127 return DESKTOP_BAR_VISIBLE; 128 } 129 130 bool DisplaySettingsProvider::NeedsPeriodicFullScreenCheck() const { 131 return true; 132 } 133 134 void DisplaySettingsProvider::CheckFullScreenMode( 135 FullScreenCheckMode check_mode) { 136 bool is_full_screen = false; 137 switch (check_mode) { 138 case ASSUME_FULLSCREEN_ON: 139 is_full_screen = true; 140 break; 141 case ASSUME_FULLSCREEN_OFF: 142 is_full_screen = false; 143 break; 144 case PERFORM_FULLSCREEN_CHECK: 145 is_full_screen = IsFullScreen(); 146 break; 147 default: 148 NOTREACHED(); 149 break; 150 } 151 if (is_full_screen == is_full_screen_) 152 return; 153 is_full_screen_ = is_full_screen; 154 155 FOR_EACH_OBSERVER(FullScreenObserver, 156 full_screen_observers_, 157 OnFullScreenModeChanged(is_full_screen_)); 158 } 159 160 bool DisplaySettingsProvider::IsFullScreen() { 161 return IsFullScreenMode(); 162 } 163 164 #if defined(USE_AURA) 165 // static 166 DisplaySettingsProvider* DisplaySettingsProvider::Create() { 167 return new DisplaySettingsProvider(); 168 } 169 #endif 170