summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-14 20:20:35 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-14 20:20:35 +0000
commit2be2c01334383d74703dc88ecb67fae96a9124f9 (patch)
tree33b49e76db9830e974d235047ee940c0eecacdd4
parent9c1a794e4b6c9d3ffca49889958ff381ecb82e32 (diff)
downloadchromium_src-2be2c01334383d74703dc88ecb67fae96a9124f9.zip
chromium_src-2be2c01334383d74703dc88ecb67fae96a9124f9.tar.gz
chromium_src-2be2c01334383d74703dc88ecb67fae96a9124f9.tar.bz2
This CL makes the focus remembered across tab switches for Chrome Linux with toolkit views.
It also contains clean-ups and implementation of different minor focus related things. BUG=None TEST=Open several tabs. Focus the location bar for some tabs, the page for others. Make sure that when switching between tabs the focus is restored to the last focused place (location bar or page) for each tab. Also test that deactivating/reactivating the browser window still restores focus properly. Review URL: http://codereview.chromium.org/194041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26153 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view.h3
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.h5
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_mac.h1
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_mac.mm3
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc4
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h2
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc2
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.cc14
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.h2
-rw-r--r--chrome/browser/views/location_bar_view.cc7
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc68
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h4
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_view_gtk.cc53
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_view_gtk.h3
-rw-r--r--views/controls/native/native_view_host.cc4
-rw-r--r--views/controls/native/native_view_host.h2
-rw-r--r--views/controls/native/native_view_host_gtk.cc32
-rw-r--r--views/controls/native/native_view_host_gtk.h8
18 files changed, 138 insertions, 79 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view.h b/chrome/browser/autocomplete/autocomplete_edit_view.h
index 928d7e4..cba7342 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view.h
@@ -97,6 +97,9 @@ class AutocompleteEditView {
// Closes the autocomplete popup, if it's open.
virtual void ClosePopup() = 0;
+ // Sets the focus to the autocomplete view.
+ virtual void SetFocus() = 0;
+
// Called when the temporary text in the model may have changed.
// |display_text| is the new text to show; |save_original_selection| is true
// when there wasn't previously a temporary text and thus we need to save off
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h
index 2f51e88..64fd6a2 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h
@@ -60,9 +60,6 @@ class AutocompleteEditViewGtk : public AutocompleteEditView,
GtkWidget* widget() { return alignment_.get(); }
- // Grab keyboard input focus, putting focus on the location widget.
- void SetFocus();
-
// Returns the width, in pixels, needed to display the current text. The
// returned value includes margins and borders.
int TextWidth();
@@ -103,6 +100,8 @@ class AutocompleteEditViewGtk : public AutocompleteEditView,
virtual void UpdatePopup();
virtual void ClosePopup();
+ virtual void SetFocus();
+
virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
bool save_original_selection);
virtual bool OnInlineAutocompleteTextMaybeChanged(
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h
index f6179fb..45ce48b 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h
@@ -78,6 +78,7 @@ class AutocompleteEditViewMac : public AutocompleteEditView {
virtual void RevertAll();
virtual void UpdatePopup();
virtual void ClosePopup();
+ virtual void SetFocus();
virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
bool save_original_selection);
virtual bool OnInlineAutocompleteTextMaybeChanged(
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
index dc70cc1..00485f5 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
@@ -362,6 +362,9 @@ void AutocompleteEditViewMac::ClosePopup() {
popup_view_->GetModel()->StopAutocomplete();
}
+void AutocompleteEditViewMac::SetFocus() {
+}
+
void AutocompleteEditViewMac::SetText(const std::wstring& display_text) {
NSString* ss = base::SysWideToNSString(display_text);
NSMutableAttributedString* as =
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index 7a09dac..eb7ae14 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -706,6 +706,10 @@ void AutocompleteEditViewWin::ClosePopup() {
popup_view_->GetModel()->StopAutocomplete();
}
+void AutocompleteEditViewWin::SetFocus() {
+ ::SetFocus(m_hWnd);
+}
+
IAccessible* AutocompleteEditViewWin::GetIAccessible() {
if (!autocomplete_accessibility_) {
CComObject<AutocompleteAccessibility>* accessibility = NULL;
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
index 2f64f84..a66583f 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
@@ -110,6 +110,8 @@ class AutocompleteEditViewWin
virtual void UpdatePopup();
virtual void ClosePopup();
+ virtual void SetFocus();
+
virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
bool save_original_selection);
virtual bool OnInlineAutocompleteTextMaybeChanged(
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 adc109f..83c28b7 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -148,7 +148,7 @@ class RenderWidgetHostViewGtkWidget {
}
host_view->ShowCurrentCursor();
- host_view->GetRenderWidgetHost()->Focus();
+ host_view->GetRenderWidgetHost()->GotFocus();
// The only way to enable a GtkIMContext object is to call its focus in
// handler.
diff --git a/chrome/browser/views/frame/browser_frame_gtk.cc b/chrome/browser/views/frame/browser_frame_gtk.cc
index a2ce1db..7ca24f9 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.cc
+++ b/chrome/browser/views/frame/browser_frame_gtk.cc
@@ -81,3 +81,17 @@ views::RootView* BrowserFrameGtk::CreateRootView() {
root_view_ = new BrowserRootView(browser_view_, this);
return root_view_;
}
+
+gboolean BrowserFrameGtk::OnFocusIn(GtkWidget* widget,
+ GdkEventFocus* event) {
+ browser_view_->ActivationChanged(true);
+ return views::WindowGtk::OnFocusIn(widget, event);
+}
+
+gboolean BrowserFrameGtk::OnFocusOut(GtkWidget* widget,
+ GdkEventFocus* event) {
+ browser_view_->ActivationChanged(false);
+ return views::WindowGtk::OnFocusOut(widget, event);
+}
+
+
diff --git a/chrome/browser/views/frame/browser_frame_gtk.h b/chrome/browser/views/frame/browser_frame_gtk.h
index 78e9d53..1e1f308 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.h
+++ b/chrome/browser/views/frame/browser_frame_gtk.h
@@ -36,6 +36,8 @@ class BrowserFrameGtk : public BrowserFrame,
// Overridden from views::Widget.
virtual ThemeProvider* GetThemeProvider() const;
virtual ThemeProvider* GetDefaultThemeProvider() const;
+ virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event);
+ virtual gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* event);
protected:
// WidgetGtk overrides.
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index 0723d16..fb5ca9f 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -289,11 +289,8 @@ void LocationBarView::InvalidatePageActions() {
}
void LocationBarView::Focus() {
-#if defined(OS_WIN)
- ::SetFocus(location_entry_->m_hWnd);
-#else
- gtk_widget_grab_focus(location_entry_->widget());
-#endif
+ // Focus the location entry native view.
+ location_entry_->SetFocus();
}
void LocationBarView::SetProfile(Profile* profile) {
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
index 29a6ef2..6eb37c3 100644
--- a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
@@ -17,7 +17,8 @@
NativeTabContentsContainerGtk::NativeTabContentsContainerGtk(
TabContentsContainer* container)
- : container_(container) {
+ : container_(container),
+ focus_callback_id_(0) {
}
NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() {
@@ -27,48 +28,11 @@ NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() {
// NativeTabContentsContainerGtk, NativeTabContentsContainer overrides:
void NativeTabContentsContainerGtk::AttachContents(TabContents* contents) {
- // We need to register the tab contents window with the BrowserContainer so
- // that the BrowserContainer is the focused view when the focus is on the
- // TabContents window (for the TabContents case).
- set_focus_view(this);
-
Attach(contents->GetNativeView());
-
- // TODO(port): figure out focus interception
-#if defined(OS_WIN)
- HWND contents_hwnd = contents->GetContentNativeView();
- if (contents_hwnd)
- views::FocusManager::InstallFocusSubclass(contents_hwnd, this);
-#else
- NOTIMPLEMENTED();
-#endif
}
void NativeTabContentsContainerGtk::DetachContents(TabContents* contents) {
- // TODO(port): figure out focus interception
-#if defined(OS_WIN)
- // TODO(brettw) should this move to NativeViewHost::Detach which is called
- // below? It needs cleanup regardless.
- HWND container_hwnd = contents->GetNativeView();
-
- // Hide the contents before adjusting its parent to avoid a full desktop
- // flicker.
- ShowWindow(container_hwnd, SW_HIDE);
-
- // Reset the parent to NULL to ensure hidden tabs don't receive messages.
- ::SetParent(container_hwnd, NULL);
-
- // Unregister the tab contents window from the FocusManager.
- views::FocusManager::UninstallFocusSubclass(container_hwnd);
- HWND hwnd = contents->GetContentNativeView();
- if (hwnd) {
- // We may not have an HWND anymore, if the renderer crashed and we are
- // displaying the sad tab for example.
- views::FocusManager::UninstallFocusSubclass(hwnd);
- }
-#else
gtk_widget_hide(contents->GetNativeView());
-#endif
// Now detach the TabContents.
Detach();
@@ -81,31 +45,10 @@ void NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) {
void NativeTabContentsContainerGtk::RenderViewHostChanged(
RenderViewHost* old_host,
RenderViewHost* new_host) {
- // TODO(port): figure out focus interception
-#if defined(OS_WIN)
- if (old_host && old_host->view()) {
- views::FocusManager::UninstallFocusSubclass(
- old_host->view()->GetNativeView());
- }
-
- if (new_host && new_host->view()) {
- views::FocusManager::InstallFocusSubclass(
- new_host->view()->GetNativeView(), this);
- }
-
// If we are focused, we need to pass the focus to the new RenderViewHost.
- views::FocusManager* focus_manager = views::FocusManager::GetFocusManager(
- GetRootView()->GetWidget()->GetNativeView());
+ views::FocusManager* focus_manager = GetFocusManager();
if (focus_manager->GetFocusedView() == this)
Focus();
-#else
- // If we are focused, we need to pass the focus to the new RenderViewHost.
- // TODO: uncomment this once FocusManager has been ported.
- // views::FocusManager* focus_manager = views::FocusManager::GetFocusManager(
- // GetRootView()->GetWidget()->GetNativeView());
- // if (focus_manager->GetFocusedView() == this)
- // Focus();
-#endif
}
views::View* NativeTabContentsContainerGtk::GetView() {
@@ -114,14 +57,15 @@ views::View* NativeTabContentsContainerGtk::GetView() {
void NativeTabContentsContainerGtk::TabContentsFocused(
TabContents* tab_contents) {
-#if defined(OS_WIN)
+ // Called when the tab contents native view gets focused (typically through a
+ // user click). We make ourself the focused view, so the focus is restored
+ // properly when the browser window is deactivated/reactivated.
views::FocusManager* focus_manager = GetFocusManager();
if (!focus_manager) {
NOTREACHED();
return;
}
focus_manager->SetFocusedView(this);
-#endif
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h
index 0d4ed05..e30c11f 100644
--- a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_
#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_
+#include <gtk/gtk.h>
+
#include "chrome/browser/views/tab_contents/native_tab_contents_container.h"
#include "views/controls/native/native_view_host.h"
@@ -35,6 +37,8 @@ class NativeTabContentsContainerGtk : public NativeTabContentsContainer,
private:
TabContentsContainer* container_;
+ gulong focus_callback_id_;
+
DISALLOW_COPY_AND_ASSIGN(NativeTabContentsContainerGtk);
};
diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
index 8ca4d16..e39bfde 100644
--- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/views/sad_tab_view.h"
#include "chrome/browser/views/tab_contents/render_view_context_menu_win.h"
+#include "views/focus/view_storage.h"
#include "views/controls/native/native_view_host.h"
#include "views/widget/root_view.h"
@@ -97,9 +98,19 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
views::WidgetGtk(TYPE_CHILD),
ignore_next_char_event_(false) {
drag_source_.reset(new TabContentsDragSource(this));
+ last_focused_view_storage_id_ =
+ views::ViewStorage::GetSharedInstance()->CreateStorageID();
}
TabContentsViewGtk::~TabContentsViewGtk() {
+ // Make sure to remove any stored view we may still have in the ViewStorage.
+ //
+ // It is possible the view went away before us, so we only do this if the
+ // view is registered.
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+ if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
+ view_storage->RemoveView(last_focused_view_storage_id_);
+
// Just deleting the object doesn't destroy the GtkWidget. We need to do that
// manually, and synchronously, since subsequent signal handlers may expect
// to locate this object.
@@ -218,12 +229,48 @@ void TabContentsViewGtk::SetInitialFocus() {
}
void TabContentsViewGtk::StoreFocus() {
- NOTIMPLEMENTED();
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+
+ if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
+ view_storage->RemoveView(last_focused_view_storage_id_);
+
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeView(GetNativeView());
+ if (focus_manager) {
+ // |focus_manager| can be NULL if the tab has been detached but still
+ // exists.
+ views::View* focused_view = focus_manager->GetFocusedView();
+ if (focused_view)
+ view_storage->StoreView(last_focused_view_storage_id_, focused_view);
+ }
}
void TabContentsViewGtk::RestoreFocus() {
- NOTIMPLEMENTED();
- SetInitialFocus();
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+ views::View* last_focused_view =
+ view_storage->RetrieveView(last_focused_view_storage_id_);
+ if (!last_focused_view) {
+ SetInitialFocus();
+ } else {
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeView(GetNativeView());
+
+ // If you hit this DCHECK, please report it to Jay (jcampan).
+ DCHECK(focus_manager != NULL) << "No focus manager when restoring focus.";
+
+ if (last_focused_view->IsFocusable() && focus_manager &&
+ focus_manager->ContainsView(last_focused_view)) {
+ last_focused_view->RequestFocus();
+ } else {
+ // The focused view may not belong to the same window hierarchy (e.g.
+ // if the location bar was focused and the tab is dragged out), or it may
+ // no longer be focusable (e.g. if the location bar was focused and then
+ // we switched to fullscreen mode). In that case we default to the
+ // default focus.
+ SetInitialFocus();
+ }
+ view_storage->RemoveView(last_focused_view_storage_id_);
+ }
}
void TabContentsViewGtk::UpdateDragCursor(WebDragOperation operation) {
diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.h b/chrome/browser/views/tab_contents/tab_contents_view_gtk.h
index 71fbdf6..8788468 100644
--- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.h
@@ -81,6 +81,9 @@ class TabContentsViewGtk : public TabContentsView,
// Whether to ignore the next CHAR keyboard event.
bool ignore_next_char_event_;
+ // The id used in the ViewStorage to store the last focused view.
+ int last_focused_view_storage_id_;
+
// The context menu. Callbacks are asynchronous so we need to keep it around.
scoped_ptr<RenderViewContextMenuWin> context_menu_;
diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc
index e6637a9..9cbeaf7 100644
--- a/views/controls/native/native_view_host.cc
+++ b/views/controls/native/native_view_host.cc
@@ -33,6 +33,10 @@ NativeViewHost::~NativeViewHost() {
void NativeViewHost::Attach(gfx::NativeView native_view) {
DCHECK(!native_view_);
native_view_ = native_view;
+ // If set_focus_view() has not been invoked, this view is the one that should
+ // be seen as focused when the native view receives focus.
+ if (!focus_view_)
+ focus_view_ = this;
native_wrapper_->NativeViewAttached();
}
diff --git a/views/controls/native/native_view_host.h b/views/controls/native/native_view_host.h
index d34ccf9..679e176 100644
--- a/views/controls/native/native_view_host.h
+++ b/views/controls/native/native_view_host.h
@@ -71,12 +71,12 @@ class NativeViewHost : public View {
virtual void Layout();
virtual void Paint(gfx::Canvas* canvas);
virtual void VisibilityChanged(View* starting_from, bool is_visible);
+ virtual void Focus();
protected:
virtual void VisibleBoundsInRootChanged();
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
virtual std::string GetClassName() const;
- virtual void Focus();
private:
// The attached native view.
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc
index 5e91d18..306aa94 100644
--- a/views/controls/native/native_view_host_gtk.cc
+++ b/views/controls/native/native_view_host_gtk.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "views/controls/native/native_view_host.h"
+#include "views/focus/focus_manager.h"
#include "views/widget/widget_gtk.h"
namespace views {
@@ -19,6 +20,7 @@ NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host)
: host_(host),
installed_clip_(false),
destroy_signal_id_(0),
+ focus_signal_id_(0),
fixed_(NULL) {
CreateFixed(false);
}
@@ -44,6 +46,12 @@ void NativeViewHostGtk::NativeViewAttached() {
this);
}
+ if (!focus_signal_id_) {
+ focus_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()),
+ "focus-in-event",
+ G_CALLBACK(CallFocusIn), this);
+ }
+
// Always layout though.
host_->Layout();
@@ -61,8 +69,10 @@ void NativeViewHostGtk::NativeViewDetaching() {
destroy_signal_id_);
destroy_signal_id_ = 0;
- // TODO(port): focus.
- // FocusManager::UninstallFocusSubclass(native_view());
+ g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
+ focus_signal_id_);
+ focus_signal_id_ = 0;
+
installed_clip_ = false;
// Release ownership back to the caller.
@@ -154,7 +164,8 @@ void NativeViewHostGtk::HideWidget() {
}
void NativeViewHostGtk::SetFocus() {
- NOTIMPLEMENTED();
+ DCHECK(host_->native_view());
+ gtk_widget_grab_focus(host_->native_view());
}
////////////////////////////////////////////////////////////////////////////////
@@ -199,7 +210,20 @@ WidgetGtk* NativeViewHostGtk::GetHostWidget() const {
// static
void NativeViewHostGtk::CallDestroy(GtkObject* object,
NativeViewHostGtk* host) {
- return host->host_->NativeViewDestroyed();
+ host->host_->NativeViewDestroyed();
+}
+
+// static
+void NativeViewHostGtk::CallFocusIn(GtkWidget* widget,
+ GdkEventFocus* event,
+ NativeViewHostGtk* host) {
+ FocusManager* focus_manager =
+ FocusManager::GetFocusManagerForNativeView(widget);
+ if (!focus_manager) {
+ NOTREACHED();
+ return;
+ }
+ focus_manager->SetFocusedView(host->host_->focus_view());
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/native/native_view_host_gtk.h b/views/controls/native/native_view_host_gtk.h
index 70cf438..81a2a7a1 100644
--- a/views/controls/native/native_view_host_gtk.h
+++ b/views/controls/native/native_view_host_gtk.h
@@ -54,6 +54,11 @@ class NativeViewHostGtk : public NativeViewHostWrapper {
// Invoked from the 'destroy' signal.
static void CallDestroy(GtkObject* object, NativeViewHostGtk* host);
+ // Invoked from the 'focus-in-event' signal.
+ static void CallFocusIn(GtkWidget* widget,
+ GdkEventFocus* event,
+ NativeViewHostGtk* button);
+
// Our associated NativeViewHost.
NativeViewHost* host_;
@@ -68,6 +73,9 @@ class NativeViewHostGtk : public NativeViewHostWrapper {
// Signal handle id for 'destroy' signal.
gulong destroy_signal_id_;
+ // Signal handle id for 'focus-in-event' signal.
+ gulong focus_signal_id_;
+
// The GtkFixed that contains the attached gfx::NativeView (used for
// clipping).
GtkWidget* fixed_;