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

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

Issue 1531213002: Mac: Implement firstRectForCharacterRange:actualRange in BridgedContentView. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed reduntant statement. Created 5 years 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
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 8
9 #import "base/mac/foundation_util.h" 9 #import "base/mac/foundation_util.h"
10 #import "base/mac/mac_util.h" 10 #import "base/mac/mac_util.h"
(...skipping 25 matching lines...) Expand all
36 EXPECT_EQ(a.location, b.location); \ 36 EXPECT_EQ(a.location, b.location); \
37 EXPECT_EQ(a.length, b.length); 37 EXPECT_EQ(a.length, b.length);
38 38
39 namespace { 39 namespace {
40 40
41 // Empty range shortcut for readibility. 41 // Empty range shortcut for readibility.
42 NSRange EmptyRange() { 42 NSRange EmptyRange() {
43 return NSMakeRange(NSNotFound, 0); 43 return NSMakeRange(NSNotFound, 0);
44 } 44 }
45 45
46 // Changes NSRect to gfx::Rect and converts it from Apple's coordinate system
47 // (origin at bottom left) to coordinate system with origin at top left.
48 gfx::Rect ConvertCoordinateSystem(NSRect rect) {
tapted 2015/12/17 08:42:20 gfx::ScreenRectFromNSRect
karandeepb 2015/12/18 09:15:06 Done.
49 NSRect screen_rect = [[NSScreen mainScreen] frame];
50 rect.origin.y = screen_rect.size.height - NSMaxY(rect);
51 return gfx::Rect(NSRectToCGRect(rect));
52 }
53
46 } // namespace 54 } // namespace
47 55
48 // Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates 56 // Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates
49 // NSWindow's behavior when attempting to toggle fullscreen state again, when 57 // NSWindow's behavior when attempting to toggle fullscreen state again, when
50 // the last attempt failed but Cocoa has not yet sent 58 // the last attempt failed but Cocoa has not yet sent
51 // windowDidFailToEnterFullScreen:. 59 // windowDidFailToEnterFullScreen:.
52 @interface BridgedNativeWidgetTestFullScreenWindow : NativeWidgetMacNSWindow { 60 @interface BridgedNativeWidgetTestFullScreenWindow : NativeWidgetMacNSWindow {
53 @private 61 @private
54 int ignoredToggleFullScreenCount_; 62 int ignoredToggleFullScreenCount_;
55 } 63 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // before the tests covering the Init() flow are ready to do that. 129 // before the tests covering the Init() flow are ready to do that.
122 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS; 130 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;
123 131
124 // To control the lifetime without an actual window that must be closed, 132 // To control the lifetime without an actual window that must be closed,
125 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET. 133 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET.
126 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 134 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
127 135
128 // Opacity defaults to "infer" which is usually updated by ViewsDelegate. 136 // Opacity defaults to "infer" which is usually updated by ViewsDelegate.
129 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW; 137 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW;
130 138
139 init_params_.bounds = gfx::Rect(100, 100, 100, 100);
140
131 native_widget_mac_->GetWidget()->Init(init_params_); 141 native_widget_mac_->GetWidget()->Init(init_params_);
132 } 142 }
133 143
134 protected: 144 protected:
135 scoped_ptr<Widget> widget_; 145 scoped_ptr<Widget> widget_;
136 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|. 146 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|.
137 147
138 // Make the InitParams available to tests to cover initialization codepaths. 148 // Make the InitParams available to tests to cover initialization codepaths.
139 Widget::InitParams init_params_; 149 Widget::InitParams init_params_;
140 }; 150 };
(...skipping 26 matching lines...) Expand all
167 177
168 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { 178 BridgedNativeWidgetTest::BridgedNativeWidgetTest() {
169 } 179 }
170 180
171 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() { 181 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
172 } 182 }
173 183
174 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) { 184 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
175 Textfield* textfield = new Textfield(); 185 Textfield* textfield = new Textfield();
176 textfield->SetText(ASCIIToUTF16(text)); 186 textfield->SetText(ASCIIToUTF16(text));
187 textfield->SetBoundsRect(init_params_.bounds);
177 view_->AddChildView(textfield); 188 view_->AddChildView(textfield);
178 189
179 // Request focus so the InputMethod can dispatch events to the RootView, and 190 // Request focus so the InputMethod can dispatch events to the RootView, and
180 // have them delivered to the textfield. Note that focusing a textfield 191 // have them delivered to the textfield. Note that focusing a textfield
181 // schedules a task to flash the cursor, so this requires |message_loop_|. 192 // schedules a task to flash the cursor, so this requires |message_loop_|.
182 textfield->RequestFocus(); 193 textfield->RequestFocus();
183 194
184 [ns_view_ setTextInputClient:textfield]; 195 [ns_view_ setTextInputClient:textfield];
185 } 196 }
186 197
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 EXPECT_EQ("a", GetText()); 509 EXPECT_EQ("a", GetText());
499 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); 510 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
500 511
501 // Should succeed after moving left first. 512 // Should succeed after moving left first.
502 [ns_view_ doCommandBySelector:@selector(moveLeft:)]; 513 [ns_view_ doCommandBySelector:@selector(moveLeft:)];
503 [ns_view_ doCommandBySelector:@selector(deleteForward:)]; 514 [ns_view_ doCommandBySelector:@selector(deleteForward:)];
504 EXPECT_EQ("", GetText()); 515 EXPECT_EQ("", GetText());
505 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); 516 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
506 } 517 }
507 518
519 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange) {
520 InstallTextField("");
521 ui::TextInputClient* textInputClient = [ns_view_ textInputClient];
tapted 2015/12/17 08:42:20 hacker_style (eg. `client` for brevity too)
karandeepb 2015/12/18 09:15:06 Done.
522 NSRange range;
523 NSRange actual_range = NSMakeRange(-1, -1);
524 NSRect rect;
525 gfx::Rect bounds;
526
527 // Empty composition.
528 rect = [ns_view_ firstRectForCharacterRange:NSMakeRange(0, 0)
529 actualRange:&actual_range];
530 bounds = textInputClient->GetCaretBounds();
531 bounds.set_width(0);
532 EXPECT_TRUE(ConvertCoordinateSystem(rect) == bounds);
533 EXPECT_TRUE(NSEqualRanges(NSMakeRange(0, 0), actual_range));
534
535 rect = [ns_view_ firstRectForCharacterRange:NSMakeRange(1, 1)
536 actualRange:&actual_range];
537 EXPECT_TRUE(ConvertCoordinateSystem(rect) == bounds);
538 EXPECT_TRUE(NSEqualRanges(NSMakeRange(1, 0), actual_range));
539
540 // Set composition with caret before second character('e').
541 ui::CompositionText composition;
542 composition.selection = gfx::Range(1);
543 composition.text = base::UTF8ToUTF16("test_str");
544 size_t count = composition.text.length();
545 textInputClient->SetCompositionText(composition);
546
547 range = NSMakeRange(1, 0);
548 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
549 bounds = textInputClient->GetCaretBounds();
550 bounds.set_width(0);
551 EXPECT_TRUE(ConvertCoordinateSystem(rect) == bounds);
552 EXPECT_TRUE(NSEqualRanges(range, actual_range));
553
554 range = NSMakeRange(2, 0);
555 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
556 EXPECT_FALSE(ConvertCoordinateSystem(rect) == bounds);
557 EXPECT_TRUE(NSEqualRanges(range, actual_range));
558
559 // Query outside composition range.
560 range = NSMakeRange(count + 1, 0);
561 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
562 EXPECT_TRUE(ConvertCoordinateSystem(rect) == bounds);
563 EXPECT_TRUE(NSEqualRanges(range, actual_range));
564
565 std::vector<gfx::Rect> char_bounds, caret_bounds;
tapted 2015/12/17 08:42:20 it's uncommon to declare multiple things on a line
karandeepb 2015/12/18 09:15:06 Done.
566 char_bounds.resize(count);
567 caret_bounds.resize(count + 1);
568
569 // Generate caret_bounds between different characters.
570 for (size_t i = 0; i <= count; i++) {
571 composition.selection = gfx::Range(i);
572 textInputClient->SetCompositionText(composition);
573 caret_bounds[i] = textInputClient->GetCaretBounds();
574 }
575
576 // Generate individual character bounds from caret positions.
577 for (size_t i = 0; i < count; i++) {
578 char_bounds[i].set_origin(caret_bounds[i].origin());
579 char_bounds[i].set_width(caret_bounds[i + 1].x() - caret_bounds[i].x());
580 char_bounds[i].set_height(
581 std::max(caret_bounds[i].height(), caret_bounds[i + 1].height()));
582 }
583
584 // Verify bounds for all valid ranges.
585 for (size_t i = 0; i < count; i++) {
586 for (size_t j = i + 1; j <= count; j++) {
587 range = NSMakeRange(i, j - i);
588 rect =
589 [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
590
591 bounds = gfx::Rect();
592 for (size_t k = i; k < j; k++)
593 bounds.Union(char_bounds[k]);
594
595 EXPECT_TRUE(ConvertCoordinateSystem(rect) == bounds);
596 EXPECT_TRUE(NSEqualRanges(range, actual_range));
597 }
598 }
599
600 // Check NSZeroRect is returned if bridged_content_view has no textInputClient
601 // available.
602 [ns_view_ setTextInputClient:nil];
603 rect = [ns_view_ firstRectForCharacterRange:NSMakeRange(0, 0)
604 actualRange:&actual_range];
605 EXPECT_TRUE(NSEqualRects(rect, NSZeroRect));
606 }
607
508 typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest; 608 typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;
509 609
510 // Simulate the notifications that AppKit would send out if a fullscreen 610 // Simulate the notifications that AppKit would send out if a fullscreen
511 // operation begins, and then fails and must abort. This notification sequence 611 // operation begins, and then fails and must abort. This notification sequence
512 // was determined by posting delayed tasks to toggle fullscreen state and then 612 // was determined by posting delayed tasks to toggle fullscreen state and then
513 // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause 613 // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause
514 // the fullscreen transition to fail. 614 // the fullscreen transition to fail.
515 TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { 615 TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
516 if (base::mac::IsOSSnowLeopard()) 616 if (base::mac::IsOSSnowLeopard())
517 return; 617 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 [center postNotificationName:NSWindowDidExitFullScreenNotification 676 [center postNotificationName:NSWindowDidExitFullScreenNotification
577 object:window]; 677 object:window];
578 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. 678 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
579 EXPECT_FALSE(bridge()->target_fullscreen_state()); 679 EXPECT_FALSE(bridge()->target_fullscreen_state());
580 680
581 widget_->CloseNow(); 681 widget_->CloseNow();
582 } 682 }
583 683
584 } // namespace test 684 } // namespace test
585 } // namespace views 685 } // namespace views
OLDNEW
« ui/views/cocoa/bridged_content_view.mm ('K') | « ui/views/cocoa/bridged_content_view.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698