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
3 // found in the LICENSE file.
5 #include "ui/views/widget/native_widget_mac.h"
7 #import <Cocoa/Cocoa.h>
9 #import "base/mac/scoped_nsobject.h"
10 #import "ui/base/test/windowed_nsnotification_observer.h"
11 #include "ui/views/test/test_widget_observer.h"
12 #include "ui/views/test/widget_test.h"
17 // Tests for NativeWidgetMac that rely on global window manager state, and can
18 // not be parallelized.
19 class NativeWidgetMacInteractiveUITest
21 public ::testing::WithParamInterface<bool> {
25 NativeWidgetMacInteractiveUITest()
26 : activationCount_(0), deactivationCount_(0) {}
28 Widget* MakeWidget() {
29 return GetParam() ? CreateTopLevelFramelessPlatformWidget()
30 : CreateTopLevelPlatformWidget();
34 scoped_ptr<Observer> observer_;
36 int deactivationCount_;
39 DISALLOW_COPY_AND_ASSIGN(NativeWidgetMacInteractiveUITest);
42 class NativeWidgetMacInteractiveUITest::Observer : public TestWidgetObserver {
44 Observer(NativeWidgetMacInteractiveUITest* parent, Widget* widget)
45 : TestWidgetObserver(widget), parent_(parent) {}
47 void OnWidgetActivationChanged(Widget* widget, bool active) override {
49 parent_->activationCount_++;
51 parent_->deactivationCount_++;
55 NativeWidgetMacInteractiveUITest* parent_;
57 DISALLOW_COPY_AND_ASSIGN(Observer);
60 // Test that showing a window causes it to attain global keyWindow status.
61 TEST_P(NativeWidgetMacInteractiveUITest, ShowAttainsKeyStatus) {
62 Widget* widget = MakeWidget();
63 observer_.reset(new Observer(this, widget));
65 EXPECT_FALSE(widget->IsActive());
66 EXPECT_EQ(0, activationCount_);
68 EXPECT_TRUE(widget->IsActive());
70 EXPECT_TRUE([widget->GetNativeWindow() isKeyWindow]);
71 EXPECT_EQ(1, activationCount_);
72 EXPECT_EQ(0, deactivationCount_);
74 // Now check that losing and gaining key status due events outside of Widget
76 Widget* widget2 = MakeWidget(); // Note: not observed.
77 EXPECT_EQ(0, deactivationCount_);
79 EXPECT_EQ(1, deactivationCount_);
82 EXPECT_FALSE(widget->IsActive());
83 EXPECT_EQ(1, deactivationCount_);
84 EXPECT_EQ(1, activationCount_);
86 [widget->GetNativeWindow() makeKeyAndOrderFront:nil];
88 EXPECT_TRUE(widget->IsActive());
89 EXPECT_EQ(1, deactivationCount_);
90 EXPECT_EQ(2, activationCount_);
95 EXPECT_EQ(1, deactivationCount_);
96 EXPECT_EQ(2, activationCount_);
99 // Test that ShowInactive does not take keyWindow status.
100 TEST_P(NativeWidgetMacInteractiveUITest, ShowInactiveIgnoresKeyStatus) {
101 Widget* widget = MakeWidget();
103 base::scoped_nsobject<WindowedNSNotificationObserver> waiter(
104 [[WindowedNSNotificationObserver alloc]
105 initForNotification:NSWindowDidBecomeKeyNotification
106 object:widget->GetNativeWindow()]);
108 EXPECT_FALSE(widget->IsVisible());
109 EXPECT_FALSE([widget->GetNativeWindow() isVisible]);
110 EXPECT_FALSE(widget->IsActive());
111 EXPECT_FALSE([widget->GetNativeWindow() isKeyWindow]);
112 widget->ShowInactive();
114 EXPECT_TRUE(widget->IsVisible());
115 EXPECT_TRUE([widget->GetNativeWindow() isVisible]);
116 EXPECT_FALSE(widget->IsActive());
117 EXPECT_FALSE([widget->GetNativeWindow() isKeyWindow]);
119 // If the window were to become active, this would activate it.
120 RunPendingMessages();
121 EXPECT_FALSE(widget->IsActive());
122 EXPECT_FALSE([widget->GetNativeWindow() isKeyWindow]);
123 EXPECT_EQ(0, [waiter notificationCount]);
125 // Activating the inactive widget should make it key, asynchronously.
128 EXPECT_EQ(1, [waiter notificationCount]);
129 EXPECT_TRUE(widget->IsActive());
130 EXPECT_TRUE([widget->GetNativeWindow() isKeyWindow]);
135 INSTANTIATE_TEST_CASE_P(NativeWidgetMacInteractiveUITestInstance,
136 NativeWidgetMacInteractiveUITest,