OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/views/widget/native_widget_mac.h" | 5 #import "ui/views/widget/native_widget_mac.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #import "base/mac/foundation_util.h" | 9 #import "base/mac/foundation_util.h" |
10 #import "base/mac/scoped_nsobject.h" | 10 #import "base/mac/scoped_nsobject.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 @end | 46 @end |
47 | 47 |
48 // Test NSWindow that provides hooks via method overrides to verify behavior. | 48 // Test NSWindow that provides hooks via method overrides to verify behavior. |
49 @interface NativeWidgetMacTestWindow : NativeWidgetMacNSWindow { | 49 @interface NativeWidgetMacTestWindow : NativeWidgetMacNSWindow { |
50 @private | 50 @private |
51 int invalidateShadowCount_; | 51 int invalidateShadowCount_; |
52 } | 52 } |
53 @property(readonly, nonatomic) int invalidateShadowCount; | 53 @property(readonly, nonatomic) int invalidateShadowCount; |
54 @end | 54 @end |
55 | 55 |
| 56 // Used to mock BridgedContentView so that calls to drawRect: can be |
| 57 // intercepted. |
| 58 @interface MockBridgedView : NSView { |
| 59 @private |
| 60 // Number of times -[NSView drawRect:] has been called. |
| 61 NSUInteger drawRectCount_; |
| 62 |
| 63 // The dirtyRect parameter passed to last invocation of drawRect:. |
| 64 NSRect lastDirtyRect_; |
| 65 } |
| 66 |
| 67 @property(assign, nonatomic) NSUInteger drawRectCount; |
| 68 @property(assign, nonatomic) NSRect lastDirtyRect; |
| 69 @end |
| 70 |
56 namespace views { | 71 namespace views { |
57 namespace test { | 72 namespace test { |
58 | 73 |
59 // BridgedNativeWidget friend to access private members. | 74 // BridgedNativeWidget friend to access private members. |
60 class BridgedNativeWidgetTestApi { | 75 class BridgedNativeWidgetTestApi { |
61 public: | 76 public: |
62 explicit BridgedNativeWidgetTestApi(NSWindow* window) { | 77 explicit BridgedNativeWidgetTestApi(NSWindow* window) { |
63 bridge_ = NativeWidgetMac::GetBridgeForNativeWindow(window); | 78 bridge_ = NativeWidgetMac::GetBridgeForNativeWindow(window); |
64 } | 79 } |
65 | 80 |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 NSRect expected = [[[NSScreen screens] firstObject] visibleFrame]; | 1097 NSRect expected = [[[NSScreen screens] firstObject] visibleFrame]; |
1083 NSRect actual = gfx::ScreenRectToNSRect(widget.GetWorkAreaBoundsInScreen()); | 1098 NSRect actual = gfx::ScreenRectToNSRect(widget.GetWorkAreaBoundsInScreen()); |
1084 EXPECT_FALSE(NSIsEmptyRect(actual)); | 1099 EXPECT_FALSE(NSIsEmptyRect(actual)); |
1085 EXPECT_NSEQ(expected, actual); | 1100 EXPECT_NSEQ(expected, actual); |
1086 | 1101 |
1087 [widget.GetNativeWindow() close]; | 1102 [widget.GetNativeWindow() close]; |
1088 actual = gfx::ScreenRectToNSRect(widget.GetWorkAreaBoundsInScreen()); | 1103 actual = gfx::ScreenRectToNSRect(widget.GetWorkAreaBoundsInScreen()); |
1089 EXPECT_TRUE(NSIsEmptyRect(actual)); | 1104 EXPECT_TRUE(NSIsEmptyRect(actual)); |
1090 } | 1105 } |
1091 | 1106 |
| 1107 // Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect |
| 1108 // parameter to BridgedContentView::drawRect, for a titled window (window with a |
| 1109 // toolbar). |
| 1110 TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Titled) { |
| 1111 Widget* widget = CreateTopLevelPlatformWidget(); |
| 1112 |
| 1113 gfx::Rect screen_rect(50, 50, 100, 100); |
| 1114 widget->SetBounds(screen_rect); |
| 1115 |
| 1116 // Setup the mock content view for the NSWindow, so that we can intercept |
| 1117 // drawRect. |
| 1118 NSWindow* window = widget->GetNativeWindow(); |
| 1119 base::scoped_nsobject<MockBridgedView> mock_bridged_view( |
| 1120 [[MockBridgedView alloc] init]); |
| 1121 [window setContentView:mock_bridged_view]; |
| 1122 |
| 1123 // Ensure the initial draw of the window is done. |
| 1124 base::RunLoop().RunUntilIdle(); |
| 1125 |
| 1126 // Add a dummy view to the widget. This will cause SchedulePaint to be called |
| 1127 // on the dummy view. |
| 1128 View* dummy_view = new View(); |
| 1129 gfx::Rect dummy_bounds(25, 30, 10, 15); |
| 1130 dummy_view->SetBoundsRect(dummy_bounds); |
| 1131 // Reset drawRect count. |
| 1132 [mock_bridged_view setDrawRectCount:0]; |
| 1133 widget->GetContentsView()->AddChildView(dummy_view); |
| 1134 |
| 1135 // SchedulePaint is asyncronous. Wait for drawRect: to be called. |
| 1136 base::RunLoop().RunUntilIdle(); |
| 1137 |
| 1138 EXPECT_EQ(1u, [mock_bridged_view drawRectCount]); |
| 1139 int client_area_height = widget->GetClientAreaBoundsInScreen().height(); |
| 1140 // These are expected dummy_view bounds in AppKit coordinate system. The y |
| 1141 // coordinate of rect origin is calculated as: |
| 1142 // client_area_height - 30 (dummy_view's y coordinate) - 15 (dummy view's |
| 1143 // height). |
| 1144 gfx::Rect expected_appkit_bounds(25, client_area_height - 45, 10, 15); |
| 1145 EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(), |
| 1146 [mock_bridged_view lastDirtyRect]); |
| 1147 widget->CloseNow(); |
| 1148 } |
| 1149 |
| 1150 // Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect |
| 1151 // parameter to BridgedContentView::drawRect, for a borderless window. |
| 1152 TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Borderless) { |
| 1153 Widget* widget = CreateTopLevelFramelessPlatformWidget(); |
| 1154 |
| 1155 gfx::Rect screen_rect(50, 50, 100, 100); |
| 1156 widget->SetBounds(screen_rect); |
| 1157 |
| 1158 // Setup the mock content view for the NSWindow, so that we can intercept |
| 1159 // drawRect. |
| 1160 NSWindow* window = widget->GetNativeWindow(); |
| 1161 base::scoped_nsobject<MockBridgedView> mock_bridged_view( |
| 1162 [[MockBridgedView alloc] init]); |
| 1163 [window setContentView:mock_bridged_view]; |
| 1164 |
| 1165 // Ensure the initial draw of the window is done. |
| 1166 base::RunLoop().RunUntilIdle(); |
| 1167 |
| 1168 // Add a dummy view to the widget. This will cause SchedulePaint to be called |
| 1169 // on the dummy view. |
| 1170 View* dummy_view = new View(); |
| 1171 gfx::Rect dummy_bounds(25, 30, 10, 15); |
| 1172 dummy_view->SetBoundsRect(dummy_bounds); |
| 1173 // Reset drawRect count. |
| 1174 [mock_bridged_view setDrawRectCount:0]; |
| 1175 widget->GetRootView()->AddChildView(dummy_view); |
| 1176 |
| 1177 // SchedulePaint is asyncronous. Wait for drawRect: to be called. |
| 1178 base::RunLoop().RunUntilIdle(); |
| 1179 |
| 1180 EXPECT_EQ(1u, [mock_bridged_view drawRectCount]); |
| 1181 // These are expected dummy_view bounds in AppKit coordinate system. The y |
| 1182 // coordinate of rect origin is calculated as: |
| 1183 // 100(client area height) - 30 (dummy_view's y coordinate) - 15 (dummy view's |
| 1184 // height). |
| 1185 gfx::Rect expected_appkit_bounds(25, 55, 10, 15); |
| 1186 EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(), |
| 1187 [mock_bridged_view lastDirtyRect]); |
| 1188 widget->CloseNow(); |
| 1189 } |
| 1190 |
1092 } // namespace test | 1191 } // namespace test |
1093 } // namespace views | 1192 } // namespace views |
1094 | 1193 |
1095 @implementation TestStopAnimationWaiter | 1194 @implementation TestStopAnimationWaiter |
1096 - (void)setWindowStateForEnd { | 1195 - (void)setWindowStateForEnd { |
1097 views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd); | 1196 views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd); |
1098 } | 1197 } |
1099 @end | 1198 @end |
1100 | 1199 |
1101 @implementation NativeWidgetMacTestWindow | 1200 @implementation NativeWidgetMacTestWindow |
1102 | 1201 |
1103 @synthesize invalidateShadowCount = invalidateShadowCount_; | 1202 @synthesize invalidateShadowCount = invalidateShadowCount_; |
1104 | 1203 |
1105 - (void)invalidateShadow { | 1204 - (void)invalidateShadow { |
1106 ++invalidateShadowCount_; | 1205 ++invalidateShadowCount_; |
1107 [super invalidateShadow]; | 1206 [super invalidateShadow]; |
1108 } | 1207 } |
1109 | 1208 |
1110 @end | 1209 @end |
| 1210 |
| 1211 @implementation MockBridgedView |
| 1212 |
| 1213 @synthesize drawRectCount = drawRectCount_; |
| 1214 @synthesize lastDirtyRect = lastDirtyRect_; |
| 1215 |
| 1216 - (void)drawRect:(NSRect)dirtyRect { |
| 1217 ++drawRectCount_; |
| 1218 lastDirtyRect_ = dirtyRect; |
| 1219 } |
| 1220 |
| 1221 @end |
OLD | NEW |