1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/frame/browser_view_ash.h"
#include <algorithm>
#include "base/check.h"
#include "chrome/browser/ui/sad_tab_helper.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/scrim_view.h"
#include "chrome/browser/ui/views/sad_tab_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/views/controls/webview/webview.h"
BrowserViewAsh::BrowserViewAsh(std::unique_ptr<Browser> browser)
: BrowserView(std::move(browser)) {}
void BrowserViewAsh::Layout(PassKey) {
LayoutSuperclass<BrowserView>(this);
// In ChromeOS ash we round the bottom two corners of the browser frame by
// rounding the respective corners of visible client contents i.e main web
// contents, devtools web contents and side panel. When ever there is change
// in the layout or visibility of these contents (devtools opened, devtools
// docked placement change, side panel open etc), we might need to update
// which corners are currently rounded. See
// `BrowserNonClientFrameViewChromeOS::UpdateWindowRoundedCorners()` for more
// details.
DCHECK(GetWidget());
GetWidget()->non_client_view()->frame_view()->UpdateWindowRoundedCorners();
}
void BrowserViewAsh::UpdateWindowRoundedCorners(
const gfx::RoundedCornersF& window_radii) {
SidePanel* side_panel = unified_side_panel();
const bool right_aligned_side_panel_showing =
side_panel->GetVisible() && side_panel->IsRightAligned();
const bool left_aligned_side_panel_showing =
side_panel->GetVisible() && !side_panel->IsRightAligned();
// If side panel is visible, round one of the bottom two corners of the side
// panel based on its alignment w.r.t to web contents.
const gfx::RoundedCornersF side_panel_radii(
0, 0, right_aligned_side_panel_showing ? window_radii.lower_right() : 0,
left_aligned_side_panel_showing ? window_radii.lower_left() : 0);
if (side_panel_radii != side_panel->background_radii()) {
side_panel->SetBackgroundRadii(side_panel_radii);
}
views::WebView* devtools_webview = devtools_web_view();
CHECK(devtools_webview);
CHECK(devtools_webview->holder());
// If devtools are visible, round one of the bottom two corners of the
// the devtools context based on the alignment of the side panel. Since
// devtools cover the full bounds of the web contents container, if the side
// panel is not visible, we have to round the bottom two corners of side panel
// irrespective of its docked placement.
const gfx::RoundedCornersF devtools_webview_radii(
0, 0, right_aligned_side_panel_showing ? 0 : window_radii.lower_right(),
left_aligned_side_panel_showing ? 0 : window_radii.lower_left());
if (devtools_webview_radii_ != devtools_webview_radii) {
devtools_webview_radii_ = devtools_webview_radii;
devtools_webview->holder()->SetCornerRadii(devtools_webview_radii_);
}
const DevToolsDockedPlacement devtools_placement =
devtools_docked_placement();
CHECK_NE(devtools_placement, DevToolsDockedPlacement::kUnknown);
// Rounded the contents webview.
std::vector<ContentsWebView*> contents_views =
GetAllVisibleContentsWebViews();
ContentsWebView* contents_webview = contents_views.front();
// In a split view, the contents area bounds are equivalent to the
// MultiContentsView parent bounds.
const gfx::Rect& contents_bounds = contents_views.size() > 1
? contents_webview->parent()->bounds()
: contents_webview->bounds();
const views::View* container = contents_container();
const bool devtools_showing = contents_bounds != container->GetLocalBounds();
// With window controls overlay enabled, the web content extends over the
// entire window height, overlapping the window's top-two rounded corners.
// Consequently, we need to make the top two corners of the web_view
// rounded as well.
const bool round_content_webview_top_corner =
IsWindowControlsOverlayEnabled();
const gfx::RoundedCornersF contents_webview_radii(
round_content_webview_top_corner ? window_radii.upper_left() : 0,
round_content_webview_top_corner ? window_radii.upper_right() : 0,
right_aligned_side_panel_showing ||
(devtools_showing &&
devtools_placement != DevToolsDockedPlacement::kLeft)
? 0
: window_radii.lower_right(),
left_aligned_side_panel_showing ||
(devtools_showing &&
devtools_placement != DevToolsDockedPlacement::kRight)
? 0
: window_radii.lower_left());
CHECK(contents_webview);
CHECK(contents_webview->holder());
if (contents_webview->web_contents()) {
// SideTabView is shown when the renderer crashes. Initially the SabTabView
// gets the same corners as the contents webview it gets attached to but its
// radii needs to be updated as it is unaware of the client view layout
// changes.
if (auto* sad_tab_helper =
SadTabHelper::FromWebContents(contents_webview->web_contents());
sad_tab_helper && sad_tab_helper->sad_tab()) {
SadTabView* sad_tab_view =
static_cast<SadTabView*>(sad_tab_helper->sad_tab());
if (sad_tab_view->GetBackgroundRadii() != contents_webview_radii) {
sad_tab_view->SetBackgroundRadii(contents_webview_radii);
}
} else {
// We only round contents_webview, if SadTabView is not showing.
if (contents_webview_radii_ != contents_webview_radii) {
contents_webview_radii_ = contents_webview_radii;
contents_webview->holder()->SetCornerRadii(contents_webview_radii);
}
}
}
if (contents_webview->GetBackgroundRadii() != contents_webview_radii) {
contents_webview->SetBackgroundRadii(contents_webview_radii);
}
// Ensure that browser scrims are rounded as well.
window_scrim_view()->SetRoundedCorners(window_radii);
contents_scrim_view()->SetRoundedCorners(contents_webview_radii);
devtools_scrim_view()->SetRoundedCorners(devtools_webview_radii);
}
|