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

Side by Side Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 3782012: Merge 62820 - Implement IME for Mac plugins using the Cocoa event model on 10... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/552/src/
Patch Set: Created 10 years, 2 months 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | chrome/browser/renderer_host/test/test_render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698