diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-02 21:39:07 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-02 21:39:07 +0000 |
commit | 406c913ffa55edfe40c707760ae4b64c4f37fe65 (patch) | |
tree | 68d4459f1de5c8794d05656f90c7b3349df1a331 /chrome/browser | |
parent | 1e1f5b25219fba0e0531fd1c118b0acb4ddf4e8f (diff) | |
download | chromium_src-406c913ffa55edfe40c707760ae4b64c4f37fe65.zip chromium_src-406c913ffa55edfe40c707760ae4b64c4f37fe65.tar.gz chromium_src-406c913ffa55edfe40c707760ae4b64c4f37fe65.tar.bz2 |
Enable focus-change via tabbing on Linux.
Review URL: http://codereview.chromium.org/28248
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10725 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_view_gtk.cc | 46 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_view_gtk.h | 18 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/tab_contents_container_gtk.h | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_gtk.cc | 12 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents_view_gtk.cc | 23 |
6 files changed, 90 insertions, 19 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_view_gtk.cc b/chrome/browser/gtk/browser_toolbar_view_gtk.cc index 98dbb8f..ffee692 100644 --- a/chrome/browser/gtk/browser_toolbar_view_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_view_gtk.cc @@ -84,6 +84,13 @@ void BrowserToolbarGtk::Init(Profile* profile) { gtk_widget_set_size_request(entry_, 0, 27); g_signal_connect(G_OBJECT(entry_), "activate", G_CALLBACK(OnEntryActivate), this); + g_signal_connect(G_OBJECT(entry_), "focus", + G_CALLBACK(OnEntryFocus), this); + g_signal_connect(G_OBJECT(entry_), "focus-in-event", + G_CALLBACK(OnEntryFocusIn), this); + g_signal_connect(G_OBJECT(entry_), "focus-out-event", + G_CALLBACK(OnEntryFocusOut), this); + gtk_box_pack_start(GTK_BOX(toolbar_), entry_, TRUE, TRUE, 0); go_.reset(BuildToolbarButton(IDR_GO, IDR_GO_P, IDR_GO_H, 0, L"")); @@ -103,6 +110,10 @@ void BrowserToolbarGtk::AddToolbarToBox(GtkWidget* box) { gtk_box_pack_start(GTK_BOX(box), toolbar_, FALSE, FALSE, 0); } +void BrowserToolbarGtk::FocusLocationBar() { + gtk_widget_grab_focus(entry_); +} + void BrowserToolbarGtk::EnabledStateChangedForCommand(int id, bool enabled) { GtkWidget* widget = NULL; switch (id) { @@ -188,6 +199,7 @@ CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton( WideToUTF8(localized_tooltip).c_str()); g_signal_connect(G_OBJECT(button->widget()), "clicked", G_CALLBACK(OnButtonClick), this); + GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0); return button; @@ -209,6 +221,7 @@ CustomContainerButton* BrowserToolbarGtk::BuildToolbarMenuButton( WideToUTF8(localized_tooltip).c_str()); g_signal_connect(G_OBJECT(button->widget()), "button-press-event", G_CALLBACK(OnMenuButtonPressEvent), this); + GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0); @@ -224,7 +237,37 @@ void BrowserToolbarGtk::OnEntryActivate(GtkEntry *entry, OpenURL(dest, GURL(), CURRENT_TAB, PageTransition::TYPED); } -/* static */ +// static +gboolean BrowserToolbarGtk::OnEntryFocus(GtkWidget* widget, + GtkDirectionType direction, + BrowserToolbarGtk* host) { + if (!GTK_WIDGET_HAS_FOCUS(widget)) { + gtk_widget_grab_focus(widget); + return TRUE; + } + + return FALSE; +} + +// static +gboolean BrowserToolbarGtk::OnEntryFocusIn(GtkWidget* widget, + GdkEventFocus* focus, + BrowserToolbarGtk* host) { + // Set the caret at the end of the text. + gtk_editable_set_position(GTK_EDITABLE(widget), -1); + return FALSE; +} + +// static +gboolean BrowserToolbarGtk::OnEntryFocusOut(GtkWidget* widget, + GdkEventFocus* focus, + BrowserToolbarGtk* host) { + // Clear the selected text (if any). + gtk_editable_set_position(GTK_EDITABLE(widget), 0); + return FALSE; +} + +// static void BrowserToolbarGtk::OnButtonClick(GtkWidget* button, BrowserToolbarGtk* toolbar) { int tag = -1; @@ -291,6 +334,7 @@ CustomDrawButton* BrowserToolbarGtk::BuildBackForwardButton( G_CALLBACK(OnBackForwardPressEvent), this); g_signal_connect(G_OBJECT(button->widget()), "clicked", G_CALLBACK(OnButtonClick), this); + GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0); // Popup the menu as left-aligned relative to this widget rather than the diff --git a/chrome/browser/gtk/browser_toolbar_view_gtk.h b/chrome/browser/gtk/browser_toolbar_view_gtk.h index 08a797c..63983022 100644 --- a/chrome/browser/gtk/browser_toolbar_view_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_view_gtk.h @@ -40,6 +40,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // Adds this GTK toolbar into a sizing box. void AddToolbarToBox(GtkWidget* box); + // Set focus on the entry box. + void FocusLocationBar(); + // Overridden from CommandUpdater::CommandObserver: virtual void EnabledStateChangedForCommand(int id, bool enabled); @@ -74,6 +77,21 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // enter. static void OnEntryActivate(GtkEntry *entry, BrowserToolbarGtk* toolbar); + // Gtk callback for the "focus" signal on the |entry_| widget. + static gboolean OnEntryFocus(GtkWidget* widget, + GtkDirectionType direction, + BrowserToolbarGtk* host); + + // Gtk callback for the "focus-in" signal on the |entry_| widget. + static gboolean OnEntryFocusIn(GtkWidget* widget, + GdkEventFocus* focus, + BrowserToolbarGtk* host); + + // Gtk callback for the "focus-out" signal on the |entry_| widget. + static gboolean OnEntryFocusOut(GtkWidget* widget, + GdkEventFocus* focus, + BrowserToolbarGtk* host); + // Gtk callback for the "clicked" signal. static void OnButtonClick(GtkWidget* button, BrowserToolbarGtk* toolbar); diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 4135c72..346990f 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -266,7 +266,7 @@ LocationBar* BrowserWindowGtk::GetLocationBar() const { } void BrowserWindowGtk::SetFocusToLocationBar() { - NOTIMPLEMENTED(); + toolbar_->FocusLocationBar(); } void BrowserWindowGtk::UpdateStopGoState(bool is_loading) { diff --git a/chrome/browser/gtk/tab_contents_container_gtk.h b/chrome/browser/gtk/tab_contents_container_gtk.h index 927f1f6..c8868b6 100644 --- a/chrome/browser/gtk/tab_contents_container_gtk.h +++ b/chrome/browser/gtk/tab_contents_container_gtk.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__ -#define CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__ +#ifndef CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H_ +#define CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H_ #include <gtk/gtk.h> @@ -53,7 +53,7 @@ class TabContentsContainerGtk : public NotificationObserver { // vbox_. GtkWidget* vbox_; - DISALLOW_EVIL_CONSTRUCTORS(TabContentsContainerGtk); + DISALLOW_COPY_AND_ASSIGN(TabContentsContainerGtk); }; -#endif // CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__ +#endif // CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H_ diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 23f3067..750cb48f 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -43,8 +43,6 @@ class RenderWidgetHostViewGtkWidget { G_CALLBACK(KeyPressReleaseEvent), host_view); g_signal_connect(widget, "key-release-event", G_CALLBACK(KeyPressReleaseEvent), host_view); - g_signal_connect(widget, "focus", - G_CALLBACK(Focus), host_view); g_signal_connect(widget, "focus-in-event", G_CALLBACK(FocusIn), host_view); g_signal_connect(widget, "focus-out-event", @@ -89,16 +87,6 @@ class RenderWidgetHostViewGtkWidget { return FALSE; } - static gboolean Focus(GtkWidget* widget, GtkDirectionType focus, - RenderWidgetHostViewGtk* host_view) { - // We override this so that pressing tab navigates within the web contents - // rather than tabbing out of it. However, we do want to be able to tab - // out of it at the appropriate points. TODO(port): study how this works - // on Windows and implement it. - NOTIMPLEMENTED(); - return TRUE; - } - static gboolean FocusIn(GtkWidget* widget, GdkEventFocus* focus, RenderWidgetHostViewGtk* host_view) { host_view->GetRenderWidgetHost()->Focus(); diff --git a/chrome/browser/tab_contents/web_contents_view_gtk.cc b/chrome/browser/tab_contents/web_contents_view_gtk.cc index e82b128..5b14c08 100644 --- a/chrome/browser/tab_contents/web_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/web_contents_view_gtk.cc @@ -10,10 +10,27 @@ #include "base/gfx/rect.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/browser/tab_contents/web_contents.h" namespace { +// Called when the content view gtk widget is tabbed to. We always return true +// and grab focus if we don't have it. The call to SetInitialFocus() forwards +// the tab to webkit. We leave focus via TakeFocus(). +// We cast the WebContents to a TabContents because SetInitialFocus is public +// in TabContents and protected in WebContents. +gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, + TabContents* tab_contents) { + if (GTK_WIDGET_HAS_FOCUS(widget)) + return TRUE; + + gtk_widget_grab_focus(widget); + bool reverse = focus == GTK_DIR_TAB_BACKWARD; + tab_contents->SetInitialFocus(reverse); + return TRUE; +} + // Callback used in WebContentsViewGtk::CreateViewForWidget(). void RemoveWidget(GtkWidget* widget, void* container) { gtk_container_remove(GTK_CONTAINER(container), widget); @@ -50,6 +67,8 @@ RenderWidgetHostView* WebContentsViewGtk::CreateViewForWidget( RenderWidgetHostViewGtk* view = new RenderWidgetHostViewGtk(render_widget_host); gtk_widget_show(view->native_view()); + g_signal_connect(view->native_view(), "focus", + G_CALLBACK(OnFocus), web_contents_); gtk_container_foreach(GTK_CONTAINER(vbox_), RemoveWidget, vbox_); gtk_box_pack_start(GTK_BOX(vbox_), view->native_view(), TRUE, TRUE, 0); return view; @@ -121,8 +140,10 @@ void WebContentsViewGtk::UpdateDragCursor(bool is_drop_target) { NOTIMPLEMENTED(); } +// This is called when we the renderer asks us to take focus back (i.e., it has +// iterated past the last focusable element on the page). void WebContentsViewGtk::TakeFocus(bool reverse) { - NOTIMPLEMENTED(); + web_contents_->delegate()->SetFocusToLocationBar(); } void WebContentsViewGtk::HandleKeyboardEvent(const WebKeyboardEvent& event) { |