Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: ui/views/cocoa/bridged_native_widget_unittest.mm

Issue 1718043003: MacViews: Clip contents for non-rectangular windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add tests. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.mm ('k') | ui/views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/cocoa/bridged_native_widget.h" 5 #import "ui/views/cocoa/bridged_native_widget.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #import <Quartz/Quartz.h>
8 9
9 #import "base/mac/foundation_util.h" 10 #import "base/mac/foundation_util.h"
10 #import "base/mac/mac_util.h" 11 #import "base/mac/mac_util.h"
11 #import "base/mac/sdk_forward_declarations.h" 12 #import "base/mac/sdk_forward_declarations.h"
12 #include "base/macros.h" 13 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
15 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
16 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
17 #import "testing/gtest_mac.h" 18 #import "testing/gtest_mac.h"
19 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+CGPath.h"
18 #import "ui/base/cocoa/window_size_constants.h" 20 #import "ui/base/cocoa/window_size_constants.h"
19 #include "ui/base/ime/input_method.h" 21 #include "ui/base/ime/input_method.h"
20 #import "ui/gfx/test/ui_cocoa_test_helper.h" 22 #import "ui/gfx/test/ui_cocoa_test_helper.h"
21 #import "ui/gfx/mac/coordinate_conversion.h" 23 #import "ui/gfx/mac/coordinate_conversion.h"
24 #include "ui/views/bubble/bubble_delegate.h"
22 #import "ui/views/cocoa/bridged_content_view.h" 25 #import "ui/views/cocoa/bridged_content_view.h"
23 #import "ui/views/cocoa/native_widget_mac_nswindow.h" 26 #import "ui/views/cocoa/native_widget_mac_nswindow.h"
24 #import "ui/views/cocoa/views_nswindow_delegate.h" 27 #import "ui/views/cocoa/views_nswindow_delegate.h"
25 #include "ui/views/controls/textfield/textfield.h" 28 #include "ui/views/controls/textfield/textfield.h"
26 #include "ui/views/view.h" 29 #include "ui/views/view.h"
27 #include "ui/views/widget/native_widget_mac.h" 30 #include "ui/views/widget/native_widget_mac.h"
28 #include "ui/views/widget/root_view.h" 31 #include "ui/views/widget/root_view.h"
29 #include "ui/views/widget/widget.h" 32 #include "ui/views/widget/widget.h"
30 #include "ui/views/widget/widget_observer.h" 33 #include "ui/views/widget/widget_observer.h"
31 34
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 public: 157 public:
155 BridgedNativeWidgetTestBase() 158 BridgedNativeWidgetTestBase()
156 : widget_(new Widget), 159 : widget_(new Widget),
157 native_widget_mac_(new MockNativeWidgetMac(widget_.get())) { 160 native_widget_mac_(new MockNativeWidgetMac(widget_.get())) {
158 } 161 }
159 162
160 scoped_ptr<BridgedNativeWidget>& bridge() { 163 scoped_ptr<BridgedNativeWidget>& bridge() {
161 return native_widget_mac_->bridge(); 164 return native_widget_mac_->bridge();
162 } 165 }
163 166
164 // Overridden from testing::Test: 167 // Can be overriden in derived classes to provide additional |init_params_|.
165 void SetUp() override { 168 virtual void InitParams() {
166 ui::CocoaTest::SetUp();
167
168 init_params_.native_widget = native_widget_mac_; 169 init_params_.native_widget = native_widget_mac_;
169 170
170 // Use a frameless window, otherwise Widget will try to center the window 171 // Use a frameless window, otherwise Widget will try to center the window
171 // before the tests covering the Init() flow are ready to do that. 172 // before the tests covering the Init() flow are ready to do that.
172 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS; 173 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;
173 174
174 // To control the lifetime without an actual window that must be closed, 175 // To control the lifetime without an actual window that must be closed,
175 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET. 176 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET.
176 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 177 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
177 178
178 // Opacity defaults to "infer" which is usually updated by ViewsDelegate. 179 // Opacity defaults to "infer" which is usually updated by ViewsDelegate.
179 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW; 180 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW;
180 181
181 init_params_.bounds = gfx::Rect(100, 100, 100, 100); 182 init_params_.bounds = gfx::Rect(100, 100, 100, 100);
183 }
182 184
185 // Overridden from testing::Test:
186 void SetUp() override {
187 ui::CocoaTest::SetUp();
188 InitParams();
183 native_widget_mac_->GetWidget()->Init(init_params_); 189 native_widget_mac_->GetWidget()->Init(init_params_);
184 } 190 }
185 191
186 protected: 192 protected:
187 scoped_ptr<Widget> widget_; 193 scoped_ptr<Widget> widget_;
188 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|. 194 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|.
189 195
190 // Make the InitParams available to tests to cover initialization codepaths. 196 // Make the InitParams available to tests to cover initialization codepaths.
191 Widget::InitParams init_params_; 197 Widget::InitParams init_params_;
192 }; 198 };
193 199
194 class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase { 200 class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase {
195 public: 201 public:
196 BridgedNativeWidgetTest(); 202 BridgedNativeWidgetTest();
197 ~BridgedNativeWidgetTest() override; 203 ~BridgedNativeWidgetTest() override;
198 204
199 // Install a textfield with input type |text_input_type| in the view hierarchy 205 // Install a textfield with input type |text_input_type| in the view hierarchy
200 // and make it the text input client. 206 // and make it the text input client.
201 void InstallTextField(const std::string& text, 207 void InstallTextField(const std::string& text,
202 ui::TextInputType text_input_type); 208 ui::TextInputType text_input_type);
203 209
204 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view 210 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view
205 // hierarchy and make it the text input client. 211 // hierarchy and make it the text input client.
206 void InstallTextField(const std::string& text); 212 void InstallTextField(const std::string& text);
207 213
208 // Returns the current text as std::string. 214 // Returns the current text as std::string.
209 std::string GetText(); 215 std::string GetText();
210 216
217 // Returns the mask layer associated with bridge().
218 CAShapeLayer* GetMaskLayer();
219
211 // testing::Test: 220 // testing::Test:
212 void SetUp() override; 221 void SetUp() override;
213 void TearDown() override; 222 void TearDown() override;
214 223
215 protected: 224 protected:
216 scoped_ptr<views::View> view_; 225 scoped_ptr<views::View> view_;
217 scoped_ptr<BridgedNativeWidget> bridge_; 226 scoped_ptr<BridgedNativeWidget> bridge_;
218 BridgedContentView* ns_view_; // Weak. Owned by bridge_. 227 BridgedContentView* ns_view_; // Weak. Owned by bridge_.
219 base::MessageLoopForUI message_loop_; 228 base::MessageLoopForUI message_loop_;
220 229
(...skipping 29 matching lines...) Expand all
250 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); 259 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT);
251 } 260 }
252 261
253 std::string BridgedNativeWidgetTest::GetText() { 262 std::string BridgedNativeWidgetTest::GetText() {
254 NSRange range = NSMakeRange(0, NSUIntegerMax); 263 NSRange range = NSMakeRange(0, NSUIntegerMax);
255 NSAttributedString* text = 264 NSAttributedString* text =
256 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL]; 265 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL];
257 return SysNSStringToUTF8([text string]); 266 return SysNSStringToUTF8([text string]);
258 } 267 }
259 268
269 CAShapeLayer* BridgedNativeWidgetTest::GetMaskLayer() {
270 return base::mac::ObjCCastStrict<CAShapeLayer>(
271 [[bridge()->compositor_superview_ layer] mask]);
272 }
273
260 void BridgedNativeWidgetTest::SetUp() { 274 void BridgedNativeWidgetTest::SetUp() {
261 BridgedNativeWidgetTestBase::SetUp(); 275 BridgedNativeWidgetTestBase::SetUp();
262 276
263 view_.reset(new views::internal::RootView(widget_.get())); 277 view_.reset(new views::internal::RootView(widget_.get()));
264 base::scoped_nsobject<NSWindow> window([test_window() retain]); 278 base::scoped_nsobject<NSWindow> window([test_window() retain]);
265 279
266 // BridgedNativeWidget expects to be initialized with a hidden (deferred) 280 // BridgedNativeWidget expects to be initialized with a hidden (deferred)
267 // window. 281 // window.
268 [window orderOut:nil]; 282 [window orderOut:nil];
269 EXPECT_FALSE([window delegate]); 283 EXPECT_FALSE([window delegate]);
270 bridge()->Init(window, init_params_); 284 bridge()->Init(window, init_params_);
271 285
272 // The delegate should exist before setting the root view. 286 // The delegate should exist before setting the root view.
273 EXPECT_TRUE([window delegate]); 287 EXPECT_TRUE([window delegate]);
274 bridge()->SetRootView(view_.get()); 288 bridge()->SetRootView(view_.get());
275 ns_view_ = bridge()->ns_view(); 289 ns_view_ = bridge()->ns_view();
276 290
291 bridge()->AddCompositorSuperview();
292
277 // Pretend it has been shown via NativeWidgetMac::Show(). 293 // Pretend it has been shown via NativeWidgetMac::Show().
278 [window orderFront:nil]; 294 [window orderFront:nil];
279 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()]; 295 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()];
280 } 296 }
281 297
282 void BridgedNativeWidgetTest::TearDown() { 298 void BridgedNativeWidgetTest::TearDown() {
283 view_.reset(); 299 view_.reset();
284 BridgedNativeWidgetTestBase::TearDown(); 300 BridgedNativeWidgetTestBase::TearDown();
285 } 301 }
286 302
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 [window_delegate windowDidFailToExitFullScreen:window]; 760 [window_delegate windowDidFailToExitFullScreen:window];
745 EXPECT_FALSE(bridge()->target_fullscreen_state()); 761 EXPECT_FALSE(bridge()->target_fullscreen_state());
746 [center postNotificationName:NSWindowDidExitFullScreenNotification 762 [center postNotificationName:NSWindowDidExitFullScreenNotification
747 object:window]; 763 object:window];
748 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. 764 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
749 EXPECT_FALSE(bridge()->target_fullscreen_state()); 765 EXPECT_FALSE(bridge()->target_fullscreen_state());
750 766
751 widget_->CloseNow(); 767 widget_->CloseNow();
752 } 768 }
753 769
770 TEST_F(BridgedNativeWidgetTest, NoMaskLayer) {
771 // BridgedNativeWidgetTest creates a frameless window which does not have a
772 // non-client view. Hence it shouldn't have a mask layer.
773 EXPECT_FALSE(GetMaskLayer());
774 }
775
776 // This class provides a bubble delegate to the widget, which has a non-empty
777 // window mask.
778 class BridgedNativeWidgetMaskTest : public BridgedNativeWidgetTest {
779 public:
780 void InitParams() override {
781 BridgedNativeWidgetTest::InitParams();
782 init_params_.type = Widget::InitParams::TYPE_BUBBLE;
783 init_params_.delegate = new BubbleDelegateView();
784 }
785 };
786
787 TEST_F(BridgedNativeWidgetMaskTest, MaskLayer) {
788 CAShapeLayer* mask_layer = GetMaskLayer();
789 EXPECT_TRUE(mask_layer);
790 EXPECT_TRUE([mask_layer path]);
791 EXPECT_TRUE(
792 CGPathEqualToPath([[ns_view_ windowMask] gtm_CGPath], [mask_layer path]));
793
794 CGPathRef prev_path = [mask_layer path];
795
796 // Resize the window and ensure the mask path changes accordingly.
797 const int kTestNewWidth = 400;
798 const int kTestNewHeight = 300;
799 NSRect new_frame = NSMakeRect(0, 0, kTestNewWidth, kTestNewHeight);
800 EXPECT_NSNE(new_frame, [test_window() frame]);
801 [test_window() setFrame:new_frame display:NO];
802 mask_layer = GetMaskLayer();
803
804 EXPECT_FALSE(CGPathEqualToPath(prev_path, [mask_layer path]));
805 EXPECT_TRUE([mask_layer path]);
806 EXPECT_TRUE(
807 CGPathEqualToPath([[ns_view_ windowMask] gtm_CGPath], [mask_layer path]));
808 }
809
754 } // namespace test 810 } // namespace test
755 } // namespace views 811 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.mm ('k') | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698