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

Unified Diff: views/widget/widget_gtk.cc

Issue 6675005: Integrate the new input method API for Views into Chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Windows build. Created 9 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 | « views/widget/widget_gtk.h ('k') | views/widget/widget_win.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: views/widget/widget_gtk.cc
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 9f5354319156b6d878acd0392b87c17f8be69dae..00824f503892ad00c94a3b65f58fd2b11304cb44 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -25,6 +25,7 @@
#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/path.h"
#include "views/views_delegate.h"
+#include "views/controls/textfield/native_textfield_views.h"
#include "views/focus/view_storage.h"
#include "views/widget/drop_target_gtk.h"
#include "views/widget/gtk_views_fixed.h"
@@ -294,6 +295,9 @@ WidgetGtk::WidgetGtk(Type type)
}
WidgetGtk::~WidgetGtk() {
+ // We need to delete the input method before calling DestroyRootView(),
+ // because it'll set focus_manager_ to NULL.
+ input_method_.reset();
DestroyRootView();
DCHECK(delete_on_destroy_ || widget_ == NULL);
if (type_ != TYPE_CHILD)
@@ -516,6 +520,20 @@ void WidgetGtk::Init(GtkWidget* parent,
CreateGtkWidget(parent, bounds);
delegate_->OnNativeWidgetCreated();
+ // Creates input method for toplevel widget after calling
+ // delegate_->OnNativeWidgetCreated(), to make sure that focus manager is
+ // already created at this point.
+ // TODO(suzhe): Always enable input method when we start to use
+ // RenderWidgetHostViewViews in normal ChromeOS.
+#if !defined(TOUCH_UI)
+ if (type_ != TYPE_CHILD && NativeTextfieldViews::IsTextfieldViewsEnabled()) {
+#else
+ if (type_ != TYPE_CHILD) {
+#endif
+ input_method_.reset(new InputMethodGtk(this));
+ input_method_->Init(GetWidget());
+ }
+
if (opacity_ != 255)
SetOpacity(opacity_);
@@ -665,22 +683,21 @@ void WidgetGtk::ClearNativeFocus() {
gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL);
}
-bool WidgetGtk::HandleKeyboardEvent(GdkEventKey* event) {
+bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) {
if (!GetFocusManager())
return false;
- KeyEvent key(reinterpret_cast<NativeEvent>(event));
- int key_code = key.key_code();
+ const int key_code = key.key_code();
bool handled = false;
// Always reset |should_handle_menu_key_release_| unless we are handling a
// VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
// be activated when handling a VKEY_MENU key release event which is preceded
// by an un-handled VKEY_MENU key press event.
- if (key_code != ui::VKEY_MENU || event->type != GDK_KEY_RELEASE)
+ if (key_code != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED)
should_handle_menu_key_release_ = false;
- if (event->type == GDK_KEY_PRESS) {
+ if (key.type() == ui::ET_KEY_PRESSED) {
// VKEY_MENU is triggered by key release event.
// FocusManager::OnKeyEvent() returns false when the key has been consumed.
if (key_code != ui::VKEY_MENU)
@@ -768,6 +785,18 @@ bool WidgetGtk::HasMouseCapture() const {
return GTK_WIDGET_HAS_GRAB(window_contents_);
}
+InputMethod* WidgetGtk::GetInputMethodNative() {
+ return input_method_.get();
+}
+
+void WidgetGtk::ReplaceInputMethod(InputMethod* input_method) {
+ input_method_.reset(input_method);
+ if (input_method) {
+ input_method->set_delegate(this);
+ input_method->Init(GetWidget());
+ }
+}
+
gfx::Rect WidgetGtk::GetWindowScreenBounds() const {
// Client == Window bounds on Gtk.
return GetClientAreaScreenBounds();
@@ -858,6 +887,7 @@ void WidgetGtk::Close() {
void WidgetGtk::CloseNow() {
if (widget_) {
+ input_method_.reset();
gtk_widget_destroy(widget_); // Triggers OnDestroy().
}
}
@@ -1195,6 +1225,10 @@ gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
if (type_ == TYPE_CHILD)
return false;
+ // Only top-level Widget should have an InputMethod instance.
+ if (input_method_.get())
+ input_method_->OnFocus();
+
// See description of got_initial_focus_in_ for details on this.
if (!got_initial_focus_in_) {
got_initial_focus_in_ = true;
@@ -1213,6 +1247,10 @@ gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
if (type_ == TYPE_CHILD)
return false;
+ // Only top-level Widget should have an InputMethod instance.
+ if (input_method_.get())
+ input_method_->OnBlur();
+
// The top-level window lost focus, store the focused view.
GetFocusManager()->StoreFocusedView();
return false;
@@ -1220,43 +1258,13 @@ gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
gboolean WidgetGtk::OnKeyEvent(GtkWidget* widget, GdkEventKey* event) {
KeyEvent key(reinterpret_cast<NativeEvent>(event));
+ if (input_method_.get())
+ input_method_->DispatchKeyEvent(key);
+ else
+ DispatchKeyEventPostIME(key);
- // Always reset |should_handle_menu_key_release_| unless we are handling a
- // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
- // be activated when handling a VKEY_MENU key release event which is preceded
- // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent().
- if (key.key_code() != ui::VKEY_MENU || event->type != GDK_KEY_RELEASE)
- should_handle_menu_key_release_ = false;
-
- bool handled = false;
-
- // Dispatch the key event to View hierarchy first.
- handled = GetRootView()->ProcessKeyEvent(key);
-
- // Dispatch the key event to native GtkWidget hierarchy.
- // To prevent GtkWindow from handling the key event as a keybinding, we need
- // to bypass GtkWindow's default key event handler and dispatch the event
- // here.
- if (!handled && GTK_IS_WINDOW(widget))
- handled = gtk_window_propagate_key_event(GTK_WINDOW(widget), event);
-
- // On Linux, in order to handle VKEY_MENU (Alt) accelerator key correctly and
- // avoid issues like: http://crbug.com/40966 and http://crbug.com/49701, we
- // should only send the key event to the focus manager if it's not handled by
- // any View or native GtkWidget.
- // The flow is different when the focus is in a RenderWidgetHostViewGtk, which
- // always consumes the key event and send it back to us later by calling
- // HandleKeyboardEvent() directly, if it's not handled by webkit.
- if (!handled)
- handled = HandleKeyboardEvent(event);
-
- // Dispatch the key event for bindings processing.
- if (!handled && GTK_IS_WINDOW(widget))
- handled = gtk_bindings_activate_event(GTK_OBJECT(widget), event);
-
- // Always return true for toplevel window to prevents GtkWindow's default key
- // event handler.
- return GTK_IS_WINDOW(widget) ? true : handled;
+ // Returns true to prevent GtkWindow's default key event handler.
+ return true;
}
gboolean WidgetGtk::OnQueryTooltip(GtkWidget* widget,
@@ -1334,6 +1342,45 @@ gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() {
return GDK_WINDOW_XID(window_contents_->window);
}
+void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) {
+ // Always reset |should_handle_menu_key_release_| unless we are handling a
+ // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
+ // be activated when handling a VKEY_MENU key release event which is preceded
+ // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent().
+ if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED)
+ should_handle_menu_key_release_ = false;
+
+ bool handled = false;
+
+ // Dispatch the key event to View hierarchy first.
+ handled = GetRootView()->ProcessKeyEvent(key);
+
+ if (key.key_code() == ui::VKEY_PROCESSKEY || handled)
+ return;
+
+ // Dispatch the key event to native GtkWidget hierarchy.
+ // To prevent GtkWindow from handling the key event as a keybinding, we need
+ // to bypass GtkWindow's default key event handler and dispatch the event
+ // here.
+ GdkEventKey* event = reinterpret_cast<GdkEventKey*>(key.native_event());
+ if (!handled && event && GTK_IS_WINDOW(widget_))
+ handled = gtk_window_propagate_key_event(GTK_WINDOW(widget_), event);
+
+ // On Linux, in order to handle VKEY_MENU (Alt) accelerator key correctly and
+ // avoid issues like: http://crbug.com/40966 and http://crbug.com/49701, we
+ // should only send the key event to the focus manager if it's not handled by
+ // any View or native GtkWidget.
+ // The flow is different when the focus is in a RenderWidgetHostViewGtk, which
+ // always consumes the key event and send it back to us later by calling
+ // HandleKeyboardEvent() directly, if it's not handled by webkit.
+ if (!handled)
+ handled = HandleKeyboardEvent(key);
+
+ // Dispatch the key event for bindings processing.
+ if (!handled && event && GTK_IS_WINDOW(widget_))
+ gtk_bindings_activate_event(GTK_OBJECT(widget_), event);
+}
+
gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
// Clear the background to be totally transparent. We don't need to
// paint the root view here as that is done by OnPaint.
« no previous file with comments | « views/widget/widget_gtk.h ('k') | views/widget/widget_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698