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 @@
#include "ui/display/display_observer.h"
#import "ui/views/cocoa/bridged_native_widget_owner.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"
#include "ui/views/views_export.h"
#include "ui/views/widget/widget.h"
@class BridgedContentView;
@class ModalShowAnimationWithLayer;
@class NativeWidgetMacNSWindow;
@class ViewsNSWindowDelegate;
namespace views {
......@@ -88,14 +88,10 @@ class VIEWS_EXPORT BridgedNativeWidget
BridgedNativeWidget(BridgedNativeWidgetHost* host, NativeWidgetMac* parent);
~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.
// 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
// boundary, it will not be possible to call SetWindow. Move the relevant
// sub-classes so that they can be allocated via CreateWindow.
// boundary, it will not be possible to explicitly set an NSWindow in this
// way.
void SetWindow(base::scoped_nsobject<NativeWidgetMacNSWindow> window);
// Initialize the bridge (after the NSWindow has been created).
void Init(const Widget::InitParams& params);
......@@ -192,7 +188,7 @@ class VIEWS_EXPORT BridgedNativeWidget
NativeWidgetMac* native_widget_mac() { return native_widget_mac_; }
BridgedContentView* ns_view() { return bridged_view_; }
NativeWidgetMacNSWindow* ns_window() { return window_; }
NSWindow* ns_window();
TooltipManager* tooltip_manager() { return tooltip_manager_.get(); }
......
......@@ -18,7 +18,6 @@
#include "components/viz/common/surfaces/local_surface_id.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/window_size_constants.h"
#include "ui/base/hit_test.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h"
......@@ -245,17 +244,6 @@ BridgedNativeWidget::~BridgedNativeWidget() {
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(
base::scoped_nsobject<NativeWidgetMacNSWindow> window) {
DCHECK(!window_);
......@@ -950,6 +938,10 @@ bool BridgedNativeWidget::ShouldRunCustomAnimationFor(
switches::kDisableModalAnimations);
}
NSWindow* BridgedNativeWidget::ns_window() {
return window_.get();
}
////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidget, ui::CATransactionObserver
......
......@@ -248,6 +248,45 @@ NSTextInputContext* g_fake_current_input_context = nullptr;
@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 test {
......@@ -263,7 +302,13 @@ class MockNativeWidgetMac : public NativeWidgetMac {
void InitNativeWidget(const Widget::InitParams& params) override {
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);
// Usually the bridge gets initialized here. It is skipped to run extra
......@@ -1542,10 +1587,10 @@ typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;
// mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause
// the fullscreen transition to fail.
TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
NativeWidgetMacNSWindow* window =
base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>(
BridgedNativeWidgetTestWindow* window =
base::mac::ObjCCastStrict<BridgedNativeWidgetTestWindow>(
widget_->GetNativeWindow());
[window disableToggleFullScreenForTesting];
[window setIgnoreToggleFullScreen:YES];
widget_->Show();
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
......@@ -1559,11 +1604,11 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
// 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
// back into fullscreen but get ignored by Cocoa.
EXPECT_EQ(0, [window toggleFullScreenCountForTesting]);
EXPECT_EQ(0, [window ignoredToggleFullScreenCount]);
EXPECT_TRUE(bridge()->target_fullscreen_state());
[center postNotificationName:NSWindowDidExitFullScreenNotification
object:window];
EXPECT_EQ(1, [window toggleFullScreenCountForTesting]);
EXPECT_EQ(1, [window ignoredToggleFullScreenCount]);
EXPECT_FALSE(bridge()->target_fullscreen_state());
// Cocoa follows up with a failure message sent to the NSWindowDelegate (there
......@@ -1592,7 +1637,7 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
EXPECT_FALSE(bridge()->target_fullscreen_state());
[center postNotificationName:NSWindowDidExitFullScreenNotification
object:window];
EXPECT_EQ(1, [window toggleFullScreenCountForTesting]); // No change.
EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
EXPECT_FALSE(bridge()->target_fullscreen_state());
widget_->CloseNow();
......
......@@ -47,16 +47,6 @@ VIEWS_EXPORT
// create one.
- (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
#endif // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_
......@@ -7,6 +7,7 @@
#include "base/mac/foundation_util.h"
#import "base/mac/sdk_forward_declarations.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/views_nswindow_delegate.h"
#import "ui/views/cocoa/window_touch_bar_delegate.h"
......@@ -82,24 +83,14 @@
base::scoped_nsobject<CommandDispatcher> commandDispatcher_;
base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_;
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
styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation {
if ((self = [super initWithContentRect:contentRect
DCHECK(NSEqualRects(contentRect, ui::kWindowSizeDeterminedLater));
if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:windowStyle
backing:bufferingType
defer:deferCreation])) {
......@@ -109,13 +100,8 @@
}
// This override doesn't do anything, but keeping it helps diagnose lifetime
// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow,
// and adds hooks for tests.
// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow.
- (void)dealloc {
if (deallocFlagForTesting_) {
DCHECK(!*deallocFlagForTesting_);
*deallocFlagForTesting_ = true;
}
[super dealloc];
}
......@@ -140,10 +126,6 @@
touchBarDelegate_ = delegate;
}
- (void)disableToggleFullScreenForTesting {
toggleFullscreenDisabledForTesting_ = YES;
}
// Private methods.
- (ViewsNSWindowDelegate*)viewsNSWindowDelegate {
......@@ -245,36 +227,10 @@
// when ordering in a window for the first time.
- (void)orderWindow:(NSWindowOrderingMode)orderingMode
relativeTo:(NSInteger)otherWindowNumber {
++orderWindowCountForTesting_;
[super orderWindow:orderingMode relativeTo:otherWindowNumber];
[[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.
- (BOOL)performKeyEquivalent:(NSEvent*)event {
......
......@@ -147,6 +147,10 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
protected:
// Creates the NSWindow that will be passed to the BridgedNativeWidget.
// 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(
const Widget::InitParams& params);
......
......@@ -28,6 +28,7 @@
#import "ui/views/cocoa/bridged_native_widget_host_impl.h"
#include "ui/views/cocoa/cocoa_mouse_capture.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"
#include "ui/views/widget/drop_helper.h"
#include "ui/views/widget/widget_delegate.h"
......
......@@ -56,6 +56,18 @@
- (BOOL)_isTitleHidden;
@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
// intercepted.
@interface MockBridgedView : NSView {
......@@ -109,6 +121,33 @@ class 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
// need access to Cocoa APIs.
class NativeWidgetMacTest : public WidgetTest {
......@@ -135,14 +174,14 @@ class NativeWidgetMacTest : public WidgetTest {
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,
NativeWidgetMacNSWindow** window) {
NativeWidgetMacTestWindow** window) {
Widget* widget = new Widget;
params.native_widget = new NativeWidgetMac(widget);
params.native_widget = new TestWindowNativeWidgetMac(widget);
widget->Init(params);
widget->Show();
*window = base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>(
*window = base::mac::ObjCCastStrict<NativeWidgetMacTestWindow>(
widget->GetNativeWindow());
EXPECT_TRUE(*window);
return widget;
......@@ -430,8 +469,8 @@ TEST_F(NativeWidgetMacTest, DISABLED_OrderFrontAfterMiniaturize) {
// Test that ShowInactive() on already-visible child widgets is ignored, since
// it may cause a space transition. See https://crbug.com/866760.
TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) {
NativeWidgetMacNSWindow* parent_window;
NativeWidgetMacNSWindow* child_window;
NativeWidgetMacTestWindow* parent_window;
NativeWidgetMacTestWindow* child_window;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
......@@ -439,29 +478,28 @@ TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) {
Widget* parent = CreateWidgetWithTestWindow(init_params, &parent_window);
// CreateWidgetWithTestWindow calls Show()
EXPECT_EQ(1, [parent_window orderWindowCountForTesting]);
EXPECT_EQ(1, [parent_window orderWindowCount]);
init_params.parent = parent->GetNativeView();
Widget* child = CreateWidgetWithTestWindow(init_params, &child_window);
// The child is ordered twice, once by Show() and again (by AppKit) when it is
// registered as a child window.
EXPECT_EQ(2, [child_window orderWindowCountForTesting]);
EXPECT_EQ(2, [child_window orderWindowCount]);
// 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
// order without taking focus, so it should invoke -[NSWindow orderWindow:..].
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
// already be in a correct stacking order and we must avoid a Space switch.
child->ShowInactive();
EXPECT_EQ(2, [child_window orderWindowCountForTesting]); // No change.
EXPECT_EQ(
2, [parent_window orderWindowCountForTesting]); // Parent also unchanged.
EXPECT_EQ(2, [child_window orderWindowCount]); // No change.
EXPECT_EQ(2, [parent_window orderWindowCount]); // Parent also unchanged.
parent->CloseNow();
}
......@@ -838,13 +876,13 @@ TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
TestNativeParentWindow* native_parent = MakeNativeParent();
[native_parent setDeallocFlag:&native_parent_dealloced];
NativeWidgetMacNSWindow* window;
NativeWidgetMacTestWindow* window;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_POPUP);
init_params.parent = [native_parent_ contentView];
init_params.bounds = gfx::Rect(0, 0, 100, 200);
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
......@@ -1757,7 +1795,7 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) {
// Test calls to invalidate the shadow when composited frames arrive.
TEST_F(NativeWidgetMacTest, InvalidateShadow) {
NativeWidgetMacNSWindow* window;
NativeWidgetMacTestWindow* window;
const gfx::Rect rect(0, 0, 100, 200);
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
......@@ -1768,7 +1806,7 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) {
BridgedNativeWidgetTestApi(window).SimulateFrameSwap(rect.size());
// 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();
init_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
......@@ -1776,40 +1814,40 @@ TEST_F(NativeWidgetMacTest, InvalidateShadow) {
BridgedNativeWidgetTestApi test_api(window);
// 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());
EXPECT_EQ(1, [window invalidateShadowCountForTesting]);
EXPECT_EQ(1, [window invalidateShadowCount]);
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.
[window setContentSize:NSMakeSize(123, 456)];
// A "late" frame swap at the old size should do nothing.
test_api.SimulateFrameSwap(rect.size());
EXPECT_EQ(1, [window invalidateShadowCountForTesting]);
EXPECT_EQ(1, [window invalidateShadowCount]);
test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(2, [window invalidateShadowCountForTesting]);
EXPECT_EQ(2, [window invalidateShadowCount]);
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.
widget->Hide();
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
// invalidation.
widget->Show();
test_api.SimulateFrameSwap(gfx::Size(123, 456));
EXPECT_EQ(3, [window invalidateShadowCountForTesting]);
EXPECT_EQ(3, [window invalidateShadowCount]);
widget->CloseNow();
}
// Test that the contentView opacity corresponds to the window type.
TEST_F(NativeWidgetMacTest, ContentOpacity) {
NativeWidgetMacNSWindow* window;
NativeWidgetMacTestWindow* window;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
......@@ -2338,6 +2376,33 @@ TEST_F(NativeWidgetMacTest, TouchBar) {
}
@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
@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