OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/external_tab_container.h" | 5 #include "chrome/browser/external_tab_container.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/win_util.h" | 8 #include "base/win_util.h" |
9 #include "chrome/browser/automation/automation_provider.h" | 9 #include "chrome/browser/automation/automation_provider.h" |
10 #include "chrome/browser/profile.h" | 10 #include "chrome/browser/profile.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 } | 67 } |
68 tab_contents_->SetupController(profile); | 68 tab_contents_->SetupController(profile); |
69 tab_contents_->set_delegate(this); | 69 tab_contents_->set_delegate(this); |
70 | 70 |
71 WebContents* web_conents = tab_contents_->AsWebContents(); | 71 WebContents* web_conents = tab_contents_->AsWebContents(); |
72 if (web_conents) | 72 if (web_conents) |
73 web_conents->render_view_host()->AllowExternalHostBindings(); | 73 web_conents->render_view_host()->AllowExternalHostBindings(); |
74 | 74 |
75 // Create a TabContentsContainerView to handle focus cycling using Tab and | 75 // Create a TabContentsContainerView to handle focus cycling using Tab and |
76 // Shift-Tab. | 76 // Shift-Tab. |
| 77 // TODO(sanjeevr): We need to create a dummy FocusTraversable object to |
| 78 // represent the frame of the external host. This will allow Tab and |
| 79 // Shift-Tab to cycle into the external frame. |
77 tab_contents_container_ = new TabContentsContainerView(); | 80 tab_contents_container_ = new TabContentsContainerView(); |
78 root_view_.AddChildView(tab_contents_container_); | 81 root_view_.AddChildView(tab_contents_container_); |
79 // Note that SetTabContents must be called after AddChildView is called | |
80 tab_contents_container_->SetTabContents(tab_contents_); | 82 tab_contents_container_->SetTabContents(tab_contents_); |
81 // Add a dummy view to catch when the user tabs out of the tab | |
82 // Create a dummy FocusTraversable object to represent the frame of the | |
83 // external host. This will allow Tab and Shift-Tab to cycle into the | |
84 // external frame. When the tab_contents_container_ loses focus, | |
85 // the focus will be moved to this class (See OnSetFocus in this file). | |
86 // An alternative to using views::View and catching when the focus manager | |
87 // shifts the focus to the dummy view could be to implement our own view | |
88 // and handle AboutToRequestFocusFromTabTraversal. | |
89 views::View* dummy = new views::View(); | |
90 dummy->SetFocusable(true); | |
91 DCHECK(dummy->IsFocusable()); | |
92 root_view_.AddChildView(dummy); | |
93 | 83 |
94 NavigationController* controller = tab_contents_->controller(); | 84 NavigationController* controller = tab_contents_->controller(); |
95 DCHECK(controller); | 85 DCHECK(controller); |
96 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, | 86 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, |
97 Source<NavigationController>(controller)); | 87 Source<NavigationController>(controller)); |
98 NotificationService::current()->Notify( | 88 NotificationService::current()->Notify( |
99 NotificationType::EXTERNAL_TAB_CREATED, | 89 NotificationType::EXTERNAL_TAB_CREATED, |
100 Source<NavigationController>(controller), | 90 Source<NavigationController>(controller), |
101 NotificationService::NoDetails()); | 91 NotificationService::NoDetails()); |
102 | 92 |
103 // Now apply the parenting and style | 93 // Now apply the parenting and style |
104 if (parent) | 94 if (parent) |
105 SetParent(parent); | 95 SetParent(parent); |
106 | 96 |
107 // We need WS_POPUP to be on the window during initialization, but | 97 // We need WS_POPUP to be on the window during initialization, but |
108 // once initialized and parent-ed, we apply the requested style which | 98 // once initialized and parent-ed, we apply the requested style which |
109 // may or may not include the popup bit. | 99 // may or may not include the popup bit. |
110 ModifyStyle(WS_POPUP, style, 0); | 100 ModifyStyle(WS_POPUP, style, 0); |
111 | 101 |
112 ::ShowWindow(tab_contents_->GetContainerHWND(), SW_SHOW); | 102 ::ShowWindow(tab_contents_->GetContainerHWND(), SW_SHOW); |
113 return true; | 103 return true; |
114 } | 104 } |
115 | 105 |
116 void ExternalTabContainer::OnDestroy() { | 106 void ExternalTabContainer::OnDestroy() { |
117 views::FocusManager* focus_manager = | 107 views::FocusManager * focus_manager = |
118 views::FocusManager::GetFocusManager(GetHWND()); | 108 views::FocusManager::GetFocusManager(GetHWND()); |
119 if (focus_manager) { | 109 if (focus_manager) { |
120 focus_manager->RemoveKeystrokeListener(this); | 110 focus_manager->RemoveKeystrokeListener(this); |
121 } | 111 } |
122 root_view_.RemoveAllChildViews(true); | 112 root_view_.RemoveAllChildViews(true); |
123 if (tab_contents_) { | 113 if (tab_contents_) { |
124 NavigationController* controller = tab_contents_->controller(); | 114 NavigationController* controller = tab_contents_->controller(); |
125 DCHECK(controller); | 115 DCHECK(controller); |
126 | 116 |
127 NotificationService::current()->Notify( | 117 NotificationService::current()->Notify( |
(...skipping 15 matching lines...) Expand all Loading... |
143 if (tab_contents_) { | 133 if (tab_contents_) { |
144 RECT client_rect = {0}; | 134 RECT client_rect = {0}; |
145 GetClientRect(&client_rect); | 135 GetClientRect(&client_rect); |
146 ::SetWindowPos(tab_contents_->GetContainerHWND(), NULL, client_rect.left, | 136 ::SetWindowPos(tab_contents_->GetContainerHWND(), NULL, client_rect.left, |
147 client_rect.top, client_rect.right - client_rect.left, | 137 client_rect.top, client_rect.right - client_rect.left, |
148 client_rect.bottom - client_rect.top, SWP_NOZORDER); | 138 client_rect.bottom - client_rect.top, SWP_NOZORDER); |
149 } | 139 } |
150 return 0; | 140 return 0; |
151 } | 141 } |
152 | 142 |
153 LRESULT ExternalTabContainer::OnSetFocus(UINT msg, WPARAM wp, LPARAM lp, | 143 // TODO(sanjeevr): The implementation of the TabContentsDelegate interface |
154 BOOL& handled) { | 144 // needs to be fully fleshed out based on the requirements of the |
155 if (automation_) { | 145 // "Chrome tab in external browser" feature. |
156 views::FocusManager* focus_manager = | |
157 views::FocusManager::GetFocusManager(GetHWND()); | |
158 DCHECK(focus_manager); | |
159 if (focus_manager) { | |
160 focus_manager->ClearFocus(); | |
161 automation_->Send(new AutomationMsg_TabbedOut(win_util::IsShiftPressed(), | |
162 false)); | |
163 } | |
164 } | |
165 | |
166 return 0; | |
167 } | |
168 | 146 |
169 void ExternalTabContainer::OpenURLFromTab(TabContents* source, | 147 void ExternalTabContainer::OpenURLFromTab(TabContents* source, |
170 const GURL& url, | 148 const GURL& url, |
171 const GURL& referrer, | 149 const GURL& referrer, |
172 WindowOpenDisposition disposition, | 150 WindowOpenDisposition disposition, |
173 PageTransition::Type transition) { | 151 PageTransition::Type transition) { |
174 switch (disposition) { | 152 switch (disposition) { |
175 case CURRENT_TAB: | 153 case CURRENT_TAB: |
176 case NEW_FOREGROUND_TAB: | 154 case NEW_FOREGROUND_TAB: |
177 case NEW_BACKGROUND_TAB: | 155 case NEW_BACKGROUND_TAB: |
178 case NEW_WINDOW: | 156 case NEW_WINDOW: |
179 if (automation_) { | 157 if (automation_) { |
180 automation_->Send(new AutomationMsg_OpenURL(0, url, disposition)); | 158 automation_->Send(new AutomationMsg_OpenURL(0, url, disposition)); |
181 } | 159 } |
182 break; | 160 break; |
183 default: | 161 default: |
184 break; | 162 break; |
185 } | 163 } |
186 } | 164 } |
187 | 165 |
188 void ExternalTabContainer::NavigationStateChanged(const TabContents* source, | 166 void ExternalTabContainer::NavigationStateChanged(const TabContents* source, |
189 unsigned changed_flags) { | 167 unsigned changed_flags) { |
190 if (automation_) { | 168 if (automation_) { |
191 automation_->Send( | 169 automation_->Send( |
192 new AutomationMsg_NavigationStateChanged(0, changed_flags)); | 170 new AutomationMsg_NavigationStateChanged(0,changed_flags)); |
193 } | 171 } |
194 } | 172 } |
195 | 173 |
196 void ExternalTabContainer::ReplaceContents(TabContents* source, TabContents* new
_contents) { | 174 void ExternalTabContainer::ReplaceContents(TabContents* source, TabContents* new
_contents) { |
197 } | 175 } |
198 | 176 |
199 void ExternalTabContainer::AddNewContents(TabContents* source, | 177 void ExternalTabContainer::AddNewContents(TabContents* source, |
200 TabContents* new_contents, | 178 TabContents* new_contents, |
201 WindowOpenDisposition disposition, | 179 WindowOpenDisposition disposition, |
202 const gfx::Rect& initial_pos, | 180 const gfx::Rect& initial_pos, |
203 bool user_gesture) { | 181 bool user_gesture) { |
204 } | 182 } |
205 | 183 |
206 void ExternalTabContainer::ActivateContents(TabContents* contents) { | 184 void ExternalTabContainer::ActivateContents(TabContents* contents) { |
207 } | 185 } |
208 | 186 |
209 void ExternalTabContainer::LoadingStateChanged(TabContents* source) { | 187 void ExternalTabContainer::LoadingStateChanged(TabContents* source) { |
210 } | 188 } |
211 | 189 |
212 void ExternalTabContainer::CloseContents(TabContents* source) { | 190 void ExternalTabContainer::CloseContents(TabContents* source) { |
213 } | 191 } |
214 | 192 |
215 void ExternalTabContainer::MoveContents(TabContents* source, | 193 void ExternalTabContainer::MoveContents(TabContents* source, const gfx::Rect& po
s) { |
216 const gfx::Rect& pos) { | |
217 } | 194 } |
218 | 195 |
219 bool ExternalTabContainer::IsPopup(TabContents* source) { | 196 bool ExternalTabContainer::IsPopup(TabContents* source) { |
220 return false; | 197 return false; |
221 } | 198 } |
222 | 199 |
223 void ExternalTabContainer::URLStarredChanged(TabContents* source, | 200 void ExternalTabContainer::URLStarredChanged(TabContents* source, bool starred)
{ |
224 bool starred) { | |
225 } | 201 } |
226 | 202 |
227 void ExternalTabContainer::UpdateTargetURL(TabContents* source, | 203 void ExternalTabContainer::UpdateTargetURL(TabContents* source, |
228 const GURL& url) { | 204 const GURL& url) { |
229 if (automation_) { | 205 if (automation_) { |
230 std::wstring url_string = CA2W(url.spec().c_str()); | 206 std::wstring url_string = CA2W(url.spec().c_str()); |
231 automation_->Send( | 207 automation_->Send( |
232 new AutomationMsg_UpdateTargetUrl(0, url_string)); | 208 new AutomationMsg_UpdateTargetUrl(0, url_string)); |
233 } | 209 } |
234 } | 210 } |
235 | 211 |
236 void ExternalTabContainer::ContentsZoomChange(bool zoom_in) { | 212 void ExternalTabContainer::ContentsZoomChange(bool zoom_in) { |
237 } | 213 } |
238 | 214 |
239 void ExternalTabContainer::ToolbarSizeChanged(TabContents* source, | 215 void ExternalTabContainer::ToolbarSizeChanged(TabContents* source, |
240 bool finished) { | 216 bool finished) { |
241 } | 217 } |
242 | 218 |
243 void ExternalTabContainer::ForwardMessageToExternalHost( | 219 void ExternalTabContainer::ForwardMessageToExternalHost( |
244 const std::string& receiver, const std::string& message) { | 220 const std::string& receiver, const std::string& message) { |
245 if(automation_) { | 221 if(automation_) { |
246 automation_->Send( | 222 automation_->Send( |
247 new AutomationMsg_ForwardMessageToExternalHost(0, receiver, message)); | 223 new AutomationMsg_ForwardMessageToExternalHost(0, receiver, message)); |
248 } | 224 } |
249 } | 225 } |
250 | 226 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 274 |
299 bool ExternalTabContainer::IsVisible() { | 275 bool ExternalTabContainer::IsVisible() { |
300 return !!::IsWindowVisible(*this); | 276 return !!::IsWindowVisible(*this); |
301 } | 277 } |
302 | 278 |
303 bool ExternalTabContainer::IsActive() { | 279 bool ExternalTabContainer::IsActive() { |
304 return win_util::IsWindowActive(*this); | 280 return win_util::IsWindowActive(*this); |
305 } | 281 } |
306 | 282 |
307 bool ExternalTabContainer::ProcessKeyDown(HWND window, UINT message, | 283 bool ExternalTabContainer::ProcessKeyDown(HWND window, UINT message, |
308 WPARAM wparam, LPARAM lparam) { | 284 WPARAM wparam, LPARAM lparam) { |
309 if (!automation_) { | 285 if (!automation_) { |
310 return false; | 286 return false; |
311 } | 287 } |
312 if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) { | 288 if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) { |
313 // Tabs are handled separately (except if this is Ctrl-Tab or | 289 // Tabs are handled separately (except if this is Ctrl-Tab or |
314 // Ctrl-Shift-Tab) | 290 // Ctrl-Shift-Tab) |
315 return false; | 291 return false; |
316 } | 292 } |
317 int flags = HIWORD(lparam); | 293 int flags = HIWORD(lparam); |
318 if ((flags & KF_EXTENDED) || (flags & KF_ALTDOWN) || | 294 if ((flags & KF_EXTENDED) || (flags & KF_ALTDOWN) || |
(...skipping 22 matching lines...) Expand all Loading... |
341 | 317 |
342 void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) { | 318 void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) { |
343 // We just received an accelerator key that we had sent to external host | 319 // We just received an accelerator key that we had sent to external host |
344 // back. Since the external host was not interested in handling this, we | 320 // back. Since the external host was not interested in handling this, we |
345 // need to dispatch this message as if we had just peeked this out. (we | 321 // need to dispatch this message as if we had just peeked this out. (we |
346 // also need to call TranslateMessage to generate a WM_CHAR if needed). | 322 // also need to call TranslateMessage to generate a WM_CHAR if needed). |
347 TranslateMessage(&msg); | 323 TranslateMessage(&msg); |
348 DispatchMessage(&msg); | 324 DispatchMessage(&msg); |
349 } | 325 } |
350 | 326 |
351 void ExternalTabContainer::SetInitialFocus(bool reverse) { | |
352 DCHECK(tab_contents_); | |
353 if (tab_contents_) { | |
354 tab_contents_->SetInitialFocus(reverse); | |
355 } | |
356 } | |
357 | |
358 // static | 327 // static |
359 bool ExternalTabContainer::IsExternalTabContainer(HWND window) { | 328 bool ExternalTabContainer::IsExternalTabContainer(HWND window) { |
360 std::wstring class_name = win_util::GetClassName(window); | 329 std::wstring class_name = win_util::GetClassName(window); |
361 return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0; | 330 return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0; |
362 } | 331 } |
363 | 332 |
364 // static | 333 // static |
365 ExternalTabContainer* ExternalTabContainer::GetContainerForTab( | 334 ExternalTabContainer* ExternalTabContainer::GetContainerForTab( |
366 HWND tab_window) { | 335 HWND tab_window) { |
367 HWND parent_window = ::GetParent(tab_window); | 336 HWND parent_window = ::GetParent(tab_window); |
368 if (!::IsWindow(parent_window)) { | 337 if (!::IsWindow(parent_window)) { |
369 return NULL; | 338 return NULL; |
370 } | 339 } |
371 if (!IsExternalTabContainer(parent_window)) { | 340 if (!IsExternalTabContainer(parent_window)) { |
372 return NULL; | 341 return NULL; |
373 } | 342 } |
374 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>( | 343 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>( |
375 GetProp(parent_window, kWindowObjectKey)); | 344 GetProp(parent_window, kWindowObjectKey)); |
376 return container; | 345 return container; |
377 } | 346 } |
OLD | NEW |