Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/ui/cocoa/fullscreen_low_power_coordinator.h" | 5 #include "chrome/browser/ui/cocoa/fullscreen_low_power_coordinator.h" |
| 6 | 6 |
| 7 #include "ui/base/cocoa/animation_utils.h" | |
| 8 #include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h" | |
| 9 | |
| 7 namespace { | 10 namespace { |
| 8 | 11 |
| 9 // The minimum number of frames with valid low power contents that we need to | 12 // The number of frames we need to be in the WarmUp state before moving to the |
| 10 // receive in a row before showing the low power window. | 13 // Enabled state. |
| 11 const uint64_t kMinValidFrames = 15; | 14 const uint64_t kWarmUpFramesBeforeEnteringLowPowerMode = 30; |
| 12 | 15 |
| 13 } // namespace | 16 } // namespace |
| 14 | 17 |
| 15 @interface FullscreenLowPowerWindow : NSWindow { | 18 @interface FullscreenLowPowerWindow : NSWindow { |
| 16 base::scoped_nsobject<NSWindow> eventTargetWindow_; | 19 base::scoped_nsobject<NSWindow> eventTargetWindow_; |
| 17 } | 20 } |
| 18 - (id)initWithEventTargetWindow:(NSWindow*)eventTargetWindow | 21 - (id)initWithEventTargetWindow:(NSWindow*)eventTargetWindow |
| 19 withLayer:(CALayer*)layer; | 22 withLayer:(CALayer*)layer; |
| 20 @end | 23 @end |
| 21 | 24 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 } | 81 } |
| 79 | 82 |
| 80 NSWindow* FullscreenLowPowerCoordinatorCocoa::GetFullscreenLowPowerWindow() { | 83 NSWindow* FullscreenLowPowerCoordinatorCocoa::GetFullscreenLowPowerWindow() { |
| 81 return low_power_window_.get(); | 84 return low_power_window_.get(); |
| 82 } | 85 } |
| 83 | 86 |
| 84 void FullscreenLowPowerCoordinatorCocoa::SetInFullscreenTransition( | 87 void FullscreenLowPowerCoordinatorCocoa::SetInFullscreenTransition( |
| 85 bool in_fullscreen_transition) { | 88 bool in_fullscreen_transition) { |
| 86 allowed_by_fullscreen_transition_ = !in_fullscreen_transition; | 89 allowed_by_fullscreen_transition_ = !in_fullscreen_transition; |
| 87 EnterOrExitLowPowerModeIfNeeded(); | 90 EnterOrExitLowPowerModeIfNeeded(); |
| 91 | |
| 92 // Note that we should close the window here so that it does not appear in | |
| 93 // the background during the transition back to windowed mode. Closing a | |
| 94 // window that is in detached mode results in a janky transition and system | |
| 95 // crashes. | |
|
erikchen
2016/11/03 18:20:01
system being Chrome or macOS?
| |
| 96 // TODO(ccameron): Allow closing the window here if we have not been in | |
| 97 // detached mode for several frames. | |
| 98 // https://crbug.com/644133 | |
| 88 } | 99 } |
| 89 | 100 |
| 90 void FullscreenLowPowerCoordinatorCocoa::SetLayoutParameters( | 101 void FullscreenLowPowerCoordinatorCocoa::SetLayoutParameters( |
| 91 const NSRect& toolbar_frame, | 102 const NSRect& toolbar_frame, |
| 92 const NSRect& infobar_frame, | 103 const NSRect& infobar_frame, |
| 93 const NSRect& content_frame, | 104 const NSRect& content_frame, |
| 94 const NSRect& download_shelf_frame) { | 105 const NSRect& download_shelf_frame) { |
| 95 NSRect screen_frame = [[content_window_ screen] frame]; | 106 NSRect screen_frame = [[content_window_ screen] frame]; |
| 96 allowed_by_nsview_layout_ = true; | 107 allowed_by_nsview_layout_ = true; |
| 97 | 108 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 | 143 |
| 133 // Don't make any assumptions about other child windows. | 144 // Don't make any assumptions about other child windows. |
| 134 allowed_by_child_windows_ = false; | 145 allowed_by_child_windows_ = false; |
| 135 break; | 146 break; |
| 136 } | 147 } |
| 137 | 148 |
| 138 EnterOrExitLowPowerModeIfNeeded(); | 149 EnterOrExitLowPowerModeIfNeeded(); |
| 139 } | 150 } |
| 140 | 151 |
| 141 void FullscreenLowPowerCoordinatorCocoa::SetLowPowerLayerValid(bool valid) { | 152 void FullscreenLowPowerCoordinatorCocoa::SetLowPowerLayerValid(bool valid) { |
| 142 if (valid) | 153 State old_state = state_; |
| 143 low_power_layer_valid_frame_count_ += 1; | 154 |
| 155 low_power_layer_valid_ = valid; | |
| 156 EnterOrExitLowPowerModeIfNeeded(); | |
| 157 | |
| 158 if (state_ == old_state) | |
| 159 frames_in_state_ += 1; | |
| 144 else | 160 else |
| 145 low_power_layer_valid_frame_count_ = 0; | 161 frames_in_state_ = 0; |
| 146 EnterOrExitLowPowerModeIfNeeded(); | |
| 147 } | 162 } |
| 148 | 163 |
| 149 void FullscreenLowPowerCoordinatorCocoa::WillLoseAcceleratedWidget() { | 164 void FullscreenLowPowerCoordinatorCocoa::WillLoseAcceleratedWidget() { |
| 150 DCHECK(widget_); | 165 DCHECK(widget_); |
| 151 widget_->ResetFullscreenLowPowerCoordinator(); | 166 widget_->ResetFullscreenLowPowerCoordinator(); |
| 152 widget_ = nullptr; | 167 widget_ = nullptr; |
| 153 EnterOrExitLowPowerModeIfNeeded(); | 168 EnterOrExitLowPowerModeIfNeeded(); |
| 154 } | 169 } |
| 155 | 170 |
| 171 void FullscreenLowPowerCoordinatorCocoa::TickEnterOrExitForTesting() { | |
| 172 frames_in_state_ += 1; | |
| 173 EnterOrExitLowPowerModeIfNeeded(); | |
| 174 } | |
| 175 | |
| 156 void FullscreenLowPowerCoordinatorCocoa::EnterOrExitLowPowerModeIfNeeded() { | 176 void FullscreenLowPowerCoordinatorCocoa::EnterOrExitLowPowerModeIfNeeded() { |
| 157 bool new_in_low_power_mode = | 177 bool can_use_low_power_window = |
| 158 widget_ && low_power_window_ && | 178 widget_ && low_power_window_ && low_power_layer_valid_ && |
| 159 low_power_layer_valid_frame_count_ > kMinValidFrames && | |
| 160 allowed_by_fullscreen_transition_ && allowed_by_nsview_layout_ && | 179 allowed_by_fullscreen_transition_ && allowed_by_nsview_layout_ && |
| 161 allowed_by_child_windows_ && allowed_by_active_sheet_; | 180 allowed_by_child_windows_ && allowed_by_active_sheet_; |
| 162 | 181 |
| 163 if (new_in_low_power_mode) { | 182 switch (state_) { |
| 164 // Update whether or not we are in low power mode based on whether or not | 183 case Disabled: |
| 165 // the low power window is in front (we do not get notifications of window | 184 if (can_use_low_power_window) { |
| 166 // order change). | 185 // Ensure that the window's frame and style are set, and order it behind |
| 167 in_low_power_mode_ &= | 186 // the main window, so that it's ready to be moved in front. |
| 168 [[NSApp orderedWindows] firstObject] == low_power_window_.get(); | 187 state_ = WarmingUp; |
| 169 | 188 [low_power_window_ setStyleMask:[low_power_window_ styleMask] | |
| 170 if (!in_low_power_mode_) { | 189 NSFullScreenWindowMask]; |
| 171 [low_power_window_ setFrame:[content_window_ frame] display:YES]; | 190 [low_power_window_ setFrame:[content_window_ frame] |
| 172 [low_power_window_ | 191 display:YES |
| 173 setStyleMask:[low_power_window_ styleMask] | NSFullScreenWindowMask]; | 192 animate:NO]; |
| 174 [low_power_window_ orderWindow:NSWindowAbove | 193 [low_power_window_ orderWindow:NSWindowBelow |
| 175 relativeTo:[content_window_ windowNumber]]; | 194 relativeTo:[content_window_ windowNumber]]; |
| 176 in_low_power_mode_ = true; | 195 } |
| 177 } | 196 break; |
| 178 } else { | 197 case WarmingUp: |
| 179 if (in_low_power_mode_) { | 198 if (can_use_low_power_window) { |
| 180 [low_power_window_ orderWindow:NSWindowBelow | 199 // After a few frames, move in front of the main window. |
| 181 relativeTo:[content_window_ windowNumber]]; | 200 if (frames_in_state_ > kWarmUpFramesBeforeEnteringLowPowerMode) { |
| 182 in_low_power_mode_ = false; | 201 state_ = Enabled; |
| 183 } | 202 [low_power_window_ orderWindow:NSWindowAbove |
| 203 relativeTo:[content_window_ windowNumber]]; | |
| 204 } | |
| 205 } else { | |
| 206 state_ = Disabled; | |
| 207 } | |
| 208 break; | |
| 209 case Enabled: | |
| 210 if (can_use_low_power_window) { | |
| 211 // We do not get notifications of window order change. Check here that | |
| 212 // the low power window is in front (and move it there if it isn't). | |
| 213 if ([[NSApp orderedWindows] firstObject] != low_power_window_.get()) { | |
| 214 [low_power_window_ orderWindow:NSWindowAbove | |
| 215 relativeTo:[content_window_ windowNumber]]; | |
| 216 } | |
| 217 } else { | |
| 218 // Move behind the main window. | |
| 219 state_ = Disabled; | |
| 220 [low_power_window_ orderWindow:NSWindowBelow | |
| 221 relativeTo:[content_window_ windowNumber]]; | |
| 222 } | |
| 223 break; | |
| 184 } | 224 } |
| 185 } | 225 } |
| OLD | NEW |