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 "chrome/browser/renderer_host/gtk_im_context_wrapper.h" | 5 #include "chrome/browser/renderer_host/gtk_im_context_wrapper.h" |
6 | 6 |
7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
9 #include <gtk/gtk.h> | 9 #include <gtk/gtk.h> |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 // ui::CompositionUnderline. | 54 // ui::CompositionUnderline. |
55 COMPILE_ASSERT(sizeof(ui::CompositionUnderline) == | 55 COMPILE_ASSERT(sizeof(ui::CompositionUnderline) == |
56 sizeof(WebKit::WebCompositionUnderline), | 56 sizeof(WebKit::WebCompositionUnderline), |
57 ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff); | 57 ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff); |
58 | 58 |
59 GtkIMContextWrapper::GtkIMContextWrapper(RenderWidgetHostViewGtk* host_view) | 59 GtkIMContextWrapper::GtkIMContextWrapper(RenderWidgetHostViewGtk* host_view) |
60 : host_view_(host_view), | 60 : host_view_(host_view), |
61 context_(gtk_im_multicontext_new()), | 61 context_(gtk_im_multicontext_new()), |
62 context_simple_(gtk_im_context_simple_new()), | 62 context_simple_(gtk_im_context_simple_new()), |
63 is_focused_(false), | 63 is_focused_(false), |
64 is_ppapi_plugin_focused_(false), | |
64 is_composing_text_(false), | 65 is_composing_text_(false), |
65 is_enabled_(false), | 66 is_enabled_(false), |
66 is_in_key_event_handler_(false), | 67 is_in_key_event_handler_(false), |
67 is_composition_changed_(false), | 68 is_composition_changed_(false), |
68 suppress_next_commit_(false), | 69 suppress_next_commit_(false), |
69 last_key_code_(0), | 70 last_key_code_(0), |
70 last_key_was_up_(false), | 71 last_key_was_up_(false), |
71 last_key_filtered_no_result_(false) { | 72 last_key_filtered_no_result_(false) { |
72 DCHECK(context_); | 73 DCHECK(context_); |
73 DCHECK(context_simple_); | 74 DCHECK(context_simple_); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 host_view_->ForwardKeyboardEvent(wke); | 221 host_view_->ForwardKeyboardEvent(wke); |
221 } | 222 } |
222 | 223 |
223 last_key_code_ = key_code; | 224 last_key_code_ = key_code; |
224 last_key_was_up_ = (event->type == GDK_KEY_RELEASE); | 225 last_key_was_up_ = (event->type == GDK_KEY_RELEASE); |
225 last_key_filtered_no_result_ = (filtered && !has_result); | 226 last_key_filtered_no_result_ = (filtered && !has_result); |
226 } | 227 } |
227 | 228 |
228 void GtkIMContextWrapper::UpdateInputMethodState(WebKit::WebTextInputType type, | 229 void GtkIMContextWrapper::UpdateInputMethodState(WebKit::WebTextInputType type, |
229 const gfx::Rect& caret_rect) { | 230 const gfx::Rect& caret_rect) { |
231 text_input_type_ = type; | |
232 caret_rect_ = caret_rect; | |
233 | |
230 suppress_next_commit_ = false; | 234 suppress_next_commit_ = false; |
231 | 235 |
232 // The renderer has updated its IME status. | 236 // The renderer has updated its IME status. |
233 // Control the GtkIMContext object according to this status. | 237 // Control the GtkIMContext object according to this status. |
234 if (!context_ || !is_focused_) | 238 if (!context_ || !is_focused_) |
235 return; | 239 return; |
236 | 240 |
237 DCHECK(!is_in_key_event_handler_); | 241 DCHECK(!is_in_key_event_handler_); |
238 | 242 |
239 bool is_enabled = (type == WebKit::WebTextInputTypeText); | 243 // If the focus is on a editable text, or on a PPAPI plugin, turn IME on. |
244 bool is_enabled = (type == WebKit::WebTextInputTypeText) | |
245 || is_ppapi_plugin_focused_; | |
kochi
2011/05/25 06:19:44
Put || in the end of the previous line, rather tha
kinaba
2011/05/25 22:23:53
The whole change here is removed from the patch se
| |
240 if (is_enabled_ != is_enabled) { | 246 if (is_enabled_ != is_enabled) { |
241 is_enabled_ = is_enabled; | 247 is_enabled_ = is_enabled; |
242 if (is_enabled) | 248 if (is_enabled) |
243 gtk_im_context_focus_in(context_); | 249 gtk_im_context_focus_in(context_); |
244 else | 250 else |
245 gtk_im_context_focus_out(context_); | 251 gtk_im_context_focus_out(context_); |
246 } | 252 } |
247 | 253 |
248 if (is_enabled) { | 254 if (is_enabled) { |
249 // Updates the position of the IME candidate window. | 255 // Updates the position of the IME candidate window. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 gtk_im_context_reset(context_simple_); | 308 gtk_im_context_reset(context_simple_); |
303 gtk_im_context_focus_out(context_simple_); | 309 gtk_im_context_focus_out(context_simple_); |
304 | 310 |
305 is_composing_text_ = false; | 311 is_composing_text_ = false; |
306 | 312 |
307 // Disable RenderWidget's IME related events to save bandwidth. | 313 // Disable RenderWidget's IME related events to save bandwidth. |
308 if (host_view_->GetRenderWidgetHost()) | 314 if (host_view_->GetRenderWidgetHost()) |
309 host_view_->GetRenderWidgetHost()->SetInputMethodActive(false); | 315 host_view_->GetRenderWidgetHost()->SetInputMethodActive(false); |
310 } | 316 } |
311 | 317 |
318 void GtkIMContextWrapper::OnPpapiPluginFocusChanged(bool focused) { | |
319 if (focused != is_ppapi_plugin_focused_) { | |
320 is_ppapi_plugin_focused_ = focused; | |
321 UpdateInputMethodState(text_input_type_, caret_rect_); | |
322 } | |
323 } | |
324 | |
325 | |
312 #if !defined(TOOLKIT_VIEWS) | 326 #if !defined(TOOLKIT_VIEWS) |
313 // Not defined for views because the views context menu doesn't | 327 // Not defined for views because the views context menu doesn't |
314 // implement input methods yet. | 328 // implement input methods yet. |
315 void GtkIMContextWrapper::AppendInputMethodsContextMenu(MenuGtk* menu) { | 329 void GtkIMContextWrapper::AppendInputMethodsContextMenu(MenuGtk* menu) { |
316 gboolean show_input_method_menu = TRUE; | 330 gboolean show_input_method_menu = TRUE; |
317 | 331 |
318 g_object_get(gtk_widget_get_settings(GTK_WIDGET(host_view_->native_view())), | 332 g_object_get(gtk_widget_get_settings(GTK_WIDGET(host_view_->native_view())), |
319 "gtk-show-input-method-menu", &show_input_method_menu, NULL); | 333 "gtk-show-input-method-menu", &show_input_method_menu, NULL); |
320 if (!show_input_method_menu) | 334 if (!show_input_method_menu) |
321 return; | 335 return; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 | 464 |
451 // Send preedit text only if it's changed. | 465 // Send preedit text only if it's changed. |
452 // If a text has been committed, then we don't need to send the empty | 466 // If a text has been committed, then we don't need to send the empty |
453 // preedit text again. | 467 // preedit text again. |
454 if (is_composition_changed_) { | 468 if (is_composition_changed_) { |
455 if (composition_.text.length()) { | 469 if (composition_.text.length()) { |
456 // Another composition session has been started. | 470 // Another composition session has been started. |
457 is_composing_text_ = true; | 471 is_composing_text_ = true; |
458 // TODO(suzhe): convert both renderer_host and renderer to use | 472 // TODO(suzhe): convert both renderer_host and renderer to use |
459 // ui::CompositionText. | 473 // ui::CompositionText. |
460 const std::vector<WebKit::WebCompositionUnderline>& underlines = | 474 |
461 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>( | 475 // For now, if a PPAPI plugin is focused, we don't send ImeSetCompostion. |
kochi
2011/05/25 06:19:44
"For now" sounds ambiguous for any future referenc
kinaba
2011/05/25 22:23:53
Done (the code is moved to content/renderer/render
| |
462 composition_.underlines); | 476 if (!is_ppapi_plugin_focused_) { |
463 host->ImeSetComposition(composition_.text, underlines, | 477 const std::vector<WebKit::WebCompositionUnderline>& underlines = |
464 composition_.selection.start(), | 478 reinterpret_cast< |
465 composition_.selection.end()); | 479 const std::vector<WebKit::WebCompositionUnderline>&>( |
480 composition_.underlines); | |
481 host->ImeSetComposition(composition_.text, underlines, | |
482 composition_.selection.start(), | |
483 composition_.selection.end()); | |
484 } | |
466 } else if (!committed) { | 485 } else if (!committed) { |
467 host->ImeCancelComposition(); | 486 host->ImeCancelComposition(); |
468 } | 487 } |
469 } | 488 } |
470 } | 489 } |
471 | 490 |
472 void GtkIMContextWrapper::ConfirmComposition() { | 491 void GtkIMContextWrapper::ConfirmComposition() { |
473 if (!is_enabled_) | 492 if (!is_enabled_) |
474 return; | 493 return; |
475 | 494 |
(...skipping 19 matching lines...) Expand all Loading... | |
495 commit_text_.append(text); | 514 commit_text_.append(text); |
496 // Nothing needs to do, if it's currently in ProcessKeyEvent() | 515 // Nothing needs to do, if it's currently in ProcessKeyEvent() |
497 // handler, which will send commit text to webkit later. Otherwise, | 516 // handler, which will send commit text to webkit later. Otherwise, |
498 // we need send it here. | 517 // we need send it here. |
499 // It's possible that commit signal is fired without a key event, for | 518 // It's possible that commit signal is fired without a key event, for |
500 // example when user input via a voice or handwriting recognition software. | 519 // example when user input via a voice or handwriting recognition software. |
501 // In this case, the text must be committed directly. | 520 // In this case, the text must be committed directly. |
502 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) { | 521 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) { |
503 // Workaround http://crbug.com/45478 by sending fake key down/up events. | 522 // Workaround http://crbug.com/45478 by sending fake key down/up events. |
504 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); | 523 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); |
505 host_view_->GetRenderWidgetHost()->ImeConfirmComposition(text); | 524 if (is_ppapi_plugin_focused_) { |
525 // For now, if a PPAPI plugin is focused, we directly emit character | |
526 // events, instead of sending renderer an IME event. | |
kochi
2011/05/25 06:19:44
For now -> TODO().
E.g. TODO(kinaba): Until PPAPI
kinaba
2011/05/25 22:23:53
Done (the code is moved to content/renderer/render
| |
527 for (size_t i = 0; i<commit_text_.size(); ++i) { | |
kochi
2011/05/25 06:19:44
Style nit: spaces around "<".
kinaba
2011/05/25 22:23:53
Done (the code is moved to content/renderer/render
| |
528 NativeWebKeyboardEvent char_event(commit_text_[i], | |
529 0, | |
530 base::Time::Now().ToDoubleT()); | |
531 char_event.skip_in_browser = true; | |
532 host_view_->ForwardKeyboardEvent(char_event); | |
533 } | |
534 } else { | |
535 host_view_->GetRenderWidgetHost()->ImeConfirmComposition(text); | |
536 } | |
506 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); | 537 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); |
507 } | 538 } |
508 } | 539 } |
509 | 540 |
510 void GtkIMContextWrapper::HandlePreeditStart() { | 541 void GtkIMContextWrapper::HandlePreeditStart() { |
511 // Ignore preedit related signals triggered by CancelComposition() method. | 542 // Ignore preedit related signals triggered by CancelComposition() method. |
512 if (suppress_next_commit_) | 543 if (suppress_next_commit_) |
513 return; | 544 return; |
514 is_composing_text_ = true; | 545 is_composing_text_ = true; |
515 } | 546 } |
(...skipping 22 matching lines...) Expand all Loading... | |
538 if (composition_.text.length()) | 569 if (composition_.text.length()) |
539 is_composing_text_ = true; | 570 is_composing_text_ = true; |
540 | 571 |
541 // Nothing needs to do, if it's currently in ProcessKeyEvent() | 572 // Nothing needs to do, if it's currently in ProcessKeyEvent() |
542 // handler, which will send preedit text to webkit later. | 573 // handler, which will send preedit text to webkit later. |
543 // Otherwise, we need send it here if it's been changed. | 574 // Otherwise, we need send it here if it's been changed. |
544 if (!is_in_key_event_handler_ && is_composing_text_ && | 575 if (!is_in_key_event_handler_ && is_composing_text_ && |
545 host_view_->GetRenderWidgetHost()) { | 576 host_view_->GetRenderWidgetHost()) { |
546 // Workaround http://crbug.com/45478 by sending fake key down/up events. | 577 // Workaround http://crbug.com/45478 by sending fake key down/up events. |
547 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); | 578 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); |
548 // TODO(suzhe): convert both renderer_host and renderer to use | 579 // For now, if a PPAPI plugin is focused, we don't send ImeSetComposition. |
kochi
2011/05/25 06:19:44
Ditto.
kinaba
2011/05/25 22:23:53
Done (content/renderer/render_view.cc:3951).
| |
549 // ui::CompositionText. | 580 if (!is_ppapi_plugin_focused_) { |
550 const std::vector<WebKit::WebCompositionUnderline>& underlines = | 581 // TODO(suzhe): convert both renderer_host and renderer to use |
551 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>( | 582 // ui::CompositionText. |
552 composition_.underlines); | 583 const std::vector<WebKit::WebCompositionUnderline>& underlines = |
553 host_view_->GetRenderWidgetHost()->ImeSetComposition( | 584 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>( |
554 composition_.text, underlines, composition_.selection.start(), | 585 composition_.underlines); |
555 composition_.selection.end()); | 586 host_view_->GetRenderWidgetHost()->ImeSetComposition( |
587 composition_.text, underlines, composition_.selection.start(), | |
588 composition_.selection.end()); | |
589 } | |
556 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); | 590 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); |
557 } | 591 } |
558 } | 592 } |
559 | 593 |
560 void GtkIMContextWrapper::HandlePreeditEnd() { | 594 void GtkIMContextWrapper::HandlePreeditEnd() { |
561 if (composition_.text.length()) { | 595 if (composition_.text.length()) { |
562 // The composition session has been finished. | 596 // The composition session has been finished. |
563 composition_.Clear(); | 597 composition_.Clear(); |
564 is_composition_changed_ = true; | 598 is_composition_changed_ = true; |
565 | 599 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 | 660 |
627 void GtkIMContextWrapper::HandleHostViewRealizeThunk( | 661 void GtkIMContextWrapper::HandleHostViewRealizeThunk( |
628 GtkWidget* widget, GtkIMContextWrapper* self) { | 662 GtkWidget* widget, GtkIMContextWrapper* self) { |
629 self->HandleHostViewRealize(widget); | 663 self->HandleHostViewRealize(widget); |
630 } | 664 } |
631 | 665 |
632 void GtkIMContextWrapper::HandleHostViewUnrealizeThunk( | 666 void GtkIMContextWrapper::HandleHostViewUnrealizeThunk( |
633 GtkWidget* widget, GtkIMContextWrapper* self) { | 667 GtkWidget* widget, GtkIMContextWrapper* self) { |
634 self->HandleHostViewUnrealize(); | 668 self->HandleHostViewUnrealize(); |
635 } | 669 } |
OLD | NEW |