OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "app/app_switches.h" | 9 #include "app/app_switches.h" |
10 #include "app/surface/io_surface_support_mac.h" | 10 #include "app/surface/io_surface_support_mac.h" |
11 #import "base/chrome_application_mac.h" | 11 #import "base/chrome_application_mac.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #import "base/scoped_nsautorelease_pool.h" | 15 #import "base/scoped_nsautorelease_pool.h" |
16 #import "base/scoped_nsobject.h" | 16 #import "base/scoped_nsobject.h" |
17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/sys_info.h" |
18 #include "base/sys_string_conversions.h" | 19 #include "base/sys_string_conversions.h" |
19 #include "chrome/browser/browser_thread.h" | 20 #include "chrome/browser/browser_thread.h" |
20 #include "chrome/browser/browser_trial.h" | 21 #include "chrome/browser/browser_trial.h" |
21 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" | 22 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" |
22 #import "chrome/browser/cocoa/view_id_util.h" | 23 #import "chrome/browser/cocoa/view_id_util.h" |
23 #include "chrome/browser/plugin_process_host.h" | 24 #include "chrome/browser/plugin_process_host.h" |
24 #include "chrome/browser/renderer_host/backing_store_mac.h" | 25 #include "chrome/browser/renderer_host/backing_store_mac.h" |
25 #include "chrome/browser/renderer_host/render_process_host.h" | 26 #include "chrome/browser/renderer_host/render_process_host.h" |
26 #include "chrome/browser/renderer_host/render_view_host.h" | 27 #include "chrome/browser/renderer_host/render_view_host.h" |
27 #include "chrome/browser/renderer_host/render_widget_host.h" | 28 #include "chrome/browser/renderer_host/render_widget_host.h" |
28 #include "chrome/browser/spellchecker_platform_engine.h" | 29 #include "chrome/browser/spellchecker_platform_engine.h" |
29 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
30 #include "chrome/common/native_web_keyboard_event.h" | 31 #include "chrome/common/native_web_keyboard_event.h" |
31 #include "chrome/common/edit_command.h" | 32 #include "chrome/common/edit_command.h" |
32 #include "chrome/common/plugin_messages.h" | 33 #include "chrome/common/plugin_messages.h" |
33 #include "chrome/common/render_messages.h" | 34 #include "chrome/common/render_messages.h" |
34 #include "skia/ext/platform_canvas.h" | 35 #include "skia/ext/platform_canvas.h" |
35 #include "third_party/skia/include/core/SkColor.h" | 36 #include "third_party/skia/include/core/SkColor.h" |
36 #include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h" | 37 #include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h" |
37 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | 38 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
38 #include "webkit/glue/plugins/webplugin.h" | 39 #include "webkit/glue/plugins/webplugin.h" |
39 #include "webkit/glue/webaccessibility.h" | 40 #include "webkit/glue/webaccessibility.h" |
40 #include "webkit/glue/webmenurunner_mac.h" | 41 #include "webkit/glue/webmenurunner_mac.h" |
| 42 #import "third_party/mozilla/ComplexTextInputPanel.h" |
41 | 43 |
42 using WebKit::WebInputEvent; | 44 using WebKit::WebInputEvent; |
43 using WebKit::WebInputEventFactory; | 45 using WebKit::WebInputEventFactory; |
44 using WebKit::WebMouseEvent; | 46 using WebKit::WebMouseEvent; |
45 using WebKit::WebMouseWheelEvent; | 47 using WebKit::WebMouseWheelEvent; |
46 | 48 |
47 static inline int ToWebKitModifiers(NSUInteger flags) { | 49 static inline int ToWebKitModifiers(NSUInteger flags) { |
48 int modifiers = 0; | 50 int modifiers = 0; |
49 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 51 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
50 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; | 52 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; |
51 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; | 53 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; |
52 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 54 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
53 return modifiers; | 55 return modifiers; |
54 } | 56 } |
55 | 57 |
56 @interface RenderWidgetHostViewCocoa (Private) | 58 @interface RenderWidgetHostViewCocoa (Private) |
57 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; | 59 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; |
58 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 60 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
59 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; | 61 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; |
60 - (void)cancelChildPopups; | 62 - (void)cancelChildPopups; |
61 - (void)attachPluginLayer; | |
62 @end | 63 @end |
63 | 64 |
64 // This API was published since 10.6. Provide the declaration so it can be | 65 // This API was published since 10.6. Provide the declaration so it can be |
65 // // called below when building with the 10.5 SDK. | 66 // // called below when building with the 10.5 SDK. |
66 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 | 67 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 |
67 @class NSTextInputContext; | 68 @class NSTextInputContext; |
68 @interface NSResponder (AppKitDetails) | 69 @interface NSResponder (AppKitDetails) |
69 - (NSTextInputContext *)inputContext; | 70 - (NSTextInputContext *)inputContext; |
70 @end | 71 @end |
71 #endif | 72 #endif |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 | 884 |
884 void RenderWidgetHostViewMac::KillSelf() { | 885 void RenderWidgetHostViewMac::KillSelf() { |
885 if (shutdown_factory_.empty()) { | 886 if (shutdown_factory_.empty()) { |
886 [cocoa_view_ setHidden:YES]; | 887 [cocoa_view_ setHidden:YES]; |
887 MessageLoop::current()->PostTask(FROM_HERE, | 888 MessageLoop::current()->PostTask(FROM_HERE, |
888 shutdown_factory_.NewRunnableMethod( | 889 shutdown_factory_.NewRunnableMethod( |
889 &RenderWidgetHostViewMac::ShutdownHost)); | 890 &RenderWidgetHostViewMac::ShutdownHost)); |
890 } | 891 } |
891 } | 892 } |
892 | 893 |
| 894 void RenderWidgetHostViewMac::SetPluginImeEnabled(bool enabled, int plugin_id) { |
| 895 [cocoa_view_ setPluginImeEnabled:(enabled ? YES : NO) forPlugin:plugin_id]; |
| 896 } |
| 897 |
| 898 bool RenderWidgetHostViewMac::PostProcessEventForPluginIme( |
| 899 const NativeWebKeyboardEvent& event) { |
| 900 // Check WebInputEvent type since multiple types of events can be sent into |
| 901 // WebKit for the same OS event (e.g., RawKeyDown and Char), so filtering is |
| 902 // necessary to avoid double processing. |
| 903 // Also check the native type, since NSFlagsChanged is considered a key event |
| 904 // for WebKit purposes, but isn't considered a key event by the OS. |
| 905 if (event.type == WebInputEvent::RawKeyDown && |
| 906 [event.os_event type] == NSKeyDown) |
| 907 return [cocoa_view_ postProcessEventForPluginIme:event.os_event]; |
| 908 return false; |
| 909 } |
| 910 |
| 911 void RenderWidgetHostViewMac::PluginImeCompositionConfirmed( |
| 912 const string16& text, int plugin_id) { |
| 913 if (render_widget_host_) { |
| 914 render_widget_host_->Send(new ViewMsg_PluginImeCompositionConfirmed( |
| 915 render_widget_host_->routing_id(), text, plugin_id)); |
| 916 } |
| 917 } |
| 918 |
893 gfx::PluginWindowHandle | 919 gfx::PluginWindowHandle |
894 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, | 920 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, |
895 bool root) { | 921 bool root) { |
896 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 922 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
897 // Create an NSView to host the plugin's/compositor's pixels. | 923 // Create an NSView to host the plugin's/compositor's pixels. |
898 gfx::PluginWindowHandle handle = | 924 gfx::PluginWindowHandle handle = |
899 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | 925 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); |
900 | 926 |
901 scoped_nsobject<AcceleratedPluginView> plugin_view( | 927 scoped_nsobject<AcceleratedPluginView> plugin_view( |
902 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this | 928 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1213 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
1188 self = [super initWithFrame:NSZeroRect]; | 1214 self = [super initWithFrame:NSZeroRect]; |
1189 if (self) { | 1215 if (self) { |
1190 editCommand_helper_.reset(new RWHVMEditCommandHelper); | 1216 editCommand_helper_.reset(new RWHVMEditCommandHelper); |
1191 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1217 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
1192 | 1218 |
1193 renderWidgetHostView_.reset(r); | 1219 renderWidgetHostView_.reset(r); |
1194 canBeKeyView_ = YES; | 1220 canBeKeyView_ = YES; |
1195 takesFocusOnlyOnMouseDown_ = NO; | 1221 takesFocusOnlyOnMouseDown_ = NO; |
1196 closeOnDeactivate_ = NO; | 1222 closeOnDeactivate_ = NO; |
| 1223 pluginImeIdentifier_ = -1; |
1197 } | 1224 } |
1198 return self; | 1225 return self; |
1199 } | 1226 } |
1200 | 1227 |
1201 - (void)setCanBeKeyView:(BOOL)can { | 1228 - (void)setCanBeKeyView:(BOOL)can { |
1202 canBeKeyView_ = can; | 1229 canBeKeyView_ = can; |
1203 } | 1230 } |
1204 | 1231 |
1205 - (void)setTakesFocusOnlyOnMouseDown:(BOOL)b { | 1232 - (void)setTakesFocusOnlyOnMouseDown:(BOOL)b { |
1206 takesFocusOnlyOnMouseDown_ = b; | 1233 takesFocusOnlyOnMouseDown_ = b; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 // Clear them here so that we can know whether they have changed afterwards. | 1371 // Clear them here so that we can know whether they have changed afterwards. |
1345 textToBeInserted_.clear(); | 1372 textToBeInserted_.clear(); |
1346 markedText_.clear(); | 1373 markedText_.clear(); |
1347 underlines_.clear(); | 1374 underlines_.clear(); |
1348 unmarkTextCalled_ = NO; | 1375 unmarkTextCalled_ = NO; |
1349 hasEditCommands_ = NO; | 1376 hasEditCommands_ = NO; |
1350 editCommands_.clear(); | 1377 editCommands_.clear(); |
1351 | 1378 |
1352 // Sends key down events to input method first, then we can decide what should | 1379 // Sends key down events to input method first, then we can decide what should |
1353 // be done according to input method's feedback. | 1380 // be done according to input method's feedback. |
1354 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; | 1381 // If a plugin is active, bypass this step since events are forwarded directly |
| 1382 // to the plugin IME. |
| 1383 if (pluginImeIdentifier_ == -1) |
| 1384 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; |
1355 | 1385 |
1356 handlingKeyDown_ = NO; | 1386 handlingKeyDown_ = NO; |
1357 | 1387 |
1358 // Indicates if we should send the key event and corresponding editor commands | 1388 // Indicates if we should send the key event and corresponding editor commands |
1359 // after processing the input method result. | 1389 // after processing the input method result. |
1360 BOOL delayEventUntilAfterImeCompostion = NO; | 1390 BOOL delayEventUntilAfterImeCompostion = NO; |
1361 | 1391 |
1362 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY | 1392 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY |
1363 // while an input method is composing or inserting a text. | 1393 // while an input method is composing or inserting a text. |
1364 // Gmail checks this code in its onkeydown handler to stop auto-completing | 1394 // Gmail checks this code in its onkeydown handler to stop auto-completing |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 } | 2262 } |
2233 | 2263 |
2234 - (NSInteger)conversationIdentifier { | 2264 - (NSInteger)conversationIdentifier { |
2235 return reinterpret_cast<NSInteger>(self); | 2265 return reinterpret_cast<NSInteger>(self); |
2236 } | 2266 } |
2237 | 2267 |
2238 // Each RenderWidgetHostViewCocoa has its own input context, but we return | 2268 // Each RenderWidgetHostViewCocoa has its own input context, but we return |
2239 // nil when the caret is in non-editable content or password box to avoid | 2269 // nil when the caret is in non-editable content or password box to avoid |
2240 // making input methods do their work. | 2270 // making input methods do their work. |
2241 - (NSTextInputContext *)inputContext { | 2271 - (NSTextInputContext *)inputContext { |
| 2272 if (pluginImeIdentifier_ != -1) |
| 2273 return [[ComplexTextInputPanel sharedComplexTextInputPanel] inputContext]; |
| 2274 |
2242 switch(renderWidgetHostView_->text_input_type_) { | 2275 switch(renderWidgetHostView_->text_input_type_) { |
2243 case WebKit::WebTextInputTypeNone: | 2276 case WebKit::WebTextInputTypeNone: |
2244 case WebKit::WebTextInputTypePassword: | 2277 case WebKit::WebTextInputTypePassword: |
2245 return nil; | 2278 return nil; |
2246 default: | 2279 default: |
2247 return [super inputContext]; | 2280 return [super inputContext]; |
2248 } | 2281 } |
2249 } | 2282 } |
2250 | 2283 |
2251 - (BOOL)hasMarkedText { | 2284 - (BOOL)hasMarkedText { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2462 - (void)confirmComposition { | 2495 - (void)confirmComposition { |
2463 if (!hasMarkedText_) | 2496 if (!hasMarkedText_) |
2464 return; | 2497 return; |
2465 | 2498 |
2466 if (renderWidgetHostView_->render_widget_host_) | 2499 if (renderWidgetHostView_->render_widget_host_) |
2467 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); | 2500 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); |
2468 | 2501 |
2469 [self cancelComposition]; | 2502 [self cancelComposition]; |
2470 } | 2503 } |
2471 | 2504 |
| 2505 - (void)setPluginImeEnabled:(BOOL)enabled forPlugin:(int)pluginId { |
| 2506 if ((enabled && pluginId == pluginImeIdentifier_) || |
| 2507 (!enabled && pluginId != pluginImeIdentifier_)) |
| 2508 return; |
| 2509 |
| 2510 // If IME was already active then either it is being cancelled, or the plugin |
| 2511 // changed; either way the current input needs to be cleared. |
| 2512 if (pluginImeIdentifier_ != -1) |
| 2513 [[ComplexTextInputPanel sharedComplexTextInputPanel] cancelInput]; |
| 2514 |
| 2515 pluginImeIdentifier_ = enabled ? pluginId : -1; |
| 2516 } |
| 2517 |
| 2518 - (BOOL)postProcessEventForPluginIme:(NSEvent*)event { |
| 2519 if (pluginImeIdentifier_ == -1) |
| 2520 return false; |
| 2521 |
| 2522 // ComplexTextInputPanel only works on 10.6+. |
| 2523 static BOOL sImeSupported = NO; |
| 2524 static BOOL sHaveCheckedSupport = NO; |
| 2525 if (!sHaveCheckedSupport) { |
| 2526 int32 major, minor, bugfix; |
| 2527 base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); |
| 2528 sImeSupported = major > 10 || (major == 10 && minor > 5); |
| 2529 } |
| 2530 if (!sImeSupported) |
| 2531 return false; |
| 2532 |
| 2533 ComplexTextInputPanel* inputPanel = |
| 2534 [ComplexTextInputPanel sharedComplexTextInputPanel]; |
| 2535 NSString* composited_string = nil; |
| 2536 BOOL handled = [inputPanel interpretKeyEvent:event |
| 2537 string:&composited_string]; |
| 2538 if (composited_string) { |
| 2539 renderWidgetHostView_->PluginImeCompositionConfirmed( |
| 2540 base::SysNSStringToUTF16(composited_string), pluginImeIdentifier_); |
| 2541 } |
| 2542 return handled; |
| 2543 } |
| 2544 |
2472 - (ViewID)viewID { | 2545 - (ViewID)viewID { |
2473 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; | 2546 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; |
2474 } | 2547 } |
2475 | 2548 |
2476 // Overriding a NSResponder method to support application services. | 2549 // Overriding a NSResponder method to support application services. |
2477 | 2550 |
2478 - (id)validRequestorForSendType:(NSString*)sendType | 2551 - (id)validRequestorForSendType:(NSString*)sendType |
2479 returnType:(NSString*)returnType { | 2552 returnType:(NSString*)returnType { |
2480 id requestor = nil; | 2553 id requestor = nil; |
2481 BOOL sendTypeIsString = [sendType isEqual:NSStringPboardType]; | 2554 BOOL sendTypeIsString = [sendType isEqual:NSStringPboardType]; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2521 if (!string) return NO; | 2594 if (!string) return NO; |
2522 | 2595 |
2523 // If the user is currently using an IME, confirm the IME input, | 2596 // If the user is currently using an IME, confirm the IME input, |
2524 // and then insert the text from the service, the same as TextEdit and Safari. | 2597 // and then insert the text from the service, the same as TextEdit and Safari. |
2525 [self confirmComposition]; | 2598 [self confirmComposition]; |
2526 [self insertText:string]; | 2599 [self insertText:string]; |
2527 return YES; | 2600 return YES; |
2528 } | 2601 } |
2529 | 2602 |
2530 @end | 2603 @end |
OLD | NEW |