mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-10 09:00:42 +01:00
chrome: Improve positioning of dialogs (fixes #3628)
Dialogs will be excluded from regions near the top of the window that contain overlays, draggable regions or titlebar.
This commit is contained in:
parent
9ec3172ffa
commit
b5d542d38d
@ -264,9 +264,6 @@ std::unique_ptr<CefMenuRunner> CefBrowserPlatformDelegate::CreateMenuRunner() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::UpdateFindBarBoundingBox(
|
||||
gfx::Rect* bounds) const {}
|
||||
|
||||
bool CefBrowserPlatformDelegate::IsWindowless() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -286,9 +286,6 @@ class CefBrowserPlatformDelegate {
|
||||
// Create the platform-specific menu runner.
|
||||
virtual std::unique_ptr<CefMenuRunner> CreateMenuRunner();
|
||||
|
||||
// Optionally modify the bounding box for the Chrome Find bar.
|
||||
virtual void UpdateFindBarBoundingBox(gfx::Rect* bounds) const;
|
||||
|
||||
// Returns true if this delegate implements windowless rendering. May be
|
||||
// called on multiple threads.
|
||||
virtual bool IsWindowless() const;
|
||||
|
@ -7,11 +7,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "chrome/browser/ui/page_action/page_action_icon_type.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/base/window_open_disposition.h"
|
||||
|
||||
@ -107,6 +107,9 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
||||
// Optionally modify the bounding box for the Find bar.
|
||||
virtual void UpdateFindBarBoundingBox(gfx::Rect* bounds) {}
|
||||
|
||||
// Optionally modify the top inset for dialogs.
|
||||
virtual void UpdateDialogTopInset(int* dialog_top_y) {}
|
||||
|
||||
// Same as RequestMediaAccessPermission but returning |callback| if the
|
||||
// request is unhandled.
|
||||
[[nodiscard]] virtual content::MediaResponseCallback
|
||||
@ -118,8 +121,8 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
||||
|
||||
// Optionally override support for the specified window feature of type
|
||||
// Browser::WindowFeature.
|
||||
virtual absl::optional<bool> SupportsWindowFeature(int feature) const {
|
||||
return absl::nullopt;
|
||||
virtual std::optional<bool> SupportsWindowFeature(int feature) const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Returns true if draggable regions are supported.
|
||||
@ -128,8 +131,8 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
||||
// Returns the draggable region, if any, relative to the web contents.
|
||||
// Called from PictureInPictureBrowserFrameView::NonClientHitTest and
|
||||
// BrowserView::ShouldDescendIntoChildForEventHandling.
|
||||
virtual const absl::optional<SkRegion> GetDraggableRegion() const {
|
||||
return absl::nullopt;
|
||||
virtual const std::optional<SkRegion> GetDraggableRegion() const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Set the draggable region relative to web contents.
|
||||
|
@ -336,8 +336,16 @@ bool ChromeBrowserDelegate::IsToolbarButtonVisible(
|
||||
}
|
||||
|
||||
void ChromeBrowserDelegate::UpdateFindBarBoundingBox(gfx::Rect* bounds) {
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
browser->platform_delegate()->UpdateFindBarBoundingBox(bounds);
|
||||
if (auto cef_window_view = GetCefWindowView()) {
|
||||
cef_window_view->UpdateFindBarBoundingBox(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void ChromeBrowserDelegate::UpdateDialogTopInset(int* dialog_top_y) {
|
||||
// This may be called during Browser initialization (before Tab/WebContents
|
||||
// creation), so we can't route through the ChromeBrowserHostImpl.
|
||||
if (auto cef_window_view = GetCefWindowView()) {
|
||||
cef_window_view->UpdateDialogTopInset(dialog_top_y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,7 +385,7 @@ bool ChromeBrowserDelegate::SupportsFramelessPictureInPicture() const {
|
||||
return *frameless_pip_;
|
||||
}
|
||||
|
||||
absl::optional<bool> ChromeBrowserDelegate::SupportsWindowFeature(
|
||||
std::optional<bool> ChromeBrowserDelegate::SupportsWindowFeature(
|
||||
int feature) const {
|
||||
// Override the default value from
|
||||
// Browser::PictureInPictureBrowserSupportsWindowFeature.
|
||||
@ -386,14 +394,14 @@ absl::optional<bool> ChromeBrowserDelegate::SupportsWindowFeature(
|
||||
// Return false to hide titlebar and enable draggable regions.
|
||||
return !SupportsFramelessPictureInPicture();
|
||||
}
|
||||
return absl::nullopt;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::SupportsDraggableRegion() const {
|
||||
return SupportsFramelessPictureInPicture();
|
||||
}
|
||||
|
||||
const absl::optional<SkRegion> ChromeBrowserDelegate::GetDraggableRegion()
|
||||
const std::optional<SkRegion> ChromeBrowserDelegate::GetDraggableRegion()
|
||||
const {
|
||||
DCHECK(SupportsDraggableRegion());
|
||||
return draggable_region_;
|
||||
@ -408,14 +416,11 @@ void ChromeBrowserDelegate::WindowFullscreenStateChanged() {
|
||||
// Use a synchronous callback for notification on Windows/Linux. MacOS gets
|
||||
// notified asynchronously via CefNativeWidgetMac callbacks.
|
||||
#if !BUILDFLAG(IS_MAC)
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
if (auto chrome_browser_view = browser->chrome_browser_view()) {
|
||||
auto* cef_window = chrome_browser_view->cef_browser_view()->cef_window();
|
||||
if (auto* delegate = cef_window->delegate()) {
|
||||
// Give the CefWindowDelegate a chance to handle the event.
|
||||
delegate->OnWindowFullscreenTransition(cef_window,
|
||||
/*is_completed=*/true);
|
||||
}
|
||||
if (auto cef_window_impl = GetCefWindowImpl()) {
|
||||
if (auto* delegate = cef_window_impl->delegate()) {
|
||||
// Give the CefWindowDelegate a chance to handle the event.
|
||||
delegate->OnWindowFullscreenTransition(cef_window_impl,
|
||||
/*is_completed=*/true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -646,7 +651,7 @@ ChromeBrowserDelegate::CreateBrowserHostForPopup(
|
||||
}
|
||||
|
||||
CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents(
|
||||
content::WebContents* web_contents) {
|
||||
content::WebContents* web_contents) const {
|
||||
auto browser_host =
|
||||
ChromeBrowserHostImpl::GetBrowserForContents(web_contents);
|
||||
if (browser_host) {
|
||||
@ -655,6 +660,28 @@ CefBrowserContentsDelegate* ChromeBrowserDelegate::GetDelegateForWebContents(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ChromeBrowserDelegate::IsViewsHosted() const {
|
||||
return create_params_.browser_view != nullptr ||
|
||||
create_params_.popup_with_views_hosted_opener;
|
||||
}
|
||||
|
||||
CefWindowImpl* ChromeBrowserDelegate::GetCefWindowImpl() const {
|
||||
if (IsViewsHosted()) {
|
||||
if (auto chrome_browser_view =
|
||||
static_cast<ChromeBrowserView*>(browser_->window())) {
|
||||
return chrome_browser_view->cef_browser_view()->cef_window_impl();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefWindowView* ChromeBrowserDelegate::GetCefWindowView() const {
|
||||
if (auto cef_window_impl = GetCefWindowImpl()) {
|
||||
return cef_window_impl->cef_window_view();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace cef {
|
||||
|
||||
// static
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
class CefBrowserContentsDelegate;
|
||||
class CefRequestContextImpl;
|
||||
class CefWindowImpl;
|
||||
class CefWindowView;
|
||||
class ChromeBrowserHostImpl;
|
||||
|
||||
// Implementation of the cef::BrowserDelegate interface. Lifespan is controlled
|
||||
@ -69,13 +71,14 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
bool IsPageActionIconVisible(PageActionIconType icon_type) override;
|
||||
bool IsToolbarButtonVisible(ToolbarButtonType button_type) override;
|
||||
void UpdateFindBarBoundingBox(gfx::Rect* bounds) override;
|
||||
void UpdateDialogTopInset(int* dialog_top_y) override;
|
||||
[[nodiscard]] content::MediaResponseCallback RequestMediaAccessPermissionEx(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) override;
|
||||
absl::optional<bool> SupportsWindowFeature(int feature) const override;
|
||||
std::optional<bool> SupportsWindowFeature(int feature) const override;
|
||||
bool SupportsDraggableRegion() const override;
|
||||
const absl::optional<SkRegion> GetDraggableRegion() const override;
|
||||
const std::optional<SkRegion> GetDraggableRegion() const override;
|
||||
void UpdateDraggableRegion(const SkRegion& region) override;
|
||||
void WindowFullscreenStateChanged() override;
|
||||
|
||||
@ -137,19 +140,25 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
||||
CefRefPtr<ChromeBrowserHostImpl> opener);
|
||||
|
||||
CefBrowserContentsDelegate* GetDelegateForWebContents(
|
||||
content::WebContents* web_contents);
|
||||
content::WebContents* web_contents) const;
|
||||
|
||||
bool SupportsFramelessPictureInPicture() const;
|
||||
|
||||
bool IsViewsHosted() const;
|
||||
|
||||
// Will return nullptr if the Browser is not Views-hosted.
|
||||
CefWindowImpl* GetCefWindowImpl() const;
|
||||
CefWindowView* GetCefWindowView() const;
|
||||
|
||||
Browser* const browser_;
|
||||
base::WeakPtr<ChromeBrowserHostImpl> opener_host_;
|
||||
|
||||
// Used when creating a new browser host.
|
||||
const CefBrowserCreateParams create_params_;
|
||||
|
||||
absl::optional<bool> show_status_bubble_;
|
||||
absl::optional<SkRegion> draggable_region_;
|
||||
mutable absl::optional<bool> frameless_pip_;
|
||||
std::optional<bool> show_status_bubble_;
|
||||
std::optional<SkRegion> draggable_region_;
|
||||
mutable std::optional<bool> frameless_pip_;
|
||||
|
||||
std::unique_ptr<CefShowDevToolsParams> pending_show_devtools_params_;
|
||||
};
|
||||
|
@ -93,8 +93,15 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForGlobalId(
|
||||
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::GetBrowserForBrowser(
|
||||
const Browser* browser) {
|
||||
REQUIRE_CHROME_RUNTIME();
|
||||
return GetBrowserForContents(
|
||||
browser->tab_strip_model()->GetActiveWebContents());
|
||||
// Return the ChromeBrowserHostImpl that is currently active.
|
||||
// Views-hosted Browsers will contain a single ChromeBrowserHostImpl.
|
||||
// Otherwise, there will be a ChromeBrowserHostImpl per Tab/WebContents.
|
||||
// |contents| may be nullptr during Browser initialization or destruction.
|
||||
auto contents = browser->tab_strip_model()->GetActiveWebContents();
|
||||
if (!contents) {
|
||||
return nullptr;
|
||||
}
|
||||
return GetBrowserForContents(contents);
|
||||
}
|
||||
|
||||
ChromeBrowserHostImpl::~ChromeBrowserHostImpl() = default;
|
||||
|
@ -195,15 +195,6 @@ void CefBrowserPlatformDelegateChromeViews::PopupBrowserCreated(
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateChromeViews::UpdateFindBarBoundingBox(
|
||||
gfx::Rect* bounds) const {
|
||||
if (auto* window_impl = GetWindowImpl()) {
|
||||
if (window_impl->root_view()) {
|
||||
window_impl->root_view()->UpdateFindBarBoundingBox(bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateChromeViews::IsViewsHosted() const {
|
||||
return true;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ class CefBrowserPlatformDelegateChromeViews
|
||||
bool is_devtools) override;
|
||||
void PopupBrowserCreated(CefBrowserHostBase* new_browser,
|
||||
bool is_devtools) override;
|
||||
void UpdateFindBarBoundingBox(gfx::Rect* bounds) const override;
|
||||
bool IsViewsHosted() const override;
|
||||
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view() const { return browser_view_; }
|
||||
|
@ -141,7 +141,7 @@ bool CefBrowserViewImpl::HandleKeyboardEvent(
|
||||
}
|
||||
|
||||
// Give the CefWindowDelegate a chance to handle the event.
|
||||
if (auto* window_impl = cef_window()) {
|
||||
if (auto* window_impl = cef_window_impl()) {
|
||||
CefKeyEvent cef_event;
|
||||
if (browser_util::GetCefKeyEvent(event, cef_event) &&
|
||||
window_impl->OnKeyEvent(cef_event)) {
|
||||
@ -316,7 +316,11 @@ ChromeBrowserView* CefBrowserViewImpl::chrome_browser_view() const {
|
||||
return static_cast<ChromeBrowserView*>(root_view());
|
||||
}
|
||||
|
||||
CefWindowImpl* CefBrowserViewImpl::cef_window() const {
|
||||
CefWindowImpl* CefBrowserViewImpl::cef_window_impl() const {
|
||||
// Same implementation as GetWindow().
|
||||
if (!root_view()) {
|
||||
return nullptr;
|
||||
}
|
||||
CefRefPtr<CefWindow> window =
|
||||
view_util::GetWindowFor(root_view()->GetWidget());
|
||||
return static_cast<CefWindowImpl*>(window.get());
|
||||
|
@ -85,7 +85,7 @@ class CefBrowserViewImpl
|
||||
ChromeBrowserView* chrome_browser_view() const;
|
||||
|
||||
// Return the CefWindowImpl hosting this object.
|
||||
CefWindowImpl* cef_window() const;
|
||||
CefWindowImpl* cef_window_impl() const;
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
|
@ -278,6 +278,7 @@ void CefOverlayViewHost::SetOverlayBounds(const gfx::Rect& bounds) {
|
||||
view_->SetSize(bounds_.size());
|
||||
}
|
||||
widget_->SetBounds(bounds_);
|
||||
window_view_->OnOverlayBoundsChanged();
|
||||
|
||||
bounds_changing_ = false;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ void CefWindowImpl::ShowAsBrowserModalDialog(
|
||||
static_cast<CefBrowserViewImpl*>(browser_view.get());
|
||||
|
||||
// |browser_view| must belong to the host widget.
|
||||
auto* host_widget = static_cast<CefWindowView*>(root_view())->host_widget();
|
||||
auto* host_widget = cef_window_view()->host_widget();
|
||||
CHECK(host_widget &&
|
||||
browser_view_impl->root_view()->GetWidget() == host_widget);
|
||||
|
||||
@ -739,6 +739,10 @@ void CefWindowImpl::RemoveAllAccelerators() {
|
||||
focus_manager->UnregisterAccelerators(this);
|
||||
}
|
||||
|
||||
CefWindowView* CefWindowImpl::cef_window_view() const {
|
||||
return static_cast<CefWindowView*>(root_view());
|
||||
}
|
||||
|
||||
CefWindowImpl::CefWindowImpl(CefRefPtr<CefWindowDelegate> delegate)
|
||||
: ParentClass(delegate) {}
|
||||
|
||||
@ -747,7 +751,7 @@ CefWindowView* CefWindowImpl::CreateRootView() {
|
||||
}
|
||||
|
||||
void CefWindowImpl::InitializeRootView() {
|
||||
static_cast<CefWindowView*>(root_view())->Initialize();
|
||||
cef_window_view()->Initialize();
|
||||
}
|
||||
|
||||
void CefWindowImpl::CreateWidget(gfx::AcceleratedWidget parent_widget) {
|
||||
|
@ -133,6 +133,8 @@ class CefWindowImpl
|
||||
cef_menu_anchor_position_t anchor_position);
|
||||
void MenuClosed();
|
||||
|
||||
CefWindowView* cef_window_view() const;
|
||||
|
||||
views::Widget* widget() const { return widget_; }
|
||||
bool initialized() const { return initialized_; }
|
||||
|
||||
|
@ -92,7 +92,7 @@ class NativeFrameViewEx : public views::NativeFrameView {
|
||||
}
|
||||
|
||||
if (!view_->IsFrameless()) {
|
||||
if (auto titlebar_height = view_->GetTitlebarHeight()) {
|
||||
if (auto titlebar_height = view_->GetTitlebarHeight(/*required=*/true)) {
|
||||
window_bounds.Inset(gfx::Insets::TLBR(-(*titlebar_height), 0, 0, 0));
|
||||
}
|
||||
}
|
||||
@ -829,12 +829,23 @@ void CefWindowView::MoveOverlaysIfNecessary() {
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::InvalidateExclusionRegions() {
|
||||
if (last_dialog_top_inset_ != -1) {
|
||||
last_dialog_top_y_ = last_dialog_top_inset_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
if (regions.empty() && !draggable_region_) {
|
||||
// Still empty.
|
||||
return;
|
||||
}
|
||||
|
||||
InvalidateExclusionRegions();
|
||||
|
||||
if (regions.empty()) {
|
||||
if (draggable_region_) {
|
||||
draggable_region_.reset(nullptr);
|
||||
}
|
||||
draggable_region_.reset();
|
||||
draggable_rects_.clear();
|
||||
return;
|
||||
}
|
||||
@ -854,6 +865,10 @@ void CefWindowView::SetDraggableRegions(
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::OnOverlayBoundsChanged() {
|
||||
InvalidateExclusionRegions();
|
||||
}
|
||||
|
||||
views::NonClientFrameView* CefWindowView::GetNonClientFrameView() const {
|
||||
const views::Widget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
@ -865,7 +880,8 @@ views::NonClientFrameView* CefWindowView::GetNonClientFrameView() const {
|
||||
return widget->non_client_view()->frame_view();
|
||||
}
|
||||
|
||||
void CefWindowView::UpdateFindBarBoundingBox(gfx::Rect* bounds) const {
|
||||
void CefWindowView::UpdateBoundingBox(gfx::Rect* bounds,
|
||||
bool add_titlebar_height) const {
|
||||
// Max distance from the edges of |bounds| to qualify for subtraction.
|
||||
const int kMaxDistance = 10;
|
||||
|
||||
@ -878,16 +894,8 @@ void CefWindowView::UpdateFindBarBoundingBox(gfx::Rect* bounds) const {
|
||||
*bounds = SubtractOverlayFromBoundingBox(*bounds, rect, kMaxDistance);
|
||||
}
|
||||
|
||||
if (auto titlebar_height = GetTitlebarHeight()) {
|
||||
if (auto titlebar_height = GetTitlebarHeight(add_titlebar_height)) {
|
||||
gfx::Insets inset;
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// For framed windows on macOS we must add the titlebar height.
|
||||
const bool add_titlebar_height = !is_frameless_;
|
||||
#else
|
||||
const bool add_titlebar_height = false;
|
||||
#endif
|
||||
|
||||
if (add_titlebar_height) {
|
||||
inset.set_top(*titlebar_height);
|
||||
} else if (bounds->y() < *titlebar_height) {
|
||||
@ -900,6 +908,46 @@ void CefWindowView::UpdateFindBarBoundingBox(gfx::Rect* bounds) const {
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::UpdateFindBarBoundingBox(gfx::Rect* bounds) const {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// For framed windows on macOS we must add the titlebar height.
|
||||
const bool add_titlebar_height = !is_frameless_;
|
||||
#else
|
||||
const bool add_titlebar_height = false;
|
||||
#endif
|
||||
|
||||
UpdateBoundingBox(bounds, add_titlebar_height);
|
||||
}
|
||||
|
||||
void CefWindowView::UpdateDialogTopInset(int* dialog_top_y) const {
|
||||
if (*dialog_top_y == last_dialog_top_y_ && last_dialog_top_inset_ != -1) {
|
||||
// Return the cached value.
|
||||
*dialog_top_y = last_dialog_top_inset_;
|
||||
return;
|
||||
}
|
||||
|
||||
const views::Widget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Rect bounds(widget->GetSize());
|
||||
if (*dialog_top_y > 0) {
|
||||
// Start with the value computed in
|
||||
// BrowserViewLayout::LayoutBookmarkAndInfoBars.
|
||||
gfx::Insets inset;
|
||||
inset.set_top(*dialog_top_y);
|
||||
bounds.Inset(inset);
|
||||
}
|
||||
|
||||
UpdateBoundingBox(&bounds, /*add_titlebar_height=*/false);
|
||||
|
||||
last_dialog_top_y_ = *dialog_top_y;
|
||||
last_dialog_top_inset_ = bounds.y();
|
||||
|
||||
*dialog_top_y = bounds.y();
|
||||
}
|
||||
|
||||
views::Widget* CefWindowView::host_widget() const {
|
||||
if (host_widget_destruction_observer_) {
|
||||
return host_widget_destruction_observer_->widget();
|
||||
@ -907,7 +955,7 @@ views::Widget* CefWindowView::host_widget() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
absl::optional<float> CefWindowView::GetTitlebarHeight() const {
|
||||
std::optional<float> CefWindowView::GetTitlebarHeight(bool required) const {
|
||||
if (cef_delegate()) {
|
||||
float title_bar_height = 0;
|
||||
const bool has_title_bar_height =
|
||||
@ -918,7 +966,7 @@ absl::optional<float> CefWindowView::GetTitlebarHeight() const {
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (!is_frameless_) {
|
||||
if (required) {
|
||||
// For framed windows on macOS we must include the titlebar height in the
|
||||
// UpdateFindBarBoundingBox() calculation.
|
||||
return view_util::GetNSWindowTitleBarHeight(
|
||||
@ -926,5 +974,5 @@ absl::optional<float> CefWindowView::GetTitlebarHeight() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
return absl::nullopt;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_WINDOW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
@ -112,13 +113,19 @@ class CefWindowView
|
||||
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
// Called from CefOverlayViewHost::SetOverlayBounds().
|
||||
void OnOverlayBoundsChanged();
|
||||
|
||||
// Returns the NonClientFrameView for this Window. May be nullptr.
|
||||
views::NonClientFrameView* GetNonClientFrameView() const;
|
||||
|
||||
// Optionally modify the bounding box for the Chrome Find bar.
|
||||
void UpdateFindBarBoundingBox(gfx::Rect* bounds) const;
|
||||
|
||||
absl::optional<float> GetTitlebarHeight() const;
|
||||
// Optionally modify the top inset for Chrome dialogs.
|
||||
void UpdateDialogTopInset(int* dialog_top_y) const;
|
||||
|
||||
std::optional<float> GetTitlebarHeight(bool required) const;
|
||||
bool IsFrameless() const { return is_frameless_; }
|
||||
|
||||
// The Widget that hosts us, if we're a modal dialog. May return nullptr
|
||||
@ -130,6 +137,9 @@ class CefWindowView
|
||||
void DeleteDelegate();
|
||||
|
||||
void MoveOverlaysIfNecessary();
|
||||
void InvalidateExclusionRegions();
|
||||
|
||||
void UpdateBoundingBox(gfx::Rect* bounds, bool add_titlebar_height) const;
|
||||
|
||||
// Not owned by this object.
|
||||
Delegate* window_delegate_;
|
||||
@ -144,6 +154,9 @@ class CefWindowView
|
||||
std::unique_ptr<SkRegion> draggable_region_;
|
||||
std::vector<gfx::Rect> draggable_rects_;
|
||||
|
||||
mutable int last_dialog_top_y_ = -1;
|
||||
mutable int last_dialog_top_inset_ = -1;
|
||||
|
||||
// Tracks the Widget that hosts us, if we're a modal dialog.
|
||||
std::unique_ptr<WidgetDestructionObserver> host_widget_destruction_observer_;
|
||||
|
||||
|
@ -363,7 +363,7 @@ index 0c231b6ac5b01..6b5af98e18e42 100644
|
||||
BrowserFrame(const BrowserFrame&) = delete;
|
||||
BrowserFrame& operator=(const BrowserFrame&) = delete;
|
||||
diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
|
||||
index 4273a5f004935..a46cdb993474b 100644
|
||||
index 4273a5f004935..55f2782c262e4 100644
|
||||
--- chrome/browser/ui/views/frame/browser_view.cc
|
||||
+++ chrome/browser/ui/views/frame/browser_view.cc
|
||||
@@ -343,11 +343,10 @@ using content::NativeWebKeyboardEvent;
|
||||
@ -381,7 +381,22 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// UMA histograms that record animation smoothness for tab loading animation.
|
||||
@@ -862,11 +861,21 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
|
||||
@@ -701,6 +700,14 @@ class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate {
|
||||
return browser_view_->frame()->GetTopInset() - browser_view_->y();
|
||||
}
|
||||
|
||||
+ void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const override {
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (auto cef_delegate = browser_view_->browser_->cef_delegate()) {
|
||||
+ cef_delegate->UpdateDialogTopInset(dialog_top_y);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
bool IsToolbarVisible() const override {
|
||||
return browser_view_->IsToolbarVisible();
|
||||
}
|
||||
@@ -862,11 +869,21 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BrowserView, public:
|
||||
|
||||
@ -404,7 +419,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
// Store the actions so that the access is available for other classes.
|
||||
if (features::IsSidePanelPinningEnabled()) {
|
||||
browser_->SetUserData(BrowserActions::UserDataKey(),
|
||||
@@ -963,8 +972,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
||||
@@ -963,8 +980,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
||||
contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
|
||||
devtools_web_view_, contents_web_view_));
|
||||
|
||||
@ -422,7 +437,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
|
||||
contents_separator_ =
|
||||
top_container_->AddChildView(std::make_unique<ContentsSeparator>());
|
||||
@@ -1038,7 +1054,9 @@ BrowserView::~BrowserView() {
|
||||
@@ -1038,7 +1062,9 @@ BrowserView::~BrowserView() {
|
||||
|
||||
// All the tabs should have been destroyed already. If we were closed by the
|
||||
// OS with some tabs than the NativeBrowserFrame should have destroyed them.
|
||||
@ -432,7 +447,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
|
||||
// Stop the animation timer explicitly here to avoid running it in a nested
|
||||
// message loop, which may run by Browser destructor.
|
||||
@@ -1052,12 +1070,14 @@ BrowserView::~BrowserView() {
|
||||
@@ -1052,12 +1078,14 @@ BrowserView::~BrowserView() {
|
||||
// child views and it is an observer for avatar toolbar button if any.
|
||||
autofill_bubble_handler_.reset();
|
||||
|
||||
@ -447,7 +462,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
|
||||
// The TabStrip attaches a listener to the model. Make sure we shut down the
|
||||
// TabStrip first so that it can cleanly remove the listener.
|
||||
@@ -1075,7 +1095,9 @@ BrowserView::~BrowserView() {
|
||||
@@ -1075,7 +1103,9 @@ BrowserView::~BrowserView() {
|
||||
|
||||
// `SidePanelUI::RemoveSidePanelUIForBrowser()` deletes the
|
||||
// SidePanelCoordinator.
|
||||
@ -457,7 +472,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -1950,9 +1972,14 @@ void BrowserView::OnExclusiveAccessUserInput() {
|
||||
@@ -1950,9 +1980,14 @@ void BrowserView::OnExclusiveAccessUserInput() {
|
||||
|
||||
bool BrowserView::ShouldHideUIForFullscreen() const {
|
||||
// Immersive mode needs UI for the slide-down top panel.
|
||||
@ -473,7 +488,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
|
||||
}
|
||||
|
||||
@@ -3065,7 +3092,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
|
||||
@@ -3065,7 +3100,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
|
||||
}
|
||||
|
||||
DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() {
|
||||
@ -483,7 +498,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
if (auto* download_button = toolbar_button_provider_->GetDownloadButton())
|
||||
return download_button->bubble_controller();
|
||||
return nullptr;
|
||||
@@ -3616,7 +3644,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
|
||||
@@ -3616,7 +3652,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
|
||||
if (top_container()->parent() == this)
|
||||
return;
|
||||
|
||||
@ -493,7 +508,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
top_container()->DestroyLayer();
|
||||
AddChildViewAt(top_container(), 0);
|
||||
EnsureFocusOrder();
|
||||
@@ -4078,11 +4107,38 @@ void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) {
|
||||
@@ -4078,11 +4115,38 @@ void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) {
|
||||
bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
gfx::NativeView child,
|
||||
const gfx::Point& location) {
|
||||
@ -534,7 +549,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
// Draggable regions are defined relative to the web contents.
|
||||
gfx::Point point_in_contents_web_view_coords(location);
|
||||
views::View::ConvertPointToTarget(GetWidget()->GetRootView(),
|
||||
@@ -4091,7 +4147,7 @@ bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
@@ -4091,7 +4155,7 @@ bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
|
||||
// Draggable regions should be ignored for clicks into any browser view's
|
||||
// owned widgets, for example alerts, permission prompts or find bar.
|
||||
@ -543,7 +558,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
point_in_contents_web_view_coords.x(),
|
||||
point_in_contents_web_view_coords.y()) ||
|
||||
WidgetOwnedByAnchorContainsPoint(point_in_contents_web_view_coords);
|
||||
@@ -4199,8 +4255,10 @@ void BrowserView::Layout() {
|
||||
@@ -4199,8 +4263,10 @@ void BrowserView::Layout() {
|
||||
|
||||
// TODO(jamescook): Why was this in the middle of layout code?
|
||||
toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
|
||||
@ -556,7 +571,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// In chromeOS ash we round the bottom two corners of the browser frame by
|
||||
@@ -4278,6 +4336,11 @@ void BrowserView::AddedToWidget() {
|
||||
@@ -4278,6 +4344,11 @@ void BrowserView::AddedToWidget() {
|
||||
SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
|
||||
#endif
|
||||
|
||||
@ -568,7 +583,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
toolbar_->Init();
|
||||
|
||||
// TODO(pbos): Investigate whether the side panels should be creatable when
|
||||
@@ -4326,13 +4389,9 @@ void BrowserView::AddedToWidget() {
|
||||
@@ -4326,13 +4397,9 @@ void BrowserView::AddedToWidget() {
|
||||
|
||||
EnsureFocusOrder();
|
||||
|
||||
@ -584,7 +599,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
using_native_frame_ = frame_->ShouldUseNativeFrame();
|
||||
|
||||
MaybeInitializeWebUITabStrip();
|
||||
@@ -4749,7 +4808,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
|
||||
@@ -4749,7 +4816,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
|
||||
// Undo our anti-jankiness hacks and force a re-layout.
|
||||
in_process_fullscreen_ = false;
|
||||
ToolbarSizeChanged(false);
|
||||
@ -594,7 +609,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
}
|
||||
|
||||
bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const {
|
||||
@@ -5147,6 +5207,8 @@ Profile* BrowserView::GetProfile() {
|
||||
@@ -5147,6 +5215,8 @@ Profile* BrowserView::GetProfile() {
|
||||
}
|
||||
|
||||
void BrowserView::UpdateUIForTabFullscreen() {
|
||||
@ -603,7 +618,7 @@ index 4273a5f004935..a46cdb993474b 100644
|
||||
frame()->GetFrameView()->UpdateFullscreenTopUI();
|
||||
}
|
||||
|
||||
@@ -5169,6 +5231,8 @@ void BrowserView::HideDownloadShelf() {
|
||||
@@ -5169,6 +5239,8 @@ void BrowserView::HideDownloadShelf() {
|
||||
}
|
||||
|
||||
bool BrowserView::CanUserExitFullscreen() const {
|
||||
@ -644,7 +659,7 @@ index 2e4054890db75..1a518ba936fd1 100644
|
||||
// Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
|
||||
// interface to keep these two classes decoupled and testable.
|
||||
diff --git chrome/browser/ui/views/frame/browser_view_layout.cc chrome/browser/ui/views/frame/browser_view_layout.cc
|
||||
index 5e39a622e391e..e0b67a6902182 100644
|
||||
index 5e39a622e391e..1d4504370305f 100644
|
||||
--- chrome/browser/ui/views/frame/browser_view_layout.cc
|
||||
+++ chrome/browser/ui/views/frame/browser_view_layout.cc
|
||||
@@ -48,6 +48,10 @@
|
||||
@ -658,7 +673,67 @@ index 5e39a622e391e..e0b67a6902182 100644
|
||||
using views::View;
|
||||
using web_modal::ModalDialogHostObserver;
|
||||
using web_modal::WebContentsModalDialogHost;
|
||||
@@ -583,6 +587,13 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
|
||||
@@ -92,6 +96,10 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
||||
observer.OnHostDestroying();
|
||||
}
|
||||
|
||||
+ bool HasObservers() const {
|
||||
+ return !observer_list_.empty();
|
||||
+ }
|
||||
+
|
||||
void NotifyPositionRequiresUpdate() {
|
||||
for (ModalDialogHostObserver& observer : observer_list_)
|
||||
observer.OnPositionRequiresUpdate();
|
||||
@@ -102,7 +110,7 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
||||
views::View* view = browser_view_layout_->contents_container_;
|
||||
gfx::Rect rect = view->ConvertRectToWidget(view->GetLocalBounds());
|
||||
const int middle_x = rect.x() + rect.width() / 2;
|
||||
- const int top = browser_view_layout_->dialog_top_y_;
|
||||
+ const int top = GetDialogTopY();
|
||||
return gfx::Point(middle_x - size.width() / 2, top);
|
||||
}
|
||||
|
||||
@@ -117,7 +125,7 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
||||
gfx::Size GetMaximumDialogSize() override {
|
||||
views::View* view = browser_view_layout_->contents_container_;
|
||||
gfx::Rect content_area = view->ConvertRectToWidget(view->GetLocalBounds());
|
||||
- const int top = browser_view_layout_->dialog_top_y_;
|
||||
+ const int top = GetDialogTopY();
|
||||
return gfx::Size(content_area.width(), content_area.bottom() - top);
|
||||
}
|
||||
|
||||
@@ -131,6 +139,13 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
||||
return GetHostWidget()->GetNativeView();
|
||||
}
|
||||
|
||||
+ int GetDialogTopY() const {
|
||||
+ int dialog_top_y = browser_view_layout_->dialog_top_y_;
|
||||
+ browser_view_layout_->delegate_->UpdateDialogTopInsetInBrowserView(
|
||||
+ &dialog_top_y);
|
||||
+ return dialog_top_y;
|
||||
+ }
|
||||
+
|
||||
// Add/remove observer.
|
||||
void AddObserver(ModalDialogHostObserver* observer) override {
|
||||
observer_list_.AddObserver(observer);
|
||||
@@ -441,6 +456,8 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
|
||||
if (exclusive_access_bubble)
|
||||
exclusive_access_bubble->RepositionIfVisible();
|
||||
|
||||
+ // Avoid unnecessary calls to UpdateDialogTopInsetInBrowserView().
|
||||
+ if (dialog_host_->HasObservers()) {
|
||||
// Adjust any hosted dialogs if the browser's dialog hosting bounds changed.
|
||||
const gfx::Rect dialog_bounds(dialog_host_->GetDialogPosition(gfx::Size()),
|
||||
dialog_host_->GetMaximumDialogSize());
|
||||
@@ -454,6 +471,7 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
|
||||
latest_dialog_bounds_in_screen_ = dialog_bounds_in_screen;
|
||||
dialog_host_->NotifyPositionRequiresUpdate();
|
||||
}
|
||||
+ }
|
||||
}
|
||||
|
||||
// Return the preferred size which is the size required to give each
|
||||
@@ -583,6 +601,13 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
|
||||
|
||||
int BrowserViewLayout::LayoutToolbar(int top) {
|
||||
TRACE_EVENT0("ui", "BrowserViewLayout::LayoutToolbar");
|
||||
@ -672,6 +747,18 @@ index 5e39a622e391e..e0b67a6902182 100644
|
||||
int browser_view_width = vertical_layout_rect_.width();
|
||||
bool toolbar_visible = delegate_->IsToolbarVisible();
|
||||
int height = toolbar_visible ? toolbar_->GetPreferredSize().height() : 0;
|
||||
diff --git chrome/browser/ui/views/frame/browser_view_layout_delegate.h chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
||||
index 29ad5517bd3c9..b0fe093467abc 100644
|
||||
--- chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
||||
+++ chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
||||
@@ -28,6 +28,7 @@ class BrowserViewLayoutDelegate {
|
||||
const gfx::Rect& available_space,
|
||||
views::Label& window_title_label) const = 0;
|
||||
virtual int GetTopInsetInBrowserView() const = 0;
|
||||
+ virtual void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const = 0;
|
||||
virtual bool IsToolbarVisible() const = 0;
|
||||
virtual bool IsBookmarkBarVisible() const = 0;
|
||||
virtual bool IsContentsSeparatorEnabled() const = 0;
|
||||
diff --git chrome/browser/ui/views/frame/contents_web_view.cc chrome/browser/ui/views/frame/contents_web_view.cc
|
||||
index 8267a265a8e10..ee08f18e96a34 100644
|
||||
--- chrome/browser/ui/views/frame/contents_web_view.cc
|
||||
|
Loading…
x
Reference in New Issue
Block a user