Chromium Code Reviews| 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 |