Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" | 5 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #import "base/mac/foundation_util.h" | 11 #import "base/mac/foundation_util.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/native_library.h" | 13 #include "base/native_library.h" |
| 14 #include "ui/gfx/animation/tween.h" | 14 #include "ui/gfx/animation/tween.h" |
| 15 | 15 |
| 16 // The window animations in this file use private APIs as described here: | 16 // The window animations in this file use private APIs as described here: |
| 17 // http://code.google.com/p/undocumented-goodness/source/browse/trunk/CoreGraphi cs/CGSPrivate.h | 17 // http://code.google.com/p/undocumented-goodness/source/browse/trunk/CoreGraphi cs/CGSPrivate.h |
| 18 // There are two important things to keep in mind when modifying this file: | 18 // There are two important things to keep in mind when modifying this file: |
| 19 // - For most operations the origin of the coordinate system is top left. | 19 // - For most operations the origin of the coordinate system is top left. |
| 20 // - Perspective and shear transformations get clipped if they are bigger | 20 // - Perspective and shear transformations get clipped if they are bigger |
| 21 // than the window size. This does not seem to apply to scale transformations. | 21 // than the window size. This does not seem to apply to scale transformations. |
| 22 | 22 |
| 23 // Use of private APIs is dangerous, and is known to cause WindowServer crashes. | |
| 24 // https://bugs.chromium.org/p/chromium/issues/detail?id=515627 | |
| 25 | |
| 23 // Length of the animation in seconds. | 26 // Length of the animation in seconds. |
| 24 const NSTimeInterval kAnimationDuration = 0.18; | 27 const NSTimeInterval kAnimationDuration = 0.18; |
| 25 | 28 |
| 26 // The number of pixels above the final destination to animate from. | |
| 27 const CGFloat kShowHideVerticalOffset = 20; | |
| 28 | |
| 29 // Scale the window by this factor when animating. | |
| 30 const CGFloat kShowHideScaleFactor = 0.99; | |
| 31 | |
| 32 // Size of the perspective effect as a factor of the window width. | |
| 33 const CGFloat kShowHidePerspectiveFactor = 0.04; | |
| 34 | |
| 35 // Forward declare private CoreGraphics APIs used to transform windows. | 29 // Forward declare private CoreGraphics APIs used to transform windows. |
| 36 extern "C" { | 30 extern "C" { |
| 37 | 31 |
| 38 typedef float float32; | 32 typedef float float32; |
| 39 | 33 |
| 40 typedef int32_t CGSWindow; | 34 typedef int32_t CGSWindow; |
| 41 typedef int32_t CGSConnection; | 35 typedef int32_t CGSConnection; |
| 42 | 36 |
| 43 typedef struct { | 37 typedef struct { |
| 44 float32 x; | 38 float32 x; |
| 45 float32 y; | 39 float32 y; |
| 46 } MeshPoint; | 40 } MeshPoint; |
| 47 | 41 |
| 48 typedef struct { | 42 typedef struct { |
| 49 MeshPoint local; | 43 MeshPoint local; |
| 50 MeshPoint global; | 44 MeshPoint global; |
| 51 } CGPointWarp; | 45 } CGPointWarp; |
| 52 | 46 |
| 53 CGSConnection _CGSDefaultConnection(); | 47 CGSConnection _CGSDefaultConnection(); |
| 54 CGError CGSSetWindowTransform(const CGSConnection cid, | 48 CGError CGSSetWindowTransform(const CGSConnection cid, |
|
tapted
2016/03/14 00:03:22
You said CGSSetWindowWarp caused the crashes, but
| |
| 55 const CGSWindow wid, | 49 const CGSWindow wid, |
| 56 CGAffineTransform transform); | 50 CGAffineTransform transform); |
| 57 CGError CGSSetWindowWarp(const CGSConnection cid, | |
| 58 const CGSWindow wid, | |
| 59 int32_t w, | |
| 60 int32_t h, | |
| 61 CGPointWarp* mesh); | |
| 62 CGError CGSSetWindowAlpha(const CGSConnection cid, | 51 CGError CGSSetWindowAlpha(const CGSConnection cid, |
| 63 const CGSWindow wid, | 52 const CGSWindow wid, |
| 64 float32 alpha); | 53 float32 alpha); |
| 65 | 54 |
| 66 } // extern "C" | 55 } // extern "C" |
| 67 | 56 |
| 68 namespace { | 57 namespace { |
| 69 | 58 |
| 70 struct KeyFrame { | 59 struct KeyFrame { |
| 71 float value; | 60 float value; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 | 101 |
| 113 NSPoint origin = GetCGSWindowScreenOrigin(window); | 102 NSPoint origin = GetCGSWindowScreenOrigin(window); |
| 114 CGFloat new_x = -origin.x + scale_offset_x; | 103 CGFloat new_x = -origin.x + scale_offset_x; |
| 115 CGFloat new_y = -origin.y + scale_offset_y; | 104 CGFloat new_y = -origin.y + scale_offset_y; |
| 116 transform = CGAffineTransformTranslate(transform, new_x, new_y); | 105 transform = CGAffineTransformTranslate(transform, new_x, new_y); |
| 117 | 106 |
| 118 CGSConnection cid = _CGSDefaultConnection(); | 107 CGSConnection cid = _CGSDefaultConnection(); |
| 119 CGSSetWindowTransform(cid, [window windowNumber], transform); | 108 CGSSetWindowTransform(cid, [window windowNumber], transform); |
| 120 } | 109 } |
| 121 | 110 |
| 122 // Unsets any window warp that may have been previously applied. | |
| 123 // Window warp prevents other effects such as CGSSetWindowTransform from | |
| 124 // being applied. | |
| 125 void ClearWindowWarp(NSWindow* window) { | |
| 126 CGSConnection cid = _CGSDefaultConnection(); | |
| 127 CGSSetWindowWarp(cid, [window windowNumber], 0, 0, NULL); | |
| 128 } | |
| 129 | |
| 130 // Applies various transformations using a warp effect. The window is | |
| 131 // translated vertically by |y_offset|. The window is scaled by |scale| and | |
| 132 // translated so that the it remains centered relative to its original position. | |
| 133 // Finally, perspective is effect is applied by shrinking the top of the window. | |
| 134 void SetWindowWarp(NSWindow* window, | |
| 135 float y_offset, | |
| 136 float scale, | |
| 137 float perspective_offset) { | |
| 138 NSRect win_rect = [window frame]; | |
| 139 win_rect.origin = NSZeroPoint; | |
| 140 NSRect screen_rect = win_rect; | |
| 141 screen_rect.origin = GetCGSWindowScreenOrigin(window); | |
| 142 | |
| 143 // Apply a vertical translate. | |
| 144 screen_rect.origin.y -= y_offset; | |
| 145 | |
| 146 // Apply a scale and translate to keep the window centered. | |
| 147 screen_rect.origin.x += (NSWidth(win_rect) - NSWidth(screen_rect)) / 2.0; | |
| 148 screen_rect.origin.y += (NSHeight(win_rect) - NSHeight(screen_rect)) / 2.0; | |
| 149 | |
| 150 // A 2 x 2 mesh that maps each corner of the window to a location in screen | |
| 151 // coordinates. Note that the origin of the coordinate system is top, left. | |
| 152 CGPointWarp mesh[2][2] = { | |
| 153 {{ | |
| 154 // Top left. | |
| 155 {NSMinX(win_rect), NSMinY(win_rect)}, | |
| 156 {NSMinX(screen_rect) + perspective_offset, NSMinY(screen_rect)}, | |
| 157 }, | |
| 158 { | |
| 159 // Top right. | |
| 160 {NSMaxX(win_rect), NSMinY(win_rect)}, | |
| 161 {NSMaxX(screen_rect) - perspective_offset, NSMinY(screen_rect)}, }}, | |
| 162 {{ | |
| 163 // Bottom left. | |
| 164 {NSMinX(win_rect), NSMaxY(win_rect)}, | |
| 165 {NSMinX(screen_rect), NSMaxY(screen_rect)}, | |
| 166 }, | |
| 167 { | |
| 168 // Bottom right. | |
| 169 {NSMaxX(win_rect), NSMaxY(win_rect)}, | |
| 170 {NSMaxX(screen_rect), NSMaxY(screen_rect)}, }}, | |
| 171 }; | |
| 172 | |
| 173 CGSConnection cid = _CGSDefaultConnection(); | |
| 174 CGSSetWindowWarp(cid, [window windowNumber], 2, 2, &(mesh[0][0])); | |
| 175 } | |
| 176 | |
| 177 // Sets the various effects that are a part of the Show/Hide animation. | 111 // Sets the various effects that are a part of the Show/Hide animation. |
| 178 // Value is a number between 0 and 1 where 0 means the window is completely | 112 // Value is a number between 0 and 1 where 0 means the window is completely |
| 179 // hidden and 1 means the window is fully visible. | 113 // hidden and 1 means the window is fully visible. |
| 180 void UpdateWindowShowHideAnimationState(NSWindow* window, CGFloat value) { | 114 void UpdateWindowShowHideAnimationState(NSWindow* window, CGFloat value) { |
| 181 CGFloat inverse_value = 1.0 - value; | |
| 182 | |
| 183 SetWindowAlpha(window, value); | 115 SetWindowAlpha(window, value); |
| 184 CGFloat y_offset = kShowHideVerticalOffset * inverse_value; | |
| 185 CGFloat scale = 1.0 - (1.0 - kShowHideScaleFactor) * inverse_value; | |
| 186 CGFloat perspective_offset = | |
| 187 ([window frame].size.width * kShowHidePerspectiveFactor) * inverse_value; | |
| 188 | |
| 189 SetWindowWarp(window, y_offset, scale, perspective_offset); | |
| 190 } | 116 } |
| 191 | 117 |
| 192 } // namespace | 118 } // namespace |
| 193 | 119 |
| 194 @interface ConstrainedWindowAnimationBase () | 120 @interface ConstrainedWindowAnimationBase () |
| 195 // Subclasses should override these to update the window state for the current | 121 // Subclasses should override these to update the window state for the current |
| 196 // animation value. | 122 // animation value. |
| 197 - (void)setWindowStateForStart; | 123 - (void)setWindowStateForStart; |
| 198 - (void)setWindowStateForValue:(float)value; | 124 - (void)setWindowStateForValue:(float)value; |
| 199 - (void)setWindowStateForEnd; | 125 - (void)setWindowStateForEnd; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 - (void)setWindowStateForStart { | 174 - (void)setWindowStateForStart { |
| 249 SetWindowAlpha(window_, 0.0); | 175 SetWindowAlpha(window_, 0.0); |
| 250 } | 176 } |
| 251 | 177 |
| 252 - (void)setWindowStateForValue:(float)value { | 178 - (void)setWindowStateForValue:(float)value { |
| 253 UpdateWindowShowHideAnimationState(window_, value); | 179 UpdateWindowShowHideAnimationState(window_, value); |
| 254 } | 180 } |
| 255 | 181 |
| 256 - (void)setWindowStateForEnd { | 182 - (void)setWindowStateForEnd { |
| 257 SetWindowAlpha(window_, 1.0); | 183 SetWindowAlpha(window_, 1.0); |
| 258 ClearWindowWarp(window_); | |
| 259 } | 184 } |
| 260 | 185 |
| 261 @end | 186 @end |
| 262 | 187 |
| 263 @implementation ConstrainedWindowAnimationHide | 188 @implementation ConstrainedWindowAnimationHide |
| 264 | 189 |
| 265 - (void)setWindowStateForValue:(float)value { | 190 - (void)setWindowStateForValue:(float)value { |
| 266 UpdateWindowShowHideAnimationState(window_, 1.0 - value); | 191 UpdateWindowShowHideAnimationState(window_, 1.0 - value); |
| 267 } | 192 } |
| 268 | 193 |
| 269 - (void)setWindowStateForEnd { | 194 - (void)setWindowStateForEnd { |
| 270 SetWindowAlpha(window_, 0.0); | 195 SetWindowAlpha(window_, 0.0); |
| 271 ClearWindowWarp(window_); | |
| 272 } | 196 } |
| 273 | 197 |
| 274 @end | 198 @end |
| 275 | 199 |
| 276 @implementation ConstrainedWindowAnimationPulse | 200 @implementation ConstrainedWindowAnimationPulse |
| 277 | 201 |
| 278 // Sets the window scale based on the animation progress. | 202 // Sets the window scale based on the animation progress. |
| 279 - (void)setWindowStateForValue:(float)value { | 203 - (void)setWindowStateForValue:(float)value { |
| 280 KeyFrame frames[] = { | 204 KeyFrame frames[] = { |
| 281 {0.00, 1.0}, {0.40, 1.02}, {0.60, 1.02}, {1.00, 1.0}, | 205 {0.00, 1.0}, {0.40, 1.02}, {0.60, 1.02}, {1.00, 1.0}, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 293 } | 217 } |
| 294 | 218 |
| 295 SetWindowScale(window_, scale); | 219 SetWindowScale(window_, scale); |
| 296 } | 220 } |
| 297 | 221 |
| 298 - (void)setWindowStateForEnd { | 222 - (void)setWindowStateForEnd { |
| 299 SetWindowScale(window_, 1.0); | 223 SetWindowScale(window_, 1.0); |
| 300 } | 224 } |
| 301 | 225 |
| 302 @end | 226 @end |
| OLD | NEW |