| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/gtk_im_context_wrapper.h" | 5 #include "content/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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 if (is_enabled_) | 277 if (is_enabled_) |
| 278 gtk_im_context_focus_in(context_); | 278 gtk_im_context_focus_in(context_); |
| 279 | 279 |
| 280 // context_simple_ is always enabled. | 280 // context_simple_ is always enabled. |
| 281 // Actually it doesn't care focus state at all. | 281 // Actually it doesn't care focus state at all. |
| 282 gtk_im_context_focus_in(context_simple_); | 282 gtk_im_context_focus_in(context_simple_); |
| 283 | 283 |
| 284 // Enables RenderWidget's IME related events, so that we can be notified | 284 // Enables RenderWidget's IME related events, so that we can be notified |
| 285 // when WebKit wants to enable or disable IME. | 285 // when WebKit wants to enable or disable IME. |
| 286 if (host_view_->GetRenderWidgetHost()) | 286 if (host_view_->GetRenderWidgetHost()) |
| 287 static_cast<RenderWidgetHostImpl*>( | 287 host_view_->GetRenderWidgetHost()->AsRWHImpl()->SetInputMethodActive(true); |
| 288 host_view_->GetRenderWidgetHost())->SetInputMethodActive(true); | |
| 289 } | 288 } |
| 290 | 289 |
| 291 void GtkIMContextWrapper::OnFocusOut() { | 290 void GtkIMContextWrapper::OnFocusOut() { |
| 292 if (!is_focused_) | 291 if (!is_focused_) |
| 293 return; | 292 return; |
| 294 | 293 |
| 295 // Tracks the focused state so that we won't give focus to the | 294 // Tracks the focused state so that we won't give focus to the |
| 296 // GtkIMContext object unexpectly. | 295 // GtkIMContext object unexpectly. |
| 297 is_focused_ = false; | 296 is_focused_ = false; |
| 298 | 297 |
| 299 // Notify the GtkIMContext object of this focus-out event only if IME is | 298 // Notify the GtkIMContext object of this focus-out event only if IME is |
| 300 // enabled by WebKit. | 299 // enabled by WebKit. |
| 301 if (is_enabled_) { | 300 if (is_enabled_) { |
| 302 // To reset the GtkIMContext object and prevent data loss. | 301 // To reset the GtkIMContext object and prevent data loss. |
| 303 ConfirmComposition(); | 302 ConfirmComposition(); |
| 304 gtk_im_context_focus_out(context_); | 303 gtk_im_context_focus_out(context_); |
| 305 } | 304 } |
| 306 | 305 |
| 307 // To make sure it'll be in correct state when focused in again. | 306 // To make sure it'll be in correct state when focused in again. |
| 308 gtk_im_context_reset(context_simple_); | 307 gtk_im_context_reset(context_simple_); |
| 309 gtk_im_context_focus_out(context_simple_); | 308 gtk_im_context_focus_out(context_simple_); |
| 310 | 309 |
| 311 is_composing_text_ = false; | 310 is_composing_text_ = false; |
| 312 | 311 |
| 313 // Disable RenderWidget's IME related events to save bandwidth. | 312 // Disable RenderWidget's IME related events to save bandwidth. |
| 314 if (host_view_->GetRenderWidgetHost()) | 313 if (host_view_->GetRenderWidgetHost()) |
| 315 static_cast<RenderWidgetHostImpl*>( | 314 host_view_->GetRenderWidgetHost()->AsRWHImpl()->SetInputMethodActive(false); |
| 316 host_view_->GetRenderWidgetHost())->SetInputMethodActive(false); | |
| 317 } | 315 } |
| 318 | 316 |
| 319 #if !defined(TOOLKIT_VIEWS) | 317 #if !defined(TOOLKIT_VIEWS) |
| 320 // Not defined for views because the views context menu doesn't | 318 // Not defined for views because the views context menu doesn't |
| 321 // implement input methods yet. | 319 // implement input methods yet. |
| 322 GtkWidget* GtkIMContextWrapper::BuildInputMethodsGtkMenu() { | 320 GtkWidget* GtkIMContextWrapper::BuildInputMethodsGtkMenu() { |
| 323 GtkWidget* submenu = gtk_menu_new(); | 321 GtkWidget* submenu = gtk_menu_new(); |
| 324 gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(context_), | 322 gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(context_), |
| 325 GTK_MENU_SHELL(submenu)); | 323 GTK_MENU_SHELL(submenu)); |
| 326 return submenu; | 324 return submenu; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 } | 463 } |
| 466 | 464 |
| 467 void GtkIMContextWrapper::ConfirmComposition() { | 465 void GtkIMContextWrapper::ConfirmComposition() { |
| 468 if (!is_enabled_) | 466 if (!is_enabled_) |
| 469 return; | 467 return; |
| 470 | 468 |
| 471 DCHECK(!is_in_key_event_handler_); | 469 DCHECK(!is_in_key_event_handler_); |
| 472 | 470 |
| 473 if (is_composing_text_) { | 471 if (is_composing_text_) { |
| 474 if (host_view_->GetRenderWidgetHost()) | 472 if (host_view_->GetRenderWidgetHost()) |
| 475 static_cast<RenderWidgetHostImpl*>( | 473 host_view_->GetRenderWidgetHost()->AsRWHImpl()->ImeConfirmComposition(); |
| 476 host_view_->GetRenderWidgetHost())->ImeConfirmComposition(); | |
| 477 | 474 |
| 478 // Reset the input method. | 475 // Reset the input method. |
| 479 CancelComposition(); | 476 CancelComposition(); |
| 480 } | 477 } |
| 481 } | 478 } |
| 482 | 479 |
| 483 void GtkIMContextWrapper::HandleCommit(const string16& text) { | 480 void GtkIMContextWrapper::HandleCommit(const string16& text) { |
| 484 if (suppress_next_commit_) { | 481 if (suppress_next_commit_) { |
| 485 suppress_next_commit_ = false; | 482 suppress_next_commit_ = false; |
| 486 return; | 483 return; |
| 487 } | 484 } |
| 488 | 485 |
| 489 // Append the text to the buffer, because commit signal might be fired | 486 // Append the text to the buffer, because commit signal might be fired |
| 490 // multiple times when processing a key event. | 487 // multiple times when processing a key event. |
| 491 commit_text_.append(text); | 488 commit_text_.append(text); |
| 492 // Nothing needs to do, if it's currently in ProcessKeyEvent() | 489 // Nothing needs to do, if it's currently in ProcessKeyEvent() |
| 493 // handler, which will send commit text to webkit later. Otherwise, | 490 // handler, which will send commit text to webkit later. Otherwise, |
| 494 // we need send it here. | 491 // we need send it here. |
| 495 // It's possible that commit signal is fired without a key event, for | 492 // It's possible that commit signal is fired without a key event, for |
| 496 // example when user input via a voice or handwriting recognition software. | 493 // example when user input via a voice or handwriting recognition software. |
| 497 // In this case, the text must be committed directly. | 494 // In this case, the text must be committed directly. |
| 498 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) { | 495 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) { |
| 499 // Workaround http://crbug.com/45478 by sending fake key down/up events. | 496 // Workaround http://crbug.com/45478 by sending fake key down/up events. |
| 500 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); | 497 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); |
| 501 static_cast<RenderWidgetHostImpl*>( | 498 host_view_->GetRenderWidgetHost()->AsRWHImpl()->ImeConfirmComposition(text); |
| 502 host_view_->GetRenderWidgetHost())->ImeConfirmComposition(text); | |
| 503 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); | 499 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); |
| 504 } | 500 } |
| 505 } | 501 } |
| 506 | 502 |
| 507 void GtkIMContextWrapper::HandlePreeditStart() { | 503 void GtkIMContextWrapper::HandlePreeditStart() { |
| 508 // Ignore preedit related signals triggered by CancelComposition() method. | 504 // Ignore preedit related signals triggered by CancelComposition() method. |
| 509 if (suppress_next_commit_) | 505 if (suppress_next_commit_) |
| 510 return; | 506 return; |
| 511 is_composing_text_ = true; | 507 is_composing_text_ = true; |
| 512 } | 508 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 540 // Otherwise, we need send it here if it's been changed. | 536 // Otherwise, we need send it here if it's been changed. |
| 541 if (!is_in_key_event_handler_ && is_composing_text_ && | 537 if (!is_in_key_event_handler_ && is_composing_text_ && |
| 542 host_view_->GetRenderWidgetHost()) { | 538 host_view_->GetRenderWidgetHost()) { |
| 543 // Workaround http://crbug.com/45478 by sending fake key down/up events. | 539 // Workaround http://crbug.com/45478 by sending fake key down/up events. |
| 544 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); | 540 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::RawKeyDown); |
| 545 // TODO(suzhe): convert both renderer_host and renderer to use | 541 // TODO(suzhe): convert both renderer_host and renderer to use |
| 546 // ui::CompositionText. | 542 // ui::CompositionText. |
| 547 const std::vector<WebKit::WebCompositionUnderline>& underlines = | 543 const std::vector<WebKit::WebCompositionUnderline>& underlines = |
| 548 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>( | 544 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>( |
| 549 composition_.underlines); | 545 composition_.underlines); |
| 550 static_cast<RenderWidgetHostImpl*>( | 546 host_view_->GetRenderWidgetHost()->AsRWHImpl()->ImeSetComposition( |
| 551 host_view_->GetRenderWidgetHost())->ImeSetComposition( | |
| 552 composition_.text, underlines, composition_.selection.start(), | 547 composition_.text, underlines, composition_.selection.start(), |
| 553 composition_.selection.end()); | 548 composition_.selection.end()); |
| 554 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); | 549 SendFakeCompositionKeyEvent(WebKit::WebInputEvent::KeyUp); |
| 555 } | 550 } |
| 556 } | 551 } |
| 557 | 552 |
| 558 void GtkIMContextWrapper::HandlePreeditEnd() { | 553 void GtkIMContextWrapper::HandlePreeditEnd() { |
| 559 if (composition_.text.length()) { | 554 if (composition_.text.length()) { |
| 560 // The composition session has been finished. | 555 // The composition session has been finished. |
| 561 composition_.Clear(); | 556 composition_.Clear(); |
| 562 is_composition_changed_ = true; | 557 is_composition_changed_ = true; |
| 563 | 558 |
| 564 // If there is still a preedit text when firing "preedit-end" signal, | 559 // If there is still a preedit text when firing "preedit-end" signal, |
| 565 // we need inform webkit to clear it. | 560 // we need inform webkit to clear it. |
| 566 // It's only necessary when it's not in ProcessKeyEvent (). | 561 // It's only necessary when it's not in ProcessKeyEvent (). |
| 567 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) | 562 if (!is_in_key_event_handler_ && host_view_->GetRenderWidgetHost()) |
| 568 static_cast<RenderWidgetHostImpl*>( | 563 host_view_->GetRenderWidgetHost()->AsRWHImpl()->ImeCancelComposition(); |
| 569 host_view_->GetRenderWidgetHost())->ImeCancelComposition(); | |
| 570 } | 564 } |
| 571 | 565 |
| 572 // Don't set is_composing_text_ to false here, because "preedit_end" | 566 // Don't set is_composing_text_ to false here, because "preedit_end" |
| 573 // signal may be fired before "commit" signal. | 567 // signal may be fired before "commit" signal. |
| 574 } | 568 } |
| 575 | 569 |
| 576 gboolean GtkIMContextWrapper::HandleRetrieveSurrounding(GtkIMContext* context) { | 570 gboolean GtkIMContextWrapper::HandleRetrieveSurrounding(GtkIMContext* context) { |
| 577 if (!is_enabled_) | 571 if (!is_enabled_) |
| 578 return TRUE; | 572 return TRUE; |
| 579 | 573 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 | 643 |
| 650 void GtkIMContextWrapper::HandleHostViewRealizeThunk( | 644 void GtkIMContextWrapper::HandleHostViewRealizeThunk( |
| 651 GtkWidget* widget, GtkIMContextWrapper* self) { | 645 GtkWidget* widget, GtkIMContextWrapper* self) { |
| 652 self->HandleHostViewRealize(widget); | 646 self->HandleHostViewRealize(widget); |
| 653 } | 647 } |
| 654 | 648 |
| 655 void GtkIMContextWrapper::HandleHostViewUnrealizeThunk( | 649 void GtkIMContextWrapper::HandleHostViewUnrealizeThunk( |
| 656 GtkWidget* widget, GtkIMContextWrapper* self) { | 650 GtkWidget* widget, GtkIMContextWrapper* self) { |
| 657 self->HandleHostViewUnrealize(); | 651 self->HandleHostViewUnrealize(); |
| 658 } | 652 } |
| OLD | NEW |