diff options
Diffstat (limited to 'ui/views/widget/native_widget_mac_unittest.mm')
-rw-r--r-- | ui/views/widget/native_widget_mac_unittest.mm | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 2f0104c..25183e6 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm @@ -6,6 +6,7 @@ #import <Cocoa/Cocoa.h> +#import "base/mac/foundation_util.h" #import "base/mac/scoped_nsobject.h" #import "base/mac/scoped_objc_class_swizzler.h" #include "base/run_loop.h" @@ -13,11 +14,15 @@ #include "base/strings/sys_string_conversions.h" #include "base/test/test_timeouts.h" #import "testing/gtest_mac.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkCanvas.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" +#import "ui/base/cocoa/window_size_constants.h" #import "ui/events/test/cocoa_test_event_utils.h" #include "ui/events/test/event_generator.h" #import "ui/gfx/mac/coordinate_conversion.h" #import "ui/views/cocoa/bridged_native_widget.h" +#import "ui/views/cocoa/native_widget_mac_nswindow.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" #include "ui/views/native_cursor.h" @@ -39,9 +44,67 @@ - (BOOL)_isTitleHidden; @end +// Test NSWindow that provides hooks via method overrides to verify behavior. +@interface NativeWidetMacTestWindow : NativeWidgetMacNSWindow { + @private + int invalidateShadowCount_; +} +@property(readonly, nonatomic) int invalidateShadowCount; +@end + namespace views { namespace test { +// BridgedNativeWidget friend to access private members. +class BridgedNativeWidgetTestApi { + public: + explicit BridgedNativeWidgetTestApi(NSWindow* window) { + bridge_ = NativeWidgetMac::GetBridgeForNativeWindow(window); + } + + // Simulate a frame swap from the compositor. Assumes scale factor of 1.0f. + void SimulateFrameSwap(const gfx::Size& size) { + const float kScaleFactor = 1.0f; + SkBitmap bitmap; + bitmap.allocN32Pixels(size.width(), size.height()); + SkCanvas canvas(bitmap); + bridge_->compositor_widget_->GotSoftwareFrame(kScaleFactor, &canvas); + std::vector<ui::LatencyInfo> latency_info; + bridge_->AcceleratedWidgetSwapCompleted(latency_info); + } + + private: + BridgedNativeWidget* bridge_; + + 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: + gfx::NativeWindow 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 [[[NativeWidetMacTestWindow 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 { @@ -63,6 +126,19 @@ class NativeWidgetMacTest : public WidgetTest { return native_parent_; } + // Create a Widget backed by the NativeWidetMacTestWindow NSWindow subclass. + Widget* CreateWidgetWithTestWindow(Widget::InitParams params, + NativeWidetMacTestWindow** window) { + Widget* widget = new Widget; + params.native_widget = new TestWindowNativeWidgetMac(widget); + widget->Init(params); + widget->Show(); + *window = base::mac::ObjCCastStrict<NativeWidetMacTestWindow>( + widget->GetNativeWindow()); + EXPECT_TRUE(*window); + return widget; + } + private: base::scoped_nsobject<NSWindow> native_parent_; @@ -796,6 +872,47 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) { widget->CloseNow(); } +// Test calls to invalidate the shadow when composited frames arrive. +TEST_F(NativeWidgetMacTest, InvalidateShadow) { + NativeWidetMacTestWindow* window; + const gfx::Rect rect(0, 0, 100, 200); + Widget::InitParams init_params = + CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); + init_params.bounds = rect; + Widget* widget = CreateWidgetWithTestWindow(init_params, &window); + + // Simulate the initial paint. + BridgedNativeWidgetTestApi(window).SimulateFrameSwap(rect.size()); + + // Default is an opaque window, so shadow doesn't need to be invalidated. + EXPECT_EQ(0, [window invalidateShadowCount]); + widget->CloseNow(); + + init_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; + widget = CreateWidgetWithTestWindow(init_params, &window); + BridgedNativeWidgetTestApi test_api(window); + + // First paint on a translucent window needs to invalidate the shadow. Once. + EXPECT_EQ(0, [window invalidateShadowCount]); + test_api.SimulateFrameSwap(rect.size()); + EXPECT_EQ(1, [window invalidateShadowCount]); + test_api.SimulateFrameSwap(rect.size()); + 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 invalidateShadowCount]); + + test_api.SimulateFrameSwap(gfx::Size(123, 456)); + EXPECT_EQ(2, [window invalidateShadowCount]); + test_api.SimulateFrameSwap(gfx::Size(123, 456)); + EXPECT_EQ(2, [window invalidateShadowCount]); + + widget->CloseNow(); +} + } // namespace test } // namespace views @@ -804,3 +921,14 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) { views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd); } @end + +@implementation NativeWidetMacTestWindow + +@synthesize invalidateShadowCount = invalidateShadowCount_; + +- (void)invalidateShadow { + ++invalidateShadowCount_; + [super invalidateShadow]; +} + +@end |