| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/views/tab_contents/native_tab_contents_container_win.h" | 5 #include "chrome/browser/views/tab_contents/native_tab_contents_container_win.h" |
| 6 | 6 |
| 7 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
| 8 #include "chrome/browser/tab_contents/interstitial_page.h" | 8 #include "chrome/browser/tab_contents/interstitial_page.h" |
| 9 #include "chrome/browser/tab_contents/tab_contents.h" | 9 #include "chrome/browser/tab_contents/tab_contents.h" |
| 10 #include "chrome/browser/views/tab_contents/tab_contents_container.h" | 10 #include "chrome/browser/views/tab_contents/tab_contents_container.h" |
| 11 #include "views/focus/focus_manager.h" | 11 #include "views/focus/focus_manager.h" |
| 12 #include "views/widget/root_view.h" | |
| 13 #include "views/widget/widget.h" | |
| 14 | 12 |
| 15 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
| 16 // NativeTabContentsContainerWin, public: | 14 // NativeTabContentsContainerWin, public: |
| 17 | 15 |
| 18 NativeTabContentsContainerWin::NativeTabContentsContainerWin( | 16 NativeTabContentsContainerWin::NativeTabContentsContainerWin( |
| 19 TabContentsContainer* container) | 17 TabContentsContainer* container) |
| 20 : container_(container) { | 18 : container_(container) { |
| 21 } | 19 } |
| 22 | 20 |
| 23 NativeTabContentsContainerWin::~NativeTabContentsContainerWin() { | 21 NativeTabContentsContainerWin::~NativeTabContentsContainerWin() { |
| 24 } | 22 } |
| 25 | 23 |
| 26 //////////////////////////////////////////////////////////////////////////////// | 24 //////////////////////////////////////////////////////////////////////////////// |
| 27 // NativeTabContentsContainerWin, NativeTabContentsContainer overrides: | 25 // NativeTabContentsContainerWin, NativeTabContentsContainer overrides: |
| 28 | 26 |
| 29 void NativeTabContentsContainerWin::AttachContents(TabContents* contents) { | 27 void NativeTabContentsContainerWin::AttachContents(TabContents* contents) { |
| 30 // We need to register the tab contents window with the BrowserContainer so | 28 // We need to register the tab contents window with the BrowserContainer so |
| 31 // that the BrowserContainer is the focused view when the focus is on the | 29 // that the BrowserContainer is the focused view when the focus is on the |
| 32 // TabContents window (for the TabContents case). | 30 // TabContents window (for the TabContents case). |
| 33 set_focus_view(this); | 31 set_focus_view(this); |
| 34 | 32 |
| 35 Attach(contents->GetNativeView()); | 33 Attach(contents->GetNativeView()); |
| 36 HWND contents_hwnd = contents->GetContentNativeView(); | |
| 37 if (contents_hwnd) | |
| 38 views::FocusManager::InstallFocusSubclass(contents_hwnd, this); | |
| 39 } | 34 } |
| 40 | 35 |
| 41 void NativeTabContentsContainerWin::DetachContents(TabContents* contents) { | 36 void NativeTabContentsContainerWin::DetachContents(TabContents* contents) { |
| 42 // TODO(brettw) should this move to NativeViewHost::Detach which is called bel
ow? | 37 // TODO(brettw) should this move to NativeViewHost::Detach which is called |
| 38 // below? |
| 43 // It needs cleanup regardless. | 39 // It needs cleanup regardless. |
| 44 HWND container_hwnd = contents->GetNativeView(); | 40 HWND container_hwnd = contents->GetNativeView(); |
| 45 if (container_hwnd) { | 41 if (container_hwnd) { |
| 46 // Hide the contents before adjusting its parent to avoid a full desktop | 42 // Hide the contents before adjusting its parent to avoid a full desktop |
| 47 // flicker. | 43 // flicker. |
| 48 ShowWindow(container_hwnd, SW_HIDE); | 44 ShowWindow(container_hwnd, SW_HIDE); |
| 49 | 45 |
| 50 // Reset the parent to NULL to ensure hidden tabs don't receive messages. | 46 // Reset the parent to NULL to ensure hidden tabs don't receive messages. |
| 51 ::SetParent(container_hwnd, NULL); | 47 ::SetParent(container_hwnd, NULL); |
| 52 | |
| 53 // Unregister the tab contents window from the FocusManager. | |
| 54 views::FocusManager::UninstallFocusSubclass(container_hwnd); | |
| 55 } | |
| 56 | |
| 57 HWND hwnd = contents->GetContentNativeView(); | |
| 58 if (hwnd) { | |
| 59 // We may not have an HWND anymore, if the renderer crashed and we are | |
| 60 // displaying the sad tab for example. | |
| 61 views::FocusManager::UninstallFocusSubclass(hwnd); | |
| 62 } | 48 } |
| 63 | 49 |
| 64 // Now detach the TabContents. | 50 // Now detach the TabContents. |
| 65 Detach(); | 51 Detach(); |
| 66 } | 52 } |
| 67 | 53 |
| 68 void NativeTabContentsContainerWin::SetFastResize(bool fast_resize) { | 54 void NativeTabContentsContainerWin::SetFastResize(bool fast_resize) { |
| 69 set_fast_resize(fast_resize); | 55 set_fast_resize(fast_resize); |
| 70 } | 56 } |
| 71 | 57 |
| 72 void NativeTabContentsContainerWin::RenderViewHostChanged( | 58 void NativeTabContentsContainerWin::RenderViewHostChanged( |
| 73 RenderViewHost* old_host, | 59 RenderViewHost* old_host, |
| 74 RenderViewHost* new_host) { | 60 RenderViewHost* new_host) { |
| 75 if (old_host && old_host->view()) { | |
| 76 views::FocusManager::UninstallFocusSubclass( | |
| 77 old_host->view()->GetNativeView()); | |
| 78 } | |
| 79 | |
| 80 if (new_host && new_host->view()) { | |
| 81 views::FocusManager::InstallFocusSubclass( | |
| 82 new_host->view()->GetNativeView(), this); | |
| 83 } | |
| 84 | |
| 85 // If we are focused, we need to pass the focus to the new RenderViewHost. | 61 // If we are focused, we need to pass the focus to the new RenderViewHost. |
| 86 views::FocusManager* focus_manager = views::FocusManager::GetFocusManager( | 62 if (GetFocusManager()->GetFocusedView() == this) |
| 87 GetRootView()->GetWidget()->GetNativeView()); | |
| 88 if (focus_manager->GetFocusedView() == this) | |
| 89 Focus(); | 63 Focus(); |
| 90 } | 64 } |
| 91 | 65 |
| 92 views::View* NativeTabContentsContainerWin::GetView() { | 66 views::View* NativeTabContentsContainerWin::GetView() { |
| 93 return this; | 67 return this; |
| 94 } | 68 } |
| 95 | 69 |
| 70 void NativeTabContentsContainerWin::TabContentsFocused( |
| 71 TabContents* tab_contents) { |
| 72 views::FocusManager* focus_manager = GetFocusManager(); |
| 73 if (!focus_manager) { |
| 74 NOTREACHED(); |
| 75 return; |
| 76 } |
| 77 focus_manager->SetFocusedView(this); |
| 78 } |
| 79 |
| 96 //////////////////////////////////////////////////////////////////////////////// | 80 //////////////////////////////////////////////////////////////////////////////// |
| 97 // NativeTabContentsContainerWin, views::View overrides: | 81 // NativeTabContentsContainerWin, views::View overrides: |
| 98 | 82 |
| 99 bool NativeTabContentsContainerWin::SkipDefaultKeyEventProcessing( | 83 bool NativeTabContentsContainerWin::SkipDefaultKeyEventProcessing( |
| 100 const views::KeyEvent& e) { | 84 const views::KeyEvent& e) { |
| 101 // Don't look-up accelerators or tab-traverse if we are showing a non-crashed | 85 // Don't look-up accelerators or tab-traversal if we are showing a non-crashed |
| 102 // TabContents. | 86 // TabContents. |
| 103 // We'll first give the page a chance to process the key events. If it does | 87 // We'll first give the page a chance to process the key events. If it does |
| 104 // not process them, they'll be returned to us and we'll treat them as | 88 // not process them, they'll be returned to us and we'll treat them as |
| 105 // accelerators then. | 89 // accelerators then. |
| 106 return container_->tab_contents() && | 90 return container_->tab_contents() && |
| 107 !container_->tab_contents()->is_crashed(); | 91 !container_->tab_contents()->is_crashed(); |
| 108 } | 92 } |
| 109 | 93 |
| 110 views::FocusTraversable* NativeTabContentsContainerWin::GetFocusTraversable() { | |
| 111 return NULL; | |
| 112 } | |
| 113 | |
| 114 bool NativeTabContentsContainerWin::IsFocusable() const { | 94 bool NativeTabContentsContainerWin::IsFocusable() const { |
| 115 // We need to be focusable when our contents is not a view hierarchy, as | 95 // We need to be focusable when our contents is not a view hierarchy, as |
| 116 // clicking on the contents needs to focus us. | 96 // clicking on the contents needs to focus us. |
| 117 return container_->tab_contents() != NULL; | 97 return container_->tab_contents() != NULL; |
| 118 } | 98 } |
| 119 | 99 |
| 120 void NativeTabContentsContainerWin::Focus() { | 100 void NativeTabContentsContainerWin::Focus() { |
| 121 if (container_->tab_contents()) { | 101 if (container_->tab_contents()) |
| 122 // Set the native focus on the actual content of the tab, that is the | 102 container_->tab_contents()->Focus(); |
| 123 // interstitial if one is showing. | |
| 124 if (container_->tab_contents()->interstitial_page()) { | |
| 125 container_->tab_contents()->interstitial_page()->Focus(); | |
| 126 return; | |
| 127 } | |
| 128 SetFocus(container_->tab_contents()->GetContentNativeView()); | |
| 129 } | |
| 130 } | 103 } |
| 131 | 104 |
| 132 void NativeTabContentsContainerWin::RequestFocus() { | 105 void NativeTabContentsContainerWin::RequestFocus() { |
| 133 // This is a hack to circumvent the fact that a view does not explicitly get | 106 // This is a hack to circumvent the fact that a the Focus() method is not |
| 134 // a call to set the focus if it already has the focus. This causes a problem | 107 // invoked when RequestFocus() is called on an already focused view. |
| 135 // with tabs such as the TabContents that instruct the RenderView that it got | 108 // The TabContentsContainer is the view focused when the TabContents has |
| 136 // focus when they actually get the focus. When switching from one TabContents | 109 // focus. When switching between from one tab that has focus to another tab |
| 137 // tab that has focus to another TabContents tab that had focus, since the | 110 // that should also have focus, RequestFocus() is invoked one the |
| 138 // TabContentsContainerView already has focus, Focus() would not be called and | 111 // TabContentsContainer. In order to make sure Focus() is invoked we need to |
| 139 // the RenderView would not get notified it got focused. | 112 // clear the focus before hands. |
| 140 // By clearing the focused view before-hand, we ensure Focus() will be called. | 113 GetFocusManager()->ClearFocus(); |
| 141 GetRootView()->FocusView(NULL); | |
| 142 View::RequestFocus(); | 114 View::RequestFocus(); |
| 143 } | 115 } |
| 144 | 116 |
| 145 void NativeTabContentsContainerWin::AboutToRequestFocusFromTabTraversal( | 117 void NativeTabContentsContainerWin::AboutToRequestFocusFromTabTraversal( |
| 146 bool reverse) { | 118 bool reverse) { |
| 147 if (!container_->tab_contents()) | |
| 148 return; | |
| 149 // Give an opportunity to the tab to reset its focus. | |
| 150 if (container_->tab_contents()->interstitial_page()) { | |
| 151 container_->tab_contents()->interstitial_page()-> | |
| 152 FocusThroughTabTraversal(reverse); | |
| 153 return; | |
| 154 } | |
| 155 container_->tab_contents()->FocusThroughTabTraversal(reverse); | 119 container_->tab_contents()->FocusThroughTabTraversal(reverse); |
| 156 } | 120 } |
| 157 | 121 |
| 158 bool NativeTabContentsContainerWin::GetAccessibleRole( | 122 bool NativeTabContentsContainerWin::GetAccessibleRole( |
| 159 AccessibilityTypes::Role* role) { | 123 AccessibilityTypes::Role* role) { |
| 160 DCHECK(role); | 124 DCHECK(role); |
| 161 | 125 |
| 162 *role = AccessibilityTypes::ROLE_GROUPING; | 126 *role = AccessibilityTypes::ROLE_GROUPING; |
| 163 return true; | 127 return true; |
| 164 } | 128 } |
| 165 | 129 |
| 166 //////////////////////////////////////////////////////////////////////////////// | 130 //////////////////////////////////////////////////////////////////////////////// |
| 167 // NativeTabContentsContainer, public: | 131 // NativeTabContentsContainer, public: |
| 168 | 132 |
| 169 // static | 133 // static |
| 170 NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( | 134 NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( |
| 171 TabContentsContainer* container) { | 135 TabContentsContainer* container) { |
| 172 return new NativeTabContentsContainerWin(container); | 136 return new NativeTabContentsContainerWin(container); |
| 173 } | 137 } |
| OLD | NEW |