| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include <QuartzCore/QuartzCore.h> | 5 #include <QuartzCore/QuartzCore.h> |
| 6 | 6 |
| 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/scoped_cftyperef.h" | 11 #include "base/mac/scoped_cftyperef.h" |
| 12 #import "base/mac/scoped_nsautorelease_pool.h" | 12 #import "base/mac/scoped_nsautorelease_pool.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #import "base/memory/scoped_nsobject.h" | 14 #import "base/memory/scoped_nsobject.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/sys_info.h" | 16 #include "base/sys_info.h" |
| 17 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
| 18 #import "chrome/browser/accessibility/browser_accessibility_cocoa.h" | 18 #import "chrome/browser/accessibility/browser_accessibility_cocoa.h" |
| 19 #include "chrome/browser/accessibility/browser_accessibility_state.h" | 19 #include "chrome/browser/accessibility/browser_accessibility_state.h" |
| 20 #include "chrome/browser/browser_trial.h" | 20 #include "chrome/browser/browser_trial.h" |
| 21 #import "chrome/browser/renderer_host/text_input_client_mac.h" |
| 21 #include "chrome/browser/spellchecker_platform_engine.h" | 22 #include "chrome/browser/spellchecker_platform_engine.h" |
| 22 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" | 23 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" |
| 23 #import "chrome/browser/ui/cocoa/view_id_util.h" | 24 #import "chrome/browser/ui/cocoa/view_id_util.h" |
| 24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
| 25 #include "chrome/common/render_messages.h" | 26 #include "chrome/common/render_messages.h" |
| 26 #include "chrome/common/spellcheck_messages.h" | 27 #include "chrome/common/spellcheck_messages.h" |
| 27 #include "content/browser/browser_thread.h" | 28 #include "content/browser/browser_thread.h" |
| 28 #include "content/browser/gpu_process_host.h" | 29 #include "content/browser/gpu_process_host.h" |
| 29 #include "content/browser/gpu_process_host_ui_shim.h" | 30 #include "content/browser/gpu_process_host_ui_shim.h" |
| 30 #include "content/browser/plugin_process_host.h" | 31 #include "content/browser/plugin_process_host.h" |
| 31 #include "content/browser/renderer_host/backing_store_mac.h" | 32 #include "content/browser/renderer_host/backing_store_mac.h" |
| 32 #include "content/browser/renderer_host/render_process_host.h" | 33 #include "content/browser/renderer_host/render_process_host.h" |
| 33 #include "content/browser/renderer_host/render_view_host.h" | 34 #include "content/browser/renderer_host/render_view_host.h" |
| 34 #include "content/browser/renderer_host/render_widget_host.h" | 35 #include "content/browser/renderer_host/render_widget_host.h" |
| 35 #include "content/common/edit_command.h" | 36 #include "content/common/edit_command.h" |
| 36 #include "content/common/gpu/gpu_messages.h" | 37 #include "content/common/gpu/gpu_messages.h" |
| 37 #include "content/common/native_web_keyboard_event.h" | 38 #include "content/common/native_web_keyboard_event.h" |
| 38 #include "content/common/plugin_messages.h" | 39 #include "content/common/plugin_messages.h" |
| 39 #include "content/common/view_messages.h" | 40 #include "content/common/view_messages.h" |
| 40 #include "skia/ext/platform_canvas.h" | 41 #include "skia/ext/platform_canvas.h" |
| 41 #import "third_party/mozilla/ComplexTextInputPanel.h" | 42 #import "third_party/mozilla/ComplexTextInputPanel.h" |
| 42 #include "third_party/skia/include/core/SkColor.h" | 43 #include "third_party/skia/include/core/SkColor.h" |
| 43 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact
ory.h" | 44 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact
ory.h" |
| 44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 45 #include "ui/gfx/gl/gl_switches.h" | 46 #include "ui/gfx/gl/gl_switches.h" |
| 47 #include "ui/gfx/point.h" |
| 46 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 48 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| 47 #include "ui/gfx/surface/io_surface_support_mac.h" | 49 #include "ui/gfx/surface/io_surface_support_mac.h" |
| 48 #include "webkit/glue/webaccessibility.h" | 50 #include "webkit/glue/webaccessibility.h" |
| 49 #include "webkit/plugins/npapi/webplugin.h" | 51 #include "webkit/plugins/npapi/webplugin.h" |
| 50 | 52 |
| 51 using WebKit::WebInputEvent; | 53 using WebKit::WebInputEvent; |
| 52 using WebKit::WebInputEventFactory; | 54 using WebKit::WebInputEventFactory; |
| 53 using WebKit::WebMouseEvent; | 55 using WebKit::WebMouseEvent; |
| 54 using WebKit::WebMouseWheelEvent; | 56 using WebKit::WebMouseWheelEvent; |
| 55 | 57 |
| 56 static inline int ToWebKitModifiers(NSUInteger flags) { | 58 static inline int ToWebKitModifiers(NSUInteger flags) { |
| 57 int modifiers = 0; | 59 int modifiers = 0; |
| 58 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 60 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
| 59 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; | 61 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; |
| 60 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; | 62 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; |
| 61 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 63 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
| 62 return modifiers; | 64 return modifiers; |
| 63 } | 65 } |
| 64 | 66 |
| 65 @interface RenderWidgetHostViewCocoa (Private) | 67 // Private methods: |
| 68 @interface RenderWidgetHostViewCocoa () |
| 69 @property(nonatomic, assign) NSRange selectedRange; |
| 70 @property(nonatomic, assign) NSRange markedRange; |
| 71 |
| 66 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; | 72 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; |
| 67 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 73 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
| 68 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; | 74 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; |
| 69 - (void)cancelChildPopups; | 75 - (void)cancelChildPopups; |
| 70 - (void)checkForPluginImeCancellation; | 76 - (void)checkForPluginImeCancellation; |
| 71 @end | 77 @end |
| 72 | 78 |
| 73 // This API was published since 10.6. Provide the declaration so it can be | 79 // This API was published since 10.6. Provide the declaration so it can be |
| 74 // // called below when building with the 10.5 SDK. | 80 // // called below when building with the 10.5 SDK. |
| 75 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 | 81 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 |
| 76 @class NSTextInputContext; | 82 @class NSTextInputContext; |
| 77 @interface NSResponder (AppKitDetails) | 83 @interface NSResponder (AppKitDetails) |
| 78 - (NSTextInputContext *)inputContext; | 84 - (NSTextInputContext *)inputContext; |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 } | 853 } |
| 848 | 854 |
| 849 void RenderWidgetHostViewMac::ImeUpdateTextInputState( | 855 void RenderWidgetHostViewMac::ImeUpdateTextInputState( |
| 850 WebKit::WebTextInputType type, | 856 WebKit::WebTextInputType type, |
| 851 const gfx::Rect& caret_rect) { | 857 const gfx::Rect& caret_rect) { |
| 852 if (text_input_type_ != type) { | 858 if (text_input_type_ != type) { |
| 853 text_input_type_ = type; | 859 text_input_type_ = type; |
| 854 if (HasFocus()) | 860 if (HasFocus()) |
| 855 SetTextInputActive(true); | 861 SetTextInputActive(true); |
| 856 } | 862 } |
| 857 | |
| 858 // We need to convert the coordinate of the cursor rectangle sent from the | |
| 859 // renderer and save it. Our input method backend uses a coordinate system | |
| 860 // whose origin is the upper-left corner of this view. On the other hand, | |
| 861 // Cocoa uses a coordinate system whose origin is the lower-left corner of | |
| 862 // this view. So, we convert the cursor rectangle and save it. | |
| 863 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; | |
| 864 } | 863 } |
| 865 | 864 |
| 866 void RenderWidgetHostViewMac::ImeCancelComposition() { | 865 void RenderWidgetHostViewMac::ImeCancelComposition() { |
| 867 [cocoa_view_ cancelComposition]; | 866 [cocoa_view_ cancelComposition]; |
| 868 } | 867 } |
| 869 | 868 |
| 869 void RenderWidgetHostViewMac::ImeCompositionRangeChanged( |
| 870 const ui::Range& range) { |
| 871 // The RangeChanged message is only sent with valid values. The current |
| 872 // caret position (start == end) will be sent if there is no IME range. |
| 873 [cocoa_view_ setMarkedRange:range.ToNSRange()]; |
| 874 } |
| 875 |
| 870 void RenderWidgetHostViewMac::DidUpdateBackingStore( | 876 void RenderWidgetHostViewMac::DidUpdateBackingStore( |
| 871 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, | 877 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
| 872 const std::vector<gfx::Rect>& copy_rects) { | 878 const std::vector<gfx::Rect>& copy_rects) { |
| 873 if (!is_hidden_) { | 879 if (!is_hidden_) { |
| 874 std::vector<gfx::Rect> rects(copy_rects); | 880 std::vector<gfx::Rect> rects(copy_rects); |
| 875 | 881 |
| 876 // Because the findbar might be open, we cannot use scrollRect:by: here. For | 882 // Because the findbar might be open, we cannot use scrollRect:by: here. For |
| 877 // now, simply mark all of scroll rect as dirty. | 883 // now, simply mark all of scroll rect as dirty. |
| 878 if (!scroll_rect.IsEmpty()) | 884 if (!scroll_rect.IsEmpty()) |
| 879 rects.push_back(scroll_rect); | 885 rects.push_back(scroll_rect); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 | 982 |
| 977 NSString* tooltip_nsstring = base::SysWideToNSString(display_text); | 983 NSString* tooltip_nsstring = base::SysWideToNSString(display_text); |
| 978 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; | 984 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; |
| 979 } | 985 } |
| 980 } | 986 } |
| 981 | 987 |
| 982 // | 988 // |
| 983 // RenderWidgetHostViewCocoa uses the stored selection text, | 989 // RenderWidgetHostViewCocoa uses the stored selection text, |
| 984 // which implements NSServicesRequests protocol. | 990 // which implements NSServicesRequests protocol. |
| 985 // | 991 // |
| 986 void RenderWidgetHostViewMac::SelectionChanged(const std::string& text) { | 992 void RenderWidgetHostViewMac::SelectionChanged(const std::string& text, |
| 993 const ui::Range& range) { |
| 987 selected_text_ = text; | 994 selected_text_ = text; |
| 995 [cocoa_view_ setSelectedRange:range.ToNSRange()]; |
| 988 } | 996 } |
| 989 | 997 |
| 990 bool RenderWidgetHostViewMac::IsPopup() const { | 998 bool RenderWidgetHostViewMac::IsPopup() const { |
| 991 return popup_type_ != WebKit::WebPopupTypeNone; | 999 return popup_type_ != WebKit::WebPopupTypeNone; |
| 992 } | 1000 } |
| 993 | 1001 |
| 994 BackingStore* RenderWidgetHostViewMac::AllocBackingStore( | 1002 BackingStore* RenderWidgetHostViewMac::AllocBackingStore( |
| 995 const gfx::Size& size) { | 1003 const gfx::Size& size) { |
| 996 return new BackingStoreMac(render_widget_host_, size); | 1004 return new BackingStoreMac(render_widget_host_, size); |
| 997 } | 1005 } |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 } else { | 1387 } else { |
| 1380 if (text_input_type_ == WebKit::WebTextInputTypePassword) | 1388 if (text_input_type_ == WebKit::WebTextInputTypePassword) |
| 1381 DisablePasswordInput(); | 1389 DisablePasswordInput(); |
| 1382 } | 1390 } |
| 1383 } | 1391 } |
| 1384 | 1392 |
| 1385 // RenderWidgetHostViewCocoa --------------------------------------------------- | 1393 // RenderWidgetHostViewCocoa --------------------------------------------------- |
| 1386 | 1394 |
| 1387 @implementation RenderWidgetHostViewCocoa | 1395 @implementation RenderWidgetHostViewCocoa |
| 1388 | 1396 |
| 1389 @synthesize caretRect = caretRect_; | 1397 @synthesize selectedRange = selectedRange_; |
| 1398 @synthesize markedRange = markedRange_; |
| 1390 | 1399 |
| 1391 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1400 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| 1392 self = [super initWithFrame:NSZeroRect]; | 1401 self = [super initWithFrame:NSZeroRect]; |
| 1393 if (self) { | 1402 if (self) { |
| 1394 editCommand_helper_.reset(new RWHVMEditCommandHelper); | 1403 editCommand_helper_.reset(new RWHVMEditCommandHelper); |
| 1395 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1404 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
| 1396 | 1405 |
| 1397 renderWidgetHostView_.reset(r); | 1406 renderWidgetHostView_.reset(r); |
| 1398 canBeKeyView_ = YES; | 1407 canBeKeyView_ = YES; |
| 1399 focusedPluginIdentifier_ = -1; | 1408 focusedPluginIdentifier_ = -1; |
| (...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2504 NSUnderlineStyleAttributeName, | 2513 NSUnderlineStyleAttributeName, |
| 2505 NSUnderlineColorAttributeName, | 2514 NSUnderlineColorAttributeName, |
| 2506 NSMarkedClauseSegmentAttributeName, | 2515 NSMarkedClauseSegmentAttributeName, |
| 2507 NSTextInputReplacementRangeAttributeName, | 2516 NSTextInputReplacementRangeAttributeName, |
| 2508 nil]); | 2517 nil]); |
| 2509 } | 2518 } |
| 2510 return validAttributesForMarkedText_.get(); | 2519 return validAttributesForMarkedText_.get(); |
| 2511 } | 2520 } |
| 2512 | 2521 |
| 2513 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { | 2522 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { |
| 2514 NOTIMPLEMENTED(); | 2523 DCHECK([self window]); |
| 2515 return NSNotFound; | 2524 // |thePoint| is in screen coordinates, but needs to be converted to WebKit |
| 2525 // coordinates (upper left origin). Scroll offsets will be taken care of in |
| 2526 // the renderer. |
| 2527 thePoint = [[self window] convertScreenToBase:thePoint]; |
| 2528 thePoint = [self convertPoint:thePoint fromView:nil]; |
| 2529 thePoint.y = NSHeight([self frame]) - thePoint.y; |
| 2530 |
| 2531 NSUInteger point = |
| 2532 TextInputClientMac::GetInstance()->GetCharacterIndexAtPoint( |
| 2533 renderWidgetHostView_->render_widget_host_, |
| 2534 gfx::Point(thePoint.x, thePoint.y)); |
| 2535 return point; |
| 2516 } | 2536 } |
| 2517 | 2537 |
| 2518 - (NSRect)firstRectForCharacterRange:(NSRange)theRange { | 2538 - (NSRect)firstRectForCharacterRange:(NSRange)theRange { |
| 2519 // An input method requests a cursor rectangle to display its candidate | 2539 NSRect rect = TextInputClientMac::GetInstance()->GetFirstRectForRange( |
| 2520 // window. | 2540 renderWidgetHostView_->render_widget_host_, theRange); |
| 2521 // Calculate the screen coordinate of the cursor rectangle saved in | |
| 2522 // RenderWidgetHostViewMac::ImeUpdateTextInputState() and send it to the | |
| 2523 // input method. | |
| 2524 // Since this window may be moved since we receive the cursor rectangle last | |
| 2525 // time we sent the cursor rectangle to the input method, so we should map | |
| 2526 // from the view coordinate to the screen coordinate every time when an input | |
| 2527 // method need it. | |
| 2528 NSRect resultRect = [self convertRect:caretRect_ toView:nil]; | |
| 2529 NSWindow* window = [self window]; | |
| 2530 if (window) | |
| 2531 resultRect.origin = [window convertBaseToScreen:resultRect.origin]; | |
| 2532 | 2541 |
| 2533 return resultRect; | 2542 // The returned rectangle is in WebKit coordinates (upper left origin), so |
| 2534 } | 2543 // flip the coordinate system and then convert it into screen coordinates for |
| 2535 | 2544 // return. |
| 2536 - (NSRange)selectedRange { | 2545 NSRect viewFrame = [self frame]; |
| 2537 // Return the selected range saved in the setMarkedText method. | 2546 rect.origin.y = NSHeight(viewFrame) - rect.origin.y; |
| 2538 return hasMarkedText_ ? selectedRange_ : NSMakeRange(NSNotFound, 0); | 2547 rect.origin.y -= rect.size.height; |
| 2548 rect = [self convertRectToBase:rect]; |
| 2549 rect.origin = [[self window] convertBaseToScreen:rect.origin]; |
| 2550 return rect; |
| 2539 } | 2551 } |
| 2540 | 2552 |
| 2541 - (NSRange)markedRange { | 2553 - (NSRange)markedRange { |
| 2542 // An input method calls this method to check if an application really has | 2554 // An input method calls this method to check if an application really has |
| 2543 // a text being composed when hasMarkedText call returns true. | 2555 // a text being composed when hasMarkedText call returns true. |
| 2544 // Returns the range saved in the setMarkedText method so the input method | 2556 // Returns the range saved in the setMarkedText method so the input method |
| 2545 // calls the setMarkedText method and we can update the composition node | 2557 // calls the setMarkedText method and we can update the composition node |
| 2546 // there. (When this method returns an empty range, the input method doesn't | 2558 // there. (When this method returns an empty range, the input method doesn't |
| 2547 // call the setMarkedText method.) | 2559 // call the setMarkedText method.) |
| 2548 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); | 2560 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); |
| 2549 } | 2561 } |
| 2550 | 2562 |
| 2551 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)range { | 2563 - (NSAttributedString*)attributedSubstringFromRange:(NSRange)range { |
| 2552 // TODO(hbono): Even though many input method works without implementing | 2564 NSAttributedString* str = |
| 2553 // this method, we need to save a copy of the string in the setMarkedText | 2565 TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( |
| 2554 // method and create a NSAttributedString with the given range. | 2566 renderWidgetHostView_->render_widget_host_, range); |
| 2555 // http://crbug.com/37715 | 2567 return str; |
| 2556 return nil; | |
| 2557 } | 2568 } |
| 2558 | 2569 |
| 2559 - (NSInteger)conversationIdentifier { | 2570 - (NSInteger)conversationIdentifier { |
| 2560 return reinterpret_cast<NSInteger>(self); | 2571 return reinterpret_cast<NSInteger>(self); |
| 2561 } | 2572 } |
| 2562 | 2573 |
| 2563 // Each RenderWidgetHostViewCocoa has its own input context, but we return | 2574 // Each RenderWidgetHostViewCocoa has its own input context, but we return |
| 2564 // nil when the caret is in non-editable content or password box to avoid | 2575 // nil when the caret is in non-editable content or password box to avoid |
| 2565 // making input methods do their work. | 2576 // making input methods do their work. |
| 2566 - (NSTextInputContext *)inputContext { | 2577 - (NSTextInputContext *)inputContext { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 } | 2616 } |
| 2606 | 2617 |
| 2607 - (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange { | 2618 - (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange { |
| 2608 // An input method updates the composition string. | 2619 // An input method updates the composition string. |
| 2609 // We send the given text and range to the renderer so it can update the | 2620 // We send the given text and range to the renderer so it can update the |
| 2610 // composition node of WebKit. | 2621 // composition node of WebKit. |
| 2611 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; | 2622 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; |
| 2612 NSString* im_text = isAttributedString ? [string string] : string; | 2623 NSString* im_text = isAttributedString ? [string string] : string; |
| 2613 int length = [im_text length]; | 2624 int length = [im_text length]; |
| 2614 | 2625 |
| 2615 markedRange_ = NSMakeRange(0, length); | 2626 // |markedRange_| will get set on a callback from ImeSetComposition(). |
| 2616 selectedRange_ = newSelRange; | 2627 selectedRange_ = newSelRange; |
| 2617 markedText_ = base::SysNSStringToUTF16(im_text); | 2628 markedText_ = base::SysNSStringToUTF16(im_text); |
| 2618 hasMarkedText_ = (length > 0); | 2629 hasMarkedText_ = (length > 0); |
| 2619 | 2630 |
| 2620 underlines_.clear(); | 2631 underlines_.clear(); |
| 2621 if (isAttributedString) { | 2632 if (isAttributedString) { |
| 2622 ExtractUnderlines(string, &underlines_); | 2633 ExtractUnderlines(string, &underlines_); |
| 2623 } else { | 2634 } else { |
| 2624 // Use a thin black underline by default. | 2635 // Use a thin black underline by default. |
| 2625 underlines_.push_back( | 2636 underlines_.push_back( |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2897 if (!string) return NO; | 2908 if (!string) return NO; |
| 2898 | 2909 |
| 2899 // If the user is currently using an IME, confirm the IME input, | 2910 // If the user is currently using an IME, confirm the IME input, |
| 2900 // and then insert the text from the service, the same as TextEdit and Safari. | 2911 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2901 [self confirmComposition]; | 2912 [self confirmComposition]; |
| 2902 [self insertText:string]; | 2913 [self insertText:string]; |
| 2903 return YES; | 2914 return YES; |
| 2904 } | 2915 } |
| 2905 | 2916 |
| 2906 @end | 2917 @end |
| OLD | NEW |