summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 21:39:07 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 21:39:07 +0000
commit406c913ffa55edfe40c707760ae4b64c4f37fe65 (patch)
tree68d4459f1de5c8794d05656f90c7b3349df1a331 /chrome/browser
parent1e1f5b25219fba0e0531fd1c118b0acb4ddf4e8f (diff)
downloadchromium_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.cc46
-rw-r--r--chrome/browser/gtk/browser_toolbar_view_gtk.h18
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc2
-rw-r--r--chrome/browser/gtk/tab_contents_container_gtk.h8
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc12
-rw-r--r--chrome/browser/tab_contents/web_contents_view_gtk.cc23
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) {