172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/view_ids.h"
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/interstitial_page.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/accessibility/accessible_view_state.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_manager.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeTabContentsContainerGtk, public:
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeTabContentsContainerGtk::NativeTabContentsContainerGtk(
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContentsContainer* container)
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : container_(container),
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_callback_id_(0) {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeTabContentsContainerGtk, NativeTabContentsContainer overrides:
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::AttachContents(TabContents* contents) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Attach(contents->GetNativeView());
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::DetachContents(TabContents* contents) {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_hide(contents->GetNativeView());
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now detach the TabContents.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Detach();
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_fast_resize(fast_resize);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::RenderViewHostChanged(
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHost* old_host,
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHost* new_host) {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we are focused, we need to pass the focus to the new RenderViewHost.
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager* focus_manager = GetFocusManager();
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (focus_manager->GetFocusedView() == this)
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    OnFocus();
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::View* NativeTabContentsContainerGtk::GetView() {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return this;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::TabContentsFocused(
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* tab_contents) {
61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if !defined(TOUCH_UI)
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called when the tab contents native view gets focused (typically through a
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // user click).  We make ourself the focused view, so the focus is restored
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // properly when the browser window is deactivated/reactivated.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager* focus_manager = GetFocusManager();
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!focus_manager) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager->SetFocusedView(this);
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#else
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // no native views in TOUCH_UI, so don't steal the focus
73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeTabContentsContainerGtk, views::View overrides:
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeTabContentsContainerGtk::SkipDefaultKeyEventProcessing(
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const views::KeyEvent& e) {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't look-up accelerators or tab-traverse if we are showing a non-crashed
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We'll first give the page a chance to process the key events.  If it does
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not process them, they'll be returned to us and we'll treat them as
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // accelerators then.
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return container_->tab_contents() &&
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         !container_->tab_contents()->is_crashed();
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::FocusTraversable* NativeTabContentsContainerGtk::GetFocusTraversable() {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeTabContentsContainerGtk::IsFocusable() const {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We need to be focusable when our contents is not a view hierarchy, as
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // clicking on the contents needs to focus us.
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return container_->tab_contents() != NULL;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NativeTabContentsContainerGtk::OnFocus() {
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (container_->tab_contents())
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    container_->tab_contents()->Focus();
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::RequestFocus() {
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is a hack to circumvent the fact that a view does not explicitly get
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a call to set the focus if it already has the focus. This causes a problem
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // with tabs such as the TabContents that instruct the RenderView that it got
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // focus when they actually get the focus. When switching from one TabContents
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // tab that has focus to another TabContents tab that had focus, since the
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // TabContentsContainerView already has focus, OnFocus() would not be called
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // and the RenderView would not get notified it got focused.
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // By clearing the focused view before-hand, we ensure OnFocus() will be
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // called.
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  views::FocusManager* focus_manager = GetFocusManager();
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (focus_manager)
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    focus_manager->SetFocusedView(NULL);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  View::RequestFocus();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeTabContentsContainerGtk::AboutToRequestFocusFromTabTraversal(
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool reverse) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!container_->tab_contents())
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Give an opportunity to the tab to reset its focus.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (container_->tab_contents()->interstitial_page()) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    container_->tab_contents()->interstitial_page()->FocusThroughTabTraversal(
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reverse);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  container_->tab_contents()->FocusThroughTabTraversal(reverse);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsContainerGtk::GetAccessibleState(
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui::AccessibleViewState* state) {
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->role = ui::AccessibilityTypes::ROLE_GROUPING;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeTabContentsContainer, public:
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContentsContainer* container) {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new NativeTabContentsContainerGtk(container);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
147