| 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 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 EXPECT_FALSE(hide_waiter.method_called()); | 1038 EXPECT_FALSE(hide_waiter.method_called()); |
| 1039 | 1039 |
| 1040 // Wait for the hide again. It will call close on its retained copy of the | 1040 // Wait for the hide again. It will call close on its retained copy of the |
| 1041 // child NSWindow, but that's fine since all the C++ objects are detached. | 1041 // child NSWindow, but that's fine since all the C++ objects are detached. |
| 1042 hide_waiter.WaitForMethod(); | 1042 hide_waiter.WaitForMethod(); |
| 1043 EXPECT_TRUE(hide_waiter.method_called()); | 1043 EXPECT_TRUE(hide_waiter.method_called()); |
| 1044 } | 1044 } |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 // Tests behavior of window-modal dialogs, displayed as sheets. | 1047 // Tests behavior of window-modal dialogs, displayed as sheets. |
| 1048 // Disabled: fails due to sharding adjustments. DCHECK fails during closure when | 1048 TEST_F(NativeWidgetMacTest, WindowModalSheet) { |
| 1049 // the parent window receives an asynchronous occlusion state change from the | |
| 1050 // window server, after the child has its parent window relationship removed. | |
| 1051 // TODO(tapted): Fix it. http://cbrug.com/666503. | |
| 1052 TEST_F(NativeWidgetMacTest, DISABLED_WindowModalSheet) { | |
| 1053 NSWindow* native_parent = | 1049 NSWindow* native_parent = |
| 1054 MakeNativeParentWithStyle(NSClosableWindowMask | NSTitledWindowMask); | 1050 MakeNativeParentWithStyle(NSClosableWindowMask | NSTitledWindowMask); |
| 1055 | 1051 |
| 1056 Widget* sheet_widget = views::DialogDelegate::CreateDialogWidget( | 1052 Widget* sheet_widget = views::DialogDelegate::CreateDialogWidget( |
| 1057 new ModalDialogDelegate(ui::MODAL_TYPE_WINDOW), nullptr, | 1053 new ModalDialogDelegate(ui::MODAL_TYPE_WINDOW), nullptr, |
| 1058 [native_parent contentView]); | 1054 [native_parent contentView]); |
| 1059 | 1055 |
| 1056 WidgetChangeObserver widget_observer(sheet_widget); |
| 1057 |
| 1060 // Retain, to run checks after the Widget is torn down. | 1058 // Retain, to run checks after the Widget is torn down. |
| 1061 base::scoped_nsobject<NSWindow> sheet_window( | 1059 base::scoped_nsobject<NSWindow> sheet_window( |
| 1062 [sheet_widget->GetNativeWindow() retain]); | 1060 [sheet_widget->GetNativeWindow() retain]); |
| 1063 | 1061 |
| 1064 // Although there is no titlebar displayed, sheets need NSTitledWindowMask in | 1062 // Although there is no titlebar displayed, sheets need NSTitledWindowMask in |
| 1065 // order to properly engage window-modal behavior in AppKit. | 1063 // order to properly engage window-modal behavior in AppKit. |
| 1066 EXPECT_EQ(NSTitledWindowMask, [sheet_window styleMask]); | 1064 EXPECT_EQ(NSTitledWindowMask, [sheet_window styleMask]); |
| 1067 | 1065 |
| 1068 sheet_widget->SetBounds(gfx::Rect(50, 50, 200, 150)); | 1066 sheet_widget->SetBounds(gfx::Rect(50, 50, 200, 150)); |
| 1069 EXPECT_FALSE(sheet_widget->IsVisible()); | 1067 EXPECT_FALSE(sheet_widget->IsVisible()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1088 *did_observe_ptr = true; | 1086 *did_observe_ptr = true; |
| 1089 }]; | 1087 }]; |
| 1090 | 1088 |
| 1091 sheet_widget->Show(); // Should run the above block, then animate the sheet. | 1089 sheet_widget->Show(); // Should run the above block, then animate the sheet. |
| 1092 EXPECT_TRUE(did_observe); | 1090 EXPECT_TRUE(did_observe); |
| 1093 [[NSNotificationCenter defaultCenter] removeObserver:observer]; | 1091 [[NSNotificationCenter defaultCenter] removeObserver:observer]; |
| 1094 | 1092 |
| 1095 // Modal, so the close button in the parent window should get disabled. | 1093 // Modal, so the close button in the parent window should get disabled. |
| 1096 EXPECT_FALSE([parent_close_button isEnabled]); | 1094 EXPECT_FALSE([parent_close_button isEnabled]); |
| 1097 | 1095 |
| 1096 // The sheet should be hidden and shown in step with the parent. |
| 1097 widget_observer.WaitForVisibleCounts(1, 0); |
| 1098 EXPECT_TRUE(sheet_widget->IsVisible()); |
| 1099 |
| 1100 // TODO(tapted): Ideally [native_parent orderOut:nil] would also work here. |
| 1101 // But it does not. AppKit's childWindow management breaks down after an |
| 1102 // -orderOut: (see BridgedNativeWidget::OnVisibilityChanged()). For regular |
| 1103 // child windows, BridgedNativeWidget fixes the behavior with its own |
| 1104 // management. However, it can't do that for sheets without encountering |
| 1105 // http://crbug.com/605098 and http://crbug.com/667602. -[NSApp hide:] makes |
| 1106 // the NSWindow hidden in a different way, which does not break like |
| 1107 // -orderOut: does. Which is good, because a user can always do -[NSApp |
| 1108 // hide:], e.g., with Cmd+h, and that needs to work correctly. |
| 1109 [NSApp hide:nil]; |
| 1110 |
| 1111 widget_observer.WaitForVisibleCounts(1, 1); |
| 1112 EXPECT_FALSE(sheet_widget->IsVisible()); |
| 1113 [native_parent makeKeyAndOrderFront:nil]; |
| 1114 widget_observer.WaitForVisibleCounts(2, 1); |
| 1115 EXPECT_TRUE(sheet_widget->IsVisible()); |
| 1116 |
| 1098 // Trigger the close. Don't use CloseNow, since that tears down the UI before | 1117 // Trigger the close. Don't use CloseNow, since that tears down the UI before |
| 1099 // the close sheet animation gets a chance to run (so it's banned). | 1118 // the close sheet animation gets a chance to run (so it's banned). |
| 1100 sheet_widget->Close(); | 1119 sheet_widget->Close(); |
| 1101 EXPECT_TRUE(sheet_widget->IsVisible()); | 1120 EXPECT_TRUE(sheet_widget->IsVisible()); |
| 1102 | 1121 |
| 1103 did_observe = false; | 1122 did_observe = false; |
| 1104 | 1123 |
| 1105 // Experimentally (on 10.10), this notification is posted from within the | 1124 // Experimentally (on 10.10), this notification is posted from within the |
| 1106 // -[NSWindow orderOut:] call that is triggered from -[ViewsNSWindowDelegate | 1125 // -[NSWindow orderOut:] call that is triggered from -[ViewsNSWindowDelegate |
| 1107 // sheetDidEnd:]. |sheet_widget| will be destroyed next, so it's still safe to | 1126 // sheetDidEnd:]. |sheet_widget| will be destroyed next, so it's still safe to |
| 1108 // use in the block. However, since the orderOut just happened, it's not very | 1127 // use in the block. However, since the orderOut just happened, it's not very |
| 1109 // interesting. | 1128 // interesting. |
| 1110 observer = [[NSNotificationCenter defaultCenter] | 1129 observer = [[NSNotificationCenter defaultCenter] |
| 1111 addObserverForName:NSWindowDidEndSheetNotification | 1130 addObserverForName:NSWindowDidEndSheetNotification |
| 1112 object:native_parent | 1131 object:native_parent |
| 1113 queue:nil | 1132 queue:nil |
| 1114 usingBlock:^(NSNotification* note) { | 1133 usingBlock:^(NSNotification* note) { |
| 1115 EXPECT_TRUE([sheet_window delegate]); | 1134 EXPECT_TRUE([sheet_window delegate]); |
| 1116 *did_observe_ptr = true; | 1135 *did_observe_ptr = true; |
| 1117 }]; | 1136 }]; |
| 1118 | 1137 |
| 1119 // Pump in order to trigger -[NSWindow endSheet:..], which will block while | 1138 // Pump in order to trigger -[NSWindow endSheet:..], which will block while |
| 1120 // the animation runs, then delete |sheet_widget|. | 1139 // the animation runs, then delete |sheet_widget|. |
| 1121 TestWidgetObserver widget_observer(sheet_widget); | |
| 1122 EXPECT_TRUE([sheet_window delegate]); | 1140 EXPECT_TRUE([sheet_window delegate]); |
| 1123 base::RunLoop().RunUntilIdle(); | 1141 base::RunLoop().RunUntilIdle(); |
| 1124 EXPECT_FALSE([sheet_window delegate]); | 1142 EXPECT_FALSE([sheet_window delegate]); |
| 1125 | 1143 |
| 1126 EXPECT_TRUE(did_observe); // Also ensures the Close() actually uses sheets. | 1144 EXPECT_TRUE(did_observe); // Also ensures the Close() actually uses sheets. |
| 1127 [[NSNotificationCenter defaultCenter] removeObserver:observer]; | 1145 [[NSNotificationCenter defaultCenter] removeObserver:observer]; |
| 1128 | 1146 |
| 1129 EXPECT_TRUE(widget_observer.widget_closed()); | 1147 EXPECT_TRUE(widget_observer.widget_closed()); |
| 1130 EXPECT_TRUE([parent_close_button isEnabled]); | 1148 EXPECT_TRUE([parent_close_button isEnabled]); |
| 1131 } | 1149 } |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1835 | 1853 |
| 1836 - (void)dealloc { | 1854 - (void)dealloc { |
| 1837 if (deallocFlag_) { | 1855 if (deallocFlag_) { |
| 1838 DCHECK(!*deallocFlag_); | 1856 DCHECK(!*deallocFlag_); |
| 1839 *deallocFlag_ = true; | 1857 *deallocFlag_ = true; |
| 1840 } | 1858 } |
| 1841 [super dealloc]; | 1859 [super dealloc]; |
| 1842 } | 1860 } |
| 1843 | 1861 |
| 1844 @end | 1862 @end |
| OLD | NEW |