File: window_util.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 (147 lines) | stat: -rw-r--r-- 5,307 bytes parent folder | download | duplicates (6)
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
// Copyright 2022 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/wm/window_util.h"

#include "chromeos/ui/base/app_types.h"
#include "chromeos/ui/base/display_util.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/base/window_state_type.h"
#include "chromeos/ui/wm/constants.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"

namespace chromeos::wm {

namespace {

gfx::Size GetPreferredFloatedWindowTabletSize(const gfx::Rect& work_area,
                                              bool landscape) {
  // We use the landscape bounds to determine the preferred width and height,
  // even in portrait mode.
  const int landscape_width =
      landscape ? work_area.width() : work_area.height();
  const int landscape_height =
      landscape ? work_area.height() : work_area.width();
  const int preferred_width =
      static_cast<int>(landscape_width * kFloatedWindowTabletWidthRatio);
  const int preferred_height =
      landscape_height * kFloatedWindowTabletHeightRatio;
  return gfx::Size(preferred_width, preferred_height);
}

bool CanFloatWindowInClamshell(aura::Window* window) {
  CHECK(window);

  const gfx::Rect work_area =
      display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
  const gfx::Size minimum_size = window->delegate()->GetMinimumSize();
  if (minimum_size.width() > work_area.width() - 2 * kFloatedWindowPaddingDp ||
      minimum_size.height() >
          work_area.height() - 2 * kFloatedWindowPaddingDp) {
    return false;
  }
  return true;
}

bool CanFloatWindowInTablet(aura::Window* window) {
  return !GetFloatedWindowTabletSize(window).IsEmpty();
}

}  // namespace

bool IsLandscapeOrientationForWindow(aura::Window* window) {
  display::Display display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(window);
  const OrientationType orientation = RotationToOrientation(
      GetDisplayNaturalOrientation(display), display.rotation());
  return IsLandscapeOrientation(orientation);
}

gfx::Size GetFloatedWindowTabletSize(aura::Window* window) {
  CHECK(window);

  if ((window->GetProperty(aura::client::kResizeBehaviorKey) &
       aura::client::kResizeBehaviorCanResize) == 0) {
    return gfx::Size();
  }

  const gfx::Rect work_area =
      display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
  const bool landscape = IsLandscapeOrientationForWindow(window);

  const gfx::Size preferred_size =
      GetPreferredFloatedWindowTabletSize(work_area, landscape);
  const gfx::Size minimum_size = window->delegate()->GetMinimumSize();
  if (minimum_size.height() > preferred_size.height()) {
    return gfx::Size();
  }

  const int landscape_width =
      landscape ? work_area.width() : work_area.height();

  // The maximum size for a floated window is half the landscape width minus
  // some space for the split view divider and padding.
  const int maximum_float_width =
      (landscape_width - kSplitviewDividerShortSideLength) / 2 -
      kFloatedWindowPaddingDp * 2;
  if (minimum_size.width() > maximum_float_width) {
    return gfx::Size();
  }

  // For browsers, we need to add some padding to the minimum size since the
  // browser returns a minimum size that makes the omnibox untappable for many
  // websites. However, we don't add this padding if it causes an otherwise
  // floatable window to not be floatable anymore.
  // TODO(b/278769645): Remove this workaround once browser returns a viable
  // minimum size.
  const int minimum_width_padding =
      window->GetProperty(chromeos::kAppTypeKey) == chromeos::AppType::BROWSER
          ? kBrowserExtraPaddingDp
          : 0;

  // If the preferred width is less than the minimum width, use the minimum
  // width. Add padding to the preferred width if the window is a browser, but
  // don't exceed the maximum float width.
  int width = std::max(preferred_size.width(),
                       minimum_size.width() + minimum_width_padding);
  width = std::min(width, maximum_float_width);
  return gfx::Size(width, preferred_size.height());
}

bool CanFloatWindow(aura::Window* window) {
  if (window->GetProperty(chromeos::kAppTypeKey) ==
      chromeos::AppType::NON_APP) {
    return false;
  }

  if (!window->GetProperty(kSupportsFloatedStateKey)) {
    return false;
  }

  const auto state_type = window->GetProperty(chromeos::kWindowStateTypeKey);
  const bool unresizable =
      (window->GetProperty(aura::client::kResizeBehaviorKey) &
       aura::client::kResizeBehaviorCanResize) == 0;
  // Windows which occupy the entire display should not be the target of
  // unresizable floating.
  if (unresizable && (state_type == chromeos::WindowStateType::kFullscreen ||
                      state_type == chromeos::WindowStateType::kMaximized)) {
    return false;
  }

  if (window->GetProperty(aura::client::kZOrderingKey) !=
      ui::ZOrderLevel::kNormal) {
    return false;
  }

  return display::Screen::GetScreen()->InTabletMode()
             ? CanFloatWindowInTablet(window)
             : CanFloatWindowInClamshell(window);
}

}  // namespace chromeos::wm