Index: chrome/browser/ui/views/external_tab_container_win.cc |
diff --git a/chrome/browser/ui/views/external_tab_container_win.cc b/chrome/browser/ui/views/external_tab_container_win.cc |
index bc5d9ce97cff7a27ad152fd59de8a94435a193f0..d89b3a5bd223c538633620370e1f4c21c966e26f 100644 |
--- a/chrome/browser/ui/views/external_tab_container_win.cc |
+++ b/chrome/browser/ui/views/external_tab_container_win.cc |
@@ -4,6 +4,10 @@ |
#include "chrome/browser/ui/views/external_tab_container_win.h" |
+#include <atlbase.h> |
+#include <atlapp.h> |
+#include <atlconv.h> |
+#include <atlmisc.h> |
#include <string> |
#include "base/bind.h" |
@@ -36,6 +40,7 @@ |
#include "chrome/browser/ui/browser_window.h" |
#include "chrome/browser/ui/media_stream_infobar_delegate.h" |
#include "chrome/browser/ui/tab_modal_confirm_dialog.h" |
+#include "chrome/browser/ui/views/hwnd_util.h" |
#include "chrome/browser/ui/views/infobars/infobar_container_view.h" |
#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_win.h" |
#include "chrome/common/automation_messages.h" |
@@ -70,7 +75,12 @@ |
#include "ui/base/view_prop.h" |
#include "ui/views/controls/webview/webview.h" |
#include "ui/views/layout/grid_layout.h" |
-#include "ui/views/win/hwnd_message_handler.h" |
+#include "ui/views/widget/widget.h" |
+ |
+#if defined(USE_AURA) |
+#include "ui/aura/root_window.h" |
+#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
+#endif |
using content::BrowserThread; |
using content::LoadNotificationDetails; |
@@ -81,15 +91,44 @@ using content::OpenURLParams; |
using content::RenderViewHost; |
using content::SSLStatus; |
using content::WebContents; |
-using ui::ViewProp; |
using WebKit::WebCString; |
using WebKit::WebReferrerPolicy; |
using WebKit::WebSecurityPolicy; |
using WebKit::WebString; |
+namespace { |
+ |
static const char kWindowObjectKey[] = "ChromeWindowObject"; |
-namespace { |
+// The following helper functions exist to localize UI toolkit-specific code. |
+ |
+void ShowNativeView(gfx::NativeView view) { |
+#if !defined(USE_AURA) |
+ ::ShowWindow(view, SW_SHOWNA); |
+#endif |
+} |
+ |
+scoped_ptr<content::NativeWebKeyboardEvent> CreateKeyboardEvent( |
+ const MSG& msg) { |
+#if defined(USE_AURA) |
+ // TODO(grt): confirm that this is a translated character event. |
+ ui::KeyEvent key_event(msg, true); |
+ return scoped_ptr<content::NativeWebKeyboardEvent>( |
+ new content::NativeWebKeyboardEvent(&key_event)); |
+#else |
+ return scoped_ptr<content::NativeWebKeyboardEvent>( |
+ new content::NativeWebKeyboardEvent(msg)); |
+#endif |
+} |
+ |
+const MSG& MessageFromKeyboardEvent( |
+ const content::NativeWebKeyboardEvent& event) { |
+#if defined(USE_AURA) |
+ return event.os_event->native_event(); |
+#else |
+ return event.os_event; |
+#endif |
+} |
// Convert ui::MenuModel into a serializable form for Chrome Frame |
ContextMenuModel* ConvertMenuModel(const ui::MenuModel* ui_model) { |
@@ -123,7 +162,7 @@ base::LazyInstance<ExternalTabContainerWin::PendingTabs> |
ExternalTabContainerWin::ExternalTabContainerWin( |
AutomationProvider* automation, |
AutomationResourceMessageFilter* filter) |
- : views::NativeWidgetWin(new views::Widget), |
+ : widget_(NULL), |
automation_(automation), |
tab_contents_container_(NULL), |
tab_handle_(0), |
@@ -131,12 +170,12 @@ ExternalTabContainerWin::ExternalTabContainerWin( |
automation_resource_message_filter_(filter), |
load_requests_via_automation_(false), |
handle_top_level_requests_(false), |
+ route_all_top_level_navigations_(false), |
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
pending_(false), |
focus_manager_(NULL), |
external_tab_view_(NULL), |
unload_reply_message_(NULL), |
- route_all_top_level_navigations_(false), |
is_popup_window_(false) { |
} |
@@ -167,29 +206,28 @@ bool ExternalTabContainerWin::Init(Profile* profile, |
const GURL& referrer, |
bool infobars_enabled, |
bool route_all_top_level_navigations) { |
- if (IsWindow(GetNativeView())) { |
+ if (widget_) { |
NOTREACHED(); |
return false; |
} |
+ widget_ = new views::Widget(); |
+ widget_->AddObserver(this); |
load_requests_via_automation_ = load_requests_via_automation; |
handle_top_level_requests_ = handle_top_level_requests; |
route_all_top_level_navigations_ = route_all_top_level_navigations; |
- GetMessageHandler()->set_window_style(WS_POPUP | WS_CLIPCHILDREN); |
- |
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
params.bounds = bounds; |
- params.native_widget = this; |
- GetWidget()->Init(params); |
- if (!IsWindow(GetNativeView())) { |
- NOTREACHED(); |
- return false; |
- } |
+#if defined(USE_AURA) |
+ params.native_widget = new views::DesktopNativeWidgetAura(widget_); |
+#endif |
+ widget_->Init(params); |
+ HWND window = chrome::HWNDForWidget(widget_); |
// TODO(jcampan): limit focus traversal to contents. |
- prop_.reset(new ViewProp(GetNativeView(), kWindowObjectKey, this)); |
+ prop_.reset(new ui::ViewProp(window, kWindowObjectKey, this)); |
if (existing_contents) { |
existing_contents->GetController().SetBrowserContext(profile); |
@@ -243,15 +281,14 @@ bool ExternalTabContainerWin::Init(Profile* profile, |
// Note that it's important to do this before we call SetParent since |
// during the SetParent call we will otherwise get a WA_ACTIVATE call |
// that causes us to steal the current focus. |
- SetWindowLong( |
- GetNativeView(), GWL_STYLE, |
- (GetWindowLong(GetNativeView(), GWL_STYLE) & ~WS_POPUP) | style); |
+ SetWindowLong(window, GWL_STYLE, |
+ (GetWindowLong(window, GWL_STYLE) & ~WS_POPUP) | style); |
// Now apply the parenting and style |
if (parent) |
- SetParent(GetNativeView(), parent); |
+ SetParent(window, parent); |
- ::ShowWindow(existing_contents->GetView()->GetNativeView(), SW_SHOWNA); |
+ ShowNativeView(existing_contents->GetView()->GetNativeView()); |
LoadAccelerators(); |
SetupExternalTabView(); |
@@ -263,6 +300,7 @@ bool ExternalTabContainerWin::Init(Profile* profile, |
void ExternalTabContainerWin::Uninitialize() { |
registrar_.RemoveAll(); |
if (web_contents_.get()) { |
+ tab_contents_container_->SetWebContents(NULL); |
UnregisterRenderViewHost(web_contents_->GetRenderViewHost()); |
// Explicitly tell the RPH to shutdown, as doing so is the only thing that |
@@ -284,8 +322,9 @@ void ExternalTabContainerWin::Uninitialize() { |
// more fitting. |
web_contents_->GetRenderProcessHost()->FastShutdownForPageCount(1); |
- if (GetWidget()->GetRootView()) |
- GetWidget()->GetRootView()->RemoveAllChildViews(true); |
+ if (widget_->GetRootView()) |
+ widget_->GetRootView()->RemoveAllChildViews(true); |
+ widget_ = NULL; |
content::NotificationService::current()->Notify( |
chrome::NOTIFICATION_EXTERNAL_TAB_CLOSED, |
@@ -308,7 +347,7 @@ void ExternalTabContainerWin::Uninitialize() { |
bool ExternalTabContainerWin::Reinitialize( |
AutomationProvider* automation_provider, |
AutomationResourceMessageFilter* filter, |
- gfx::NativeWindow parent_window) { |
+ HWND parent_window) { |
if (!automation_provider || !filter) { |
NOTREACHED(); |
return false; |
@@ -323,7 +362,7 @@ bool ExternalTabContainerWin::Reinitialize( |
weak_factory_.GetWeakPtr())); |
if (parent_window) |
- SetParent(GetNativeView(), parent_window); |
+ SetParent(chrome::HWNDForWidget(widget_), parent_window); |
return true; |
} |
@@ -331,8 +370,12 @@ WebContents* ExternalTabContainerWin::GetWebContents() const { |
return web_contents_.get(); |
} |
-gfx::NativeView ExternalTabContainerWin::GetExternalTabNativeView() const { |
- return GetNativeView(); |
+HWND ExternalTabContainerWin::GetExternalTabHWND() const { |
+ return chrome::HWNDForWidget(widget_); |
+} |
+ |
+HWND ExternalTabContainerWin::GetContentHWND() const { |
+ return chrome::HWNDForNativeWindow(web_contents_->GetView()->GetNativeView()); |
} |
void ExternalTabContainerWin::SetTabHandle(int handle) { |
@@ -389,8 +432,8 @@ void ExternalTabContainerWin::RunUnloadHandlers(IPC::Message* reply_message) { |
} |
void ExternalTabContainerWin::ProcessUnhandledAccelerator(const MSG& msg) { |
- NativeWebKeyboardEvent keyboard_event(msg); |
- unhandled_keyboard_event_handler_.HandleKeyboardEvent(keyboard_event, |
+ scoped_ptr<NativeWebKeyboardEvent> keyboard_event(CreateKeyboardEvent(msg)); |
+ unhandled_keyboard_event_handler_.HandleKeyboardEvent(*keyboard_event, |
focus_manager_); |
} |
@@ -409,22 +452,6 @@ void ExternalTabContainerWin::FocusThroughTabTraversal( |
web_contents_->FocusThroughTabTraversal(reverse); |
} |
-// static |
-bool ExternalTabContainerWin::IsExternalTabContainer(HWND window) { |
- return ViewProp::GetValue(window, kWindowObjectKey) != NULL; |
-} |
- |
-// static |
-ExternalTabContainer* |
- ExternalTabContainerWin::GetExternalContainerFromNativeWindow( |
- gfx::NativeView native_window) { |
- ExternalTabContainer* tab_container = NULL; |
- if (native_window) { |
- tab_container = reinterpret_cast<ExternalTabContainer*>( |
- ViewProp::GetValue(native_window, kWindowObjectKey)); |
- } |
- return tab_container; |
-} |
//////////////////////////////////////////////////////////////////////////////// |
// ExternalTabContainer, content::WebContentsDelegate implementation: |
@@ -719,7 +746,7 @@ bool ExternalTabContainerWin::HandleContextMenu( |
ConvertMenuModel(&external_context_menu_->menu_model())); |
POINT screen_pt = { params.x, params.y }; |
- MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1); |
+ MapWindowPoints(chrome::HWNDForWidget(widget_), HWND_DESKTOP, &screen_pt, 1); |
MiniContextMenuParams ipc_params; |
ipc_params.screen_x = screen_pt.x; |
@@ -750,8 +777,9 @@ bool ExternalTabContainerWin::PreHandleKeyboardEvent( |
void ExternalTabContainerWin::HandleKeyboardEvent( |
content::WebContents* source, |
const NativeWebKeyboardEvent& event) { |
- ProcessUnhandledKeyStroke(event.os_event.hwnd, event.os_event.message, |
- event.os_event.wParam, event.os_event.lParam); |
+ const MSG& message = MessageFromKeyboardEvent(event); |
+ ProcessUnhandledKeyStroke(message.hwnd, message.message, |
+ message.wParam, message.lParam); |
} |
void ExternalTabContainerWin::BeforeUnloadFired(WebContents* tab, |
@@ -950,30 +978,23 @@ void ExternalTabContainerWin::Observe( |
} |
//////////////////////////////////////////////////////////////////////////////// |
-// ExternalTabContainer, views::NativeWidgetWin overrides: |
- |
-bool ExternalTabContainerWin::PreHandleMSG(UINT message, |
- WPARAM w_param, |
- LPARAM l_param, |
- LRESULT* result) { |
- if (message == WM_DESTROY) { |
- prop_.reset(); |
- Uninitialize(); |
- } |
- return false; |
+// WidgetObserver overrides: |
+ |
+void ExternalTabContainerWin::OnWidgetCreated(views::Widget* widget) { |
+ DCHECK_EQ(widget_, widget); |
+ // Grab a reference here which will be released in OnWidgetDestroyed. |
+ AddRef(); |
} |
-void ExternalTabContainerWin::PostHandleMSG(UINT message, |
- WPARAM w_param, |
- LPARAM l_param) { |
- // Grab a reference here which will be released in OnFinalMessage |
- if (message == WM_CREATE) |
- AddRef(); |
+void ExternalTabContainerWin::OnWidgetDestroying(views::Widget* widget) { |
+ DCHECK_EQ(widget_, widget); |
+ Uninitialize(); |
+ prop_.reset(); |
} |
-void ExternalTabContainerWin::OnFinalMessage(HWND window) { |
- GetWidget()->OnNativeWidgetDestroyed(); |
- // Release the reference which we grabbed in WM_CREATE. |
+void ExternalTabContainerWin::OnWidgetDestroyed(views::Widget* widget) { |
+ DCHECK_EQ(widget_, static_cast<views::Widget*>(NULL)); |
+ // Release the reference which we grabbed in OnWidgetCreated. |
Release(); |
} |
@@ -1144,7 +1165,7 @@ void ExternalTabContainerWin::LoadAccelerators() { |
CopyAcceleratorTable(accelerator_table, accelerators, count); |
- focus_manager_ = GetWidget()->GetFocusManager(); |
+ focus_manager_ = widget_->GetFocusManager(); |
DCHECK(focus_manager_); |
// Let's fill our own accelerator table. |
@@ -1222,7 +1243,7 @@ void ExternalTabContainerWin::SetupExternalTabView() { |
layout->AddView(info_bar_container); |
layout->StartRow(1, 0); |
layout->AddView(tab_contents_container_); |
- GetWidget()->SetContentsView(external_tab_view_); |
+ widget_->SetContentsView(external_tab_view_); |
// Note that SetWebContents must be called after AddChildView is called |
tab_contents_container_->SetWebContents(web_contents()); |
} |
@@ -1236,17 +1257,13 @@ ExternalTabContainer* ExternalTabContainer::Create( |
// static |
ExternalTabContainer* ExternalTabContainer::GetContainerForTab( |
- HWND tab_window) { |
- HWND parent_window = ::GetParent(tab_window); |
- if (!::IsWindow(parent_window)) { |
+ content::WebContents* web_contents) { |
+ HWND parent_window = chrome::HWNDForNativeWindow( |
+ web_contents->GetView()->GetTopLevelNativeWindow()); |
+ if (!::IsWindow(parent_window)) |
return NULL; |
- } |
- if (!ExternalTabContainerWin::IsExternalTabContainer(parent_window)) { |
- return NULL; |
- } |
- ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>( |
- ViewProp::GetValue(parent_window, kWindowObjectKey)); |
- return container; |
+ return reinterpret_cast<ExternalTabContainerWin*>( |
+ ui::ViewProp::GetValue(parent_window, kWindowObjectKey)); |
} |
// static |
@@ -1283,6 +1300,6 @@ WebContents* TemporaryPopupExternalTabContainerWin::OpenURLFromTab( |
WebContents* new_contents = |
ExternalTabContainerWin::OpenURLFromTab(source, forward_params); |
// support only one navigation for a dummy tab before it is killed. |
- ::DestroyWindow(GetNativeView()); |
+ widget_->CloseNow(); |
return new_contents; |
} |