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/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
12 #include "base/mac/scoped_cftyperef.h" | 12 #include "base/mac/scoped_cftyperef.h" |
13 #import "base/mac/scoped_nsautorelease_pool.h" | 13 #import "base/mac/scoped_nsautorelease_pool.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #import "base/memory/scoped_nsobject.h" | 15 #import "base/memory/scoped_nsobject.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/sys_info.h" | 17 #include "base/sys_info.h" |
18 #include "base/sys_string_conversions.h" | 18 #include "base/sys_string_conversions.h" |
19 #include "chrome/browser/browser_trial.h" | 19 #include "chrome/browser/browser_trial.h" |
20 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" | 20 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" |
21 #import "chrome/browser/renderer_host/text_input_client_mac.h" | 21 #import "chrome/browser/renderer_host/text_input_client_mac.h" |
22 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h" | 22 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h" |
23 #include "chrome/browser/ui/browser.h" | |
24 #include "chrome/browser/ui/browser_list.h" | |
23 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" | 25 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" |
24 #import "chrome/browser/ui/cocoa/view_id_util.h" | 26 #import "chrome/browser/ui/cocoa/view_id_util.h" |
25 #include "chrome/common/render_messages.h" | 27 #include "chrome/common/render_messages.h" |
26 #include "chrome/common/spellcheck_messages.h" | 28 #include "chrome/common/spellcheck_messages.h" |
27 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 29 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
28 #include "content/browser/browser_thread.h" | 30 #include "content/browser/browser_thread.h" |
29 #include "content/browser/gpu/gpu_process_host.h" | 31 #include "content/browser/gpu/gpu_process_host.h" |
30 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 32 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
31 #include "content/browser/plugin_process_host.h" | 33 #include "content/browser/plugin_process_host.h" |
32 #include "content/browser/renderer_host/backing_store_mac.h" | 34 #include "content/browser/renderer_host/backing_store_mac.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
49 #include "ui/gfx/surface/io_surface_support_mac.h" | 51 #include "ui/gfx/surface/io_surface_support_mac.h" |
50 #include "webkit/glue/webaccessibility.h" | 52 #include "webkit/glue/webaccessibility.h" |
51 #include "webkit/plugins/npapi/webplugin.h" | 53 #include "webkit/plugins/npapi/webplugin.h" |
52 | 54 |
53 using WebKit::WebInputEvent; | 55 using WebKit::WebInputEvent; |
54 using WebKit::WebInputEventFactory; | 56 using WebKit::WebInputEventFactory; |
55 using WebKit::WebMouseEvent; | 57 using WebKit::WebMouseEvent; |
56 using WebKit::WebMouseWheelEvent; | 58 using WebKit::WebMouseWheelEvent; |
57 using WebKit::WebGestureEvent; | 59 using WebKit::WebGestureEvent; |
58 | 60 |
61 // Forward-declare symbols that are part of the 10.7 SDK. | |
62 #if !defined(MAC_OS_X_VERSION_10_7) || \ | |
63 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | |
64 | |
65 enum { | |
66 NSEventPhaseNone = 0, // event not associated with a phase. | |
67 NSEventPhaseBegan = 0x1 << 0, | |
68 NSEventPhaseStationary = 0x1 << 1, | |
69 NSEventPhaseChanged = 0x1 << 2, | |
70 NSEventPhaseEnded = 0x1 << 3, | |
71 NSEventPhaseCancelled = 0x1 << 4, | |
72 }; | |
73 typedef NSUInteger NSEventPhase; | |
74 | |
75 enum { | |
76 NSEventSwipeTrackingLockDirection = 0x1 << 0, | |
77 NSEventSwipeTrackingClampGestureAmount = 0x1 << 1 | |
78 }; | |
79 typedef NSUInteger NSEventSwipeTrackingOptions; | |
80 | |
81 | |
82 @interface NSEvent(LionAPI) | |
Robert Sesek
2011/08/15 14:46:27
nit: space before (
Nico
2011/08/15 16:39:46
Done.
| |
83 // This is in the appkit 10.7 release notes, but not in | |
Mark Mentovai
2011/08/15 14:43:57
If this comment were true, this declaration should
Nico
2011/08/15 16:39:46
You're right. It's not documented at http://develo
| |
84 // the public nsevent headers? | |
85 + (BOOL)isSwipeTrackingFromScrollEventsEnabled; | |
86 | |
87 - (NSEventPhase)phase; | |
88 - (CGFloat)scrollingDeltaX; | |
89 - (CGFloat)scrollingDeltaY; | |
90 - (void)trackSwipeEventWithOptions:(NSEventSwipeTrackingOptions)options | |
91 dampenAmountThresholdMin:(CGFloat)minDampenThreshold | |
92 max:(CGFloat)maxDampenThreshold | |
93 usingHandler:(void (^)(CGFloat gestureAmount, | |
Mark Mentovai
2011/08/15 14:43:57
You must #include "chrome/browser/mac/closure_bloc
Nico
2011/08/15 16:39:46
Good news: I was aware of that and thought I had d
| |
94 NSEventPhase phase, | |
95 BOOL isComplete, | |
96 BOOL *stop))trackingHandler; | |
97 @end | |
98 | |
99 #endif // 10.7 | |
100 | |
59 static inline int ToWebKitModifiers(NSUInteger flags) { | 101 static inline int ToWebKitModifiers(NSUInteger flags) { |
60 int modifiers = 0; | 102 int modifiers = 0; |
61 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 103 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
62 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; | 104 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; |
63 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; | 105 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; |
64 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 106 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
65 return modifiers; | 107 return modifiers; |
66 } | 108 } |
67 | 109 |
68 // Private methods: | 110 // Private methods: |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 | 1053 |
1012 void RenderWidgetHostViewMac::ForceTextureReload() { | 1054 void RenderWidgetHostViewMac::ForceTextureReload() { |
1013 plugin_container_manager_.ForceTextureReload(); | 1055 plugin_container_manager_.ForceTextureReload(); |
1014 } | 1056 } |
1015 | 1057 |
1016 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color, | 1058 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color, |
1017 bool animate) { | 1059 bool animate) { |
1018 // This is not used on mac. | 1060 // This is not used on mac. |
1019 } | 1061 } |
1020 | 1062 |
1063 void RenderWidgetHostViewMac::UnhandledWheelEvent( | |
1064 const WebKit::WebMouseWheelEvent& event) { | |
1065 [cocoa_view_ setGotUnhandledWheelEvent:YES]; | |
1066 } | |
1067 | |
1068 void RenderWidgetHostViewMac::SetHasHorizontalScrollbar( | |
1069 bool has_horizontal_scrollbar) { | |
1070 [cocoa_view_ setHasHorizontalScrollbar:has_horizontal_scrollbar]; | |
1071 } | |
1072 | |
1073 void RenderWidgetHostViewMac::SetScrollOffsetPinning( | |
1074 bool is_pinned_to_left, bool is_pinned_to_right) { | |
1075 [cocoa_view_ setPinnedLeft:is_pinned_to_left]; | |
1076 [cocoa_view_ setPinnedRight:is_pinned_to_right]; | |
1077 } | |
1078 | |
1021 void RenderWidgetHostViewMac::ShutdownHost() { | 1079 void RenderWidgetHostViewMac::ShutdownHost() { |
1022 shutdown_factory_.RevokeAll(); | 1080 shutdown_factory_.RevokeAll(); |
1023 render_widget_host_->Shutdown(); | 1081 render_widget_host_->Shutdown(); |
1024 // Do not touch any members at this point, |this| has been deleted. | 1082 // Do not touch any members at this point, |this| has been deleted. |
1025 } | 1083 } |
1026 | 1084 |
1027 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { | 1085 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { |
1028 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); | 1086 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); |
1029 } | 1087 } |
1030 | 1088 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1094 DisablePasswordInput(); | 1152 DisablePasswordInput(); |
1095 } | 1153 } |
1096 } | 1154 } |
1097 | 1155 |
1098 // RenderWidgetHostViewCocoa --------------------------------------------------- | 1156 // RenderWidgetHostViewCocoa --------------------------------------------------- |
1099 | 1157 |
1100 @implementation RenderWidgetHostViewCocoa | 1158 @implementation RenderWidgetHostViewCocoa |
1101 | 1159 |
1102 @synthesize selectedRange = selectedRange_; | 1160 @synthesize selectedRange = selectedRange_; |
1103 @synthesize markedRange = markedRange_; | 1161 @synthesize markedRange = markedRange_; |
1162 @synthesize gotUnhandledWheelEvent = gotUnhandledWheelEvent_; | |
1163 @synthesize isPinnedLeft = isPinnedLeft_; | |
1164 @synthesize isPinnedRight = isPinnedRight_; | |
1165 @synthesize hasHorizontalScrollbar = hasHorizontalScrollbar_; | |
1104 | 1166 |
1105 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1167 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
1106 self = [super initWithFrame:NSZeroRect]; | 1168 self = [super initWithFrame:NSZeroRect]; |
1107 if (self) { | 1169 if (self) { |
1108 editCommand_helper_.reset(new RWHVMEditCommandHelper); | 1170 editCommand_helper_.reset(new RWHVMEditCommandHelper); |
1109 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1171 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
1110 | 1172 |
1111 renderWidgetHostView_.reset(r); | 1173 renderWidgetHostView_.reset(r); |
1112 canBeKeyView_ = YES; | 1174 canBeKeyView_ = YES; |
1113 focusedPluginIdentifier_ = -1; | 1175 focusedPluginIdentifier_ = -1; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1227 - (void)beginGestureWithEvent:(NSEvent*)event { | 1289 - (void)beginGestureWithEvent:(NSEvent*)event { |
1228 if (base::mac::IsOSLionOrLater() && | 1290 if (base::mac::IsOSLionOrLater() && |
1229 [event subtype] == kIOHIDEventTypeScroll && | 1291 [event subtype] == kIOHIDEventTypeScroll && |
1230 renderWidgetHostView_->render_widget_host_) { | 1292 renderWidgetHostView_->render_widget_host_) { |
1231 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); | 1293 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); |
1232 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); | 1294 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); |
1233 } | 1295 } |
1234 | 1296 |
1235 // Forward the gesture event to the next responder so that the browser window | 1297 // Forward the gesture event to the next responder so that the browser window |
1236 // controller has a chance to act on back/forward gestures. | 1298 // controller has a chance to act on back/forward gestures. |
1237 [[self nextResponder] beginGestureWithEvent:event]; | 1299 [[self nextResponder] beginGestureWithEvent:event]; |
Alexei Svitkine (slow)
2011/08/15 15:58:42
Since the browser controller now won't implement -
Nico
2011/08/15 16:39:46
Done.
| |
1238 } | 1300 } |
1239 | 1301 |
1240 - (void)endGestureWithEvent:(NSEvent*)event { | 1302 - (void)endGestureWithEvent:(NSEvent*)event { |
1241 if (base::mac::IsOSLionOrLater() && | 1303 if (base::mac::IsOSLionOrLater() && |
1242 [event subtype] == kIOHIDEventTypeScroll && | 1304 [event subtype] == kIOHIDEventTypeScroll && |
1243 renderWidgetHostView_->render_widget_host_) { | 1305 renderWidgetHostView_->render_widget_host_) { |
1244 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); | 1306 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); |
1245 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); | 1307 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); |
1246 } | 1308 } |
1247 | 1309 |
1248 // Forward the gesture event to the next responder so that the browser window | 1310 // Forward the gesture event to the next responder so that the browser window |
1249 // controller has a chance to act on back/forward gestures. | 1311 // controller has a chance to act on back/forward gestures. |
1250 [[self nextResponder] endGestureWithEvent:event]; | 1312 [[self nextResponder] endGestureWithEvent:event]; |
Alexei Svitkine (slow)
2011/08/15 15:58:42
Ditto.
Nico
2011/08/15 16:39:46
Done.
| |
1251 } | 1313 } |
1252 | 1314 |
1253 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { | 1315 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { |
1254 // |performKeyEquivalent:| is sent to all views of a window, not only down the | 1316 // |performKeyEquivalent:| is sent to all views of a window, not only down the |
1255 // responder chain (cf. "Handling Key Equivalents" in | 1317 // responder chain (cf. "Handling Key Equivalents" in |
1256 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html | 1318 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html |
1257 // ). We only want to handle key equivalents if we're first responder. | 1319 // ). We only want to handle key equivalents if we're first responder. |
1258 if ([[self window] firstResponder] != self) | 1320 if ([[self window] firstResponder] != self) |
1259 return NO; | 1321 return NO; |
1260 | 1322 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1490 event.skip_in_browser = true; | 1552 event.skip_in_browser = true; |
1491 widgetHost->ForwardKeyboardEvent(event); | 1553 widgetHost->ForwardKeyboardEvent(event); |
1492 } | 1554 } |
1493 } | 1555 } |
1494 | 1556 |
1495 // Possibly autohide the cursor. | 1557 // Possibly autohide the cursor. |
1496 if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) | 1558 if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) |
1497 [NSCursor setHiddenUntilMouseMoves:YES]; | 1559 [NSCursor setHiddenUntilMouseMoves:YES]; |
1498 } | 1560 } |
1499 | 1561 |
1500 - (void)scrollWheel:(NSEvent *)theEvent { | 1562 - (void)scrollWheel:(NSEvent*)theEvent { |
1501 [self cancelChildPopups]; | 1563 [self cancelChildPopups]; |
1502 | 1564 |
1565 bool canUseLionApis = [theEvent respondsToSelector:@selector(phase)]; | |
Mark Mentovai
2011/08/15 14:43:57
Stick with a BOOL for this one because that’s the
Nico
2011/08/15 16:39:46
Done.
| |
1566 | |
1567 // Scroll events always go to the web first, and can only trigger history | |
1568 // swiping if they come back unhandled. | |
1569 if (canUseLionApis && [theEvent phase] == NSEventPhaseBegan) { | |
Mark Mentovai
2011/08/15 14:43:57
Is there any reason you don’t wrap this block and
| |
1570 totalScrollDelta_ = NSZeroSize; | |
1571 gotUnhandledWheelEvent_ = false; | |
Mark Mentovai
2011/08/15 14:43:57
This property is a BOOL, so use NO.
| |
1572 } | |
1573 | |
1574 if (canUseLionApis && // Must be the first condition! | |
Mark Mentovai
2011/08/15 14:43:57
(continued from line 1569)
…it’d eliminate this t
Robert Sesek
2011/08/15 14:46:27
Is there any reason to not put this and the previo
Nico
2011/08/15 16:39:46
The reason was indentation. I moved the history tr
| |
1575 gotUnhandledWheelEvent_ && | |
1576 [NSEvent isSwipeTrackingFromScrollEventsEnabled] && | |
Robert Sesek
2011/08/15 14:46:27
Doing this the proper way means that you can use t
| |
1577 [theEvent phase] == NSEventPhaseChanged) { | |
1578 totalScrollDelta_.width += [theEvent scrollingDeltaX]; | |
1579 totalScrollDelta_.height += [theEvent scrollingDeltaY]; | |
1580 | |
1581 bool isHorizontalGesture = | |
Robert Sesek
2011/08/15 14:46:27
über/optional-nit: Cocoa BOOLs?
| |
1582 fabs(totalScrollDelta_.width) > fabs(totalScrollDelta_.height); | |
Mark Mentovai
2011/08/15 14:43:57
#include <cmath> and use std::abs instead of fabs.
Robert Sesek
2011/08/15 14:46:27
std::abs
Nico
2011/08/15 16:39:46
Done.
| |
1583 | |
1584 bool isRightScroll = [theEvent scrollingDeltaX] < 0; | |
1585 bool goForward = isRightScroll; | |
1586 | |
1587 if (isHorizontalGesture && | |
1588 // If "forward" is inactive and the user rubber-bands to the right, | |
1589 // "isPinnedLeft" will be false. When the user then rubber-bands to | |
1590 // the left in the same gesture, that should trigger history | |
1591 // immediately if there's no scrollbar, hence the check for | |
1592 // hasHorizontalScrollbar_. | |
1593 // One would think we have to check canGoBack / canGoForward here, but | |
1594 // that's actually done in the renderer | |
1595 // (ChromeClientImpl::shouldRubberBand()), when it decides if it should | |
1596 // rubberband or send back an event unhandled. | |
1597 (((isPinnedLeft_ || !hasHorizontalScrollbar_) && !isRightScroll) || | |
Mark Mentovai
2011/08/15 14:43:57
I think you can simplify this entire thing by pull
Nico
2011/08/15 16:39:46
Done.
| |
1598 ((isPinnedRight_ || !hasHorizontalScrollbar_) && isRightScroll))) { | |
1599 // The way this api works: gestureAmount is between -1 and 1 (float). If | |
1600 // the user does the gesture for more than about 25% (i.e. < -0.25 or > | |
1601 // 0.25) and then lets go, it is accepted, we get a NSEventPhaseEnded, | |
1602 // and after that the block is called with amounts animating towards 1 | |
1603 // (or -1, depending on the direction). If the user lets go below that | |
1604 // threshold, we get NSEventPhaseCancelled, and the amount animates | |
1605 // toward 0. | |
1606 [theEvent trackSwipeEventWithOptions:0 | |
1607 dampenAmountThresholdMin:-1 | |
Mark Mentovai
2011/08/15 14:43:57
Nit: align colons.
Mark Mentovai
2011/08/15 14:43:57
Do you know how AppKit uses these values? I suppos
Nico
2011/08/15 16:39:46
Done.
Nico
2011/08/15 16:39:46
I don't really understand what these values do. I
| |
1608 max:1 | |
1609 usingHandler:^(CGFloat gestureAmount, | |
1610 NSEventPhase phase, | |
1611 BOOL isComplete, | |
Robert Sesek
2011/08/15 14:46:27
Why do you not reference isComplete in this? Are y
Nico
2011/08/15 16:39:46
Yes. The way this works is that as soon as the use
| |
1612 BOOL *stop) { | |
1613 // |gestureAmount| obeys -[NSEvent isDirectionInvertedFromDevice] | |
1614 // automatically. | |
1615 // TODO(thakis): UI. | |
1616 Browser* browser = BrowserList::GetLastActive(); | |
1617 if (phase == NSEventPhaseEnded && browser) { | |
1618 if (goForward) | |
1619 browser->GoForward(CURRENT_TAB); | |
1620 else | |
1621 browser->GoBack(CURRENT_TAB); | |
1622 } | |
1623 }]; | |
1624 return; | |
1625 } | |
1626 } | |
1627 | |
1503 const WebMouseWheelEvent& event = | 1628 const WebMouseWheelEvent& event = |
1504 WebInputEventFactory::mouseWheelEvent(theEvent, self); | 1629 WebInputEventFactory::mouseWheelEvent(theEvent, self); |
1505 if (renderWidgetHostView_->render_widget_host_) | 1630 if (renderWidgetHostView_->render_widget_host_) |
1506 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); | 1631 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); |
1507 } | 1632 } |
1508 | 1633 |
1509 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation | 1634 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation |
1510 // events. On the Mac we must kill popups on outside events, thus this lovely | 1635 // events. On the Mac we must kill popups on outside events, thus this lovely |
1511 // case of filicide caused by events on parent views. | 1636 // case of filicide caused by events on parent views. |
1512 - (void)cancelChildPopups { | 1637 - (void)cancelChildPopups { |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2761 if (!string) return NO; | 2886 if (!string) return NO; |
2762 | 2887 |
2763 // If the user is currently using an IME, confirm the IME input, | 2888 // If the user is currently using an IME, confirm the IME input, |
2764 // and then insert the text from the service, the same as TextEdit and Safari. | 2889 // and then insert the text from the service, the same as TextEdit and Safari. |
2765 [self confirmComposition]; | 2890 [self confirmComposition]; |
2766 [self insertText:string]; | 2891 [self insertText:string]; |
2767 return YES; | 2892 return YES; |
2768 } | 2893 } |
2769 | 2894 |
2770 @end | 2895 @end |
OLD | NEW |