summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-20 23:07:48 +0000
committersuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-20 23:07:48 +0000
commitccbb7b6ec086e614efa111ecb5e51cb0ef1730ed (patch)
tree8b460140e85bd82af24f8b6a8ddbe334098cd2ae /views
parent9d3fd748881fc6b4000efea6471b90aead6b5eb1 (diff)
downloadchromium_src-ccbb7b6ec086e614efa111ecb5e51cb0ef1730ed.zip
chromium_src-ccbb7b6ec086e614efa111ecb5e51cb0ef1730ed.tar.gz
chromium_src-ccbb7b6ec086e614efa111ecb5e51cb0ef1730ed.tar.bz2
[Linux Views]Handle focus traversing correctly.
This CL adds a wrapper window class on top of GtkWindow to intercept its move_focus method, so that we can handle focus traversing by ourselves. BUG=49204: Chrome/views toolbar "tab" accessibility broken. TEST=See bug report. Review URL: http://codereview.chromium.org/3013006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/menu/menu_controller.cc12
-rw-r--r--views/views.gyp2
-rw-r--r--views/widget/gtk_views_window.cc40
-rw-r--r--views/widget/gtk_views_window.h43
-rw-r--r--views/widget/widget_gtk.cc4
5 files changed, 98 insertions, 3 deletions
diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc
index 22540e3..3375a6e 100644
--- a/views/controls/menu/menu_controller.cc
+++ b/views/controls/menu/menu_controller.cc
@@ -813,10 +813,11 @@ bool MenuController::Dispatch(const MSG& msg) {
#else
bool MenuController::Dispatch(GdkEvent* event) {
- gtk_main_do_event(event);
- if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED)
+ if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) {
+ gtk_main_do_event(event);
return false;
+ }
switch (event->type) {
case GDK_KEY_PRESS: {
@@ -836,10 +837,17 @@ bool MenuController::Dispatch(GdkEvent* event) {
return true;
}
+ case GDK_KEY_RELEASE:
+ return true;
+
default:
break;
}
+ // We don not want Gtk to handle keyboard events, otherwise if they get
+ // handled by Gtk, unexpected behavior may occur. For example Tab key
+ // may cause unexpected focus traversing.
+ gtk_main_do_event(event);
return exit_type_ == EXIT_NONE;
}
#endif
diff --git a/views/views.gyp b/views/views.gyp
index 3ee4096..d332604 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -278,6 +278,8 @@
'widget/drop_target_win.h',
'widget/gtk_views_fixed.cc',
'widget/gtk_views_fixed.h',
+ 'widget/gtk_views_window.cc',
+ 'widget/gtk_views_window.h',
'widget/root_view.cc',
'widget/root_view.h',
'widget/root_view_gtk.cc',
diff --git a/views/widget/gtk_views_window.cc b/views/widget/gtk_views_window.cc
new file mode 100644
index 0000000..fb3657d
--- /dev/null
+++ b/views/widget/gtk_views_window.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 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 "views/widget/gtk_views_window.h"
+#include "views/focus/focus_manager.h"
+
+G_BEGIN_DECLS
+
+G_DEFINE_TYPE(GtkViewsWindow, gtk_views_window, GTK_TYPE_WINDOW)
+
+static void gtk_views_window_move_focus(GtkWindow *window,
+ GtkDirectionType dir) {
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeWindow(window);
+ if (focus_manager) {
+ // We only support tab traversing by tab keys, so just ignore all other
+ // cases silently.
+ if (dir == GTK_DIR_TAB_BACKWARD || dir == GTK_DIR_TAB_FORWARD)
+ focus_manager->AdvanceFocus(dir == GTK_DIR_TAB_BACKWARD);
+ } else if (GTK_WINDOW_CLASS(gtk_views_window_parent_class)->move_focus) {
+ GTK_WINDOW_CLASS(gtk_views_window_parent_class)->move_focus(window, dir);
+ }
+}
+
+static void gtk_views_window_class_init(
+ GtkViewsWindowClass* views_window_class) {
+ GtkWindowClass* window_class =
+ reinterpret_cast<GtkWindowClass*>(views_window_class);
+ window_class->move_focus = gtk_views_window_move_focus;
+}
+
+static void gtk_views_window_init(GtkViewsWindow* window) {
+}
+
+GtkWidget* gtk_views_window_new(GtkWindowType type) {
+ return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_WINDOW, "type", type, NULL));
+}
+
+G_END_DECLS
diff --git a/views/widget/gtk_views_window.h b/views/widget/gtk_views_window.h
new file mode 100644
index 0000000..0dd54be
--- /dev/null
+++ b/views/widget/gtk_views_window.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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.
+
+#ifndef VIEWS_WIDGET_GTK_VIEWS_WINDOW_H_
+#define VIEWS_WIDGET_GTK_VIEWS_WINDOW_H_
+
+#include <gtk/gtkwindow.h>
+
+// GtkViewsWindow is a subclass of GtkWindow that overrides its move_focus
+// method so that we can handle focus traversing by ourselves.
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_VIEWS_WINDOW (gtk_views_window_get_type ())
+#define GTK_VIEWS_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_WINDOW, GtkViewsWindow))
+#define GTK_VIEWS_WINDOW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_WINDOW, \
+ GtkViewsWindowClass))
+#define GTK_IS_VIEWS_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_WINDOW))
+#define GTK_IS_VIEWS_WINDOW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_WINDOW))
+#define GTK_VIEWS_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_WINDOW, GtkViewsWindow))
+
+typedef struct _GtkViewsWindow GtkViewsWindow;
+typedef struct _GtkViewsWindowClass GtkViewsWindowClass;
+
+struct _GtkViewsWindow {
+ GtkWindow window;
+};
+
+struct _GtkViewsWindowClass {
+ GtkWindowClass parent_class;
+};
+
+GtkWidget* gtk_views_window_new(GtkWindowType type);
+
+G_END_DECLS
+
+#endif // VIEWS_WIDGET_GTK_VIEWS_WINDOW_H
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index c9144d7..de4ad9a 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -22,6 +22,7 @@
#include "views/widget/default_theme_provider.h"
#include "views/widget/drop_target_gtk.h"
#include "views/widget/gtk_views_fixed.h"
+#include "views/widget/gtk_views_window.h"
#include "views/widget/root_view.h"
#include "views/widget/tooltip_manager_gtk.h"
#include "views/widget/widget_delegate.h"
@@ -1336,7 +1337,8 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
gdk_window_set_composited(widget_->window, true);
}
} else {
- widget_ = gtk_window_new(
+ // Use our own window class to override GtkWindow's move_focus method.
+ widget_ = gtk_views_window_new(
(type_ == TYPE_WINDOW || type_ == TYPE_DECORATED_WINDOW) ?
GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP);
gtk_widget_set_name(widget_, "views-gtkwidget-window");