Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: ui/views/widget/native_widget_mac_unittest.mm

Issue 2521753003: MacViews: Protect against orderOut: on an NSWindow with an attached sheet. (Closed)
Patch Set: Nit comment Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698