From e09948c37e220e45bbd721a608b5bbef79c24f5f Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Sat, 7 Dec 2013 01:55:22 +0000 Subject: [PATCH] Windows: Switch to aura/views architecture for content window creation (issue #180). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1542 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- cef.gyp | 18 +- cef.gypi | 5 +- libcef/browser/browser_host_impl.cc | 49 ++-- libcef/browser/browser_host_impl.h | 21 ++ libcef/browser/browser_host_impl_win.cc | 237 ++++++++++++++++-- libcef/browser/browser_main.cc | 26 ++ libcef/browser/browser_main.h | 1 + libcef/browser/menu_creator_runner_win.cc | 10 +- libcef/browser/render_widget_host_view_osr.cc | 38 ++- libcef/browser/render_widget_host_view_osr.h | 7 +- patch/patch.cfg | 17 ++ patch/patches/build.patch | 13 +- patch/patches/native_theme_180.patch | 34 +++ patch/patches/views_widget_180.patch | 40 +++ tools/gyp_cef | 4 + 15 files changed, 460 insertions(+), 60 deletions(-) create mode 100644 patch/patches/native_theme_180.patch create mode 100644 patch/patches/views_widget_180.patch diff --git a/cef.gyp b/cef.gyp index 36b5e4dea..1b55645b0 100644 --- a/cef.gyp +++ b/cef.gyp @@ -831,6 +831,7 @@ # CEF grit resource includes '<(DEPTH)/cef/libcef/resources/grit_stub', '<(grit_out_dir)', + '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_strings', '<(SHARED_INTERMEDIATE_DIR)/webkit', ], @@ -1110,16 +1111,6 @@ 'libcef/browser/javascript_dialog_win.cc', 'libcef/browser/menu_creator_runner_win.cc', 'libcef/browser/menu_creator_runner_win.h', - # Include sources for context menu implementation. - '<(DEPTH)/ui/views/controls/menu/menu_2.cc', - '<(DEPTH)/ui/views/controls/menu/menu_2.h', - '<(DEPTH)/ui/views/controls/menu/menu_config.cc', - '<(DEPTH)/ui/views/controls/menu/menu_config.h', - '<(DEPTH)/ui/views/controls/menu/menu_config_win.cc', - '<(DEPTH)/ui/views/controls/menu/menu_listener.cc', - '<(DEPTH)/ui/views/controls/menu/menu_listener.h', - '<(DEPTH)/ui/views/controls/menu/native_menu_win.cc', - '<(DEPTH)/ui/views/controls/menu/native_menu_win.h', # Include sources for printing. '<(DEPTH)/chrome/renderer/printing/print_web_view_helper_win.cc', ], @@ -1179,6 +1170,13 @@ '<(DEPTH)/components/components.gyp:breakpad_host', ], }], + ['use_aura==1', { + 'dependencies': [ + '<(DEPTH)/ui/views/controls/webview/webview.gyp:webview', + '<(DEPTH)/ui/views/views.gyp:views', + '<(DEPTH)/ui/views/views.gyp:views_test_support', + ], + }], ], }, ], diff --git a/cef.gypi b/cef.gypi index 191c465b9..f39b80a72 100644 --- a/cef.gypi +++ b/cef.gypi @@ -4,8 +4,6 @@ { 'variables': { - 'use_ash': 0, - 'use_aura': 0, # Don't use the chrome style plugin with CEF. 'clang_use_chrome_plugins': 0, 'conditions': [ @@ -18,6 +16,9 @@ 'disable_debugallocation': 1, }, { # OS!="win" 'cef_directory' : '(&event.os_event->native_event()); +#else + return const_cast(event.os_event->native_event()); +#endif +#else // !defined(USE_AURA) + return event.os_event; +#endif // !defined(USE_AURA) +} + class CefFileDialogCallbackImpl : public CefFileDialogCallback { public: explicit CefFileDialogCallbackImpl( @@ -1306,6 +1325,10 @@ void CefBrowserHostImpl::DestroyBrowser() { web_contents_.reset(NULL); menu_creator_.reset(NULL); +#if defined(USE_AURA) + window_widget_ = NULL; +#endif + DetachAllFrames(); CefContentBrowserClient::Get()->RemoveBrowserInfo(browser_info_); @@ -1314,9 +1337,15 @@ void CefBrowserHostImpl::DestroyBrowser() { gfx::NativeView CefBrowserHostImpl::GetContentView() const { CEF_REQUIRE_UIT(); +#if defined(USE_AURA) + if (!window_widget_) + return NULL; + return window_widget_->GetNativeView(); +#else if (!web_contents_.get()) return NULL; return web_contents_->GetView()->GetNativeView(); +#endif } content::WebContents* CefBrowserHostImpl::GetWebContents() const { @@ -1784,15 +1813,9 @@ bool CefBrowserHostImpl::PreHandleKeyboardEvent( if (!GetCefKeyEvent(event, cef_event)) return false; -#if defined(OS_WIN) - CefEventHandle os_event = const_cast(&event.os_event); -#else - CefEventHandle os_event = event.os_event; -#endif - cef_event.focus_on_editable_field = focus_on_editable_field_; - return handler->OnPreKeyEvent(this, cef_event, os_event, + return handler->OnPreKeyEvent(this, cef_event, GetCefEventHandle(event), is_keyboard_shortcut); } } @@ -1812,15 +1835,9 @@ void CefBrowserHostImpl::HandleKeyboardEvent( if (handler.get()) { CefKeyEvent cef_event; if (GetCefKeyEvent(event, cef_event)) { -#if defined(OS_WIN) - CefEventHandle os_event = const_cast(&event.os_event); -#else - CefEventHandle os_event = event.os_event; -#endif - cef_event.focus_on_editable_field = focus_on_editable_field_; - if (handler->OnKeyEvent(this, cef_event, os_event)) + if (handler->OnKeyEvent(this, cef_event, GetCefEventHandle(event))) return; } } @@ -2280,6 +2297,10 @@ CefBrowserHostImpl::CefBrowserHostImpl( mouse_cursor_change_disabled_(false), devtools_frontend_(NULL), file_chooser_pending_(false) { +#if defined(USE_AURA) + window_widget_ = NULL; +#endif + DCHECK(!browser_info_->browser().get()); browser_info_->set_browser(this); diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index 690943f1f..dbc31d77a 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -30,6 +30,11 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/common/file_chooser_params.h" +#if defined(USE_AURA) +#include "third_party/WebKit/public/platform/WebCursorInfo.h" +#include "ui/base/cursor/cursor.h" +#endif + namespace content { struct NativeWebKeyboardEvent; } @@ -44,6 +49,12 @@ namespace net { class URLRequest; } +#if defined(USE_AURA) +namespace views { +class Widget; +} +#endif + struct Cef_Request_Params; struct Cef_Response_Params; class CefBrowserInfo; @@ -248,6 +259,10 @@ class CefBrowserHostImpl : public CefBrowserHost, static void RegisterWindowClass(); #endif +#if defined(USE_AURA) + ui::PlatformCursor GetPlatformCursor(blink::WebCursorInfo::Type type); +#endif + void OnSetFocus(cef_focus_source_t source); // The argument vector will be empty if the dialog was cancelled. @@ -579,6 +594,12 @@ class CefBrowserHostImpl : public CefBrowserHost, // Current title for the main frame. Only accessed on the UI thread. string16 title_; +#if defined(USE_AURA) + // Widget hosting the web contents. It will be deleted automatically when the + // associated root window is destroyed. + views::Widget* window_widget_; +#endif // defined(USE_AURA) + IMPLEMENT_REFCOUNTING(CefBrowserHostImpl); DISALLOW_EVIL_CONSTRUCTORS(CefBrowserHostImpl); }; diff --git a/libcef/browser/browser_host_impl_win.cc b/libcef/browser/browser_host_impl_win.cc index 089b598ee..4173323f5 100644 --- a/libcef/browser/browser_host_impl_win.cc +++ b/libcef/browser/browser_host_impl_win.cc @@ -11,6 +11,7 @@ #include #include +#include "libcef/browser/content_browser_client.h" #include "libcef/browser/thread_util.h" #include "base/i18n/case_conversion.h" @@ -23,11 +24,17 @@ #include "content/public/common/file_chooser_params.h" #include "grit/cef_strings.h" #include "grit/ui_strings.h" +#include "grit/ui_unscaled_resources.h" #include "net/base/mime_util.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/win/WebInputEventFactory.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/win/hwnd_util.h" +#include "ui/views/controls/webview/webview.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" +#include "webkit/common/cursors/webcursor.h" #pragma comment(lib, "dwmapi.lib") @@ -427,6 +434,174 @@ WORD KeyStatesToWord() { return result; } +// From webkit/common/cursors/webcursor_win.cc. + +using blink::WebCursorInfo; + +LPCWSTR ToCursorID(WebCursorInfo::Type type) { + switch (type) { + case WebCursorInfo::TypePointer: + return IDC_ARROW; + case WebCursorInfo::TypeCross: + return IDC_CROSS; + case WebCursorInfo::TypeHand: + return IDC_HAND; + case WebCursorInfo::TypeIBeam: + return IDC_IBEAM; + case WebCursorInfo::TypeWait: + return IDC_WAIT; + case WebCursorInfo::TypeHelp: + return IDC_HELP; + case WebCursorInfo::TypeEastResize: + return IDC_SIZEWE; + case WebCursorInfo::TypeNorthResize: + return IDC_SIZENS; + case WebCursorInfo::TypeNorthEastResize: + return IDC_SIZENESW; + case WebCursorInfo::TypeNorthWestResize: + return IDC_SIZENWSE; + case WebCursorInfo::TypeSouthResize: + return IDC_SIZENS; + case WebCursorInfo::TypeSouthEastResize: + return IDC_SIZENWSE; + case WebCursorInfo::TypeSouthWestResize: + return IDC_SIZENESW; + case WebCursorInfo::TypeWestResize: + return IDC_SIZEWE; + case WebCursorInfo::TypeNorthSouthResize: + return IDC_SIZENS; + case WebCursorInfo::TypeEastWestResize: + return IDC_SIZEWE; + case WebCursorInfo::TypeNorthEastSouthWestResize: + return IDC_SIZENESW; + case WebCursorInfo::TypeNorthWestSouthEastResize: + return IDC_SIZENWSE; + case WebCursorInfo::TypeColumnResize: + return MAKEINTRESOURCE(IDC_COLRESIZE); + case WebCursorInfo::TypeRowResize: + return MAKEINTRESOURCE(IDC_ROWRESIZE); + case WebCursorInfo::TypeMiddlePanning: + return MAKEINTRESOURCE(IDC_PAN_MIDDLE); + case WebCursorInfo::TypeEastPanning: + return MAKEINTRESOURCE(IDC_PAN_EAST); + case WebCursorInfo::TypeNorthPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH); + case WebCursorInfo::TypeNorthEastPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST); + case WebCursorInfo::TypeNorthWestPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST); + case WebCursorInfo::TypeSouthPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH); + case WebCursorInfo::TypeSouthEastPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST); + case WebCursorInfo::TypeSouthWestPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST); + case WebCursorInfo::TypeWestPanning: + return MAKEINTRESOURCE(IDC_PAN_WEST); + case WebCursorInfo::TypeMove: + return IDC_SIZEALL; + case WebCursorInfo::TypeVerticalText: + return MAKEINTRESOURCE(IDC_VERTICALTEXT); + case WebCursorInfo::TypeCell: + return MAKEINTRESOURCE(IDC_CELL); + case WebCursorInfo::TypeContextMenu: + return MAKEINTRESOURCE(IDC_ARROW); + case WebCursorInfo::TypeAlias: + return MAKEINTRESOURCE(IDC_ALIAS); + case WebCursorInfo::TypeProgress: + return IDC_APPSTARTING; + case WebCursorInfo::TypeNoDrop: + return IDC_NO; + case WebCursorInfo::TypeCopy: + return MAKEINTRESOURCE(IDC_COPYCUR); + case WebCursorInfo::TypeNone: + return MAKEINTRESOURCE(IDC_CURSOR_NONE); + case WebCursorInfo::TypeNotAllowed: + return IDC_NO; + case WebCursorInfo::TypeZoomIn: + return MAKEINTRESOURCE(IDC_ZOOMIN); + case WebCursorInfo::TypeZoomOut: + return MAKEINTRESOURCE(IDC_ZOOMOUT); + case WebCursorInfo::TypeGrab: + return MAKEINTRESOURCE(IDC_HAND_GRAB); + case WebCursorInfo::TypeGrabbing: + return MAKEINTRESOURCE(IDC_HAND_GRABBING); + } + NOTREACHED(); + return NULL; +} + +bool IsSystemCursorID(LPCWSTR cursor_id) { + return cursor_id >= IDC_ARROW; // See WinUser.h +} + +// Manages the views-based root window that hosts the web contents. This object +// will be deleted automatically when the associated root window is destroyed. +class CefWindowDelegateView : public views::WidgetDelegateView { + public: + CefWindowDelegateView() + : web_view_(NULL) { + } + + // Create the Widget and associated root window. + void Init(gfx::AcceleratedWidget parent_widget, + content::WebContents* web_contents, + const gfx::Rect& bounds) { + DCHECK(!web_view_); + web_view_ = new views::WebView(web_contents->GetBrowserContext()); + web_view_->SetWebContents(web_contents); + web_view_->SetPreferredSize(bounds.size()); + + views::Widget* widget = new views::Widget; + + // See CalculateWindowStylesFromInitParams in + // ui/views/widget/widget_hwnd_utils.cc for the conversion of |params| to + // Windows style flags. + views::Widget::InitParams params; + params.parent_widget = parent_widget; + params.bounds = bounds; + params.delegate = this; + params.top_level = true; + // Set the WS_CHILD flag. + params.child = true; + // Set the WS_VISIBLE flag. + params.type = views::Widget::InitParams::TYPE_CONTROL; + // Don't set the WS_EX_COMPOSITED flag. + params.opacity = views::Widget::InitParams::OPAQUE_WINDOW; + + // Results in a call to InitContent(). + widget->Init(params); + + // |widget| should now be associated with |this|. + DCHECK_EQ(widget, GetWidget()); + } + + private: + // Initialize the Widget's content. + void InitContent() { + set_background(views::Background::CreateStandardPanelBackground()); + SetLayoutManager(new views::FillLayout()); + AddChildView(web_view_); + } + + // WidgetDelegateView methods: + virtual bool CanResize() const OVERRIDE { return true; } + virtual bool CanMaximize() const OVERRIDE { return true; } + virtual View* GetContentsView() OVERRIDE { return this; } + + // View methods: + virtual void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) OVERRIDE { + if (details.is_add && details.child == this) + InitContent(); + } + + private: + views::WebView* web_view_; + + DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView); +}; + } // namespace // static @@ -490,12 +665,11 @@ LRESULT CALLBACK CefBrowserHostImpl::WndProc(HWND hwnd, UINT message, case WM_SIZE: // Minimizing resizes the window to 0x0 which causes our layout to go all // screwy, so we just ignore it. - if (wParam != SIZE_MINIMIZED && browser) { - // resize the web view window to the full size of the browser window + if (wParam != SIZE_MINIMIZED && browser && browser->window_widget_) { + // Resize the Widget window to the full size of the browser window. RECT rc; GetClientRect(hwnd, &rc); - MoveWindow(browser->GetContentView(), 0, 0, rc.right, rc.bottom, - TRUE); + browser->window_widget_->SetSize(gfx::Size(rc.right, rc.bottom)); } return 0; @@ -518,6 +692,20 @@ LRESULT CALLBACK CefBrowserHostImpl::WndProc(HWND hwnd, UINT message, return DefWindowProc(hwnd, message, wParam, lParam); } +ui::PlatformCursor CefBrowserHostImpl::GetPlatformCursor( + blink::WebCursorInfo::Type type) { + HMODULE module_handle = NULL; + const wchar_t* cursor_id = ToCursorID(type); + if (!IsSystemCursorID(cursor_id)) { + module_handle = ::GetModuleHandle( + CefContentBrowserClient::Get()->GetResourceDllName()); + if (!module_handle) + module_handle = ::GetModuleHandle(NULL); + } + + return LoadCursor(module_handle, cursor_id); +} + bool CefBrowserHostImpl::PlatformCreateWindow() { std::wstring windowName(CefString(&window_info_.window_name)); @@ -547,20 +735,18 @@ bool CefBrowserHostImpl::PlatformCreateWindow() { // Add a reference that will be released in the WM_DESTROY handler. AddRef(); - // Parent the TabContents to the browser window. - SetParent(web_contents_->GetView()->GetNativeView(), window_info_.window); - - // Size the web view window to the browser window. RECT cr; GetClientRect(window_info_.window, &cr); - // Respect the WS_VISIBLE window style when setting the window's position. - UINT flags = SWP_NOZORDER | SWP_SHOWWINDOW; - if (!(window_info_.style & WS_VISIBLE)) - flags |= SWP_NOACTIVATE; + DCHECK(!window_widget_); - SetWindowPos(GetContentView(), NULL, cr.left, cr.top, cr.right, - cr.bottom, flags); + CefWindowDelegateView* delegate_view = new CefWindowDelegateView(); + delegate_view->Init(window_info_.window, + web_contents(), + gfx::Rect(0, 0, cr.right, cr.bottom)); + + window_widget_ = delegate_view->GetWidget(); + window_widget_->Show(); return true; } @@ -632,8 +818,27 @@ void CefBrowserHostImpl::PlatformHandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) { // Any unhandled keyboard/character messages are sent to DefWindowProc so that // shortcut keys work correctly. - DefWindowProc(event.os_event.hwnd, event.os_event.message, - event.os_event.wParam, event.os_event.lParam); + HWND hwnd = PlatformGetWindowHandle(); + if (!hwnd) + return; + + UINT message = 0; + switch (event.type) { + case blink::WebInputEvent::RawKeyDown: + message = WM_KEYDOWN; + break; + case blink::WebInputEvent::KeyUp: + message = WM_KEYUP; + break; + case blink::WebInputEvent::Char: + message = WM_CHAR; + break; + default: + NOTREACHED(); + return; + } + + DefWindowProc(hwnd, message, event.windowsKeyCode, event.nativeKeyCode); } void CefBrowserHostImpl::PlatformRunFileChooser( diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index da28d371b..85b3da5b9 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -30,6 +30,13 @@ #include "chrome/browser/printing/print_dialog_gtk.h" #endif +#if defined(USE_AURA) +#include "ui/aura/env.h" +#include "ui/gfx/screen.h" +#include "ui/views/test/desktop_test_views_delegate.h" +#include "ui/views/widget/desktop_aura/desktop_screen.h" +#endif // defined(USE_AURA) + CefBrowserMainParts::CefBrowserMainParts( const content::MainFunctionParams& parameters) : BrowserMainParts(), @@ -47,6 +54,15 @@ void CefBrowserMainParts::PreMainMessageLoopStart() { } } +void CefBrowserMainParts::ToolkitInitialized() { +#if defined(USE_AURA) + aura::Env::CreateInstance(); + + DCHECK(!views::ViewsDelegate::views_delegate); + new views::DesktopTestViewsDelegate; +#endif +} + void CefBrowserMainParts::PostMainMessageLoopStart() { // Don't use the default WebUI controller factory because is conflicts with // CEF's internal handling of "chrome://tracing". @@ -67,6 +83,11 @@ int CefBrowserMainParts::PreCreateThreads() { // before the IO thread is started. content::GpuDataManager::GetInstance(); +#if defined(USE_AURA) + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, + views::CreateDesktopScreen()); +#endif + // Initialize user preferences. pref_store_ = new CefBrowserPrefStore(); pref_store_->SetInitializationCompleted(); @@ -138,6 +159,11 @@ void CefBrowserMainParts::PostDestroyThreads() { proxy_v8_isolate_->Dispose(); } +#if defined(USE_AURA) + aura::Env::DeleteInstance(); + delete views::ViewsDelegate::views_delegate; +#endif + PlatformCleanup(); } diff --git a/libcef/browser/browser_main.h b/libcef/browser/browser_main.h index 8ab896e41..271149bfa 100644 --- a/libcef/browser/browser_main.h +++ b/libcef/browser/browser_main.h @@ -41,6 +41,7 @@ class CefBrowserMainParts : public content::BrowserMainParts { virtual void PreMainMessageLoopStart() OVERRIDE; virtual void PostMainMessageLoopStart() OVERRIDE; + virtual void ToolkitInitialized() OVERRIDE; virtual int PreCreateThreads() OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; virtual void PostMainMessageLoopRun() OVERRIDE; diff --git a/libcef/browser/menu_creator_runner_win.cc b/libcef/browser/menu_creator_runner_win.cc index 6019c051e..48e69f6ec 100644 --- a/libcef/browser/menu_creator_runner_win.cc +++ b/libcef/browser/menu_creator_runner_win.cc @@ -7,6 +7,7 @@ #include "base/message_loop/message_loop.h" #include "content/public/browser/web_contents_view.h" +#include "ui/aura/window.h" #include "ui/gfx/point.h" #include "ui/views/controls/menu/menu_2.h" @@ -42,11 +43,10 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) { screen_point = gfx::Point(screenX, screenY); } else { - POINT temp = {manager->params().x, manager->params().y}; - HWND hwnd = - manager->browser()->GetWebContents()->GetView()->GetNativeView(); - ClientToScreen(hwnd, &temp); - screen_point = temp; + aura::Window* window = manager->browser()->GetContentView(); + const gfx::Rect& bounds_in_screen = window->GetBoundsInScreen(); + screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x, + bounds_in_screen.y() + manager->params().y); } // Show the menu. Blocks until the menu is dismissed. diff --git a/libcef/browser/render_widget_host_view_osr.cc b/libcef/browser/render_widget_host_view_osr.cc index ca862ebb1..6b368390c 100644 --- a/libcef/browser/render_widget_host_view_osr.cc +++ b/libcef/browser/render_widget_host_view_osr.cc @@ -6,13 +6,13 @@ #include "libcef/browser/backing_store_osr.h" #include "libcef/browser/browser_host_impl.h" #include "libcef/browser/render_widget_host_view_osr.h" -#include "libcef/common/content_client.h" #include "base/message_loop/message_loop.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_view_host.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "ui/gfx/size_conversions.h" #include "webkit/common/cursors/webcursor.h" namespace { @@ -66,6 +66,12 @@ CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() { // RenderWidgetHostView implementation. + +gfx::Size CefRenderWidgetHostViewOSR::GetPhysicalBackingSize() const { + return gfx::ToCeiledSize(gfx::ScaleSize(GetViewBounds().size(), + GetDeviceScaleFactor())); +} + void CefRenderWidgetHostViewOSR::InitAsChild(gfx::NativeView parent_view) { } @@ -178,17 +184,23 @@ void CefRenderWidgetHostViewOSR::UpdateCursor(const WebCursor& cursor) { TRACE_EVENT0("libcef", "CefRenderWidgetHostViewOSR::UpdateCursor"); if (!browser_impl_.get()) return; -#if defined(OS_WIN) - HMODULE hModule = ::GetModuleHandle( - CefContentClient::Get()->browser()->GetResourceDllName()); - if (!hModule) - hModule = ::GetModuleHandle(NULL); +#if defined(USE_AURA) WebCursor web_cursor = cursor; - HCURSOR hCursor = web_cursor.GetCursor((HINSTANCE)hModule); + + ui::PlatformCursor platform_cursor; + if (web_cursor.IsCustom()) { + // |web_cursor| owns the resulting |platform_cursor|. + platform_cursor = web_cursor.GetPlatformCursor(); + } else { + WebCursor::CursorInfo cursor_info; + cursor.GetCursorInfo(&cursor_info); + platform_cursor = browser_impl_->GetPlatformCursor(cursor_info.type); + } + browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange( - browser_impl_->GetBrowser(), hCursor); + browser_impl_->GetBrowser(), platform_cursor); #elif defined(OS_MACOSX) || defined(TOOLKIT_GTK) - // cursor is const, and GetNativeCursor is not + // |web_cursor| owns the resulting |native_cursor|. WebCursor web_cursor = cursor; CefCursorHandle native_cursor = web_cursor.GetNativeCursor(); browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange( @@ -250,6 +262,12 @@ void CefRenderWidgetHostViewOSR::WillWmDestroy() { } #endif +#if defined(OS_WIN) && defined(USE_AURA) +void CefRenderWidgetHostViewOSR::SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) { +} +#endif + void CefRenderWidgetHostViewOSR::GetScreenInfo(blink::WebScreenInfo* results) { if (!browser_impl_.get()) return; @@ -641,7 +659,7 @@ void CefRenderWidgetHostViewOSR::OnScreenInfoChanged() { // in the rwhv_aura (current_cursor_.SetScaleFactor) } -float CefRenderWidgetHostViewOSR::GetDeviceScaleFactor() { +float CefRenderWidgetHostViewOSR::GetDeviceScaleFactor() const { if (!browser_impl_.get()) return kDefaultScaleFactor; diff --git a/libcef/browser/render_widget_host_view_osr.h b/libcef/browser/render_widget_host_view_osr.h index 6bc088463..215c88d2b 100644 --- a/libcef/browser/render_widget_host_view_osr.h +++ b/libcef/browser/render_widget_host_view_osr.h @@ -75,6 +75,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase { public: // RenderWidgetHostView methods. + virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE; virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE; virtual content::RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE; virtual void SetSize(const gfx::Size& size) OVERRIDE; @@ -136,6 +137,10 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase { int error_code) OVERRIDE; #if defined(OS_WIN) && !defined(USE_AURA) virtual void WillWmDestroy() OVERRIDE; +#endif +#if defined(OS_WIN) && defined(USE_AURA) + virtual void SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) OVERRIDE; #endif virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE; virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE; @@ -202,7 +207,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase { bool InstallTransparency(); void OnScreenInfoChanged(); - float GetDeviceScaleFactor(); + float GetDeviceScaleFactor() const; void CancelWidget(); void NotifyShowWidget(); diff --git a/patch/patch.cfg b/patch/patch.cfg index 2511c283a..aba7275a3 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -14,6 +14,11 @@ patches = [ { # Fix Xcode 4 build on OS X Lion. # http://codereview.chromium.org/8086022/ + # + # Set use_default_render_theme=0 to use native-styled scrollbars with aura. + # Needs to be set here because setting the value in cef.gypi isn't picked up + # by third_party/WebKit/Source/build/features.gypi. + # https://code.google.com/p/chromiumembedded/issues/detail?id=180 'name': 'build', 'path': '../build/', }, @@ -58,6 +63,18 @@ patches = [ 'name': 'webplugin_win', 'path': '../content/child/npapi/', }, + { + # Allow specification of a parent window handle for Widget creation. + # https://code.google.com/p/chromiumembedded/issues/detail?id=180 + 'name': 'views_widget_180', + 'path': '../ui/views/widget/', + }, + { + # Use native-styled scrollbars with aura on Windows. + # https://code.google.com/p/chromiumembedded/issues/detail?id=180 + 'name': 'native_theme_180', + 'path': '../ui/native_theme/', + }, { # Disable scollbar bounce and overlay on OS X. # http://code.google.com/p/chromiumembedded/issues/detail?id=364 diff --git a/patch/patches/build.patch b/patch/patches/build.patch index e73ddb02c..892630268 100644 --- a/patch/patches/build.patch +++ b/patch/patches/build.patch @@ -1,6 +1,6 @@ Index: common.gypi =================================================================== ---- common.gypi (revision 102269) +--- common.gypi (revision 237081) +++ common.gypi (working copy) @@ -9,6 +9,9 @@ # Variables expected to be overriden on the GYP command line (-D) or by @@ -12,9 +12,18 @@ Index: common.gypi # Putting a variables dict inside another variables dict looks kind of # weird. This is done so that 'host_arch', 'chromeos', etc are defined as # variables within the outer variables dict here. This is necessary +@@ -186,7 +189,7 @@ + 'enable_app_list%': 0, + }], + +- ['use_aura==1 or (OS!="win" and OS!="mac" and OS!="ios" and OS!="android")', { ++ ['OS!="win" and OS!="mac" and OS!="ios" and OS!="android"', { + 'use_default_render_theme%': 1, + }, { + 'use_default_render_theme%': 0, Index: mac/strip_save_dsym =================================================================== ---- mac/strip_save_dsym (revision 102269) +--- mac/strip_save_dsym (revision 237081) +++ mac/strip_save_dsym (working copy) @@ -48,7 +48,7 @@ "bundle"] diff --git a/patch/patches/native_theme_180.patch b/patch/patches/native_theme_180.patch new file mode 100644 index 000000000..6ecf7722d --- /dev/null +++ b/patch/patches/native_theme_180.patch @@ -0,0 +1,34 @@ +Index: native_theme_aura.cc +=================================================================== +--- native_theme_aura.cc (revision 237081) ++++ native_theme_aura.cc (working copy) +@@ -17,10 +17,12 @@ + + namespace ui { + ++#if !defined(OS_WIN) + // static + NativeTheme* NativeTheme::instance() { + return NativeThemeAura::instance(); + } ++#endif + + // static + NativeThemeAura* NativeThemeAura::instance() { +Index: native_theme_win.cc +=================================================================== +--- native_theme_win.cc (revision 237081) ++++ native_theme_win.cc (working copy) +@@ -211,12 +211,10 @@ + // TODO(sky): seems like we should default to NativeThemeWin, but that currently + // breaks a couple of tests (FocusTraversalTest.NormalTraversal in + // views_unittests). +-#if !defined(USE_AURA) + // static + NativeTheme* NativeTheme::instance() { + return NativeThemeWin::instance(); + } +-#endif + + // static + NativeThemeWin* NativeThemeWin::instance() { diff --git a/patch/patches/views_widget_180.patch b/patch/patches/views_widget_180.patch new file mode 100644 index 000000000..99a56f49c --- /dev/null +++ b/patch/patches/views_widget_180.patch @@ -0,0 +1,40 @@ +Index: desktop_aura/desktop_root_window_host_win.cc +=================================================================== +--- desktop_aura/desktop_root_window_host_win.cc (revision 237081) ++++ desktop_aura/desktop_root_window_host_win.cc (working copy) +@@ -131,7 +131,9 @@ + native_widget_delegate_); + + HWND parent_hwnd = NULL; +- if (params.parent && params.parent->GetDispatcher()) { ++ if (params.parent_widget) { ++ parent_hwnd = params.parent_widget; ++ } else if (params.parent && params.parent->GetDispatcher()) { + parent_hwnd = + params.parent->GetDispatcher()->host()->GetAcceleratedWidget(); + } +Index: desktop_aura/desktop_screen_win.cc +=================================================================== +--- desktop_aura/desktop_screen_win.cc (revision 237081) ++++ desktop_aura/desktop_screen_win.cc (working copy) +@@ -54,6 +54,8 @@ + } + + HWND DesktopScreenWin::GetHWNDFromNativeView(gfx::NativeView window) const { ++ if (!window) ++ return NULL; + aura::WindowEventDispatcher* dispatcher = window->GetDispatcher(); + return dispatcher ? dispatcher->host()->GetAcceleratedWidget() : NULL; + } +Index: widget.h +=================================================================== +--- widget.h (revision 237081) ++++ widget.h (working copy) +@@ -201,6 +201,7 @@ + // Should the widget be double buffered? Default is false. + bool double_buffer; + gfx::NativeView parent; ++ gfx::AcceleratedWidget parent_widget; + // Specifies the initial bounds of the Widget. Default is empty, which means + // the NativeWidget may specify a default size. If the parent is specified, + // |bounds| is in the parent's coordinate system. If the parent is not diff --git a/tools/gyp_cef b/tools/gyp_cef index 09cfb125c..b946e4b70 100755 --- a/tools/gyp_cef +++ b/tools/gyp_cef @@ -26,6 +26,10 @@ import gyp # Add paths so that pymod_do_main(...) can import files. sys.path.insert(1, os.path.join(chrome_src, 'tools', 'grit')) sys.path.insert(1, os.path.join(chrome_src, 'chrome', 'tools', 'build')) +sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build')) +sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src', + 'build_tools')) +sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build')) sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit', 'Source', 'build', 'scripts'))