File: frame_utils.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (159 lines) | stat: -rw-r--r-- 6,473 bytes parent folder | download | duplicates (2)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ui/frame/frame_utils.h"

#include "chromeos/constants/chromeos_features.h"
#include "chromeos/ui/base/chromeos_ui_constants.h"
#include "chromeos/ui/base/display_util.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/base/window_state_type.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/hit_test_utils.h"
#include "ui/views/window/non_client_view.h"

namespace chromeos {

using WindowOpacity = views::Widget::InitParams::WindowOpacity;

int FrameBorderNonClientHitTest(views::NonClientFrameView* view,
                                const gfx::Point& point_in_widget) {
  gfx::Rect expanded_bounds = view->bounds();
  int outside_bounds = chromeos::kResizeOutsideBoundsSize;

  if (aura::Env::GetInstance()->is_touch_down())
    outside_bounds *= chromeos::kResizeOutsideBoundsScaleForTouch;
  expanded_bounds.Inset(-outside_bounds);

  if (!expanded_bounds.Contains(point_in_widget))
    return HTNOWHERE;

  // Check the frame first, as we allow a small area overlapping the contents
  // to be used for resize handles.
  views::Widget* widget = view->GetWidget();
  bool in_tablet_mode = display::Screen::GetScreen()->InTabletMode();
  // Ignore the resize border when maximized or full screen or in (split view)
  // tablet mode.
  const bool has_resize_border =
      !widget->IsMaximized() && !widget->IsFullscreen() && !in_tablet_mode;
  const int resize_border_size =
      has_resize_border ? chromeos::kResizeInsideBoundsSize : 0;

  int frame_component = view->GetHTComponentForFrame(
      point_in_widget, gfx::Insets(resize_border_size),
      chromeos::kResizeAreaCornerSize, chromeos::kResizeAreaCornerSize,
      has_resize_border);
  if (frame_component != HTNOWHERE)
    return frame_component;

  int client_component =
      widget->client_view()->NonClientHitTest(point_in_widget);
  if (client_component != HTNOWHERE)
    return client_component;

  // Check if it intersects with children (frame caption button, back button,
  // etc.).
  int hit_test_component =
      views::GetHitTestComponent(widget->non_client_view(), point_in_widget);
  if (hit_test_component != HTNOWHERE)
    return hit_test_component;

  // Caption is a safe default.
  return HTCAPTION;
}

void ResolveInferredOpacity(views::Widget::InitParams* params) {
  DCHECK_EQ(params->opacity, WindowOpacity::kInferred);
  if (params->type == views::Widget::InitParams::TYPE_WINDOW &&
      params->layer_type == ui::LAYER_TEXTURED) {
    // A framed window may have a rounded corner which requires the
    // window to be transparent. WindowManager controls the actual
    // opaque-ness of the window depending on its window state.
    params->init_properties_container.SetProperty(
        chromeos::kWindowManagerManagesOpacityKey, true);
    params->opacity = WindowOpacity::kTranslucent;
  } else {
    params->opacity = WindowOpacity::kOpaque;
  }
}

bool ShouldUseRestoreFrame(const views::Widget* widget) {
  aura::Window* window = widget->GetNativeWindow();
  // This is true when dragging a maximized window in ash. During this phase,
  // the window should look as if it was restored, but keep its maximized state.
  if (window->GetProperty(chromeos::kFrameRestoreLookKey))
    return true;

  // Maximized and fullscreen windows should use the maximized frame.
  if (widget->IsMaximized() || widget->IsFullscreen())
    return false;

  return true;
}

SnapDirection GetSnapDirectionForWindow(aura::Window* window, bool left_top) {
  const bool is_primary_display_layout = chromeos::IsDisplayLayoutPrimary(
      display::Screen::GetScreen()->GetDisplayNearestWindow(window));
  if (left_top) {
    return is_primary_display_layout ? SnapDirection::kPrimary
                                     : SnapDirection::kSecondary;
  } else {
    return is_primary_display_layout ? SnapDirection::kSecondary
                                     : SnapDirection::kPrimary;
  }
}

gfx::RoundedCornersF GetWindowRadii(const aura::Window* window) {
  if (!ShouldWindowHaveRoundedCorners(window)) {
    return gfx::RoundedCornersF();
  }

  const WindowStateType window_state = window->GetProperty(kWindowStateTypeKey);
  if (window_state == WindowStateType::kPip) {
    return gfx::RoundedCornersF(kPipRoundedCornerRadius);
  }

  const int corner_radius = features::IsRoundedWindowsEnabled()
                                ? features::RoundedWindowsRadius()
                                : kTopCornerRadiusWhenRestored;

  const bool rounded_bottom_corners = features::IsRoundedWindowsEnabled();
  return gfx::RoundedCornersF(corner_radius, corner_radius,
                              rounded_bottom_corners ? corner_radius : 0,
                              rounded_bottom_corners ? corner_radius : 0);
}

bool CanPropertyEffectWindowRadius(const void* class_property_key) {
  return class_property_key == kIsShowingInOverviewKey ||
         class_property_key == kWindowStateTypeKey;
}

bool ShouldWindowStateHaveRoundedCorners(WindowStateType type) {
  return IsNormalWindowStateType(type) || type == WindowStateType::kFloated ||
         type == WindowStateType::kPip;
}

bool ShouldWindowHaveRoundedCorners(const aura::Window* window) {
  const WindowStateType window_state = window->GetProperty(kWindowStateTypeKey);

  // In overview mode, the native window is displayed in `ash::WindowMiniView`
  // with its own `ash::WindowMiniViewHeaderView`. This mini view has its own
  // rounded corners. Therefore we do not need to round the native window.
  // Apart from redundant rounding, rounding the native frame is problematic for
  // browsers. For packaged apps, we hide the frame header but for browsers, we
  // still show the header since the tab strip is rendered over the header. In
  // overview mode, the header becomes a part of contents of WindowMiniView and
  // rounding the header ends up rounding the top corners of the contents.
  const bool in_overview = window->GetProperty(kIsShowingInOverviewKey);
  return ShouldWindowStateHaveRoundedCorners(window_state) && !in_overview;
}

}  // namespace chromeos