File: browser_view_ash.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (143 lines) | stat: -rw-r--r-- 6,313 bytes parent folder | download | duplicates (4)
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);
}