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 |