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

Unified Diff: ui/views/ime/input_method_gtk.cc

Issue 9728002: Removing deprecated GTK-Views code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/ime/input_method_gtk.h ('k') | ui/views/metrics_gtk.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/ime/input_method_gtk.cc
diff --git a/ui/views/ime/input_method_gtk.cc b/ui/views/ime/input_method_gtk.cc
deleted file mode 100644
index 8b8c97a78a4e11ad927cba54462ef38957803976..0000000000000000000000000000000000000000
--- a/ui/views/ime/input_method_gtk.cc
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/ime/input_method_gtk.h"
-
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <algorithm>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/string_util.h"
-#include "base/third_party/icu/icu_utf.h"
-#include "base/utf_string_conversions.h"
-#include "ui/base/gtk/event_synthesis_gtk.h"
-#include "ui/base/gtk/gtk_im_context_util.h"
-#include "ui/base/keycodes/keyboard_code_conversion_gtk.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/views/events/event.h"
-#include "ui/views/widget/widget.h"
-
-namespace views {
-
-InputMethodGtk::InputMethodGtk(internal::InputMethodDelegate* delegate)
- : context_(NULL),
- context_simple_(NULL),
- widget_realize_id_(0),
- widget_unrealize_id_(0),
- context_focused_(false),
- handling_key_event_(false),
- composing_text_(false),
- composition_changed_(false),
- suppress_next_result_(false) {
- set_delegate(delegate);
-}
-
-InputMethodGtk::~InputMethodGtk() {
- if (widget()) {
- GtkWidget* native_view = widget()->GetNativeView();
- if (native_view) {
- g_signal_handler_disconnect(native_view, widget_realize_id_);
- g_signal_handler_disconnect(native_view, widget_unrealize_id_);
- }
- }
- if (context_) {
- g_object_unref(context_);
- context_ = NULL;
- }
- if (context_simple_) {
- g_object_unref(context_simple_);
- context_simple_ = NULL;
- }
-}
-
-void InputMethodGtk::Init(Widget* widget) {
- DCHECK(GTK_IS_WIDGET(widget->GetNativeView()));
-
- widget_realize_id_ =
- g_signal_connect(widget->GetNativeView(), "realize",
- G_CALLBACK(OnWidgetRealizeThunk), this);
- widget_unrealize_id_ =
- g_signal_connect(widget->GetNativeView(), "unrealize",
- G_CALLBACK(OnWidgetUnrealizeThunk), this);
-
- context_ = gtk_im_multicontext_new();
- context_simple_ = gtk_im_context_simple_new();
-
- // context_ and context_simple_ share the same callback handlers.
- // All data come from them are treated equally.
- // context_ is for full input method support.
- // context_simple_ is for supporting dead/compose keys when input method is
- // disabled, eg. in password input box.
- g_signal_connect(context_, "commit",
- G_CALLBACK(OnCommitThunk), this);
- g_signal_connect(context_, "preedit_start",
- G_CALLBACK(OnPreeditStartThunk), this);
- g_signal_connect(context_, "preedit_end",
- G_CALLBACK(OnPreeditEndThunk), this);
- g_signal_connect(context_, "preedit_changed",
- G_CALLBACK(OnPreeditChangedThunk), this);
-
- g_signal_connect(context_simple_, "commit",
- G_CALLBACK(OnCommitThunk), this);
- g_signal_connect(context_simple_, "preedit_start",
- G_CALLBACK(OnPreeditStartThunk), this);
- g_signal_connect(context_simple_, "preedit_end",
- G_CALLBACK(OnPreeditEndThunk), this);
- g_signal_connect(context_simple_, "preedit_changed",
- G_CALLBACK(OnPreeditChangedThunk), this);
-
- // Set client window if the widget is already realized.
- OnWidgetRealize(widget->GetNativeView());
-
- InputMethodBase::Init(widget);
-}
-
-void InputMethodGtk::OnFocus() {
- DCHECK(!widget_focused());
- InputMethodBase::OnFocus();
- UpdateContextFocusState();
-}
-
-void InputMethodGtk::OnBlur() {
- DCHECK(widget_focused());
- ConfirmCompositionText();
- InputMethodBase::OnBlur();
- UpdateContextFocusState();
-}
-
-void InputMethodGtk::DispatchKeyEvent(const KeyEvent& key) {
- DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED);
- suppress_next_result_ = false;
-
- // We should bypass |context_| and |context_simple_| only if there is no
- // text input client focused. Otherwise, always send the key event to either
- // |context_| or |context_simple_| even if the text input type is
- // ui::TEXT_INPUT_TYPE_NONE, to make sure we can get correct character result.
- if (!GetTextInputClient()) {
- DispatchKeyEventPostIME(key);
- return;
- }
-
- handling_key_event_ = true;
- composition_changed_ = false;
- result_text_.clear();
-
- // If it's a fake key event, then we need to synthesize a GdkEventKey.
- GdkEvent* event = key.gdk_event() ? key.gdk_event() :
- SynthesizeGdkEventKey(key);
- gboolean filtered = gtk_im_context_filter_keypress(
- context_focused_ ? context_ : context_simple_, &event->key);
-
- handling_key_event_ = false;
-
- const View* old_focused_view = GetFocusedView();
- if (key.type() == ui::ET_KEY_PRESSED && filtered)
- ProcessFilteredKeyPressEvent(key);
-
- // Ensure no focus change from processing the key event.
- if (old_focused_view == GetFocusedView()) {
- if (HasInputMethodResult())
- ProcessInputMethodResult(key, filtered);
- // Ensure no focus change sending input method results to the focused View.
- if (old_focused_view == GetFocusedView()) {
- if (key.type() == ui::ET_KEY_PRESSED && !filtered)
- ProcessUnfilteredKeyPressEvent(key);
- else if (key.type() == ui::ET_KEY_RELEASED)
- DispatchKeyEventPostIME(key);
- }
- }
-
- // Free the synthesized event if there was no underlying native event.
- if (event != key.gdk_event())
- gdk_event_free(event);
-}
-
-void InputMethodGtk::OnTextInputTypeChanged(View* view) {
- if (IsViewFocused(view)) {
- DCHECK(!composing_text_);
- UpdateContextFocusState();
- }
- InputMethodBase::OnTextInputTypeChanged(view);
-}
-
-void InputMethodGtk::OnCaretBoundsChanged(View* view) {
- gfx::Rect rect;
- if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
- return;
-
- GdkRectangle gdk_rect = rect.ToGdkRectangle();
- gtk_im_context_set_cursor_location(context_, &gdk_rect);
-}
-
-void InputMethodGtk::CancelComposition(View* view) {
- if (IsViewFocused(view))
- ResetContext();
-}
-
-std::string InputMethodGtk::GetInputLocale() {
- // Not supported.
- return std::string("");
-}
-
-base::i18n::TextDirection InputMethodGtk::GetInputTextDirection() {
- // Not supported.
- return base::i18n::UNKNOWN_DIRECTION;
-}
-
-bool InputMethodGtk::IsActive() {
- // We always need to send keyboard events to either |context_| or
- // |context_simple_|, so just return true here.
- return true;
-}
-
-void InputMethodGtk::OnWillChangeFocus(View* focused_before, View* focused) {
- ConfirmCompositionText();
-}
-
-void InputMethodGtk::OnDidChangeFocus(View* focused_before, View* focused) {
- UpdateContextFocusState();
-
- // Force to update caret bounds, in case the View thinks that the caret
- // bounds has not changed.
- if (context_focused_)
- OnCaretBoundsChanged(GetFocusedView());
-}
-
-void InputMethodGtk::ConfirmCompositionText() {
- ui::TextInputClient* client = GetTextInputClient();
- if (client && client->HasCompositionText())
- client->ConfirmCompositionText();
-
- ResetContext();
-}
-
-void InputMethodGtk::ResetContext() {
- if (!GetTextInputClient())
- return;
-
- DCHECK(widget_focused());
- DCHECK(GetFocusedView());
- DCHECK(!handling_key_event_);
-
- // To prevent any text from being committed when resetting the |context_|;
- handling_key_event_ = true;
- suppress_next_result_ = true;
-
- gtk_im_context_reset(context_);
- gtk_im_context_reset(context_simple_);
-
- // Some input methods may not honour the reset call. Focusing out/in the
- // |context_| to make sure it gets reset correctly.
- if (context_focused_) {
- gtk_im_context_focus_out(context_);
- gtk_im_context_focus_in(context_);
- }
-
- composition_.Clear();
- result_text_.clear();
- handling_key_event_ = false;
- composing_text_ = false;
- composition_changed_ = false;
-}
-
-void InputMethodGtk::UpdateContextFocusState() {
- bool old_context_focused = context_focused_;
- // Use switch here in case we are going to add more text input types.
- switch (GetTextInputType()) {
- case ui::TEXT_INPUT_TYPE_NONE:
- case ui::TEXT_INPUT_TYPE_PASSWORD:
- context_focused_ = false;
- break;
- default:
- context_focused_ = true;
- break;
- }
-
- // We only focus in |context_| when the focus is in a normal textfield.
- if (old_context_focused && !context_focused_)
- gtk_im_context_focus_out(context_);
- else if (!old_context_focused && context_focused_)
- gtk_im_context_focus_in(context_);
-
- // |context_simple_| can be used in any textfield, including password box, and
- // even if the focused text input client's text input type is
- // ui::TEXT_INPUT_TYPE_NONE.
- if (GetTextInputClient())
- gtk_im_context_focus_in(context_simple_);
- else
- gtk_im_context_focus_out(context_simple_);
-}
-
-void InputMethodGtk::ProcessFilteredKeyPressEvent(const KeyEvent& key) {
- if (NeedInsertChar()) {
- DispatchKeyEventPostIME(key);
- } else {
- KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_PROCESSKEY, key.flags());
- DispatchKeyEventPostIME(key);
- }
-}
-
-void InputMethodGtk::ProcessUnfilteredKeyPressEvent(const KeyEvent& key) {
- const View* old_focused_view = GetFocusedView();
- DispatchKeyEventPostIME(key);
-
- // We shouldn't dispatch the character anymore if the key event caused focus
- // change.
- if (old_focused_view != GetFocusedView())
- return;
-
- // If a key event was not filtered by |context_| or |context_simple_|, then
- // it means the key event didn't generate any result text. For some cases,
- // the key event may still generate a valid character, eg. a control-key
- // event (ctrl-a, return, tab, etc.). We need to send the character to the
- // focused text input client by calling TextInputClient::InsertChar().
- char16 ch = key.GetCharacter();
- ui::TextInputClient* client = GetTextInputClient();
- if (ch && client)
- client->InsertChar(ch, key.flags());
-}
-
-void InputMethodGtk::ProcessInputMethodResult(const KeyEvent& key,
- bool filtered) {
- ui::TextInputClient* client = GetTextInputClient();
- DCHECK(client);
-
- if (result_text_.length()) {
- if (filtered && NeedInsertChar()) {
- for (string16::const_iterator i = result_text_.begin();
- i != result_text_.end(); ++i) {
- client->InsertChar(*i, key.flags());
- }
- } else {
- client->InsertText(result_text_);
- composing_text_ = false;
- }
- }
-
- if (composition_changed_ && !IsTextInputTypeNone()) {
- if (composition_.text.length()) {
- composing_text_ = true;
- client->SetCompositionText(composition_);
- } else if (result_text_.empty()) {
- client->ClearCompositionText();
- }
- }
-}
-
-bool InputMethodGtk::NeedInsertChar() const {
- return IsTextInputTypeNone() ||
- (!composing_text_ && result_text_.length() == 1);
-}
-
-bool InputMethodGtk::HasInputMethodResult() const {
- return result_text_.length() || composition_changed_;
-}
-
-void InputMethodGtk::SendFakeProcessKeyEvent(bool pressed) const {
- KeyEvent key(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
- ui::VKEY_PROCESSKEY, 0);
- DispatchKeyEventPostIME(key);
-}
-
-GdkEvent* InputMethodGtk::SynthesizeGdkEventKey(const KeyEvent& key) const {
- guint keyval =
- ui::GdkKeyCodeForWindowsKeyCode(key.key_code(), key.IsShiftDown());
- guint state = 0;
- state |= key.IsShiftDown() ? GDK_SHIFT_MASK : 0;
- state |= key.IsControlDown() ? GDK_CONTROL_MASK : 0;
- state |= key.IsAltDown() ? GDK_MOD1_MASK : 0;
- state |= key.IsCapsLockDown() ? GDK_LOCK_MASK : 0;
-
- DCHECK(widget()->GetNativeView()->window);
- return ui::SynthesizeKeyEvent(widget()->GetNativeView()->window,
- key.type() == ui::ET_KEY_PRESSED,
- keyval, state);
-}
-
-void InputMethodGtk::OnCommit(GtkIMContext* context, gchar* text) {
- if (suppress_next_result_) {
- suppress_next_result_ = false;
- return;
- }
-
- // We need to receive input method result even if the text input type is
- // ui::TEXT_INPUT_TYPE_NONE, to make sure we can always send correct
- // character for each key event to the focused text input client.
- if (!GetTextInputClient())
- return;
-
- string16 utf16_text(UTF8ToUTF16(text));
-
- // Append the text to the buffer, because commit signal might be fired
- // multiple times when processing a key event.
- result_text_.append(utf16_text);
-
- // If we are not handling key event, do not bother sending text result if the
- // focused text input client does not support text input.
- if (!handling_key_event_ && !IsTextInputTypeNone()) {
- SendFakeProcessKeyEvent(true);
- GetTextInputClient()->InsertText(utf16_text);
- SendFakeProcessKeyEvent(false);
- }
-}
-
-void InputMethodGtk::OnPreeditStart(GtkIMContext* context) {
- if (suppress_next_result_ || IsTextInputTypeNone())
- return;
-
- composing_text_ = true;
-}
-
-void InputMethodGtk::OnPreeditChanged(GtkIMContext* context) {
- if (suppress_next_result_ || IsTextInputTypeNone())
- return;
-
- gchar* text = NULL;
- PangoAttrList* attrs = NULL;
- gint cursor_position = 0;
- gtk_im_context_get_preedit_string(context, &text, &attrs, &cursor_position);
-
- ui::ExtractCompositionTextFromGtkPreedit(text, attrs, cursor_position,
- &composition_);
- composition_changed_ = true;
-
- g_free(text);
- pango_attr_list_unref(attrs);
-
- if (composition_.text.length())
- composing_text_ = true;
-
- if (!handling_key_event_ && !IsTextInputTypeNone()) {
- SendFakeProcessKeyEvent(true);
- GetTextInputClient()->SetCompositionText(composition_);
- SendFakeProcessKeyEvent(false);
- }
-}
-
-void InputMethodGtk::OnPreeditEnd(GtkIMContext* context) {
- if (composition_.text.empty() || IsTextInputTypeNone())
- return;
-
- composition_changed_ = true;
- composition_.Clear();
-
- if (!handling_key_event_) {
- ui::TextInputClient* client = GetTextInputClient();
- if (client && client->HasCompositionText())
- client->ClearCompositionText();
- }
-}
-
-void InputMethodGtk::OnWidgetRealize(GtkWidget* widget) {
- // We should only set im context's client window once, because when setting
- // client window, im context may destroy and recreate its internal states and
- // objects.
- if (widget->window) {
- gtk_im_context_set_client_window(context_, widget->window);
- gtk_im_context_set_client_window(context_simple_, widget->window);
- }
-}
-
-void InputMethodGtk::OnWidgetUnrealize(GtkWidget* widget) {
- gtk_im_context_set_client_window(context_, NULL);
- gtk_im_context_set_client_window(context_simple_, NULL);
-}
-
-} // namespace views
« no previous file with comments | « ui/views/ime/input_method_gtk.h ('k') | ui/views/metrics_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698