| 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_nsautorelease_pool.h" | 10 #import "base/mac/scoped_nsautorelease_pool.h" |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 NSRect nsrect = gfx::ScreenRectToNSRect(screen_rect); | 659 NSRect nsrect = gfx::ScreenRectToNSRect(screen_rect); |
| 660 NSPoint midpoint = NSMakePoint(NSMidX(nsrect), NSMidY(nsrect)); | 660 NSPoint midpoint = NSMakePoint(NSMidX(nsrect), NSMidY(nsrect)); |
| 661 | 661 |
| 662 id hit = [widget->GetNativeWindow() accessibilityHitTest:midpoint]; | 662 id hit = [widget->GetNativeWindow() accessibilityHitTest:midpoint]; |
| 663 id title = [hit accessibilityAttributeValue:NSAccessibilityTitleAttribute]; | 663 id title = [hit accessibilityAttributeValue:NSAccessibilityTitleAttribute]; |
| 664 EXPECT_NSEQ(title, @"Green"); | 664 EXPECT_NSEQ(title, @"Green"); |
| 665 | 665 |
| 666 widget->CloseNow(); | 666 widget->CloseNow(); |
| 667 } | 667 } |
| 668 | 668 |
| 669 // Tests creating a views::Widget parented off a native NSWindow. | 669 namespace { |
| 670 TEST_F(NativeWidgetMacTest, NonWidgetParent) { | |
| 671 NSWindow* native_parent = MakeNativeParent(); | |
| 672 | 670 |
| 671 Widget* AttachPopupToNativeParent(NSWindow* native_parent) { |
| 673 base::scoped_nsobject<NSView> anchor_view( | 672 base::scoped_nsobject<NSView> anchor_view( |
| 674 [[NSView alloc] initWithFrame:[[native_parent contentView] bounds]]); | 673 [[NSView alloc] initWithFrame:[[native_parent contentView] bounds]]); |
| 675 [[native_parent contentView] addSubview:anchor_view]; | 674 [[native_parent contentView] addSubview:anchor_view]; |
| 676 | 675 |
| 677 // Note: Don't use WidgetTest::CreateChildPlatformWidget because that makes | 676 // Note: Don't use WidgetTest::CreateChildPlatformWidget because that makes |
| 678 // windows of TYPE_CONTROL which need a parent Widget to obtain the focus | 677 // windows of TYPE_CONTROL which need a parent Widget to obtain the focus |
| 679 // manager. | 678 // manager. |
| 680 Widget* child = new Widget; | 679 Widget* child = new Widget; |
| 681 Widget::InitParams init_params; | 680 Widget::InitParams init_params; |
| 682 init_params.parent = anchor_view; | 681 init_params.parent = anchor_view; |
| 683 init_params.type = Widget::InitParams::TYPE_POPUP; | 682 init_params.type = Widget::InitParams::TYPE_POPUP; |
| 684 child->Init(init_params); | 683 child->Init(init_params); |
| 684 return child; |
| 685 } |
| 685 | 686 |
| 687 } // namespace |
| 688 |
| 689 // Tests creating a views::Widget parented off a native NSWindow. |
| 690 TEST_F(NativeWidgetMacTest, NonWidgetParent) { |
| 691 NSWindow* native_parent = MakeNativeParent(); |
| 692 Widget* child = AttachPopupToNativeParent(native_parent); |
| 686 TestWidgetObserver child_observer(child); | 693 TestWidgetObserver child_observer(child); |
| 687 | 694 |
| 688 // GetTopLevelNativeWidget() only goes as far as there exists a Widget (i.e. | 695 // GetTopLevelNativeWidget() only goes as far as there exists a Widget (i.e. |
| 689 // must stop at |child|. | 696 // must stop at |child|. |
| 690 internal::NativeWidgetPrivate* top_level_widget = | 697 internal::NativeWidgetPrivate* top_level_widget = |
| 691 internal::NativeWidgetPrivate::GetTopLevelNativeWidget( | 698 internal::NativeWidgetPrivate::GetTopLevelNativeWidget( |
| 692 child->GetNativeView()); | 699 child->GetNativeView()); |
| 693 EXPECT_EQ(child, top_level_widget->GetWidget()); | 700 EXPECT_EQ(child, top_level_widget->GetWidget()); |
| 694 | 701 |
| 695 // To verify the parent, we need to use NativeWidgetMac APIs. | 702 // To verify the parent, we need to use NativeWidgetMac APIs. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 706 EXPECT_TRUE(child->IsVisible()); | 713 EXPECT_TRUE(child->IsVisible()); |
| 707 EXPECT_EQ(1u, [[native_parent childWindows] count]); | 714 EXPECT_EQ(1u, [[native_parent childWindows] count]); |
| 708 EXPECT_EQ(child->GetNativeWindow(), | 715 EXPECT_EQ(child->GetNativeWindow(), |
| 709 [[native_parent childWindows] objectAtIndex:0]); | 716 [[native_parent childWindows] objectAtIndex:0]); |
| 710 EXPECT_EQ(native_parent, [child->GetNativeWindow() parentWindow]); | 717 EXPECT_EQ(native_parent, [child->GetNativeWindow() parentWindow]); |
| 711 | 718 |
| 712 // Only non-toplevel Widgets are positioned relative to the parent, so the | 719 // Only non-toplevel Widgets are positioned relative to the parent, so the |
| 713 // bounds set above should be in screen coordinates. | 720 // bounds set above should be in screen coordinates. |
| 714 EXPECT_EQ(child_bounds, child->GetWindowBoundsInScreen()); | 721 EXPECT_EQ(child_bounds, child->GetWindowBoundsInScreen()); |
| 715 | 722 |
| 716 // Removing the anchor_view from its view hierarchy is permitted. This should | 723 // Removing the anchor view from its view hierarchy is permitted. This should |
| 717 // not break the relationship between the two windows. | 724 // not break the relationship between the two windows. |
| 725 NSView* anchor_view = [[native_parent contentView] subviews][0]; |
| 726 EXPECT_TRUE(anchor_view); |
| 718 [anchor_view removeFromSuperview]; | 727 [anchor_view removeFromSuperview]; |
| 719 anchor_view.reset(); | |
| 720 EXPECT_EQ(native_parent, bridged_native_widget->parent()->GetNSWindow()); | 728 EXPECT_EQ(native_parent, bridged_native_widget->parent()->GetNSWindow()); |
| 721 | 729 |
| 722 // Closing the parent should close and destroy the child. | 730 // Closing the parent should close and destroy the child. |
| 723 EXPECT_FALSE(child_observer.widget_closed()); | 731 EXPECT_FALSE(child_observer.widget_closed()); |
| 724 [native_parent close]; | 732 [native_parent close]; |
| 725 EXPECT_TRUE(child_observer.widget_closed()); | 733 EXPECT_TRUE(child_observer.widget_closed()); |
| 726 | 734 |
| 727 EXPECT_EQ(0u, [[native_parent childWindows] count]); | 735 EXPECT_EQ(0u, [[native_parent childWindows] count]); |
| 728 } | 736 } |
| 729 | 737 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 751 // close]. This test tries to establish a situation where the last reference | 759 // close]. This test tries to establish a situation where the last reference |
| 752 // to the child window is released inside WidgetOwnerNSWindowAdapter:: | 760 // to the child window is released inside WidgetOwnerNSWindowAdapter:: |
| 753 // OnWindowWillClose(). | 761 // OnWindowWillClose(). |
| 754 base::mac::ScopedNSAutoreleasePool pool; | 762 base::mac::ScopedNSAutoreleasePool pool; |
| 755 [native_parent_.autorelease() close]; | 763 [native_parent_.autorelease() close]; |
| 756 EXPECT_TRUE(child_dealloced); | 764 EXPECT_TRUE(child_dealloced); |
| 757 } | 765 } |
| 758 EXPECT_TRUE(native_parent_dealloced); | 766 EXPECT_TRUE(native_parent_dealloced); |
| 759 } | 767 } |
| 760 | 768 |
| 769 // Tests visibility for child of native NSWindow, reshowing after -[NSApp hide]. |
| 770 TEST_F(NativeWidgetMacTest, VisibleAfterNativeParentShow) { |
| 771 NSWindow* native_parent = MakeNativeParent(); |
| 772 Widget* child = AttachPopupToNativeParent(native_parent); |
| 773 child->Show(); |
| 774 EXPECT_TRUE(child->IsVisible()); |
| 775 |
| 776 WidgetChangeObserver child_observer(child); |
| 777 [NSApp hide:nil]; |
| 778 child_observer.WaitForVisibleCounts(0, 1); |
| 779 EXPECT_FALSE(child->IsVisible()); |
| 780 |
| 781 [native_parent makeKeyAndOrderFront:nil]; |
| 782 child_observer.WaitForVisibleCounts(1, 1); |
| 783 EXPECT_TRUE(child->IsVisible()); |
| 784 |
| 785 [native_parent close]; |
| 786 } |
| 787 |
| 761 // Use Native APIs to query the tooltip text that would be shown once the | 788 // Use Native APIs to query the tooltip text that would be shown once the |
| 762 // tooltip delay had elapsed. | 789 // tooltip delay had elapsed. |
| 763 base::string16 TooltipTextForWidget(Widget* widget) { | 790 base::string16 TooltipTextForWidget(Widget* widget) { |
| 764 // For Mac, the actual location doesn't matter, since there is only one native | 791 // For Mac, the actual location doesn't matter, since there is only one native |
| 765 // view and it fills the window. This just assumes the window is at least big | 792 // view and it fills the window. This just assumes the window is at least big |
| 766 // big enough for a constant coordinate to be within it. | 793 // big enough for a constant coordinate to be within it. |
| 767 NSPoint point = NSMakePoint(30, 30); | 794 NSPoint point = NSMakePoint(30, 30); |
| 768 NSView* view = [widget->GetNativeView() hitTest:point]; | 795 NSView* view = [widget->GetNativeView() hitTest:point]; |
| 769 NSString* text = | 796 NSString* text = |
| 770 [view view:view stringForToolTip:0 point:point userData:nullptr]; | 797 [view view:view stringForToolTip:0 point:point userData:nullptr]; |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 | 1829 |
| 1803 - (void)dealloc { | 1830 - (void)dealloc { |
| 1804 if (deallocFlag_) { | 1831 if (deallocFlag_) { |
| 1805 DCHECK(!*deallocFlag_); | 1832 DCHECK(!*deallocFlag_); |
| 1806 *deallocFlag_ = true; | 1833 *deallocFlag_ = true; |
| 1807 } | 1834 } |
| 1808 [super dealloc]; | 1835 [super dealloc]; |
| 1809 } | 1836 } |
| 1810 | 1837 |
| 1811 @end | 1838 @end |
| OLD | NEW |