Commit 79550cc4 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

RemoteMacViews: Re-separate test code

This removes parts of crrev.com/583350, preserving the following
- explicitly require that NSWindows be NativeWidgetMacNSWindow

This removes the ability to create an NSWindow in the AppShim process
for now. That will be re-added later.

This is a re-land of crrev.com/584323 (reverted in crrev.com/584323),
with the changes in lifetime management (use of autorelease) removed,
because it appears that tests make assumptions about lifetime. Added
a comment about this.

TBR=tapted

Bug: 859152
Change-Id: Ia0e2811c903316a0c1ed07be6cd7275bb8cf421d
Reviewed-on: https://chromium-review.googlesource.com/1180707Reviewed-by: default avatarccameron <ccameron@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584344}
parent 0cd492d7
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
#include "ui/display/display_observer.h" #include "ui/display/display_observer.h"
#import "ui/views/cocoa/bridged_native_widget_owner.h" #import "ui/views/cocoa/bridged_native_widget_owner.h"
#import "ui/views/cocoa/cocoa_mouse_capture_delegate.h" #import "ui/views/cocoa/cocoa_mouse_capture_delegate.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#import "ui/views/focus/focus_manager.h" #import "ui/views/focus/focus_manager.h"
#include "ui/views/views_export.h" #include "ui/views/views_export.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
@class BridgedContentView; @class BridgedContentView;
@class ModalShowAnimationWithLayer; @class ModalShowAnimationWithLayer;
@class NativeWidgetMacNSWindow;
@class ViewsNSWindowDelegate; @class ViewsNSWindowDelegate;
namespace views { namespace views {
...@@ -88,14 +88,10 @@ class VIEWS_EXPORT BridgedNativeWidget ...@@ -88,14 +88,10 @@ class VIEWS_EXPORT BridgedNativeWidget
BridgedNativeWidget(BridgedNativeWidgetHost* host, NativeWidgetMac* parent); BridgedNativeWidget(BridgedNativeWidgetHost* host, NativeWidgetMac* parent);
~BridgedNativeWidget() override; ~BridgedNativeWidget() override;
// Create the NSWindow using the specified style mask.
void CreateWindow(uint64_t window_style_mask);
// Initialize the NSWindow by taking ownership of the specified object. // Initialize the NSWindow by taking ownership of the specified object.
// Either CreateWindow or SetWindow maybe used to initialize the NSWindow,
// and the initialization may happen only once.
// TODO(ccameron): When a BridgedNativeWidget is allocated across a process // TODO(ccameron): When a BridgedNativeWidget is allocated across a process
// boundary, it will not be possible to call SetWindow. Move the relevant // boundary, it will not be possible to explicitly set an NSWindow in this
// sub-classes so that they can be allocated via CreateWindow. // way.
void SetWindow(base::scoped_nsobject<NativeWidgetMacNSWindow> window); void SetWindow(base::scoped_nsobject<NativeWidgetMacNSWindow> window);
// Initialize the bridge (after the NSWindow has been created). // Initialize the bridge (after the NSWindow has been created).
void Init(const Widget::InitParams& params); void Init(const Widget::InitParams& params);
...@@ -192,7 +188,7 @@ class VIEWS_EXPORT BridgedNativeWidget ...@@ -192,7 +188,7 @@ class VIEWS_EXPORT BridgedNativeWidget
NativeWidgetMac* native_widget_mac() { return native_widget_mac_; } NativeWidgetMac* native_widget_mac() { return native_widget_mac_; }
BridgedContentView* ns_view() { return bridged_view_; } BridgedContentView* ns_view() { return bridged_view_; }
NativeWidgetMacNSWindow* ns_window() { return window_; } NSWindow* ns_window();
TooltipManager* tooltip_manager() { return tooltip_manager_.get(); } TooltipManager* tooltip_manager() { return tooltip_manager_.get(); }
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "components/viz/common/surfaces/local_surface_id.h" #include "components/viz/common/surfaces/local_surface_id.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#import "ui/base/cocoa/window_size_constants.h"
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/base/layout.h" #include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
...@@ -245,17 +244,6 @@ BridgedNativeWidget::~BridgedNativeWidget() { ...@@ -245,17 +244,6 @@ BridgedNativeWidget::~BridgedNativeWidget() {
SetRootView(nullptr); SetRootView(nullptr);
} }
void BridgedNativeWidget::CreateWindow(uint64_t window_style_mask) {
DCHECK(!window_);
window_.reset([[NativeWidgetMacNSWindow alloc]
initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:window_style_mask
backing:NSBackingStoreBuffered
defer:NO]);
[window_ setReleasedWhenClosed:NO]; // Owned by scoped_nsobject.
[window_ setDelegate:window_delegate_];
}
void BridgedNativeWidget::SetWindow( void BridgedNativeWidget::SetWindow(
base::scoped_nsobject<NativeWidgetMacNSWindow> window) { base::scoped_nsobject<NativeWidgetMacNSWindow> window) {
DCHECK(!window_); DCHECK(!window_);
...@@ -950,6 +938,10 @@ bool BridgedNativeWidget::ShouldRunCustomAnimationFor( ...@@ -950,6 +938,10 @@ bool BridgedNativeWidget::ShouldRunCustomAnimationFor(
switches::kDisableModalAnimations); switches::kDisableModalAnimations);
} }
NSWindow* BridgedNativeWidget::ns_window() {
return window_.get();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidget, ui::CATransactionObserver // BridgedNativeWidget, ui::CATransactionObserver
......
...@@ -248,6 +248,45 @@ NSTextInputContext* g_fake_current_input_context = nullptr; ...@@ -248,6 +248,45 @@ NSTextInputContext* g_fake_current_input_context = nullptr;
@end @end
// Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates
// NSWindow's behavior when attempting to toggle fullscreen state again, when
// the last attempt failed but Cocoa has not yet sent
// windowDidFailToEnterFullScreen:.
@interface BridgedNativeWidgetTestWindow : NativeWidgetMacNSWindow {
@private
BOOL ignoreToggleFullScreen_;
int ignoredToggleFullScreenCount_;
}
@property(assign, nonatomic) BOOL ignoreToggleFullScreen;
@property(readonly, nonatomic) int ignoredToggleFullScreenCount;
@end
@implementation BridgedNativeWidgetTestWindow
@synthesize ignoreToggleFullScreen = ignoreToggleFullScreen_;
@synthesize ignoredToggleFullScreenCount = ignoredToggleFullScreenCount_;
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay {
// This is used in simulations without a message loop. Don't start a message
// loop since that would expose the tests to system notifications and
// potential flakes. Instead, just pretend the message loop is flushed here.
if (ignoreToggleFullScreen_ && aSelector == @selector(toggleFullScreen:))
[self toggleFullScreen:anArgument];
else
[super performSelector:aSelector withObject:anArgument afterDelay:delay];
}
- (void)toggleFullScreen:(id)sender {
if (ignoreToggleFullScreen_)
++ignoredToggleFullScreenCount_;
else
[super toggleFullScreen:sender];
}
@end
namespace views { namespace views {
namespace test { namespace test {
...@@ -263,7 +302,13 @@ class MockNativeWidgetMac : public NativeWidgetMac { ...@@ -263,7 +302,13 @@ class MockNativeWidgetMac : public NativeWidgetMac {
void InitNativeWidget(const Widget::InitParams& params) override { void InitNativeWidget(const Widget::InitParams& params) override {
ownership_ = params.ownership; ownership_ = params.ownership;
bridge()->CreateWindow(NSBorderlessWindowMask); base::scoped_nsobject<NativeWidgetMacNSWindow> window(
[[BridgedNativeWidgetTestWindow alloc]
initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO]);
bridge()->SetWindow(window);
bridge()->Init(params); bridge()->Init(params);
// Usually the bridge gets initialized here. It is skipped to run extra // Usually the bridge gets initialized here. It is skipped to run extra
...@@ -1542,10 +1587,10 @@ typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest; ...@@ -1542,10 +1587,10 @@ typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;
// mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause
// the fullscreen transition to fail. // the fullscreen transition to fail.
TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
NativeWidgetMacNSWindow* window = BridgedNativeWidgetTestWindow* window =
base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>( base::mac::ObjCCastStrict<BridgedNativeWidgetTestWindow>(
widget_->GetNativeWindow()); widget_->GetNativeWindow());
[window disableToggleFullScreenForTesting]; [window setIgnoreToggleFullScreen:YES];
widget_->Show(); widget_->Show();
NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
...@@ -1559,11 +1604,11 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { ...@@ -1559,11 +1604,11 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
// On a failure, Cocoa starts by sending an unexpected *exit* fullscreen, and // On a failure, Cocoa starts by sending an unexpected *exit* fullscreen, and
// BridgedNativeWidget will think it's just a delayed transition and try to go // BridgedNativeWidget will think it's just a delayed transition and try to go
// back into fullscreen but get ignored by Cocoa. // back into fullscreen but get ignored by Cocoa.
EXPECT_EQ(0, [window toggleFullScreenCountForTesting]); EXPECT_EQ(0, [window ignoredToggleFullScreenCount]);
EXPECT_TRUE(bridge()->target_fullscreen_state()); EXPECT_TRUE(bridge()->target_fullscreen_state());
[center postNotificationName:NSWindowDidExitFullScreenNotification [center postNotificationName:NSWindowDidExitFullScreenNotification
object:window]; object:window];
EXPECT_EQ(1, [window toggleFullScreenCountForTesting]); EXPECT_EQ(1, [window ignoredToggleFullScreenCount]);
EXPECT_FALSE(bridge()->target_fullscreen_state()); EXPECT_FALSE(bridge()->target_fullscreen_state());
// Cocoa follows up with a failure message sent to the NSWindowDelegate (there // Cocoa follows up with a failure message sent to the NSWindowDelegate (there
...@@ -1592,7 +1637,7 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { ...@@ -1592,7 +1637,7 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
EXPECT_FALSE(bridge()->target_fullscreen_state()); EXPECT_FALSE(bridge()->target_fullscreen_state());
[center postNotificationName:NSWindowDidExitFullScreenNotification [center postNotificationName:NSWindowDidExitFullScreenNotification
object:window]; object:window];
EXPECT_EQ(1, [window toggleFullScreenCountForTesting]); // No change. EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
EXPECT_FALSE(bridge()->target_fullscreen_state()); EXPECT_FALSE(bridge()->target_fullscreen_state());
widget_->CloseNow(); widget_->CloseNow();
......
...@@ -47,16 +47,6 @@ VIEWS_EXPORT ...@@ -47,16 +47,6 @@ VIEWS_EXPORT
// create one. // create one.
- (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate; - (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate;
// Override -[NSWindow toggleFullScreen:] to be a no-op for testing.
- (void)disableToggleFullScreenForTesting;
// Methods to query properties for tests.
// TODO(ccameron): It may be more appropriate to put testing methods into a
// separate subclass.
@property(readonly, nonatomic) int invalidateShadowCountForTesting;
@property(readonly, nonatomic) int orderWindowCountForTesting;
@property(readonly, nonatomic) int toggleFullScreenCountForTesting;
@property(assign, nonatomic) bool* deallocFlagForTesting;
@end @end
#endif // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_ #endif // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#import "base/mac/sdk_forward_declarations.h" #import "base/mac/sdk_forward_declarations.h"
#import "ui/base/cocoa/user_interface_item_command_handler.h" #import "ui/base/cocoa/user_interface_item_command_handler.h"
#import "ui/base/cocoa/window_size_constants.h"
#import "ui/views/cocoa/bridged_native_widget.h" #import "ui/views/cocoa/bridged_native_widget.h"
#import "ui/views/cocoa/views_nswindow_delegate.h" #import "ui/views/cocoa/views_nswindow_delegate.h"
#import "ui/views/cocoa/window_touch_bar_delegate.h" #import "ui/views/cocoa/window_touch_bar_delegate.h"
...@@ -82,24 +83,14 @@ ...@@ -82,24 +83,14 @@
base::scoped_nsobject<CommandDispatcher> commandDispatcher_; base::scoped_nsobject<CommandDispatcher> commandDispatcher_;
base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_; base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_;
id<WindowTouchBarDelegate> touchBarDelegate_; // Weak. id<WindowTouchBarDelegate> touchBarDelegate_; // Weak.
BOOL toggleFullscreenDisabledForTesting_;
int invalidateShadowCountForTesting_;
int orderWindowCountForTesting_;
int toggleFullScreenCountForTesting_;
bool* deallocFlagForTesting_;
} }
@synthesize invalidateShadowCountForTesting = invalidateShadowCountForTesting_;
@synthesize orderWindowCountForTesting = orderWindowCountForTesting_;
@synthesize toggleFullScreenCountForTesting = toggleFullScreenCountForTesting_;
@synthesize deallocFlagForTesting = deallocFlagForTesting_;
- (instancetype)initWithContentRect:(NSRect)contentRect - (instancetype)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation { defer:(BOOL)deferCreation {
if ((self = [super initWithContentRect:contentRect DCHECK(NSEqualRects(contentRect, ui::kWindowSizeDeterminedLater));
if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:windowStyle styleMask:windowStyle
backing:bufferingType backing:bufferingType
defer:deferCreation])) { defer:deferCreation])) {
...@@ -109,13 +100,8 @@ ...@@ -109,13 +100,8 @@
} }
// This override doesn't do anything, but keeping it helps diagnose lifetime // This override doesn't do anything, but keeping it helps diagnose lifetime
// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow, // issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow.
// and adds hooks for tests.
- (void)dealloc { - (void)dealloc {
if (deallocFlagForTesting_) {
DCHECK(!*deallocFlagForTesting_);
*deallocFlagForTesting_ = true;
}
[super dealloc]; [super dealloc];
} }
...@@ -140,10 +126,6 @@ ...@@ -140,10 +126,6 @@
touchBarDelegate_ = delegate; touchBarDelegate_ = delegate;
} }
- (void)disableToggleFullScreenForTesting {
toggleFullscreenDisabledForTesting_ = YES;
}
// Private methods. // Private methods.
- (ViewsNSWindowDelegate*)viewsNSWindowDelegate { - (ViewsNSWindowDelegate*)viewsNSWindowDelegate {
...@@ -245,36 +227,10 @@ ...@@ -245,36 +227,10 @@
// when ordering in a window for the first time. // when ordering in a window for the first time.
- (void)orderWindow:(NSWindowOrderingMode)orderingMode - (void)orderWindow:(NSWindowOrderingMode)orderingMode
relativeTo:(NSInteger)otherWindowNumber { relativeTo:(NSInteger)otherWindowNumber {
++orderWindowCountForTesting_;
[super orderWindow:orderingMode relativeTo:otherWindowNumber]; [super orderWindow:orderingMode relativeTo:otherWindowNumber];
[[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; [[self viewsNSWindowDelegate] onWindowOrderChanged:nil];
} }
- (void)invalidateShadow {
++invalidateShadowCountForTesting_;
[super invalidateShadow];
}
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay {
if (toggleFullscreenDisabledForTesting_ && aSelector == @selector
(toggleFullScreen:)) {
// This is used in simulations without a message loop. Don't start a message
// loop since that would expose the tests to system notifications and
// potential flakes. Instead, just pretend the message loop is flushed here.
[self toggleFullScreen:anArgument];
} else {
[super performSelector:aSelector withObject:anArgument afterDelay:delay];
}
}
- (void)toggleFullScreen:(id)sender {
++toggleFullScreenCountForTesting_;
if (!toggleFullscreenDisabledForTesting_)
[super toggleFullScreen:sender];
}
// NSResponder implementation. // NSResponder implementation.
- (BOOL)performKeyEquivalent:(NSEvent*)event { - (BOOL)performKeyEquivalent:(NSEvent*)event {
......
...@@ -147,6 +147,10 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate { ...@@ -147,6 +147,10 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
protected: protected:
// Creates the NSWindow that will be passed to the BridgedNativeWidget. // Creates the NSWindow that will be passed to the BridgedNativeWidget.
// Called by InitNativeWidget. The return value will be autoreleased. // Called by InitNativeWidget. The return value will be autoreleased.
// Note that some tests (in particular, views_unittests that interact
// with ScopedFakeNSWindowFullscreen, on 10.10) assume that these windows
// are autoreleased, and will crash if the window has a more precise
// lifetime.
virtual NativeWidgetMacNSWindow* CreateNSWindow( virtual NativeWidgetMacNSWindow* CreateNSWindow(
const Widget::InitParams& params); const Widget::InitParams& params);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#import "ui/views/cocoa/bridged_native_widget_host_impl.h" #import "ui/views/cocoa/bridged_native_widget_host_impl.h"
#include "ui/views/cocoa/cocoa_mouse_capture.h" #include "ui/views/cocoa/cocoa_mouse_capture.h"
#import "ui/views/cocoa/drag_drop_client_mac.h" #import "ui/views/cocoa/drag_drop_client_mac.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#import "ui/views/cocoa/views_nswindow_delegate.h" #import "ui/views/cocoa/views_nswindow_delegate.h"
#include "ui/views/widget/drop_helper.h" #include "ui/views/widget/drop_helper.h"
#include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_delegate.h"
......
...@@ -56,6 +56,18 @@ ...@@ -56,6 +56,18 @@
- (BOOL)_isTitleHidden; - (BOOL)_isTitleHidden;
@end @end
// Test NSWindow that provides hooks via method overrides to verify behavior.
@interface NativeWidgetMacTestWindow : NativeWidgetMacNSWindow {
@private
int invalidateShadowCount_;
int orderWindowCount_;
bool* deallocFlag_;
}
@property(readonly, nonatomic) int invalidateShadowCount;
@property(readonly, nonatomic) int orderWindowCount;
@property(assign, nonatomic) bool* deallocFlag;
@end
// Used to mock BridgedContentView so that calls to drawRect: can be // Used to mock BridgedContentView so that calls to drawRect: can be
// intercepted. // intercepted.
@interface MockBridgedView : NSView { @interface MockBridgedView : NSView {
...@@ -109,6 +121,33 @@ class BridgedNativeWidgetTestApi { ...@@ -109,6 +121,33 @@ class BridgedNativeWidgetTestApi {
DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTestApi); DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTestApi);
}; };
// Custom native_widget to create a NativeWidgetMacTestWindow.
class TestWindowNativeWidgetMac : public NativeWidgetMac {
public:
explicit TestWindowNativeWidgetMac(Widget* delegate)
: NativeWidgetMac(delegate) {}
protected:
// NativeWidgetMac:
NativeWidgetMacNSWindow* CreateNSWindow(
const Widget::InitParams& params) override {
NSUInteger style_mask = NSBorderlessWindowMask;
if (params.type == Widget::InitParams::TYPE_WINDOW) {
style_mask = NSTexturedBackgroundWindowMask | NSTitledWindowMask |
NSClosableWindowMask | NSMiniaturizableWindowMask |
NSResizableWindowMask;
}
return [[[NativeWidgetMacTestWindow alloc]
initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO] autorelease];
}
private:
DISALLOW_COPY_AND_ASSIGN(TestWindowNativeWidgetMac);
};
// Tests for parts of NativeWidgetMac not covered by BridgedNativeWidget, which // Tests for parts of NativeWidgetMac not covered by BridgedNativeWidget, which
// need access to Cocoa APIs. // need access to Cocoa APIs.
class NativeWidgetMacTest : public WidgetTest { class NativeWidgetMacTest : public WidgetTest {
...@@ -135,14 +174,14 @@ class NativeWidgetMacTest : public WidgetTest { ...@@ -135,14 +174,14 @@ class NativeWidgetMacTest : public WidgetTest {
return MakeNativeParentWithStyle(NSBorderlessWindowMask); return MakeNativeParentWithStyle(NSBorderlessWindowMask);
} }
// Create a Widget backed by the NativeWidgetMacNSWindow NSWindow subclass. // Create a Widget backed by the NativeWidgetMacTestWindow NSWindow subclass.
Widget* CreateWidgetWithTestWindow(Widget::InitParams params, Widget* CreateWidgetWithTestWindow(Widget::InitParams params,
NativeWidgetMacNSWindow** window) { NativeWidgetMacTestWindow** window) {
Widget* widget = new Widget; Widget* widget = new Widget;
params.native_widget = new NativeWidgetMac(widget); params.native_widget = new TestWindowNativeWidgetMac(widget);
widget->Init(params); widget->Init(params);
widget->Show(); widget->Show();
*window = base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>( *window = base::mac::ObjCCastStrict<NativeWidgetMacTestWindow>(
widget->GetNativeWindow()); widget->GetNativeWindow());
EXPECT_TRUE(*window); EXPECT_TRUE(*window);
return widget; return widget;
...@@ -430,8 +469,8 @@ TEST_F(NativeWidgetMacTest, DISABLED_OrderFrontAfterMiniaturize) { ...@@ -430,8 +469,8 @@ TEST_F(NativeWidgetMacTest, DISABLED_OrderFrontAfterMiniaturize) {
// Test that ShowInactive() on already-visible child widgets is ignored, since // Test that ShowInactive() on already-visible child widgets is ignored, since
// it may cause a space transition. See https://crbug.com/866760. // it may cause a space transition. See https://crbug.com/866760.
TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) { TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) {
NativeWidgetMacNSWindow* parent_window; NativeWidgetMacTestWindow* parent_window;
NativeWidgetMacNSWindow* child_window; NativeWidgetMacTestWindow* child_window;
Widget::InitParams init_params = Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW); CreateParams(Widget::InitParams::TYPE_WINDOW);
...@@ -439,29 +478,28 @@ TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) { ...@@ -439,29 +478,28 @@ TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) {
Widget* parent = CreateWidgetWithTestWindow(init_params, &parent_window); Widget* parent = CreateWidgetWithTestWindow(init_params, &parent_window);
// CreateWidgetWithTestWindow calls Show() // CreateWidgetWithTestWindow calls Show()
EXPECT_EQ(1, [parent_window orderWindowCountForTesting]); EXPECT_EQ(1, [parent_window orderWindowCount]);
init_params.parent = parent->GetNativeView(); init_params.parent = parent->GetNativeView();
Widget* child = CreateWidgetWithTestWindow(init_params, &child_window); Widget* child = CreateWidgetWithTestWindow(init_params, &child_window);
// The child is ordered twice, once by Show() and again (by AppKit) when it is // The child is ordered twice, once by Show() and again (by AppKit) when it is
// registered as a child window. // registered as a child window.
EXPECT_EQ(2, [child_window orderWindowCountForTesting]); EXPECT_EQ(2, [child_window orderWindowCount]);
// Parent is unchanged. // Parent is unchanged.
EXPECT_EQ(1, [parent_window orderWindowCountForTesting]); EXPECT_EQ(1, [parent_window orderWindowCount]);
// ShowInactive() on a visible regular window may serve to raise its stacking // ShowInactive() on a visible regular window may serve to raise its stacking
// order without taking focus, so it should invoke -[NSWindow orderWindow:..]. // order without taking focus, so it should invoke -[NSWindow orderWindow:..].
parent->ShowInactive(); parent->ShowInactive();
EXPECT_EQ(2, [parent_window orderWindowCountForTesting]); // Increases. EXPECT_EQ(2, [parent_window orderWindowCount]); // Increases.
// However, ShowInactive() on the child should have no effect. It should // However, ShowInactive() on the child should have no effect. It should
// already be in a correct stacking order and we must avoid a Space switch. // already be in a correct stacking order and we must avoid a Space switch.
child->ShowInactive(); child->ShowInactive();
EXPECT_EQ(2, [child_window orderWindowCountForTesting]); // No change. EXPECT_EQ(2, [child_window orderWindowCount]); // No change.
EXPECT_EQ( EXPECT_EQ(2, [parent_window orderWindowCount]); // Parent also unchanged.
2, [parent_window orderWindowCountForTesting]); // Parent also unchanged.
parent->CloseNow(); parent->CloseNow();
} }
...@@ -838,13 +876,13 @@ TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) { ...@@ -838,13 +876,13 @@ TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
TestNativeParentWindow* native_parent = MakeNativeParent(); TestNativeParentWindow* native_parent = MakeNativeParent();
[native_parent setDeallocFlag:&native_parent_dealloced]; [native_parent setDeallocFlag:&native_parent_dealloced];
NativeWidgetMacNSWindow* window; NativeWidgetMacTestWindow* window;
Widget::InitParams init_params = Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_POPUP); CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.parent = [native_parent_ contentView]; init_params.parent = [native_parent_ contentView];
init_params.bounds = gfx::Rect(0, 0, 100, 200); init_params.bounds = gfx::Rect(0, 0, 100, 200);
CreateWidgetWithTestWindow(init_params, &window); CreateWidgetWithTestWindow(init_params, &window);
[window setDeallocFlagForTesting:&child_dealloced]; [window setDeallocFlag:&child_dealloced];
} }
{ {
// On 10.11, closing a weak reference on the parent window works, but older // On 10.11, closing a weak reference on the parent window works, but older
...@@ -1757,7 +1795,7 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) { ...@@ -1757,7 +1795,7 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) {
// Test calls to invalidate the shadow when composited frames arrive. // Test calls to invalidate the shadow when composited frames arrive.
TEST_F(NativeWidgetMacTest, InvalidateShadow) { TEST_F(NativeWidgetMacTest, InvalidateShadow) {
NativeWidgetMacNSWindow* window; NativeWidgetMacTestWindow* window;
const gfx::Rect rect(0, 0, 100, 200); const gfx::Rect rect(0, 0, 100, 200);
Widget::InitParams init_params = Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
...@@ -1768,7 +1806,7 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) { ...@@ -1768,7 +1806,7 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) {
BridgedNativeWidgetTestApi(window).SimulateFrameSwap(rect.size()); BridgedNativeWidgetTestApi(window).SimulateFrameSwap(rect.size());
// Default is an opaque window, so shadow doesn't need to be invalidated. // Default is an opaque window, so shadow doesn't need to be invalidated.
EXPECT_EQ(0, [window invalidateShadowCountForTesting]); EXPECT_EQ(0, [window invalidateShadowCount]);
widget->CloseNow(); widget->CloseNow();
init_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; init_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
...@@ -1776,40 +1814,40 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) { ...@@ -1776,40 +1814,40 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) {
BridgedNativeWidgetTestApi test_api(window); BridgedNativeWidgetTestApi test_api(window);
// First paint on a translucent window needs to invalidate the shadow. Once. // First paint on a translucent window needs to invalidate the shadow. Once.
EXPECT_EQ(0, [window invalidateShadowCountForTesting]); EXPECT_EQ(0, [window invalidateShadowCount]);
test_api.SimulateFrameSwap(rect.size()); test_api.SimulateFrameSwap(rect.size());
EXPECT_EQ(1, [window invalidateShadowCountForTesting]); EXPECT_EQ(1, [window invalidateShadowCount]);
test_api.SimulateFrameSwap(rect.size()); test_api.SimulateFrameSwap(rect.size());
EXPECT_EQ(1, [window invalidateShadowCountForTesting]); EXPECT_EQ(1, [window invalidateShadowCount]);
// Resizing the window also needs to trigger a shadow invalidation. // Resizing the window also needs to trigger a shadow invalidation.
[window setContentSize:NSMakeSize(123, 456)]; [window setContentSize:NSMakeSize(123, 456)];
// A "late" frame swap at the old size should do nothing. // A "late" frame swap at the old size should do nothing.
test_api.SimulateFrameSwap(rect.size()); test_api.SimulateFrameSwap(rect.size());
EXPECT_EQ(1, [window invalidateShadowCountForTesting]); EXPECT_EQ(1, [window invalidateShadowCount]);
test_api.SimulateFrameSwap(gfx::Size(123, 456)); test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(2, [window invalidateShadowCountForTesting]); EXPECT_EQ(2, [window invalidateShadowCount]);
test_api.SimulateFrameSwap(gfx::Size(123, 456)); test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(2, [window invalidateShadowCountForTesting]); EXPECT_EQ(2, [window invalidateShadowCount]);
// Hiding the window does not require shadow invalidation. // Hiding the window does not require shadow invalidation.
widget->Hide(); widget->Hide();
test_api.SimulateFrameSwap(gfx::Size(123, 456)); test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(2, [window invalidateShadowCountForTesting]); EXPECT_EQ(2, [window invalidateShadowCount]);
// Showing a translucent window after hiding it, should trigger shadow // Showing a translucent window after hiding it, should trigger shadow
// invalidation. // invalidation.
widget->Show(); widget->Show();
test_api.SimulateFrameSwap(gfx::Size(123, 456)); test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(3, [window invalidateShadowCountForTesting]); EXPECT_EQ(3, [window invalidateShadowCount]);
widget->CloseNow(); widget->CloseNow();
} }
// Test that the contentView opacity corresponds to the window type. // Test that the contentView opacity corresponds to the window type.
TEST_F(NativeWidgetMacTest, ContentOpacity) { TEST_F(NativeWidgetMacTest, ContentOpacity) {
NativeWidgetMacNSWindow* window; NativeWidgetMacTestWindow* window;
Widget::InitParams init_params = Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
...@@ -2338,6 +2376,33 @@ TEST_F(NativeWidgetMacTest, TouchBar) { ...@@ -2338,6 +2376,33 @@ TEST_F(NativeWidgetMacTest, TouchBar) {
} }
@end @end
@implementation NativeWidgetMacTestWindow
@synthesize invalidateShadowCount = invalidateShadowCount_;
@synthesize orderWindowCount = orderWindowCount_;
@synthesize deallocFlag = deallocFlag_;
- (void)dealloc {
if (deallocFlag_) {
DCHECK(!*deallocFlag_);
*deallocFlag_ = true;
}
[super dealloc];
}
- (void)invalidateShadow {
++invalidateShadowCount_;
[super invalidateShadow];
}
- (void)orderWindow:(NSWindowOrderingMode)orderingMode
relativeTo:(NSInteger)otherWindowNumber {
++orderWindowCount_;
[super orderWindow:orderingMode relativeTo:otherWindowNumber];
}
@end
@implementation MockBridgedView @implementation MockBridgedView
@synthesize drawRectCount = drawRectCount_; @synthesize drawRectCount = drawRectCount_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment