mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
views: Add support for absolute positioned overlay views.
To test: Run `cefclient.exe --use-views --hide-frame --hide-controls` Add `--enable-chrome-runtime` for the same behavior using the Chrome location bar instead of a text field.
This commit is contained in:
15
libcef/browser/chrome/views/chrome_views_util.cc
Normal file
15
libcef/browser/chrome/views/chrome_views_util.cc
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2021 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/chrome/views/chrome_views_util.h"
|
||||
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
|
||||
namespace cef {
|
||||
|
||||
bool IsCefView(views::View* view) {
|
||||
return view_util::GetFor(view, /*find_known_parent=*/false) != nullptr;
|
||||
}
|
||||
|
||||
} // namespace cef
|
20
libcef/browser/chrome/views/chrome_views_util.h
Normal file
20
libcef/browser/chrome/views/chrome_views_util.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_VIEWS_H_
|
||||
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_VIEWS_H_
|
||||
#pragma once
|
||||
|
||||
namespace views {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace cef {
|
||||
|
||||
// Returns true if |view| is a CefView.
|
||||
bool IsCefView(views::View* view);
|
||||
|
||||
} // namespace cef
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_VIEWS_H_
|
330
libcef/browser/views/overlay_view_host.cc
Normal file
330
libcef/browser/views/overlay_view_host.cc
Normal file
@@ -0,0 +1,330 @@
|
||||
// Copyright 2021 The Chromium Embedded Framework Authors. Portions copyright
|
||||
// 2011 The Chromium 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/overlay_view_host.h"
|
||||
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
#include "libcef/browser/views/window_view.h"
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "chrome/browser/ui/views/frame/browser_view.h"
|
||||
#include "chrome/browser/ui/views/theme_copying_widget.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/views/view_constants_aura.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
class CefOverlayControllerImpl : public CefOverlayController {
|
||||
public:
|
||||
CefOverlayControllerImpl(CefOverlayViewHost* host, CefRefPtr<CefView> view)
|
||||
: host_(host), view_(view) {}
|
||||
|
||||
bool IsValid() override {
|
||||
// View validity implies that CefOverlayViewHost is still valid, because the
|
||||
// Widget that it owns (and that owns the View) is still valid.
|
||||
return view_ && view_->IsValid();
|
||||
}
|
||||
|
||||
bool IsSame(CefRefPtr<CefOverlayController> that) override {
|
||||
return that && that->GetContentsView()->IsSame(view_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefView> GetContentsView() override { return view_; }
|
||||
|
||||
CefRefPtr<CefWindow> GetWindow() override {
|
||||
if (IsValid()) {
|
||||
return view_util::GetWindowFor(host_->window_view()->GetWidget());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cef_docking_mode_t GetDockingMode() override {
|
||||
if (IsValid()) {
|
||||
return host_->docking_mode();
|
||||
}
|
||||
return CEF_DOCKING_MODE_TOP_LEFT;
|
||||
}
|
||||
|
||||
void Destroy() override {
|
||||
if (IsValid()) {
|
||||
host_->Destroy();
|
||||
view_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetBounds(const CefRect& bounds) override {
|
||||
if (IsValid() && host_->docking_mode() == CEF_DOCKING_MODE_CUSTOM) {
|
||||
host_->SetOverlayBounds(
|
||||
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
}
|
||||
}
|
||||
|
||||
CefRect GetBounds() override {
|
||||
if (IsValid()) {
|
||||
const auto& bounds = host_->bounds();
|
||||
return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
||||
}
|
||||
return CefRect();
|
||||
}
|
||||
|
||||
CefRect GetBoundsInScreen() override {
|
||||
if (IsValid()) {
|
||||
const auto& bounds = host_->widget()->GetWindowBoundsInScreen();
|
||||
return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
||||
}
|
||||
return CefRect();
|
||||
}
|
||||
|
||||
void SetSize(const CefSize& size) override {
|
||||
if (IsValid() && host_->docking_mode() == CEF_DOCKING_MODE_CUSTOM) {
|
||||
// Update the size without changing the origin.
|
||||
const auto& origin = host_->bounds().origin();
|
||||
host_->SetOverlayBounds(
|
||||
gfx::Rect(origin, gfx::Size(size.width, size.height)));
|
||||
}
|
||||
}
|
||||
|
||||
CefSize GetSize() override {
|
||||
const auto& bounds = GetBounds();
|
||||
return CefSize(bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
void SetPosition(const CefPoint& position) override {
|
||||
if (IsValid() && host_->docking_mode() == CEF_DOCKING_MODE_CUSTOM) {
|
||||
// Update the origin without changing the size.
|
||||
const auto& size = host_->bounds().size();
|
||||
host_->SetOverlayBounds(
|
||||
gfx::Rect(gfx::Point(position.x, position.y), size));
|
||||
}
|
||||
}
|
||||
|
||||
CefPoint GetPosition() override {
|
||||
const auto& bounds = GetBounds();
|
||||
return CefPoint(bounds.x, bounds.y);
|
||||
}
|
||||
|
||||
void SetInsets(const CefInsets& insets) override {
|
||||
if (IsValid() && host_->docking_mode() != CEF_DOCKING_MODE_CUSTOM) {
|
||||
host_->SetOverlayInsets(insets);
|
||||
}
|
||||
}
|
||||
|
||||
CefInsets GetInsets() override {
|
||||
if (IsValid()) {
|
||||
return host_->insets();
|
||||
}
|
||||
return CefInsets();
|
||||
}
|
||||
|
||||
void SizeToPreferredSize() override {
|
||||
if (IsValid()) {
|
||||
if (host_->docking_mode() == CEF_DOCKING_MODE_CUSTOM) {
|
||||
// Update the size without changing the origin.
|
||||
const auto& origin = host_->bounds().origin();
|
||||
const auto& preferred_size = host_->view()->GetPreferredSize();
|
||||
host_->SetOverlayBounds(gfx::Rect(origin, preferred_size));
|
||||
} else {
|
||||
host_->MoveIfNecessary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetVisible(bool visible) override {
|
||||
if (IsValid()) {
|
||||
if (visible) {
|
||||
host_->MoveIfNecessary();
|
||||
host_->widget()->Show();
|
||||
} else {
|
||||
host_->widget()->Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsVisible() override {
|
||||
if (IsValid()) {
|
||||
return host_->widget()->IsVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsDrawn() override { return IsVisible(); }
|
||||
|
||||
private:
|
||||
CefOverlayViewHost* const host_;
|
||||
CefRefPtr<CefView> view_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefOverlayControllerImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefOverlayControllerImpl);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefOverlayViewHost::CefOverlayViewHost(CefWindowView* window_view,
|
||||
cef_docking_mode_t docking_mode)
|
||||
: window_view_(window_view), docking_mode_(docking_mode) {}
|
||||
|
||||
void CefOverlayViewHost::Init(views::View* widget_view,
|
||||
CefRefPtr<CefView> view) {
|
||||
DCHECK(view);
|
||||
|
||||
// Match the logic in CEF_PANEL_IMPL_D::AddChildView().
|
||||
auto controls_view = view->IsAttached()
|
||||
? base::WrapUnique(view_util::GetFor(view))
|
||||
: view_util::PassOwnership(view);
|
||||
DCHECK(controls_view.get());
|
||||
|
||||
cef_controller_ = new CefOverlayControllerImpl(this, view);
|
||||
|
||||
// Initialize the Widget.
|
||||
widget_ = std::make_unique<ThemeCopyingWidget>(window_view_->GetWidget());
|
||||
views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
|
||||
params.delegate = this;
|
||||
params.name = "CefOverlayViewHost";
|
||||
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
||||
params.parent = window_view_->GetWidget()->GetNativeView();
|
||||
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
|
||||
params.activatable = views::Widget::InitParams::Activatable::kNo;
|
||||
widget_->Init(std::move(params));
|
||||
|
||||
view_ = widget_->GetContentsView()->AddChildView(std::move(controls_view));
|
||||
|
||||
// Make the Widget background transparent. The View might still be opaque.
|
||||
if (widget_->GetCompositor()) {
|
||||
widget_->GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// See matching logic in view_util::GetWindowFor.
|
||||
widget_->GetNativeView()->SetProperty(views::kHostViewKey, widget_view);
|
||||
#endif
|
||||
|
||||
if (cef::IsChromeRuntimeEnabled()) {
|
||||
// Some attributes associated with a Chrome toolbar are located via the
|
||||
// Widget. See matching logic in BrowserView::AddedToWidget.
|
||||
auto browser_view = BrowserView::GetBrowserViewForNativeWindow(
|
||||
view_util::GetNativeWindow(window_view_->GetWidget()));
|
||||
if (browser_view) {
|
||||
widget_->SetNativeWindowProperty(BrowserView::kBrowserViewKey,
|
||||
browser_view);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the initial bounds after the View has been added to the Widget.
|
||||
// Otherwise, preferred size won't calculate correctly.
|
||||
gfx::Rect bounds;
|
||||
if (docking_mode_ == CEF_DOCKING_MODE_CUSTOM) {
|
||||
if (view_->size().IsEmpty()) {
|
||||
// Size to the preferred size to start.
|
||||
view_->SizeToPreferredSize();
|
||||
}
|
||||
|
||||
// Top-left origin with existing size.
|
||||
bounds = gfx::Rect(gfx::Point(), view_->size());
|
||||
} else {
|
||||
bounds = ComputeBounds();
|
||||
}
|
||||
SetOverlayBounds(bounds);
|
||||
|
||||
// Register for future bounds change notifications.
|
||||
view_->AddObserver(this);
|
||||
|
||||
// Initially hidden.
|
||||
widget_->Hide();
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::Destroy() {
|
||||
if (widget_ && !widget_->IsClosed()) {
|
||||
// Remove the child View immediately. It may be reused by the client.
|
||||
auto view = view_util::GetFor(view_, /*find_known_parent=*/false);
|
||||
widget_->GetContentsView()->RemoveChildView(view_);
|
||||
if (view) {
|
||||
view_util::ResumeOwnership(view);
|
||||
}
|
||||
|
||||
widget_->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::MoveIfNecessary() {
|
||||
if (bounds_changing_ || docking_mode_ == CEF_DOCKING_MODE_CUSTOM) {
|
||||
return;
|
||||
}
|
||||
SetOverlayBounds(ComputeBounds());
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::SetOverlayBounds(const gfx::Rect& bounds) {
|
||||
// Avoid re-entrancy of this method.
|
||||
if (bounds_changing_)
|
||||
return;
|
||||
|
||||
gfx::Rect new_bounds = bounds;
|
||||
|
||||
// Keep the result inside the widget.
|
||||
new_bounds.Intersect(window_view_->bounds());
|
||||
|
||||
if (new_bounds == bounds_)
|
||||
return;
|
||||
|
||||
bounds_changing_ = true;
|
||||
|
||||
bounds_ = new_bounds;
|
||||
if (view_->size() != bounds_.size()) {
|
||||
view_->SetSize(bounds_.size());
|
||||
}
|
||||
widget_->SetBounds(bounds_);
|
||||
|
||||
bounds_changing_ = false;
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::SetOverlayInsets(const CefInsets& insets) {
|
||||
if (insets == insets_)
|
||||
return;
|
||||
insets_ = insets;
|
||||
MoveIfNecessary();
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::OnViewBoundsChanged(views::View* observed_view) {
|
||||
MoveIfNecessary();
|
||||
}
|
||||
|
||||
gfx::Rect CefOverlayViewHost::ComputeBounds() const {
|
||||
// This method is only used with corner docking.
|
||||
DCHECK_NE(docking_mode_, CEF_DOCKING_MODE_CUSTOM);
|
||||
|
||||
// Find the area we have to work with.
|
||||
const auto& widget_bounds = window_view_->bounds();
|
||||
|
||||
// Ask the view how large an area it needs to draw on.
|
||||
const auto& prefsize = view_->GetPreferredSize();
|
||||
|
||||
// Swap left/right docking with RTL.
|
||||
const bool is_rtl = base::i18n::IsRTL();
|
||||
|
||||
// Dock to the correct corner, considering insets in the docking corner only.
|
||||
int x = widget_bounds.x();
|
||||
int y = widget_bounds.y();
|
||||
if (((docking_mode_ == CEF_DOCKING_MODE_TOP_RIGHT ||
|
||||
docking_mode_ == CEF_DOCKING_MODE_BOTTOM_RIGHT) &&
|
||||
!is_rtl) ||
|
||||
((docking_mode_ == CEF_DOCKING_MODE_TOP_LEFT ||
|
||||
docking_mode_ == CEF_DOCKING_MODE_BOTTOM_LEFT) &&
|
||||
is_rtl)) {
|
||||
x += widget_bounds.width() - prefsize.width() - insets_.right;
|
||||
} else {
|
||||
x += insets_.left;
|
||||
}
|
||||
if (docking_mode_ == CEF_DOCKING_MODE_BOTTOM_LEFT ||
|
||||
docking_mode_ == CEF_DOCKING_MODE_BOTTOM_RIGHT) {
|
||||
y += widget_bounds.height() - prefsize.height() - insets_.bottom;
|
||||
} else {
|
||||
y += insets_.top;
|
||||
}
|
||||
|
||||
return gfx::Rect(x, y, prefsize.width(), prefsize.height());
|
||||
}
|
79
libcef/browser/views/overlay_view_host.h
Normal file
79
libcef/browser/views/overlay_view_host.h
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2021 The Chromium Embedded Framework Authors. Portions copyright
|
||||
// 2011 The Chromium Authors. All rights reserved. Use of this source code is
|
||||
// governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_VIEWS_OVERLAY_VIEW_HOST_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_OVERLAY_VIEW_HOST_H_
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "include/views/cef_overlay_controller.h"
|
||||
#include "include/views/cef_view.h"
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "ui/views/view_observer.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
class CefWindowView;
|
||||
|
||||
// Host class for a child Widget that behaves as an overlay control. Based on
|
||||
// Chrome's DropdownBarHost.
|
||||
class CefOverlayViewHost : public views::WidgetDelegate,
|
||||
public views::ViewObserver {
|
||||
public:
|
||||
// |window_view| is the top-level view that contains this overlay.
|
||||
CefOverlayViewHost(CefWindowView* window_view,
|
||||
cef_docking_mode_t docking_mode);
|
||||
|
||||
// Initializes the CefOverlayViewHost. This creates the Widget that |view|
|
||||
// paints into. |host_view| is the view whose position in the |window_view_|
|
||||
// view hierarchy determines the z-order of the widget relative to views with
|
||||
// layers and views with associated NativeViews.
|
||||
void Init(views::View* host_view, CefRefPtr<CefView> view);
|
||||
|
||||
void Destroy();
|
||||
|
||||
void MoveIfNecessary();
|
||||
|
||||
void SetOverlayBounds(const gfx::Rect& bounds);
|
||||
void SetOverlayInsets(const CefInsets& insets);
|
||||
|
||||
// views::ViewObserver methods:
|
||||
void OnViewBoundsChanged(views::View* observed_view) override;
|
||||
|
||||
cef_docking_mode_t docking_mode() const { return docking_mode_; }
|
||||
CefRefPtr<CefOverlayController> controller() const { return cef_controller_; }
|
||||
CefWindowView* window_view() const { return window_view_; }
|
||||
views::Widget* widget() const { return widget_.get(); }
|
||||
views::View* view() const { return view_; }
|
||||
gfx::Rect bounds() const { return bounds_; }
|
||||
CefInsets insets() const { return insets_; }
|
||||
|
||||
private:
|
||||
gfx::Rect ComputeBounds() const;
|
||||
|
||||
// The CefWindowView that created us.
|
||||
CefWindowView* const window_view_;
|
||||
|
||||
const cef_docking_mode_t docking_mode_;
|
||||
|
||||
// Our view, which is responsible for drawing the UI.
|
||||
views::View* view_ = nullptr;
|
||||
|
||||
// The Widget implementation that is created and maintained by the overlay.
|
||||
// It contains |view_|.
|
||||
std::unique_ptr<views::Widget> widget_;
|
||||
|
||||
CefRefPtr<CefOverlayController> cef_controller_;
|
||||
|
||||
gfx::Rect bounds_;
|
||||
bool bounds_changing_ = false;
|
||||
|
||||
CefInsets insets_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefOverlayViewHost);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_OVERLAY_VIEW_HOST_H_
|
@@ -299,6 +299,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/border.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
@@ -384,6 +385,8 @@ CEF_VIEW_IMPL_T class CefViewImpl : public CefViewAdapter, public CefViewClass {
|
||||
CefSize GetSize() override;
|
||||
void SetPosition(const CefPoint& position) override;
|
||||
CefPoint GetPosition() override;
|
||||
void SetInsets(const CefInsets& insets) override;
|
||||
CefInsets GetInsets() override;
|
||||
CefSize GetPreferredSize() override;
|
||||
void SizeToPreferredSize() override;
|
||||
CefSize GetMinimumSize() override;
|
||||
@@ -571,6 +574,20 @@ CEF_VIEW_IMPL_T CefPoint CEF_VIEW_IMPL_D::GetPosition() {
|
||||
return CefPoint(bounds.x, bounds.y);
|
||||
}
|
||||
|
||||
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetInsets(const CefInsets& insets) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
gfx::Insets gfx_insets(insets.top, insets.left, insets.bottom, insets.right);
|
||||
root_view()->SetBorder(
|
||||
gfx_insets.IsEmpty() ? nullptr : views::CreateEmptyBorder(gfx_insets));
|
||||
}
|
||||
|
||||
CEF_VIEW_IMPL_T CefInsets CEF_VIEW_IMPL_D::GetInsets() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefInsets());
|
||||
const auto insets = root_view()->GetInsets();
|
||||
return CefInsets(insets.top(), insets.left(), insets.bottom(),
|
||||
insets.right());
|
||||
}
|
||||
|
||||
CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetPreferredSize() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefSize());
|
||||
const gfx::Size& size = root_view()->GetPreferredSize();
|
||||
|
@@ -20,6 +20,11 @@
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/views/view_constants_aura.h"
|
||||
#endif
|
||||
|
||||
namespace view_util {
|
||||
|
||||
namespace {
|
||||
@@ -160,6 +165,18 @@ void ResumeOwnership(CefRefPtr<CefView> view) {
|
||||
CefRefPtr<CefWindow> GetWindowFor(views::Widget* widget) {
|
||||
CefRefPtr<CefWindow> window;
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// Retrieve the parent Widget for an overlay.
|
||||
if (widget) {
|
||||
// See matching logic in CefOverlayViewHost::Init.
|
||||
auto widget_view =
|
||||
widget->GetNativeView()->GetProperty(views::kHostViewKey);
|
||||
if (widget_view) {
|
||||
widget = widget_view->GetWidget();
|
||||
}
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
if (widget) {
|
||||
// The views::WidgetDelegate should be a CefWindowView and |content_view|
|
||||
// should be the same CefWindowView. However, just in case the views::Widget
|
||||
|
@@ -156,6 +156,13 @@ CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::Layout() {
|
||||
// If Layout() did not provide a size then use the preferred size.
|
||||
if (ParentClass::size().IsEmpty())
|
||||
ParentClass::SizeToPreferredSize();
|
||||
|
||||
if (cef_delegate()) {
|
||||
const auto new_bounds = ParentClass::bounds();
|
||||
CefRect new_rect(new_bounds.x(), new_bounds.y(), new_bounds.width(),
|
||||
new_bounds.height());
|
||||
cef_delegate()->OnLayoutChanged(GetCefView(), new_rect);
|
||||
}
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::ViewHierarchyChanged(
|
||||
@@ -202,8 +209,9 @@ CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyChildViewChanged(
|
||||
// Only notify for children that have a known CEF root view. For example,
|
||||
// don't notify when ScrollView adds child scroll bars.
|
||||
CefRefPtr<CefView> child = view_util::GetFor(details.child, false);
|
||||
if (child)
|
||||
if (child) {
|
||||
cef_delegate()->OnChildViewChanged(GetCefView(), details.is_add, child);
|
||||
}
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyParentViewChanged(
|
||||
@@ -217,10 +225,11 @@ CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyParentViewChanged(
|
||||
return;
|
||||
|
||||
// The immediate parent might be an intermediate view so find the closest
|
||||
// known CEF root view.
|
||||
// known CEF root view. |parent| might be nullptr for overlays.
|
||||
CefRefPtr<CefView> parent = view_util::GetFor(details.parent, true);
|
||||
DCHECK(parent);
|
||||
cef_delegate()->OnParentViewChanged(GetCefView(), details.is_add, parent);
|
||||
if (parent) {
|
||||
cef_delegate()->OnParentViewChanged(GetCefView(), details.is_add, parent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_VIEW_H_
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
#include "libcef/browser/views/window_view.h"
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "ui/base/test/ui_controls.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
@@ -278,6 +279,15 @@ CefRefPtr<CefImage> CefWindowImpl::GetWindowAppIcon() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefOverlayController> CefWindowImpl::AddOverlayView(
|
||||
CefRefPtr<CefView> view,
|
||||
cef_docking_mode_t docking_mode) {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
if (root_view())
|
||||
return root_view()->AddOverlayView(view, docking_mode);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefWindowImpl::GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) {
|
||||
ParentClass::GetDebugInfo(info, include_children);
|
||||
|
@@ -58,6 +58,9 @@ class CefWindowImpl
|
||||
CefRefPtr<CefImage> GetWindowIcon() override;
|
||||
void SetWindowAppIcon(CefRefPtr<CefImage> image) override;
|
||||
CefRefPtr<CefImage> GetWindowAppIcon() override;
|
||||
CefRefPtr<CefOverlayController> AddOverlayView(
|
||||
CefRefPtr<CefView> view,
|
||||
cef_docking_mode_t docking_mode) override;
|
||||
void ShowMenu(CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) override;
|
||||
|
@@ -312,6 +312,7 @@ void CefWindowView::CreateWidget() {
|
||||
#endif
|
||||
|
||||
widget->Init(std::move(params));
|
||||
widget->AddObserver(this);
|
||||
|
||||
// |widget| should now be associated with |this|.
|
||||
DCHECK_EQ(widget, GetWidget());
|
||||
@@ -465,6 +466,11 @@ void CefWindowView::ViewHierarchyChanged(
|
||||
ParentClass::ViewHierarchyChanged(details);
|
||||
}
|
||||
|
||||
void CefWindowView::OnWidgetBoundsChanged(views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) {
|
||||
MoveOverlaysIfNecessary();
|
||||
}
|
||||
|
||||
display::Display CefWindowView::GetDisplay() const {
|
||||
const views::Widget* widget = GetWidget();
|
||||
if (widget) {
|
||||
@@ -500,6 +506,39 @@ void CefWindowView::SetWindowAppIcon(CefRefPtr<CefImage> window_app_icon) {
|
||||
widget->UpdateWindowIcon();
|
||||
}
|
||||
|
||||
CefRefPtr<CefOverlayController> CefWindowView::AddOverlayView(
|
||||
CefRefPtr<CefView> view,
|
||||
cef_docking_mode_t docking_mode) {
|
||||
DCHECK(view.get());
|
||||
DCHECK(view->IsValid());
|
||||
if (!view.get() || !view->IsValid())
|
||||
return nullptr;
|
||||
|
||||
views::Widget* widget = GetWidget();
|
||||
if (widget) {
|
||||
// Owned by the View hierarchy. Acts as a z-order reference for the overlay.
|
||||
auto overlay_host_view = AddChildView(std::make_unique<views::View>());
|
||||
|
||||
overlay_hosts_.push_back(
|
||||
std::make_unique<CefOverlayViewHost>(this, docking_mode));
|
||||
|
||||
auto& overlay_host = overlay_hosts_.back();
|
||||
overlay_host->Init(overlay_host_view, view);
|
||||
|
||||
return overlay_host->controller();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefWindowView::MoveOverlaysIfNecessary() {
|
||||
if (overlay_hosts_.empty())
|
||||
return;
|
||||
for (auto& overlay_host : overlay_hosts_) {
|
||||
overlay_host->MoveIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
if (regions.empty()) {
|
||||
|
@@ -6,19 +6,24 @@
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_WINDOW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
#include "include/views/cef_window_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/overlay_view_host.h"
|
||||
#include "libcef/browser/views/panel_view.h"
|
||||
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
// Manages the views-based root window. This object will be deleted
|
||||
// automatically when the associated root window is destroyed.
|
||||
class CefWindowView
|
||||
: public CefPanelView<views::WidgetDelegateView, CefWindowDelegate> {
|
||||
: public CefPanelView<views::WidgetDelegateView, CefWindowDelegate>,
|
||||
public views::WidgetObserver {
|
||||
public:
|
||||
typedef CefPanelView<views::WidgetDelegateView, CefWindowDelegate>
|
||||
ParentClass;
|
||||
@@ -70,6 +75,10 @@ class CefWindowView
|
||||
void ViewHierarchyChanged(
|
||||
const views::ViewHierarchyChangedDetails& details) override;
|
||||
|
||||
// views::WidgetObserver methods:
|
||||
void OnWidgetBoundsChanged(views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) override;
|
||||
|
||||
// Returns the Display containing this Window.
|
||||
display::Display GetDisplay() const;
|
||||
|
||||
@@ -89,6 +98,10 @@ class CefWindowView
|
||||
void SetWindowAppIcon(CefRefPtr<CefImage> window_app_icon);
|
||||
CefRefPtr<CefImage> window_app_icon() const { return window_app_icon_; }
|
||||
|
||||
CefRefPtr<CefOverlayController> AddOverlayView(
|
||||
CefRefPtr<CefView> view,
|
||||
cef_docking_mode_t docking_mode);
|
||||
|
||||
// Set/get the draggable regions.
|
||||
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
@@ -100,6 +113,8 @@ class CefWindowView
|
||||
// Called when removed from the Widget and before |this| is deleted.
|
||||
void DeleteDelegate();
|
||||
|
||||
void MoveOverlaysIfNecessary();
|
||||
|
||||
// Not owned by this object.
|
||||
Delegate* window_delegate_;
|
||||
|
||||
@@ -112,6 +127,9 @@ class CefWindowView
|
||||
|
||||
std::unique_ptr<SkRegion> draggable_region_;
|
||||
|
||||
// Hosts for overlay widgets.
|
||||
std::vector<std::unique_ptr<CefOverlayViewHost>> overlay_hosts_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefWindowView);
|
||||
};
|
||||
|
||||
|
11
libcef/common/i18n_util_impl.cc
Normal file
11
libcef/common/i18n_util_impl.cc
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2021 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 "include/cef_i18n_util.h"
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
|
||||
bool CefIsRTL() {
|
||||
return base::i18n::IsRTL();
|
||||
}
|
Reference in New Issue
Block a user