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

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: Add some DCHECKs. 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 5f470c53d751aabe3a816fe52b23fd5d239ca542..4081a48401656e20d6b67f0785d91e497357fd69 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -504,6 +504,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());
+ }
+
if (opacity_ != 255)
SetOpacity(opacity_);
@@ -568,10 +576,13 @@ void WidgetGtk::Init(GtkWidget* parent,
// so we need to connect signal handlers to the gtk window.
// See views::Views::Focus and views::FocusManager::ClearNativeFocus
// for more details.
- g_signal_connect(widget_, "key_press_event",
- G_CALLBACK(&OnKeyEventThunk), this);
- g_signal_connect(widget_, "key_release_event",
- G_CALLBACK(&OnKeyEventThunk), this);
+ // Child Widget should never get keyboard focus.
+ if (type_ != TYPE_CHILD) {
+ g_signal_connect(widget_, "key_press_event",
+ G_CALLBACK(&OnKeyEventThunk), this);
+ g_signal_connect(widget_, "key_release_event",
+ G_CALLBACK(&OnKeyEventThunk), this);
+ }
oshima 2011/03/22 01:50:39 This may break screen locker. Can you verify?
James Su 2011/03/22 08:41:14 Hmm, according to the code, it'll break screen loc
// Drag and drop.
gtk_drag_dest_set(window_contents_, static_cast<GtkDestDefaults>(0),
@@ -752,6 +763,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 +870,7 @@ void WidgetGtk::Close() {
void WidgetGtk::CloseNow() {
if (widget_) {
+ input_method_.reset();
gtk_widget_destroy(widget_); // Triggers OnDestroy().
}
}
@@ -1181,44 +1205,17 @@ gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
}
gboolean WidgetGtk::OnKeyEvent(GtkWidget* widget, GdkEventKey* event) {
- KeyEvent key(reinterpret_cast<NativeEvent>(event));
-
- // 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);
+ // Only top-level Widget could be focused and receive keyboard events.
+ DCHECK(GTK_IS_WINDOW(widget_));
- // Dispatch the key event for bindings processing.
- if (!handled && GTK_IS_WINDOW(widget))
- handled = gtk_bindings_activate_event(GTK_OBJECT(widget), event);
+ KeyEvent key(reinterpret_cast<NativeEvent>(event));
+ if (input_method_.get())
+ input_method_->DispatchKeyEvent(key);
+ else
+ DispatchKeyEventPostIME(key);
- // 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,
@@ -1298,6 +1295,48 @@ gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() {
return GDK_WINDOW_XID(window_contents_->window);
}
+void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) {
+ // Only top-level Widget could be focused and receive keyboard events.
+ DCHECK(GTK_IS_WINDOW(widget_));
+
+ // 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);
+
+ GdkEventKey* event = reinterpret_cast<GdkEventKey*>(key.native_event());
+ if (key.key_code() == ui::VKEY_PROCESSKEY || handled || !event)
+ 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.
+ 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_))
+ 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