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

Side by Side Diff: chrome/browser/renderer_host/gtk_im_context_wrapper.cc

Issue 6990072: The first step for enabling off-the-spot IME on Pepper on ChromeOS/Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 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) 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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698