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 "chrome/browser/chrome_thread.h" | 9 #include "chrome/browser/chrome_thread.h" |
10 #include "app/app_switches.h" | 10 #include "app/app_switches.h" |
11 #include "app/surface/io_surface_support_mac.h" | 11 #include "app/surface/io_surface_support_mac.h" |
12 #import "base/chrome_application_mac.h" | 12 #import "base/chrome_application_mac.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/histogram.h" | 14 #include "base/histogram.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #import "base/scoped_nsautorelease_pool.h" | 16 #import "base/scoped_nsautorelease_pool.h" |
17 #import "base/scoped_nsobject.h" | 17 #import "base/scoped_nsobject.h" |
18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 19 #include "base/sys_info.h" |
19 #include "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.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 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 | 885 |
885 void RenderWidgetHostViewMac::KillSelf() { | 886 void RenderWidgetHostViewMac::KillSelf() { |
886 if (shutdown_factory_.empty()) { | 887 if (shutdown_factory_.empty()) { |
887 [cocoa_view_ setHidden:YES]; | 888 [cocoa_view_ setHidden:YES]; |
888 MessageLoop::current()->PostTask(FROM_HERE, | 889 MessageLoop::current()->PostTask(FROM_HERE, |
889 shutdown_factory_.NewRunnableMethod( | 890 shutdown_factory_.NewRunnableMethod( |
890 &RenderWidgetHostViewMac::ShutdownHost)); | 891 &RenderWidgetHostViewMac::ShutdownHost)); |
891 } | 892 } |
892 } | 893 } |
893 | 894 |
| 895 void RenderWidgetHostViewMac::SetPluginImeEnabled(bool enabled, int plugin_id) { |
| 896 [cocoa_view_ setPluginImeEnabled:(enabled ? YES : NO) forPlugin:plugin_id]; |
| 897 } |
| 898 |
| 899 bool RenderWidgetHostViewMac::PostProcessEventForPluginIme( |
| 900 const NativeWebKeyboardEvent& event) { |
| 901 // Check WebInputEvent type since multiple types of events can be sent into |
| 902 // WebKit for the same OS event (e.g., RawKeyDown and Char), so filtering is |
| 903 // necessary to avoid double processing. |
| 904 // Also check the native type, since NSFlagsChanged is considered a key event |
| 905 // for WebKit purposes, but isn't considered a key event by the OS. |
| 906 if (event.type == WebInputEvent::RawKeyDown && |
| 907 [event.os_event type] == NSKeyDown) |
| 908 return [cocoa_view_ postProcessEventForPluginIme:event.os_event]; |
| 909 return false; |
| 910 } |
| 911 |
| 912 void RenderWidgetHostViewMac::PluginImeCompositionConfirmed( |
| 913 const string16& text, int plugin_id) { |
| 914 if (render_widget_host_) { |
| 915 render_widget_host_->Send(new ViewMsg_PluginImeCompositionConfirmed( |
| 916 render_widget_host_->routing_id(), text, plugin_id)); |
| 917 } |
| 918 } |
| 919 |
894 gfx::PluginWindowHandle | 920 gfx::PluginWindowHandle |
895 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, | 921 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, |
896 bool root) { | 922 bool root) { |
897 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 923 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
898 // Create an NSView to host the plugin's/compositor's pixels. | 924 // Create an NSView to host the plugin's/compositor's pixels. |
899 gfx::PluginWindowHandle handle = | 925 gfx::PluginWindowHandle handle = |
900 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | 926 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); |
901 | 927 |
902 scoped_nsobject<AcceleratedPluginView> plugin_view( | 928 scoped_nsobject<AcceleratedPluginView> plugin_view( |
903 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this | 929 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 renderWidgetHostView_.reset(r); | 1211 renderWidgetHostView_.reset(r); |
1186 canBeKeyView_ = YES; | 1212 canBeKeyView_ = YES; |
1187 takesFocusOnlyOnMouseDown_ = NO; | 1213 takesFocusOnlyOnMouseDown_ = NO; |
1188 closeOnDeactivate_ = NO; | 1214 closeOnDeactivate_ = NO; |
1189 | 1215 |
1190 rendererAccessible_ = | 1216 rendererAccessible_ = |
1191 !CommandLine::ForCurrentProcess()->HasSwitch( | 1217 !CommandLine::ForCurrentProcess()->HasSwitch( |
1192 switches::kDisableRendererAccessibility); | 1218 switches::kDisableRendererAccessibility); |
1193 accessibilityRequested_ = NO; | 1219 accessibilityRequested_ = NO; |
1194 accessibilityReceived_ = NO; | 1220 accessibilityReceived_ = NO; |
| 1221 pluginImeIdentifier_ = -1; |
1195 } | 1222 } |
1196 return self; | 1223 return self; |
1197 } | 1224 } |
1198 | 1225 |
1199 - (void)setCanBeKeyView:(BOOL)can { | 1226 - (void)setCanBeKeyView:(BOOL)can { |
1200 canBeKeyView_ = can; | 1227 canBeKeyView_ = can; |
1201 } | 1228 } |
1202 | 1229 |
1203 - (void)setTakesFocusOnlyOnMouseDown:(BOOL)b { | 1230 - (void)setTakesFocusOnlyOnMouseDown:(BOOL)b { |
1204 takesFocusOnlyOnMouseDown_ = b; | 1231 takesFocusOnlyOnMouseDown_ = b; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 // Clear them here so that we can know whether they have changed afterwards. | 1369 // Clear them here so that we can know whether they have changed afterwards. |
1343 textToBeInserted_.clear(); | 1370 textToBeInserted_.clear(); |
1344 markedText_.clear(); | 1371 markedText_.clear(); |
1345 underlines_.clear(); | 1372 underlines_.clear(); |
1346 unmarkTextCalled_ = NO; | 1373 unmarkTextCalled_ = NO; |
1347 hasEditCommands_ = NO; | 1374 hasEditCommands_ = NO; |
1348 editCommands_.clear(); | 1375 editCommands_.clear(); |
1349 | 1376 |
1350 // Sends key down events to input method first, then we can decide what should | 1377 // Sends key down events to input method first, then we can decide what should |
1351 // be done according to input method's feedback. | 1378 // be done according to input method's feedback. |
1352 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; | 1379 // If a plugin is active, bypass this step since events are forwarded directly |
| 1380 // to the plugin IME. |
| 1381 if (pluginImeIdentifier_ == -1) |
| 1382 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; |
1353 | 1383 |
1354 handlingKeyDown_ = NO; | 1384 handlingKeyDown_ = NO; |
1355 | 1385 |
1356 // Indicates if we should send the key event and corresponding editor commands | 1386 // Indicates if we should send the key event and corresponding editor commands |
1357 // after processing the input method result. | 1387 // after processing the input method result. |
1358 BOOL delayEventUntilAfterImeCompostion = NO; | 1388 BOOL delayEventUntilAfterImeCompostion = NO; |
1359 | 1389 |
1360 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY | 1390 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY |
1361 // while an input method is composing or inserting a text. | 1391 // while an input method is composing or inserting a text. |
1362 // Gmail checks this code in its onkeydown handler to stop auto-completing | 1392 // Gmail checks this code in its onkeydown handler to stop auto-completing |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 } | 2254 } |
2225 | 2255 |
2226 - (NSInteger)conversationIdentifier { | 2256 - (NSInteger)conversationIdentifier { |
2227 return reinterpret_cast<NSInteger>(self); | 2257 return reinterpret_cast<NSInteger>(self); |
2228 } | 2258 } |
2229 | 2259 |
2230 // Each RenderWidgetHostViewCocoa has its own input context, but we return | 2260 // Each RenderWidgetHostViewCocoa has its own input context, but we return |
2231 // nil when the caret is in non-editable content or password box to avoid | 2261 // nil when the caret is in non-editable content or password box to avoid |
2232 // making input methods do their work. | 2262 // making input methods do their work. |
2233 - (NSTextInputContext *)inputContext { | 2263 - (NSTextInputContext *)inputContext { |
| 2264 if (pluginImeIdentifier_ != -1) |
| 2265 return [[ComplexTextInputPanel sharedComplexTextInputPanel] inputContext]; |
| 2266 |
2234 switch(renderWidgetHostView_->text_input_type_) { | 2267 switch(renderWidgetHostView_->text_input_type_) { |
2235 case WebKit::WebTextInputTypeNone: | 2268 case WebKit::WebTextInputTypeNone: |
2236 case WebKit::WebTextInputTypePassword: | 2269 case WebKit::WebTextInputTypePassword: |
2237 return nil; | 2270 return nil; |
2238 default: | 2271 default: |
2239 return [super inputContext]; | 2272 return [super inputContext]; |
2240 } | 2273 } |
2241 } | 2274 } |
2242 | 2275 |
2243 - (BOOL)hasMarkedText { | 2276 - (BOOL)hasMarkedText { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2454 - (void)confirmComposition { | 2487 - (void)confirmComposition { |
2455 if (!hasMarkedText_) | 2488 if (!hasMarkedText_) |
2456 return; | 2489 return; |
2457 | 2490 |
2458 if (renderWidgetHostView_->render_widget_host_) | 2491 if (renderWidgetHostView_->render_widget_host_) |
2459 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); | 2492 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); |
2460 | 2493 |
2461 [self cancelComposition]; | 2494 [self cancelComposition]; |
2462 } | 2495 } |
2463 | 2496 |
| 2497 - (void)setPluginImeEnabled:(BOOL)enabled forPlugin:(int)pluginId { |
| 2498 if ((enabled && pluginId == pluginImeIdentifier_) || |
| 2499 (!enabled && pluginId != pluginImeIdentifier_)) |
| 2500 return; |
| 2501 |
| 2502 // If IME was already active then either it is being cancelled, or the plugin |
| 2503 // changed; either way the current input needs to be cleared. |
| 2504 if (pluginImeIdentifier_ != -1) |
| 2505 [[ComplexTextInputPanel sharedComplexTextInputPanel] cancelInput]; |
| 2506 |
| 2507 pluginImeIdentifier_ = enabled ? pluginId : -1; |
| 2508 } |
| 2509 |
| 2510 - (BOOL)postProcessEventForPluginIme:(NSEvent*)event { |
| 2511 if (pluginImeIdentifier_ == -1) |
| 2512 return false; |
| 2513 |
| 2514 // ComplexTextInputPanel only works on 10.6+. |
| 2515 static BOOL sImeSupported = NO; |
| 2516 static BOOL sHaveCheckedSupport = NO; |
| 2517 if (!sHaveCheckedSupport) { |
| 2518 int32 major, minor, bugfix; |
| 2519 base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); |
| 2520 sImeSupported = major > 10 || (major == 10 && minor > 5); |
| 2521 } |
| 2522 if (!sImeSupported) |
| 2523 return false; |
| 2524 |
| 2525 ComplexTextInputPanel* inputPanel = |
| 2526 [ComplexTextInputPanel sharedComplexTextInputPanel]; |
| 2527 NSString* composited_string = nil; |
| 2528 BOOL handled = [inputPanel interpretKeyEvent:event |
| 2529 string:&composited_string]; |
| 2530 if (composited_string) { |
| 2531 renderWidgetHostView_->PluginImeCompositionConfirmed( |
| 2532 base::SysNSStringToUTF16(composited_string), pluginImeIdentifier_); |
| 2533 } |
| 2534 return handled; |
| 2535 } |
| 2536 |
2464 - (ViewID)viewID { | 2537 - (ViewID)viewID { |
2465 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; | 2538 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; |
2466 } | 2539 } |
2467 | 2540 |
2468 // Overriding a NSResponder method to support application services. | 2541 // Overriding a NSResponder method to support application services. |
2469 | 2542 |
2470 - (id)validRequestorForSendType:(NSString*)sendType | 2543 - (id)validRequestorForSendType:(NSString*)sendType |
2471 returnType:(NSString*)returnType { | 2544 returnType:(NSString*)returnType { |
2472 id requestor = nil; | 2545 id requestor = nil; |
2473 BOOL sendTypeIsString = [sendType isEqual:NSStringPboardType]; | 2546 BOOL sendTypeIsString = [sendType isEqual:NSStringPboardType]; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2513 if (!string) return NO; | 2586 if (!string) return NO; |
2514 | 2587 |
2515 // If the user is currently using an IME, confirm the IME input, | 2588 // If the user is currently using an IME, confirm the IME input, |
2516 // and then insert the text from the service, the same as TextEdit and Safari. | 2589 // and then insert the text from the service, the same as TextEdit and Safari. |
2517 [self confirmComposition]; | 2590 [self confirmComposition]; |
2518 [self insertText:string]; | 2591 [self insertText:string]; |
2519 return YES; | 2592 return YES; |
2520 } | 2593 } |
2521 | 2594 |
2522 @end | 2595 @end |
OLD | NEW |