Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(354)

Side by Side Diff: chrome/browser/external_tab_container.cc

Issue 113892: ExternalTabContainer should subclass WidgetWin rather than Widget and ATL CWi... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/external_tab_container.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "app/win_util.h" 7 #include "app/win_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/win_util.h" 9 #include "base/win_util.h"
10 #include "chrome/browser/automation/automation_provider.h" 10 #include "chrome/browser/automation/automation_provider.h"
11 #include "chrome/browser/browser.h" 11 #include "chrome/browser/browser.h"
12 #include "chrome/browser/extensions/extension_function_dispatcher.h" 12 #include "chrome/browser/extensions/extension_function_dispatcher.h"
13 #include "chrome/browser/load_notification_details.h" 13 #include "chrome/browser/load_notification_details.h"
14 #include "chrome/browser/profile.h" 14 #include "chrome/browser/profile.h"
15 #include "chrome/browser/tab_contents/provisional_load_details.h" 15 #include "chrome/browser/tab_contents/provisional_load_details.h"
16 #include "chrome/browser/tab_contents/tab_contents.h" 16 #include "chrome/browser/tab_contents/tab_contents.h"
17 #include "chrome/browser/views/tab_contents/tab_contents_container.h" 17 #include "chrome/browser/views/tab_contents/tab_contents_container.h"
18 #include "chrome/common/chrome_constants.h" 18 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/notification_service.h" 19 #include "chrome/common/notification_service.h"
20 #include "chrome/test/automation/automation_messages.h" 20 #include "chrome/test/automation/automation_messages.h"
21 // Included for SetRootViewForHWND.
22 #include "views/widget/widget_win.h"
23 21
24 static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject"; 22 static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject";
25 23
26 // TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_ 24 // TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_
27 // member variables are now obsolete and we don't use them. 25 // member variables are now obsolete and we don't use them.
28 // We need to remove them. 26 // We need to remove them.
29 ExternalTabContainer::ExternalTabContainer( 27 ExternalTabContainer::ExternalTabContainer(
30 AutomationProvider* automation) 28 AutomationProvider* automation)
31 : automation_(automation), 29 : automation_(automation),
32 root_view_(this),
33 tab_contents_(NULL), 30 tab_contents_(NULL),
34 external_accel_table_(NULL), 31 external_accel_table_(NULL),
35 external_accel_entry_count_(0), 32 external_accel_entry_count_(0),
36 tab_contents_container_(NULL), 33 tab_contents_container_(NULL),
37 tab_handle_(0), 34 tab_handle_(0),
38 ignore_next_load_notification_(false) { 35 ignore_next_load_notification_(false) {
39 } 36 }
40 37
41 ExternalTabContainer::~ExternalTabContainer() { 38 ExternalTabContainer::~ExternalTabContainer() {
42 Uninitialize(m_hWnd); 39 Uninitialize(GetNativeView());
43 } 40 }
44 41
45 bool ExternalTabContainer::Init(Profile* profile, HWND parent, 42 bool ExternalTabContainer::Init(Profile* profile,
46 const gfx::Rect& dimensions, 43 HWND parent,
47 unsigned int style) { 44 const gfx::Rect& bounds,
45 DWORD style) {
48 if (IsWindow()) { 46 if (IsWindow()) {
49 NOTREACHED(); 47 NOTREACHED();
50 return false; 48 return false;
51 } 49 }
52 50
53 // First create the container window 51 set_window_style(WS_POPUP);
54 if (!Create(NULL, dimensions.ToRECT())) { 52 views::WidgetWin::Init(parent, bounds, true);
tommi (sloooow) - chröme 2009/05/27 20:50:29 this changes the semantics from before where NULL
55 NOTREACHED();
56 return false;
57 }
58 53
59 // We don't ever remove the prop because the lifetime of this object 54 // We don't ever remove the prop because the lifetime of this object
60 // is the same as the lifetime of the window 55 // is the same as the lifetime of the window
61 SetProp(*this, kWindowObjectKey, this); 56 SetProp(GetNativeView(), kWindowObjectKey, this);
62 57
63 views::SetRootViewForHWND(m_hWnd, &root_view_);
64 // CreateFocusManager will subclass this window and delete the FocusManager
65 // instance when this window goes away.
66 views::FocusManager* focus_manager = 58 views::FocusManager* focus_manager =
67 views::FocusManager::CreateFocusManager(m_hWnd, GetRootView()); 59 views::FocusManager::GetFocusManager(GetNativeView());
68
69 DCHECK(focus_manager);
70 focus_manager->AddKeystrokeListener(this); 60 focus_manager->AddKeystrokeListener(this);
71 61
72 tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL); 62 tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL);
73 tab_contents_->set_delegate(this); 63 tab_contents_->set_delegate(this);
74 tab_contents_->render_view_host()->AllowExternalHostBindings(); 64 tab_contents_->render_view_host()->AllowExternalHostBindings();
75 65
76 // Create a TabContentsContainer to handle focus cycling using Tab and 66 // Create a TabContentsContainer to handle focus cycling using Tab and
77 // Shift-Tab. 67 // Shift-Tab.
78 tab_contents_container_ = new TabContentsContainer; 68 tab_contents_container_ = new TabContentsContainer;
79 root_view_.AddChildView(tab_contents_container_); 69 SetContentsView(tab_contents_container_);
70
80 // Note that SetTabContents must be called after AddChildView is called 71 // Note that SetTabContents must be called after AddChildView is called
81 tab_contents_container_->ChangeTabContents(tab_contents_); 72 tab_contents_container_->ChangeTabContents(tab_contents_);
82 73
83 NavigationController* controller = &tab_contents_->controller(); 74 NavigationController* controller = &tab_contents_->controller();
84 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, 75 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
85 Source<NavigationController>(controller)); 76 Source<NavigationController>(controller));
86 registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR, 77 registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
87 Source<NavigationController>(controller)); 78 Source<NavigationController>(controller));
88 registrar_.Add(this, NotificationType::LOAD_STOP, 79 registrar_.Add(this, NotificationType::LOAD_STOP,
89 Source<NavigationController>(controller)); 80 Source<NavigationController>(controller));
90 NotificationService::current()->Notify( 81 NotificationService::current()->Notify(
91 NotificationType::EXTERNAL_TAB_CREATED, 82 NotificationType::EXTERNAL_TAB_CREATED,
92 Source<NavigationController>(controller), 83 Source<NavigationController>(controller),
93 NotificationService::NoDetails()); 84 NotificationService::NoDetails());
94 85
95 // We need WS_POPUP to be on the window during initialization, but 86 // We need WS_POPUP to be on the window during initialization, but
96 // once initialized we apply the requested style which may or may not 87 // once initialized we apply the requested style which may or may not
97 // include the popup bit. 88 // include the popup bit.
98 // Note that it's important to do this before we call SetParent since 89 // Note that it's important to do this before we call SetParent since
99 // during the SetParent call we will otherwise get a WA_ACTIVATE call 90 // during the SetParent call we will otherwise get a WA_ACTIVATE call
100 // that causes us to steal the current focus. 91 // that causes us to steal the current focus.
101 ModifyStyle(WS_POPUP, style, 0); 92 SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);
ananta 2009/05/27 13:46:24 Should this be GetWindowLong(GWL_STYLE) | WS_POPUP
tommi (sloooow) - chröme 2009/05/27 20:50:29 I think this is how it should be. We want to remo
102 93
103 // Now apply the parenting and style 94 // Now apply the parenting and style
104 if (parent) 95 if (parent)
105 SetParent(parent); 96 SetParent(GetNativeView(), parent);
106 97
107 ::ShowWindow(tab_contents_->GetNativeView(), SW_SHOWNA); 98 ::ShowWindow(tab_contents_->GetNativeView(), SW_SHOWNA);
108 return true; 99 return true;
109 } 100 }
110 101
111 bool ExternalTabContainer::Uninitialize(HWND window) { 102 void ExternalTabContainer::SetAccelerators(HACCEL accel_table,
112 if (::IsWindow(window)) { 103 int accel_table_entry_count) {
113 views::FocusManager* focus_manager = 104 external_accel_table_ = accel_table;
114 views::FocusManager::GetFocusManager(window); 105 external_accel_entry_count_ = accel_table_entry_count;
115 if (focus_manager) {
116 focus_manager->RemoveKeystrokeListener(this);
117 }
118 }
119
120 root_view_.RemoveAllChildViews(true);
121 if (tab_contents_) {
122 NotificationService::current()->Notify(
123 NotificationType::EXTERNAL_TAB_CLOSED,
124 Source<NavigationController>(&tab_contents_->controller()),
125 Details<ExternalTabContainer>(this));
126
127 delete tab_contents_;
128 tab_contents_ = NULL;
129 }
130
131 return true;
132 } 106 }
133 107
134 void ExternalTabContainer::OnFinalMessage(HWND window) { 108 void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
135 delete this; 109 // We just received an accelerator key that we had sent to external host
110 // back. Since the external host was not interested in handling this, we
111 // need to dispatch this message as if we had just peeked this out. (we
112 // also need to call TranslateMessage to generate a WM_CHAR if needed).
113 TranslateMessage(&msg);
114 DispatchMessage(&msg);
136 } 115 }
137 116
138 LRESULT ExternalTabContainer::OnSize(UINT, WPARAM, LPARAM, BOOL& handled) { 117 void ExternalTabContainer::SetInitialFocus(bool reverse) {
118 DCHECK(tab_contents_);
139 if (tab_contents_) { 119 if (tab_contents_) {
140 RECT client_rect = {0}; 120 static_cast<TabContents*>(tab_contents_)->Focus();
141 GetClientRect(&client_rect); 121 static_cast<TabContents*>(tab_contents_)->SetInitialFocus(reverse);
142 ::SetWindowPos(tab_contents_->GetNativeView(), NULL, client_rect.left,
143 client_rect.top, client_rect.right - client_rect.left,
144 client_rect.bottom - client_rect.top, SWP_NOZORDER);
145 } 122 }
146 return 0;
147 } 123 }
148 124
149 LRESULT ExternalTabContainer::OnDestroy(UINT, WPARAM, LPARAM, BOOL& handled) { 125 // static
150 Uninitialize(m_hWnd); 126 bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
151 return 0; 127 std::wstring class_name = win_util::GetClassName(window);
128 return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0;
tommi (sloooow) - chröme 2009/05/27 20:50:29 maybe return class_name.compare(chrome::kExternalT
152 } 129 }
153 130
131 // static
132 ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
133 HWND tab_window) {
134 HWND parent_window = ::GetParent(tab_window);
135 if (!::IsWindow(parent_window)) {
136 return NULL;
137 }
138 if (!IsExternalTabContainer(parent_window)) {
139 return NULL;
140 }
141 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
142 GetProp(parent_window, kWindowObjectKey));
143 return container;
144 }
145
146 ////////////////////////////////////////////////////////////////////////////////
147 // ExternalTabContainer, TabContentsDelegate implementation:
148
154 void ExternalTabContainer::OpenURLFromTab(TabContents* source, 149 void ExternalTabContainer::OpenURLFromTab(TabContents* source,
155 const GURL& url, 150 const GURL& url,
156 const GURL& referrer, 151 const GURL& referrer,
157 WindowOpenDisposition disposition, 152 WindowOpenDisposition disposition,
158 PageTransition::Type transition) { 153 PageTransition::Type transition) {
159 switch (disposition) { 154 switch (disposition) {
160 case CURRENT_TAB: 155 case CURRENT_TAB:
161 case SINGLETON_TAB: 156 case SINGLETON_TAB:
162 case NEW_FOREGROUND_TAB: 157 case NEW_FOREGROUND_TAB:
163 case NEW_BACKGROUND_TAB: 158 case NEW_BACKGROUND_TAB:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 void ExternalTabContainer::ForwardMessageToExternalHost( 229 void ExternalTabContainer::ForwardMessageToExternalHost(
235 const std::string& message, const std::string& origin, 230 const std::string& message, const std::string& origin,
236 const std::string& target) { 231 const std::string& target) {
237 if(automation_) { 232 if(automation_) {
238 automation_->Send( 233 automation_->Send(
239 new AutomationMsg_ForwardMessageToExternalHost(0, tab_handle_, 234 new AutomationMsg_ForwardMessageToExternalHost(0, tab_handle_,
240 message, origin, target)); 235 message, origin, target));
241 } 236 }
242 } 237 }
243 238
239 ExtensionFunctionDispatcher* ExternalTabContainer::
240 CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host,
241 const std::string& extension_id) {
242 return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id);
243 }
244
244 bool ExternalTabContainer::TakeFocus(bool reverse) { 245 bool ExternalTabContainer::TakeFocus(bool reverse) {
245 if (automation_) { 246 if (automation_) {
246 views::FocusManager* focus_manager = 247 views::FocusManager* focus_manager =
247 views::FocusManager::GetFocusManager(GetNativeView()); 248 views::FocusManager::GetFocusManager(GetNativeView());
248 DCHECK(focus_manager); 249 DCHECK(focus_manager);
249 if (focus_manager) { 250 if (focus_manager) {
250 focus_manager->ClearFocus(); 251 focus_manager->ClearFocus();
251 automation_->Send(new AutomationMsg_TabbedOut(0, tab_handle_, 252 automation_->Send(new AutomationMsg_TabbedOut(0, tab_handle_,
252 win_util::IsShiftPressed())); 253 win_util::IsShiftPressed()));
253 } 254 }
254 } 255 }
255 256
256 return true; 257 return true;
257 } 258 }
258 259
260 ////////////////////////////////////////////////////////////////////////////////
261 // ExternalTabContainer, NotificationObserver implementation:
262
259 void ExternalTabContainer::Observe(NotificationType type, 263 void ExternalTabContainer::Observe(NotificationType type,
260 const NotificationSource& source, 264 const NotificationSource& source,
261 const NotificationDetails& details) { 265 const NotificationDetails& details) {
262 if (!automation_) 266 if (!automation_)
263 return; 267 return;
264 268
265 static const int kHttpClientErrorStart = 400; 269 static const int kHttpClientErrorStart = 400;
266 static const int kHttpServerErrorEnd = 510; 270 static const int kHttpServerErrorEnd = 510;
267 271
268 switch (type.value) { 272 switch (type.value) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 0, tab_handle_, load_details->error_code(), load_details->url())); 313 0, tab_handle_, load_details->error_code(), load_details->url()));
310 314
311 ignore_next_load_notification_ = true; 315 ignore_next_load_notification_ = true;
312 break; 316 break;
313 } 317 }
314 default: 318 default:
315 NOTREACHED(); 319 NOTREACHED();
316 } 320 }
317 } 321 }
318 322
319 void ExternalTabContainer::GetBounds(gfx::Rect* out, 323 ////////////////////////////////////////////////////////////////////////////////
320 bool including_frame) const { 324 // ExternalTabContainer, views::WidgetWin overrides:
321 CRect crect; 325
322 GetWindowRect(&crect); 326 void ExternalTabContainer::OnDestroy() {
323 *out = gfx::Rect(crect); 327 Uninitialize(GetNativeView());
328 WidgetWin::OnDestroy();
324 } 329 }
325 330
326 void ExternalTabContainer::SetBounds(const gfx::Rect& bounds) { 331 ////////////////////////////////////////////////////////////////////////////////
327 SetBounds(bounds, NULL); 332 // ExternalTabContainer, views::KeystrokeListener implementation:
328 }
329
330 void ExternalTabContainer::SetBounds(const gfx::Rect& bounds,
331 gfx::NativeView other_window) {
332 NOTIMPLEMENTED();
333 }
334
335 void ExternalTabContainer::Close() {
336 NOTIMPLEMENTED();
337 }
338
339 void ExternalTabContainer::CloseNow() {
340 NOTIMPLEMENTED();
341 }
342
343 void ExternalTabContainer::Show() {
344 NOTIMPLEMENTED();
345 }
346
347 void ExternalTabContainer::Hide() {
348 NOTIMPLEMENTED();
349 }
350
351 gfx::NativeView ExternalTabContainer::GetNativeView() const {
352 return m_hWnd;
353 }
354
355 void ExternalTabContainer::PaintNow(const gfx::Rect& update_rect) {
356 RECT native_update_rect = update_rect.ToRECT();
357 RedrawWindow(&native_update_rect,
358 NULL,
359 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_NOERASE);
360 }
361
362 void ExternalTabContainer::SetOpacity(unsigned char opacity) {
363 NOTIMPLEMENTED();
364 }
365
366 views::RootView* ExternalTabContainer::GetRootView() {
367 return const_cast<views::RootView*>(&root_view_);
368 }
369
370 bool ExternalTabContainer::IsVisible() const {
371 return !!::IsWindowVisible(*this);
372 }
373
374 bool ExternalTabContainer::IsActive() const {
375 return win_util::IsWindowActive(*this);
376 }
377 333
378 bool ExternalTabContainer::ProcessKeyStroke(HWND window, UINT message, 334 bool ExternalTabContainer::ProcessKeyStroke(HWND window, UINT message,
379 WPARAM wparam, LPARAM lparam) { 335 WPARAM wparam, LPARAM lparam) {
380 if (!automation_) { 336 if (!automation_) {
381 return false; 337 return false;
382 } 338 }
383 if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) { 339 if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) {
384 // Tabs are handled separately (except if this is Ctrl-Tab or 340 // Tabs are handled separately (except if this is Ctrl-Tab or
385 // Ctrl-Shift-Tab) 341 // Ctrl-Shift-Tab)
386 return false; 342 return false;
(...skipping 18 matching lines...) Expand all
405 msg.message = message; 361 msg.message = message;
406 msg.wParam = wparam; 362 msg.wParam = wparam;
407 msg.lParam = lparam; 363 msg.lParam = lparam;
408 automation_->Send(new AutomationMsg_HandleAccelerator(0, tab_handle_, msg)); 364 automation_->Send(new AutomationMsg_HandleAccelerator(0, tab_handle_, msg));
409 return true; 365 return true;
410 } 366 }
411 367
412 return false; 368 return false;
413 } 369 }
414 370
415 void ExternalTabContainer::SetAccelerators(HACCEL accel_table, 371 ////////////////////////////////////////////////////////////////////////////////
416 int accel_table_entry_count) { 372 // ExternalTabContainer, private:
417 external_accel_table_ = accel_table;
418 external_accel_entry_count_ = accel_table_entry_count;
419 }
420 373
421 void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) { 374 void ExternalTabContainer::Uninitialize(HWND window) {
422 // We just received an accelerator key that we had sent to external host 375 if (::IsWindow(window)) {
423 // back. Since the external host was not interested in handling this, we 376 views::FocusManager* focus_manager =
424 // need to dispatch this message as if we had just peeked this out. (we 377 views::FocusManager::GetFocusManager(window);
425 // also need to call TranslateMessage to generate a WM_CHAR if needed). 378 if (focus_manager)
426 TranslateMessage(&msg); 379 focus_manager->RemoveKeystrokeListener(this);
427 DispatchMessage(&msg); 380 }
428 }
429 381
430 void ExternalTabContainer::SetInitialFocus(bool reverse) {
431 DCHECK(tab_contents_);
432 if (tab_contents_) { 382 if (tab_contents_) {
433 static_cast<TabContents*>(tab_contents_)->Focus(); 383 NotificationService::current()->Notify(
434 static_cast<TabContents*>(tab_contents_)->SetInitialFocus(reverse); 384 NotificationType::EXTERNAL_TAB_CLOSED,
385 Source<NavigationController>(&tab_contents_->controller()),
386 Details<ExternalTabContainer>(this));
387
388 delete tab_contents_;
389 tab_contents_ = NULL;
435 } 390 }
436 } 391 }
437 392
438 // static
439 bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
440 std::wstring class_name = win_util::GetClassName(window);
441 return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0;
442 }
443
444 ExtensionFunctionDispatcher* ExternalTabContainer::
445 CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host,
446 const std::string& extension_id) {
447 return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id);
448 }
449
450 // static
451 ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
452 HWND tab_window) {
453 HWND parent_window = ::GetParent(tab_window);
454 if (!::IsWindow(parent_window)) {
455 return NULL;
456 }
457 if (!IsExternalTabContainer(parent_window)) {
458 return NULL;
459 }
460 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
461 GetProp(parent_window, kWindowObjectKey));
462 return container;
463 }
OLDNEW
« no previous file with comments | « chrome/browser/external_tab_container.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698