diff options
author | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 23:07:48 +0000 |
---|---|---|
committer | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 23:07:48 +0000 |
commit | ccbb7b6ec086e614efa111ecb5e51cb0ef1730ed (patch) | |
tree | 8b460140e85bd82af24f8b6a8ddbe334098cd2ae /views | |
parent | 9d3fd748881fc6b4000efea6471b90aead6b5eb1 (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | views/views.gyp | 2 | ||||
-rw-r--r-- | views/widget/gtk_views_window.cc | 40 | ||||
-rw-r--r-- | views/widget/gtk_views_window.h | 43 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 4 |
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"); |