summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tab_contents
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tab_contents')
-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
4 files changed, 63 insertions, 65 deletions
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_;