Chromium Code Reviews| 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..a2ca82d7bd000180dfe75349a8fe7d707454a724 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 toolkik-specific code. |
|
robertshield
2013/02/27 21:15:42
kik -> kit
grt (UTC plus 2)
2013/02/28 02:48:41
Done.
|
| + |
| +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), |
|
robertshield
2013/02/27 21:15:42
just curious, was there a functional reason to cha
grt (UTC plus 2)
2013/02/28 02:48:41
Mostly just for style: when I see three bool membe
|
| 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); |
|
robertshield
2013/02/27 21:15:42
should this, and other occurrences of this call be
grt (UTC plus 2)
2013/02/28 02:48:41
That would certainly work, but I don't like that i
|
| 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; |
| } |