mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Add "cef/" prefix for CEF #includes in libcef/ directory. Sort #includes by following https://google.github.io/styleguide/cppguide.html#Names_and_Order_of_Includes
		
			
				
	
	
		
			219 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2022 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 "cef/libcef/browser/chrome/views/chrome_child_window.h"
 | 
						|
 | 
						|
#include "cef/libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
 | 
						|
#include "cef/libcef/browser/views/browser_view_impl.h"
 | 
						|
#include "cef/libcef/browser/views/window_impl.h"
 | 
						|
#include "ui/gfx/native_widget_types.h"
 | 
						|
 | 
						|
#if BUILDFLAG(IS_WIN)
 | 
						|
#include "cef/libcef/browser/native/browser_platform_delegate_native_win.h"
 | 
						|
#include "ui/views/win/hwnd_util.h"
 | 
						|
#endif
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
gfx::AcceleratedWidget GetParentWidget(const CefWindowInfo& window_info) {
 | 
						|
#if !BUILDFLAG(IS_MAC)
 | 
						|
  return window_info.parent_window;
 | 
						|
#else
 | 
						|
  // Chrome style is not supported with native parent on MacOS. See issue #3294.
 | 
						|
  return gfx::kNullAcceleratedWidget;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
CefWindowHandle GetParentHandle(const CefWindowInfo& window_info) {
 | 
						|
#if !BUILDFLAG(IS_MAC)
 | 
						|
  return window_info.parent_window;
 | 
						|
#else
 | 
						|
  return window_info.parent_view;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
class ChildWindowDelegate : public CefWindowDelegate {
 | 
						|
 public:
 | 
						|
  ChildWindowDelegate(const ChildWindowDelegate&) = delete;
 | 
						|
  ChildWindowDelegate& operator=(const ChildWindowDelegate&) = delete;
 | 
						|
 | 
						|
  static void Create(CefRefPtr<CefBrowserView> browser_view,
 | 
						|
                     const CefWindowInfo& window_info,
 | 
						|
                     gfx::AcceleratedWidget parent_handle) {
 | 
						|
    DCHECK(parent_handle != gfx::kNullAcceleratedWidget);
 | 
						|
 | 
						|
    // Create the Window. It will show itself after creation.
 | 
						|
    CefWindowImpl::Create(new ChildWindowDelegate(browser_view, window_info),
 | 
						|
                          parent_handle);
 | 
						|
  }
 | 
						|
 | 
						|
  void OnWindowCreated(CefRefPtr<CefWindow> window) override {
 | 
						|
    DCHECK(!window_);
 | 
						|
    window_ = window;
 | 
						|
 | 
						|
    // Add the browser view. It will now have an associated Widget.
 | 
						|
    window_->AddChildView(browser_view_);
 | 
						|
 | 
						|
    ShowWindow();
 | 
						|
  }
 | 
						|
 | 
						|
  void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
 | 
						|
    browser_view_ = nullptr;
 | 
						|
    window_ = nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override {
 | 
						|
    CefRect initial_bounds(window_info_.bounds);
 | 
						|
    if (initial_bounds.IsEmpty()) {
 | 
						|
      return CefRect(0, 0, 800, 600);
 | 
						|
    }
 | 
						|
    return initial_bounds;
 | 
						|
  }
 | 
						|
 | 
						|
  void ShowWindow() {
 | 
						|
#if BUILDFLAG(IS_WIN)
 | 
						|
    auto widget = static_cast<CefWindowImpl*>(window_.get())->widget();
 | 
						|
    DCHECK(widget);
 | 
						|
    const HWND widget_hwnd = HWNDForWidget(widget);
 | 
						|
    DCHECK(widget_hwnd);
 | 
						|
 | 
						|
    // The native delegate needs state to perform some actions.
 | 
						|
    auto browser = CefBrowserHostBase::FromBrowser(browser_view_->GetBrowser());
 | 
						|
    auto platform_delegate = browser->platform_delegate();
 | 
						|
    DCHECK(platform_delegate->IsViewsHosted());
 | 
						|
    auto chrome_delegate =
 | 
						|
        static_cast<CefBrowserPlatformDelegateChromeViews*>(platform_delegate);
 | 
						|
    auto native_delegate = static_cast<CefBrowserPlatformDelegateNativeWin*>(
 | 
						|
        chrome_delegate->native_delegate());
 | 
						|
    native_delegate->set_widget(widget, widget_hwnd);
 | 
						|
 | 
						|
    if (window_info_.ex_style & WS_EX_NOACTIVATE) {
 | 
						|
      const DWORD widget_ex_styles = GetWindowLongPtr(widget_hwnd, GWL_EXSTYLE);
 | 
						|
 | 
						|
      // Add the WS_EX_NOACTIVATE style on the DesktopWindowTreeHostWin HWND
 | 
						|
      // so that HWNDMessageHandler::Show() called via Widget::Show() does not
 | 
						|
      // activate the window.
 | 
						|
      SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE,
 | 
						|
                       widget_ex_styles | WS_EX_NOACTIVATE);
 | 
						|
 | 
						|
      window_->Show();
 | 
						|
 | 
						|
      // Remove the WS_EX_NOACTIVATE style so that future mouse clicks inside
 | 
						|
      // the browser correctly activate and focus the window.
 | 
						|
      SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE, widget_ex_styles);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
#endif  // BUILDFLAG(IS_WIN)
 | 
						|
 | 
						|
    window_->Show();
 | 
						|
 | 
						|
    // Give keyboard focus to the browser view.
 | 
						|
    browser_view_->RequestFocus();
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  ChildWindowDelegate(CefRefPtr<CefBrowserView> browser_view,
 | 
						|
                      const CefWindowInfo& window_info)
 | 
						|
      : browser_view_(browser_view), window_info_(window_info) {}
 | 
						|
 | 
						|
  CefRefPtr<CefBrowserView> browser_view_;
 | 
						|
  const CefWindowInfo window_info_;
 | 
						|
 | 
						|
  CefRefPtr<CefWindow> window_;
 | 
						|
 | 
						|
  IMPLEMENT_REFCOUNTING(ChildWindowDelegate);
 | 
						|
};
 | 
						|
 | 
						|
class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
 | 
						|
 public:
 | 
						|
  ChildBrowserViewDelegate() = default;
 | 
						|
 | 
						|
  ChildBrowserViewDelegate(const ChildBrowserViewDelegate&) = delete;
 | 
						|
  ChildBrowserViewDelegate& operator=(const ChildBrowserViewDelegate&) = delete;
 | 
						|
 | 
						|
  // |browser_view| will be nullptr when called for popups with non-Views-hosted
 | 
						|
  // opener.
 | 
						|
  CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
 | 
						|
      CefRefPtr<CefBrowserView> browser_view,
 | 
						|
      const CefBrowserSettings& settings,
 | 
						|
      CefRefPtr<CefClient> client,
 | 
						|
      bool is_devtools) override {
 | 
						|
    return new ChildBrowserViewDelegate();
 | 
						|
  }
 | 
						|
 | 
						|
  // |browser_view| will be nullptr when called for popups with non-Views-hosted
 | 
						|
  // opener.
 | 
						|
  bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
 | 
						|
                                 CefRefPtr<CefBrowserView> popup_browser_view,
 | 
						|
                                 bool is_devtools) override {
 | 
						|
    auto new_browser =
 | 
						|
        CefBrowserHostBase::FromBrowser(popup_browser_view->GetBrowser());
 | 
						|
    auto new_platform_delegate = new_browser->platform_delegate();
 | 
						|
    DCHECK(new_platform_delegate->IsViewsHosted());
 | 
						|
    auto new_platform_delegate_impl =
 | 
						|
        static_cast<CefBrowserPlatformDelegateChromeViews*>(
 | 
						|
            new_platform_delegate);
 | 
						|
 | 
						|
    const auto& window_info =
 | 
						|
        new_platform_delegate_impl->native_delegate()->window_info();
 | 
						|
    const auto parent_handle = GetParentWidget(window_info);
 | 
						|
    if (parent_handle != gfx::kNullAcceleratedWidget) {
 | 
						|
      ChildWindowDelegate::Create(popup_browser_view, window_info,
 | 
						|
                                  parent_handle);
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    // Use the default implementation that creates a new Views-hosted top-level
 | 
						|
    // window.
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  IMPLEMENT_REFCOUNTING(ChildBrowserViewDelegate);
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
namespace chrome_child_window {
 | 
						|
 | 
						|
bool HasParentHandle(const CefWindowInfo& window_info) {
 | 
						|
  return GetParentHandle(window_info) != kNullWindowHandle;
 | 
						|
}
 | 
						|
 | 
						|
CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
 | 
						|
    const CefBrowserCreateParams& create_params) {
 | 
						|
  // If the BrowserView already exists it means that we're dealing with a popup
 | 
						|
  // and we'll instead create the Window in OnPopupBrowserViewCreated.
 | 
						|
  if (create_params.browser_view) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!create_params.window_info) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  const auto parent_handle = GetParentWidget(*create_params.window_info);
 | 
						|
  if (parent_handle == gfx::kNullAcceleratedWidget) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create the BrowserView.
 | 
						|
  auto browser_view = CefBrowserViewImpl::Create(
 | 
						|
      *create_params.window_info, create_params.client, create_params.url,
 | 
						|
      create_params.settings, create_params.extra_info,
 | 
						|
      create_params.request_context, new ChildBrowserViewDelegate());
 | 
						|
 | 
						|
  ChildWindowDelegate::Create(browser_view, *create_params.window_info,
 | 
						|
                              parent_handle);
 | 
						|
 | 
						|
  return CefBrowserHostBase::FromBrowser(browser_view->GetBrowser());
 | 
						|
}
 | 
						|
 | 
						|
CefRefPtr<CefBrowserViewDelegate>
 | 
						|
GetDefaultBrowserViewDelegateForPopupOpener() {
 | 
						|
  return new ChildBrowserViewDelegate();
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace chrome_child_window
 |