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

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

Issue 1796773003: Implement NativeWidgetMac::ReorderNativeViews (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nits and xcode 7 compilation. Created 4 years, 9 months 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
« no previous file with comments | « ui/views/widget/native_widget_mac.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #import "base/mac/scoped_nsobject.h" 10 #import "base/mac/scoped_nsobject.h"
11 #import "base/mac/scoped_objc_class_swizzler.h" 11 #import "base/mac/scoped_objc_class_swizzler.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/test_timeouts.h" 16 #include "base/test/test_timeouts.h"
17 #import "testing/gtest_mac.h" 17 #import "testing/gtest_mac.h"
18 #include "third_party/skia/include/core/SkBitmap.h" 18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "third_party/skia/include/core/SkCanvas.h" 19 #include "third_party/skia/include/core/SkCanvas.h"
20 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" 20 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
21 #import "ui/base/cocoa/window_size_constants.h" 21 #import "ui/base/cocoa/window_size_constants.h"
22 #import "ui/events/test/cocoa_test_event_utils.h" 22 #import "ui/events/test/cocoa_test_event_utils.h"
23 #include "ui/events/test/event_generator.h" 23 #include "ui/events/test/event_generator.h"
24 #import "ui/gfx/mac/coordinate_conversion.h" 24 #import "ui/gfx/mac/coordinate_conversion.h"
25 #include "ui/views/bubble/bubble_delegate.h" 25 #include "ui/views/bubble/bubble_delegate.h"
26 #import "ui/views/cocoa/bridged_native_widget.h" 26 #import "ui/views/cocoa/bridged_native_widget.h"
27 #import "ui/views/cocoa/native_widget_mac_nswindow.h" 27 #import "ui/views/cocoa/native_widget_mac_nswindow.h"
28 #include "ui/views/controls/button/label_button.h" 28 #include "ui/views/controls/button/label_button.h"
29 #include "ui/views/controls/label.h" 29 #include "ui/views/controls/label.h"
30 #include "ui/views/controls/native/native_view_host.h"
30 #include "ui/views/native_cursor.h" 31 #include "ui/views/native_cursor.h"
31 #include "ui/views/test/native_widget_factory.h" 32 #include "ui/views/test/native_widget_factory.h"
32 #include "ui/views/test/test_widget_observer.h" 33 #include "ui/views/test/test_widget_observer.h"
33 #include "ui/views/test/widget_test.h" 34 #include "ui/views/test/widget_test.h"
34 #include "ui/views/widget/native_widget_mac.h" 35 #include "ui/views/widget/native_widget_mac.h"
35 #include "ui/views/widget/native_widget_private.h" 36 #include "ui/views/widget/native_widget_private.h"
36 #include "ui/views/window/dialog_delegate.h" 37 #include "ui/views/window/dialog_delegate.h"
37 38
38 // Donates an implementation of -[NSAnimation stopAnimation] which calls the 39 // Donates an implementation of -[NSAnimation stopAnimation] which calls the
39 // original implementation, then quits a nested run loop. 40 // original implementation, then quits a nested run loop.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 205
205 int gained_visible_count_ = 0; 206 int gained_visible_count_ = 0;
206 int lost_visible_count_ = 0; 207 int lost_visible_count_ = 0;
207 int target_gained_visible_count_ = 0; 208 int target_gained_visible_count_ = 0;
208 int target_lost_visible_count_ = 0; 209 int target_lost_visible_count_ = 0;
209 base::RunLoop* run_loop_ = nullptr; 210 base::RunLoop* run_loop_ = nullptr;
210 211
211 DISALLOW_COPY_AND_ASSIGN(WidgetChangeObserver); 212 DISALLOW_COPY_AND_ASSIGN(WidgetChangeObserver);
212 }; 213 };
213 214
215 class NativeHostHolder {
216 public:
217 NativeHostHolder()
218 : view_([[NSView alloc] init]), host_(new NativeViewHost()) {
219 host_->set_owned_by_client();
220 }
221
222 void AttachNativeView() {
223 DCHECK(!host_->native_view());
224 host_->Attach(view_.get());
225 }
226
227 void Detach() { host_->Detach(); }
228
229 gfx::NativeView view() const { return view_.get(); }
230 NativeViewHost* host() const { return host_.get(); }
231
232 private:
233 base::scoped_nsobject<NSView> view_;
234 scoped_ptr<NativeViewHost> host_;
235
236 DISALLOW_COPY_AND_ASSIGN(NativeHostHolder);
237 };
238
214 // Test visibility states triggered externally. 239 // Test visibility states triggered externally.
215 TEST_F(NativeWidgetMacTest, HideAndShowExternally) { 240 TEST_F(NativeWidgetMacTest, HideAndShowExternally) {
216 Widget* widget = CreateTopLevelPlatformWidget(); 241 Widget* widget = CreateTopLevelPlatformWidget();
217 NSWindow* ns_window = widget->GetNativeWindow(); 242 NSWindow* ns_window = widget->GetNativeWindow();
218 WidgetChangeObserver observer(widget); 243 WidgetChangeObserver observer(widget);
219 244
220 // Should initially be hidden. 245 // Should initially be hidden.
221 EXPECT_FALSE(widget->IsVisible()); 246 EXPECT_FALSE(widget->IsVisible());
222 EXPECT_FALSE([ns_window isVisible]); 247 EXPECT_FALSE([ns_window isVisible]);
223 EXPECT_EQ(0, observer.gained_visible_count()); 248 EXPECT_EQ(0, observer.gained_visible_count());
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 1354
1330 [widget->GetNativeWindow() makeFirstResponder:child_view]; 1355 [widget->GetNativeWindow() makeFirstResponder:child_view];
1331 EXPECT_FALSE(manager->GetFocusedView()); 1356 EXPECT_FALSE(manager->GetFocusedView());
1332 1357
1333 [widget->GetNativeWindow() makeFirstResponder:widget->GetNativeView()]; 1358 [widget->GetNativeWindow() makeFirstResponder:widget->GetNativeView()];
1334 EXPECT_EQ(manager->GetFocusedView(), widget->GetRootView()); 1359 EXPECT_EQ(manager->GetFocusedView(), widget->GetRootView());
1335 1360
1336 widget->CloseNow(); 1361 widget->CloseNow();
1337 } 1362 }
1338 1363
1364 class NativeWidgetMacViewsOrderTest : public WidgetTest {
1365 public:
1366 NativeWidgetMacViewsOrderTest() {}
1367
1368 protected:
1369 // testing::Test:
1370 void SetUp() override {
1371 WidgetTest::SetUp();
1372
1373 widget_ = CreateTopLevelPlatformWidget();
1374
1375 ASSERT_EQ(1u, [[widget_->GetNativeView() subviews] count]);
1376 compositor_view_ = [[widget_->GetNativeView() subviews] firstObject];
1377
1378 native_host_parent_ = new View();
1379 widget_->GetContentsView()->AddChildView(native_host_parent_);
1380
1381 const int kNativeViewCount = 3;
1382 for (int i = 0; i < kNativeViewCount; ++i) {
1383 scoped_ptr<NativeHostHolder> holder(new NativeHostHolder());
1384 native_host_parent_->AddChildView(holder->host());
1385 holder->AttachNativeView();
1386 hosts_.push_back(std::move(holder));
1387 }
1388 EXPECT_EQ(kNativeViewCount, native_host_parent_->child_count());
1389 EXPECT_TRUE(([[widget_->GetNativeView() subviews] isEqualToArray:@[
1390 compositor_view_, hosts_[0]->view(), hosts_[1]->view(), hosts_[2]->view()
1391 ]]));
1392 }
1393
1394 void TearDown() override {
1395 widget_->CloseNow();
1396 WidgetTest::TearDown();
1397 }
1398
1399 NSView* GetContentNativeView() { return widget_->GetNativeView(); }
1400
1401 Widget* widget_ = nullptr;
1402 View* native_host_parent_ = nullptr;
1403 NSView* compositor_view_ = nil;
1404 std::vector<scoped_ptr<NativeHostHolder>> hosts_;
1405
1406 private:
1407 DISALLOW_COPY_AND_ASSIGN(NativeWidgetMacViewsOrderTest);
1408 };
1409
1410 // Test that NativeViewHost::Attach()/Detach() method saves the NativeView
1411 // z-order.
1412 TEST_F(NativeWidgetMacViewsOrderTest, NativeViewAttached) {
1413 hosts_[1]->Detach();
1414 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1415 compositor_view_, hosts_[0]->view(), hosts_[2]->view()
1416 ]]));
1417
1418 hosts_[1]->AttachNativeView();
1419 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1420 compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
1421 hosts_[2]->view()
1422 ]]));
1423 }
1424
1425 // Tests that NativeViews order changes according to views::View hierarchy.
1426 TEST_F(NativeWidgetMacViewsOrderTest, ReorderViews) {
1427 native_host_parent_->ReorderChildView(hosts_[2]->host(), 1);
1428 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1429 compositor_view_, hosts_[0]->view(), hosts_[2]->view(),
1430 hosts_[1]->view()
1431 ]]));
1432
1433 native_host_parent_->RemoveChildView(hosts_[2]->host());
1434 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1435 compositor_view_, hosts_[0]->view(), hosts_[1]->view()
1436 ]]));
1437
1438 View* new_parent = new View();
1439 native_host_parent_->RemoveChildView(hosts_[1]->host());
1440 native_host_parent_->AddChildView(new_parent);
1441 new_parent->AddChildView(hosts_[1]->host());
1442 new_parent->AddChildView(hosts_[2]->host());
1443 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1444 compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
1445 hosts_[2]->view()
1446 ]]));
1447
1448 native_host_parent_->ReorderChildView(new_parent, 0);
1449 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1450 compositor_view_, hosts_[1]->view(), hosts_[2]->view(),
1451 hosts_[0]->view()
1452 ]]));
1453 }
1454
1455 // Test that unassociated native views stay on top after reordering.
1456 TEST_F(NativeWidgetMacViewsOrderTest, UnassociatedViewsIsAbove) {
1457 base::scoped_nsobject<NSView> child_view([[NSView alloc] init]);
1458 [GetContentNativeView() addSubview:child_view];
1459 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1460 compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
1461 hosts_[2]->view(), child_view
1462 ]]));
1463
1464 native_host_parent_->ReorderChildView(hosts_[2]->host(), 1);
1465 EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
1466 compositor_view_, hosts_[0]->view(), hosts_[2]->view(),
1467 hosts_[1]->view(), child_view
1468 ]]));
1469 }
1470
1339 } // namespace test 1471 } // namespace test
1340 } // namespace views 1472 } // namespace views
1341 1473
1342 @implementation TestStopAnimationWaiter 1474 @implementation TestStopAnimationWaiter
1343 - (void)setWindowStateForEnd { 1475 - (void)setWindowStateForEnd {
1344 views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd); 1476 views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd);
1345 } 1477 }
1346 @end 1478 @end
1347 1479
1348 @implementation NativeWidgetMacTestWindow 1480 @implementation NativeWidgetMacTestWindow
(...skipping 17 matching lines...) Expand all
1366 lastDirtyRect_ = dirtyRect; 1498 lastDirtyRect_ = dirtyRect;
1367 } 1499 }
1368 1500
1369 @end 1501 @end
1370 1502
1371 @implementation FocusableTestNSView 1503 @implementation FocusableTestNSView
1372 - (BOOL)acceptsFirstResponder { 1504 - (BOOL)acceptsFirstResponder {
1373 return YES; 1505 return YES;
1374 } 1506 }
1375 @end 1507 @end
OLDNEW
« no previous file with comments | « ui/views/widget/native_widget_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698