// Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "libcef/browser/views/browser_platform_delegate_views.h" #include #include "include/views/cef_window.h" #include "libcef/browser/browser_host_impl.h" #include "libcef/browser/views/browser_view_impl.h" #include "libcef/browser/views/menu_runner_views.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "ui/views/widget/widget.h" namespace { // Default popup window delegate implementation. class PopupWindowDelegate : public CefWindowDelegate { public: explicit PopupWindowDelegate(CefRefPtr browser_view) : browser_view_(browser_view) { } void OnWindowCreated(CefRefPtr window) override { window->AddChildView(browser_view_); window->Show(); browser_view_->RequestFocus(); } void OnWindowDestroyed(CefRefPtr window) override { browser_view_ = nullptr; } bool CanClose(CefRefPtr window) override { CefRefPtr browser = browser_view_->GetBrowser(); if (browser) return browser->GetHost()->TryCloseBrowser(); return true; } private: CefRefPtr browser_view_; IMPLEMENT_REFCOUNTING(PopupWindowDelegate); DISALLOW_COPY_AND_ASSIGN(PopupWindowDelegate); }; } // namespace CefBrowserPlatformDelegateViews::CefBrowserPlatformDelegateViews( std::unique_ptr native_delegate, CefRefPtr browser_view) : native_delegate_(std::move(native_delegate)), browser_view_(browser_view) { native_delegate_->set_windowless_handler(this); } void CefBrowserPlatformDelegateViews::set_browser_view( CefRefPtr browser_view) { browser_view_ = browser_view; } void CefBrowserPlatformDelegateViews::WebContentsCreated( content::WebContents* web_contents) { browser_view_->WebContentsCreated(web_contents); } void CefBrowserPlatformDelegateViews::BrowserCreated( CefBrowserHostImpl* browser) { CefBrowserPlatformDelegate::BrowserCreated(browser); browser_view_->BrowserCreated(browser); } void CefBrowserPlatformDelegateViews::NotifyBrowserCreated() { DCHECK(browser_view_); DCHECK(browser_); if (browser_view_->delegate()) browser_view_->delegate()->OnBrowserCreated(browser_view_, browser_); } void CefBrowserPlatformDelegateViews::NotifyBrowserDestroyed() { DCHECK(browser_view_); DCHECK(browser_); if (browser_view_->delegate()) browser_view_->delegate()->OnBrowserDestroyed(browser_view_, browser_); } void CefBrowserPlatformDelegateViews::BrowserDestroyed( CefBrowserHostImpl* browser) { CefBrowserPlatformDelegate::BrowserDestroyed(browser); browser_view_->BrowserDestroyed(browser); browser_view_ = nullptr; } bool CefBrowserPlatformDelegateViews::CreateHostWindow() { // Nothing to do here. return true; } void CefBrowserPlatformDelegateViews::CloseHostWindow() { views::Widget* widget = GetWindowWidget(); if (widget && !widget->IsClosed()) widget->Close(); } CefWindowHandle CefBrowserPlatformDelegateViews::GetHostWindowHandle() const { return view_util::GetWindowHandle(GetWindowWidget()); } views::Widget* CefBrowserPlatformDelegateViews::GetWindowWidget() const { if (browser_view_->root_view()) return browser_view_->root_view()->GetWidget(); return nullptr; } CefRefPtr CefBrowserPlatformDelegateViews::GetBrowserView() const { return browser_view_.get(); } void CefBrowserPlatformDelegateViews::PopupWebContentsCreated( const CefBrowserSettings& settings, CefRefPtr client, content::WebContents* new_web_contents, CefBrowserPlatformDelegate* new_platform_delegate, bool is_devtools) { DCHECK(new_platform_delegate->IsViewsHosted()); CefBrowserPlatformDelegateViews* new_platform_delegate_impl = static_cast(new_platform_delegate); CefRefPtr new_delegate; if (browser_view_->delegate()) { new_delegate = browser_view_->delegate()->GetDelegateForPopupBrowserView( browser_view_.get(), settings, client, is_devtools); } // Create a new BrowserView for the popup. CefRefPtr new_browser_view = CefBrowserViewImpl::CreateForPopup(settings, new_delegate); // Associate the PlatformDelegate with the new BrowserView. new_platform_delegate_impl->set_browser_view(new_browser_view); } void CefBrowserPlatformDelegateViews::PopupBrowserCreated( CefBrowserHostImpl* new_browser, bool is_devtools) { CefRefPtr new_browser_view = CefBrowserView::GetForBrowser(new_browser); DCHECK(new_browser_view); bool popup_handled = false; if (browser_view_->delegate()) { popup_handled = browser_view_->delegate()->OnPopupBrowserViewCreated( browser_view_.get(), new_browser_view.get(), is_devtools); } if (!popup_handled) { CefWindow::CreateTopLevelWindow( new PopupWindowDelegate(new_browser_view.get())); } } void CefBrowserPlatformDelegateViews::WasResized() { content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); if (host) host->GetWidget()->WasResized(); } void CefBrowserPlatformDelegateViews::SendKeyEvent( const content::NativeWebKeyboardEvent& event) { content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); if (host) host->GetWidget()->ForwardKeyboardEvent(event); } void CefBrowserPlatformDelegateViews::SendMouseEvent( const blink::WebMouseEvent& event) { content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); if (host) host->GetWidget()->ForwardMouseEvent(event); } void CefBrowserPlatformDelegateViews::SendMouseWheelEvent( const blink::WebMouseWheelEvent& event) { content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); if (host) host->GetWidget()->ForwardWheelEvent(event); } void CefBrowserPlatformDelegateViews::SendFocusEvent(bool setFocus) { // Will result in a call to WebContents::Focus(). if (setFocus && browser_view_->root_view()) browser_view_->root_view()->RequestFocus(); } gfx::Point CefBrowserPlatformDelegateViews::GetScreenPoint( const gfx::Point& view_pt) const { if (!browser_view_->root_view()) return view_pt; gfx::Point screen_point = view_pt; view_util::ConvertPointToScreen(browser_view_->root_view(), &screen_point, true); return screen_point; } void CefBrowserPlatformDelegateViews::ViewText(const std::string& text) { native_delegate_->ViewText(text); } void CefBrowserPlatformDelegateViews::HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) { // The BrowserView will handle accelerators. browser_view_->HandleKeyboardEvent(event); } void CefBrowserPlatformDelegateViews::HandleExternalProtocol(const GURL& url) { native_delegate_->HandleExternalProtocol(url); } void CefBrowserPlatformDelegateViews::TranslateKeyEvent( content::NativeWebKeyboardEvent& result, const CefKeyEvent& key_event) const { native_delegate_->TranslateKeyEvent(result, key_event); } void CefBrowserPlatformDelegateViews::TranslateClickEvent( blink::WebMouseEvent& result, const CefMouseEvent& mouse_event, CefBrowserHost::MouseButtonType type, bool mouseUp, int clickCount) const { native_delegate_->TranslateClickEvent(result, mouse_event, type, mouseUp, clickCount); } void CefBrowserPlatformDelegateViews::TranslateMoveEvent( blink::WebMouseEvent& result, const CefMouseEvent& mouse_event, bool mouseLeave) const { native_delegate_->TranslateMoveEvent(result, mouse_event, mouseLeave); } void CefBrowserPlatformDelegateViews::TranslateWheelEvent( blink::WebMouseWheelEvent& result, const CefMouseEvent& mouse_event, int deltaX, int deltaY) const { native_delegate_->TranslateWheelEvent(result, mouse_event, deltaX, deltaY); } CefEventHandle CefBrowserPlatformDelegateViews::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { return native_delegate_->GetEventHandle(event); } std::unique_ptr CefBrowserPlatformDelegateViews::CreateFileDialogRunner() { return native_delegate_->CreateFileDialogRunner(); } std::unique_ptr CefBrowserPlatformDelegateViews::CreateJavaScriptDialogRunner() { return native_delegate_->CreateJavaScriptDialogRunner(); } std::unique_ptr CefBrowserPlatformDelegateViews::CreateMenuRunner() { return base::WrapUnique(new CefMenuRunnerViews(browser_view_.get())); } bool CefBrowserPlatformDelegateViews::IsWindowless() const { return false; } bool CefBrowserPlatformDelegateViews::IsViewsHosted() const { return true; } CefWindowHandle CefBrowserPlatformDelegateViews::GetParentWindowHandle() const { return GetHostWindowHandle(); } gfx::Point CefBrowserPlatformDelegateViews::GetParentScreenPoint( const gfx::Point& view) const { return GetScreenPoint(view); }