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

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: Rebase. 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
Index: views/widget/widget_gtk.cc
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 84f5f35d20333fdb35d433dbc6b17d65e7faf02d..c6ca8a38724e28595886f3b57b63cc8bf2f0997b 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -292,6 +292,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)
@@ -504,6 +507,14 @@ 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.
+ if (type_ != TYPE_CHILD) {
+ input_method_.reset(new InputMethodGtk(this));
+ input_method_->Init(GetWidget());
+ }
oshima 2011/03/24 22:58:47 Looks like we create InputMethodGtk for regular ch
James Su 2011/03/25 05:57:21 Yes. I'll disable this piece of code for ChromeOS.
+
if (opacity_ != 255)
SetOpacity(opacity_);
@@ -653,22 +664,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)
@@ -752,6 +762,18 @@ bool WidgetGtk::HasNativeCapture() 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();
@@ -847,6 +869,7 @@ void WidgetGtk::Close() {
void WidgetGtk::CloseNow() {
if (widget_) {
+ input_method_.reset();
gtk_widget_destroy(widget_); // Triggers OnDestroy().
}
}
@@ -1183,43 +1206,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,
@@ -1299,6 +1292,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.

Powered by Google App Engine
This is Rietveld 408576698