blob: 1dc3cb36b45ac39ba4fcfc15b80930ad75c6c52d [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2018 The Chromium Authors
Sammie Quon83146debf2018-01-16 17:48:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/wm/overview/overview_utils.h"
6
Lei Zhangda65e85e2018-08-30 18:46:407#include <utility>
8
Katie Dektar582ae102023-12-13 03:15:549#include "ash/accessibility/accessibility_controller.h"
Sammie Quon3e9f42b2020-01-04 02:42:5410#include "ash/public/cpp/shelf_config.h"
Ahmed Fakhry927eabc62019-05-11 00:14:1511#include "ash/public/cpp/window_properties.h"
Sophie Wen3fe03cb2023-09-25 20:53:1612#include "ash/root_window_controller.h"
Mitsuru Oshimac327ca9d2019-04-08 23:17:4513#include "ash/scoped_animation_disabler.h"
Sammie Quon8cf3df22019-10-21 17:52:2314#include "ash/screen_util.h"
Sammie Quon3e9f42b2020-01-04 02:42:5415#include "ash/shelf/shelf.h"
16#include "ash/shelf/shelf_layout_manager.h"
wutao61d55b82018-02-15 07:09:3817#include "ash/shell.h"
Sammie Quon1f4a8bec2020-01-13 19:22:0018#include "ash/wm/mru_window_tracker.h"
Sammie Quon855e3722018-05-04 02:03:1719#include "ash/wm/overview/cleanup_animation_observer.h"
Sammie Quonf3a420a2019-04-12 16:14:5420#include "ash/wm/overview/delayed_animation_observer_impl.h"
Sammie Quon80e82a12019-01-23 19:55:2221#include "ash/wm/overview/overview_controller.h"
Sammie Quon16a76272023-08-29 22:32:3522#include "ash/wm/overview/overview_focus_cycler.h"
Avery Musbach8f349292019-11-12 17:29:5323#include "ash/wm/overview/overview_grid.h"
Sammie Quon1f4a8bec2020-01-13 19:22:0024#include "ash/wm/overview/overview_item.h"
Yongshun Liu0c76bec2022-08-18 23:40:5725#include "ash/wm/overview/overview_session.h"
Sammie Quon855e3722018-05-04 02:03:1726#include "ash/wm/overview/scoped_overview_animation_settings.h"
wutao61d55b82018-02-15 07:09:3827#include "ash/wm/splitview/split_view_controller.h"
Sophie Wen3fe03cb2023-09-25 20:53:1628#include "ash/wm/splitview/split_view_overview_session.h"
Michele Fan11c9ad842023-12-08 01:27:2629#include "ash/wm/splitview/split_view_types.h"
Sammie Quon17d0def2018-12-14 22:19:1530#include "ash/wm/splitview/split_view_utils.h"
wutao61d55b82018-02-15 07:09:3831#include "ash/wm/window_state.h"
Min Chen96202132018-08-24 22:45:5032#include "ash/wm/window_transient_descendant_iterator.h"
Richard Chui6acff5322020-09-21 21:39:1933#include "ash/wm/window_util.h"
Mitsuru Oshimac327ca9d2019-04-08 23:17:4534#include "ash/wm/wm_event.h"
Sammie Quon625b56a2019-12-27 20:15:3835#include "ash/wm/work_area_insets.h"
Michele Fan3c6da022023-12-09 00:52:4536#include "chromeos/ui/frame/caption_buttons/snap_controller.h"
Ahmed Fakhry363a1582019-05-07 19:11:1037#include "ui/aura/client/aura_constants.h"
wutao61d55b82018-02-15 07:09:3838#include "ui/aura/window.h"
Lei Zhang0c043322021-04-27 16:43:0539#include "ui/compositor/layer.h"
Eriko Kurimoto408253e2023-11-30 01:04:3240#include "ui/display/screen.h"
Sammie Quonb9de1062018-02-21 21:58:1741#include "ui/gfx/canvas.h"
Xianzhu Wang65ef1ad32021-10-07 03:12:3342#include "ui/gfx/geometry/transform_util.h"
Sammie Quonb9de1062018-02-21 21:58:1743#include "ui/views/view.h"
44#include "ui/views/widget/widget.h"
Richard Chuic6ad600e2022-08-18 17:21:1345#include "ui/views/widget/widget_delegate.h"
Min Chen96202132018-08-24 22:45:5046#include "ui/wm/core/coordinate_conversion.h"
Sammie Quonb9de1062018-02-21 21:58:1747#include "ui/wm/core/window_animations.h"
Sammie Quon83146debf2018-01-16 17:48:1448
49namespace ash {
50
Sophie Wene872b3f2023-08-30 02:47:2551bool IsInOverviewSession() {
Michele Fana5512322023-10-18 04:46:3052 OverviewController* overview_controller = OverviewController::Get();
Sophie Wene872b3f2023-08-30 02:47:2553 return overview_controller && overview_controller->InOverviewSession();
54}
55
56OverviewSession* GetOverviewSession() {
Michele Fana5512322023-10-18 04:46:3057 OverviewController* overview_controller = OverviewController::Get();
Sophie Wene872b3f2023-08-30 02:47:2558 return overview_controller && overview_controller->InOverviewSession()
59 ? overview_controller->overview_session()
60 : nullptr;
61}
62
wutao61d55b82018-02-15 07:09:3863bool CanCoverAvailableWorkspace(aura::Window* window) {
Sammie Quon277c6162023-10-25 03:12:5964 if (!window) {
65 return false;
66 }
Friedrich [CET]7c791002019-12-03 15:35:3567 SplitViewController* split_view_controller = SplitViewController::Get(window);
68 if (split_view_controller->InSplitViewMode())
Toshiki Kikuchid4dfe5f2024-01-11 02:47:0369 return split_view_controller->CanKeepCurrentSnapRatio(window);
James Cook00e65e92019-07-25 03:19:0870 return WindowState::Get(window)->IsMaximizedOrFullscreenOrPinned();
wutao61d55b82018-02-15 07:09:3871}
72
Toni Barzicd9238d8f2020-10-21 18:47:1473void FadeInWidgetToOverview(views::Widget* widget,
74 OverviewAnimationType animation_type,
75 bool observe) {
Sammie Quoncce77082018-08-08 17:23:2276 aura::Window* window = widget->GetNativeWindow();
Toni Barzicd9238d8f2020-10-21 18:47:1477 if (window->layer()->GetTargetOpacity() == 1.f)
Sammie Quoncce77082018-08-08 17:23:2278 return;
79
Xiaoqian Dai97f4956a2019-12-04 22:19:0180 // Fade in the widget from its current opacity.
Sammie Quoncce77082018-08-08 17:23:2281 ScopedOverviewAnimationSettings scoped_overview_animation_settings(
Sammie Quonf1182082018-08-20 18:20:0982 animation_type, window);
Sammie Quoncce77082018-08-08 17:23:2283 window->layer()->SetOpacity(1.0f);
Mitsuru Oshima6b7d5bc72018-11-03 01:00:5984
Sammie Quon346d22f2019-05-02 16:29:5885 if (observe) {
Sammie Quone5575e12019-04-12 23:05:2586 auto enter_observer = std::make_unique<EnterAnimationObserver>();
87 scoped_overview_animation_settings.AddObserver(enter_observer.get());
Michele Fana5512322023-10-18 04:46:3088 OverviewController::Get()->AddEnterAnimationObserver(
Sammie Quone5575e12019-04-12 23:05:2589 std::move(enter_observer));
Mitsuru Oshima6b7d5bc72018-11-03 01:00:5990 }
Sammie Quoncce77082018-08-08 17:23:2291}
92
Sammie Quon45981be22023-12-04 19:16:4293void PrepareWidgetForOverviewShutdown(views::Widget* widget) {
94 // The widget should no longer process events at this point.
95 widget->SetVisibilityChangedAnimationsEnabled(false);
96 widget->widget_delegate()->SetCanActivate(false);
97 widget->GetNativeWindow()->SetEventTargetingPolicy(
98 aura::EventTargetingPolicy::kNone);
99 widget->GetContentsView()->SetCanProcessEventsWithinSubtree(false);
100 widget->GetFocusManager()->set_shortcut_handling_suspended(true);
101}
102
Toni Barzicd9238d8f2020-10-21 18:47:14103void FadeOutWidgetFromOverview(std::unique_ptr<views::Widget> widget,
104 OverviewAnimationType animation_type) {
Sammie Quon45981be22023-12-04 19:16:42105 PrepareWidgetForOverviewShutdown(widget.get());
Richard Chuic6ad600e2022-08-18 17:21:13106
Sammie Quon244a5cb2019-02-08 17:27:41107 // The overview controller may be nullptr on shutdown.
Michele Fana5512322023-10-18 04:46:30108 OverviewController* controller = OverviewController::Get();
Sammie Quon855e3722018-05-04 02:03:17109 if (!controller) {
110 widget->SetOpacity(0.f);
111 return;
112 }
113
Xiaoqian Dai97f4956a2019-12-04 22:19:01114 // Fade out the widget from its current opacity. This animation continues past
115 // the lifetime of overview mode items.
Sammie Quon855e3722018-05-04 02:03:17116 ScopedOverviewAnimationSettings animation_settings(animation_type,
117 widget->GetNativeWindow());
118 // CleanupAnimationObserver will delete itself (and the widget) when the
Sammie Quonf1182082018-08-20 18:20:09119 // opacity animation is complete. Ownership over the observer is passed to the
Sammie Quon244a5cb2019-02-08 17:27:41120 // overview controller which has longer lifetime so that animations can
Sammie Quonf1182082018-08-20 18:20:09121 // continue even after the overview mode is shut down.
Sammie Quon855e3722018-05-04 02:03:17122 views::Widget* widget_ptr = widget.get();
Sammie Quon317deb52018-09-06 16:36:28123 auto observer = std::make_unique<CleanupAnimationObserver>(std::move(widget));
Sammie Quon855e3722018-05-04 02:03:17124 animation_settings.AddObserver(observer.get());
Sammie Quonf3a420a2019-04-12 16:14:54125 controller->AddExitAnimationObserver(std::move(observer));
Sammie Quon855e3722018-05-04 02:03:17126 widget_ptr->SetOpacity(0.f);
Sammie Quon855e3722018-05-04 02:03:17127}
128
Ahmed Fakhry38657f22019-05-02 17:22:56129void ImmediatelyCloseWidgetOnExit(std::unique_ptr<views::Widget> widget) {
Ahmed Fakhry363a1582019-05-07 19:11:10130 widget->GetNativeWindow()->SetProperty(aura::client::kAnimationsDisabledKey,
131 true);
Ahmed Fakhry38657f22019-05-02 17:22:56132 widget->Close();
133 widget.reset();
134}
135
Michele Fan6e0904622023-10-20 00:25:18136gfx::RectF GetUnionScreenBoundsForWindow(aura::Window* window) {
Sammie Quon82fb9792019-02-22 08:42:43137 gfx::RectF bounds;
Richard Chui6acff5322020-09-21 21:39:19138 for (auto* window_iter :
139 window_util::GetVisibleTransientTreeIterator(window)) {
Sammie Quon244a5cb2019-02-08 17:27:41140 // Ignore other window types when computing bounding box of overview target
141 // item.
Xiaoqian Dai219bf06e2018-09-07 16:55:09142 if (window_iter != window &&
Allen Bauer6d2399c2021-05-13 16:06:25143 window_iter->GetType() != aura::client::WINDOW_TYPE_NORMAL) {
Xiaoqian Dai219bf06e2018-09-07 16:55:09144 continue;
145 }
Sammie Quon82fb9792019-02-22 08:42:43146 gfx::RectF target_bounds(window_iter->GetTargetBounds());
Michele Fan6e0904622023-10-20 00:25:18147 wm::TranslateRectToScreen(window_iter->parent(), &target_bounds);
Xiaoqian Dai219bf06e2018-09-07 16:55:09148 bounds.Union(target_bounds);
149 }
Michele Fan00c11472023-10-04 03:47:47150
Xiaoqian Dai219bf06e2018-09-07 16:55:09151 return bounds;
152}
153
Mitsuru Oshimac327ca9d2019-04-08 23:17:45154void MaximizeIfSnapped(aura::Window* window) {
James Cook00e65e92019-07-25 03:19:08155 auto* window_state = WindowState::Get(window);
Mitsuru Oshimac327ca9d2019-04-08 23:17:45156 if (window_state && window_state->IsSnapped()) {
157 ScopedAnimationDisabler disabler(window);
James Cook00e65e92019-07-25 03:19:08158 WMEvent event(WM_EVENT_MAXIMIZE);
Mitsuru Oshimac327ca9d2019-04-08 23:17:45159 window_state->OnWMEvent(&event);
160 }
161}
162
Sammie Quon625b56a2019-12-27 20:15:38163gfx::Rect GetGridBoundsInScreen(aura::Window* target_root) {
164 return GetGridBoundsInScreen(target_root,
Arthur Sonzognia98e4432023-11-28 18:15:01165 /*window_dragging_state=*/std::nullopt,
Sammie Quon3e9f42b2020-01-04 02:42:54166 /*account_for_hotseat=*/true);
Sammie Quon625b56a2019-12-27 20:15:38167}
168
169gfx::Rect GetGridBoundsInScreen(
Avery Musbach8f349292019-11-12 17:29:53170 aura::Window* target_root,
Arthur Sonzognia98e4432023-11-28 18:15:01171 std::optional<SplitViewDragIndicators::WindowDraggingState>
Sammie Quon625b56a2019-12-27 20:15:38172 window_dragging_state,
Sammie Quon3e9f42b2020-01-04 02:42:54173 bool account_for_hotseat) {
Avery Musbach8f349292019-11-12 17:29:53174 auto* split_view_controller = SplitViewController::Get(target_root);
Michele Fan16a0f0c2023-06-22 02:55:30175 SplitViewController::State state = split_view_controller->state();
Sammie Quon8cf3df22019-10-21 17:52:23176
177 // If we are in splitview mode already just use the given state, otherwise
Sophie Wen3fe03cb2023-09-25 20:53:16178 // convert `window_dragging_state` to a split view state. Note this will
179 // override `state` from `split_view_overview_session` if there is any.
Avery Musbachabe3a2d2019-11-04 21:51:27180 if (!split_view_controller->InSplitViewMode() && window_dragging_state) {
181 switch (*window_dragging_state) {
Xiaoqian Dai6bdc3372022-09-19 23:06:04182 case SplitViewDragIndicators::WindowDraggingState::kToSnapPrimary:
183 state = SplitViewController::State::kPrimarySnapped;
Avery Musbachabe3a2d2019-11-04 21:51:27184 break;
Xiaoqian Dai6bdc3372022-09-19 23:06:04185 case SplitViewDragIndicators::WindowDraggingState::kToSnapSecondary:
186 state = SplitViewController::State::kSecondarySnapped;
Avery Musbachabe3a2d2019-11-04 21:51:27187 break;
188 default:
189 break;
190 }
Sammie Quon8cf3df22019-10-21 17:52:23191 }
192
Michele Fan50496c612024-01-26 22:27:57193 const gfx::Rect work_area =
Sammie Quon625b56a2019-12-27 20:15:38194 WorkAreaInsets::ForWindow(target_root)->ComputeStableWorkArea();
Michele Fan50496c612024-01-26 22:27:57195 gfx::Rect bounds = work_area;
Michele Fan11c9ad842023-12-08 01:27:26196 std::optional<SnapPosition> opposite_position;
Michele Fan16a0f0c2023-06-22 02:55:30197
198 // We should show partial overview for the following use cases:
Michele Fan50496c612024-01-26 22:27:57199 // 1. In tablet split view mode with one window snapped.
200 // 2. In clamshell `SplitViewOverviewSession`.
201 if (auto* split_view_overview_session =
202 RootWindowController::ForWindow(target_root)
203 ->split_view_overview_session()) {
Michele Fanbb51aa42024-02-13 00:13:41204 aura::Window* snapped_window = split_view_overview_session->window();
205 gfx::Rect target_bounds_in_screen(snapped_window->GetTargetBounds());
206 WindowState* window_state = WindowState::Get(snapped_window);
207 CHECK(window_state->IsSnapped());
208 opposite_position = window_state->GetStateType() ==
209 chromeos::WindowStateType::kPrimarySnapped
210 ? SnapPosition::kSecondary
211 : SnapPosition::kPrimary;
Michele Fan50496c612024-01-26 22:27:57212 wm::ConvertRectToScreen(target_root, &target_bounds_in_screen);
213 bounds.Subtract(target_bounds_in_screen);
Sophie Wenc1d74e852023-10-26 21:30:44214 } else {
215 switch (state) {
216 case SplitViewController::State::kPrimarySnapped:
217 bounds = split_view_controller->GetSnappedWindowBoundsInScreen(
Michele Fan11c9ad842023-12-08 01:27:26218 SnapPosition::kSecondary,
Michele Fan3c6da022023-12-09 00:52:45219 /*window_for_minimum_size=*/nullptr, chromeos::kDefaultSnapRatio);
Michele Fan11c9ad842023-12-08 01:27:26220 opposite_position = SnapPosition::kSecondary;
Sophie Wenc1d74e852023-10-26 21:30:44221 break;
222 case SplitViewController::State::kSecondarySnapped:
223 bounds = split_view_controller->GetSnappedWindowBoundsInScreen(
Michele Fan11c9ad842023-12-08 01:27:26224 SnapPosition::kPrimary,
Michele Fan3c6da022023-12-09 00:52:45225 /*window_for_minimum_size=*/nullptr, chromeos::kDefaultSnapRatio);
Michele Fan11c9ad842023-12-08 01:27:26226 opposite_position = SnapPosition::kPrimary;
Sophie Wenc1d74e852023-10-26 21:30:44227 break;
228 case SplitViewController::State::kNoSnap:
Sophie Wenc1d74e852023-10-26 21:30:44229 break;
230 case SplitViewController::State::kBothSnapped:
Michele Fan50496c612024-01-26 22:27:57231 // When this function is called, SplitViewController should have
232 // already handled the state change.
Sophie Wenc1d74e852023-10-26 21:30:44233 NOTREACHED();
234 }
Sammie Quon8cf3df22019-10-21 17:52:23235 }
Sammie Quon625b56a2019-12-27 20:15:38236
Richard Chui0b0a1952023-02-03 01:22:48237 // Hotseat overlaps the work area / split view bounds when extended, but in
Sammie Quon3e9f42b2020-01-04 02:42:54238 // some cases we don't want its bounds in our calculations.
Eriko Kurimoto408253e2023-11-30 01:04:32239 if (account_for_hotseat && display::Screen::GetScreen()->InTabletMode()) {
Sammie Quon3e9f42b2020-01-04 02:42:54240 const bool hotseat_extended =
Michele Fan50496c612024-01-26 22:27:57241 Shelf::ForWindow(target_root)
242 ->shelf_layout_manager()
243 ->hotseat_state() == HotseatState::kExtended;
Sammie Quon3e9f42b2020-01-04 02:42:54244 // When a window is dragged from the top of the screen, overview gets
245 // entered immediately but the window does not get deactivated right away so
246 // the hotseat state does not get updated until the window gets dragged a
247 // bit. In this case, determine whether the hotseat will be extended to
248 // avoid doing a expensive double grid layout.
Michele Fana5512322023-10-18 04:46:30249 auto* overview_session = OverviewController::Get()->overview_session();
Sammie Quon3e9f42b2020-01-04 02:42:54250 const bool hotseat_will_extend =
Richard Chui8a399562023-02-03 05:35:52251 overview_session && overview_session->ShouldEnterWithoutAnimations() &&
Sammie Quon3e9f42b2020-01-04 02:42:54252 !split_view_controller->InSplitViewMode();
253 if (hotseat_extended || hotseat_will_extend) {
Andrew Xuec9de8e2020-05-07 18:24:26254 // Use the default hotseat size here to avoid the possible re-layout
255 // due to the update in HotseatWidget::is_forced_dense_.
Sammie Quon3e9f42b2020-01-04 02:42:54256 const int hotseat_bottom_inset =
Andrew Xu08bc4942020-06-02 16:43:32257 ShelfConfig::Get()->GetHotseatSize(
258 /*density=*/HotseatDensity::kNormal) +
Sammie Quon3e9f42b2020-01-04 02:42:54259 ShelfConfig::Get()->hotseat_bottom_padding();
Andrew Xuec9de8e2020-05-07 18:24:26260
Xianzhu Wang549ddc42022-04-04 17:05:55261 bounds.Inset(gfx::Insets::TLBR(0, 0, hotseat_bottom_inset, 0));
Sammie Quon3e9f42b2020-01-04 02:42:54262 }
263 }
264
Michele Fanbb51aa42024-02-13 00:13:41265 // Clamp the bounds of the overview grid such that it doesn't go below 1/3 of
266 // the work area length
sophiewene2e8abd2023-12-05 18:04:12267 const bool horizontal = IsLayoutHorizontal(target_root);
Sammie Quon625b56a2019-12-27 20:15:38268 const int min_length =
269 (horizontal ? work_area.width() : work_area.height()) / 3;
270 const int current_length = horizontal ? bounds.width() : bounds.height();
271
272 if (current_length > min_length)
273 return bounds;
274
Michele Fanbb51aa42024-02-13 00:13:41275 // Clamp bounds' corresponding length to the minimum length.
Sammie Quon625b56a2019-12-27 20:15:38276 if (horizontal)
277 bounds.set_width(min_length);
278 else
279 bounds.set_height(min_length);
280
Michele Fanbb51aa42024-02-13 00:13:41281 // These changes below are crucial for better visualization and help
282 // preventing crashes when dragging the snapped window towards the edge. In
283 // this case, the overview components will become too small to allow any
284 // gradient painting on desk bar or applying shadows. Please ensure to go
285 // through the bounds update below when one window is snapped in overview both
286 // in clamshell and tablet mode. See the regression behavior in
287 // http://b/324478757.
288 if (opposite_position &&
289 IsPhysicalLeftOrTop(*opposite_position, target_root)) {
Sammie Quon625b56a2019-12-27 20:15:38290 // If we are shifting to the left or top we need to update the origin as
291 // well.
292 const int offset = min_length - current_length;
293 bounds.Offset(horizontal ? gfx::Vector2d(-offset, 0)
294 : gfx::Vector2d(0, -offset));
295 }
296
297 return bounds;
Sammie Quon8cf3df22019-10-21 17:52:23298}
299
Arthur Sonzognia98e4432023-11-28 18:15:01300std::optional<gfx::RectF> GetSplitviewBoundsMaintainingAspectRatio() {
Eriko Kurimoto408253e2023-11-30 01:04:32301 if (!ShouldAllowSplitView()) {
302 return absl::nullopt;
303 }
304 if (!display::Screen::GetScreen()->InTabletMode()) {
305 return absl::nullopt;
306 }
Michele Fana5512322023-10-18 04:46:30307 auto* overview_session = OverviewController::Get()->overview_session();
Sammie Quon8cf3df22019-10-21 17:52:23308 DCHECK(overview_session);
Avery Musbach8f349292019-11-12 17:29:53309 aura::Window* root_window = Shell::GetPrimaryRootWindow();
310 DCHECK(overview_session->GetGridWithRootWindow(root_window)
311 ->split_view_drag_indicators());
Avery Musbach8f349292019-11-12 17:29:53312 auto window_dragging_state =
313 overview_session->GetGridWithRootWindow(root_window)
314 ->split_view_drag_indicators()
315 ->current_window_dragging_state();
316 if (!SplitViewController::Get(root_window)->InSplitViewMode() &&
Avery Musbachabe3a2d2019-11-04 21:51:27317 SplitViewDragIndicators::GetSnapPosition(window_dragging_state) ==
Michele Fan11c9ad842023-12-08 01:27:26318 SnapPosition::kNone) {
Arthur Sonzognia98e4432023-11-28 18:15:01319 return std::nullopt;
Sammie Quon8cf3df22019-10-21 17:52:23320 }
321
Sammie Quon3e9f42b2020-01-04 02:42:54322 // The hotseat bounds do not affect splitview after a window is snapped, so
323 // the aspect ratio should reflect it and not worry about the hotseat.
Lei Zhangf2166c62022-09-17 02:03:11324 return gfx::RectF(GetGridBoundsInScreen(root_window, window_dragging_state,
Lei Zhangf2166c62022-09-17 02:03:11325 /*account_for_hotseat=*/false));
Sammie Quon8cf3df22019-10-21 17:52:23326}
327
Danton Vu1cc0aa842019-07-31 19:04:49328bool ShouldUseTabletModeGridLayout() {
Eriko Kurimoto408253e2023-11-30 01:04:32329 return display::Screen::GetScreen()->InTabletMode();
Danton Vu1cc0aa842019-07-31 19:04:49330}
331
Mitsuru Oshimafff5741c2019-12-10 00:00:11332gfx::Rect ToStableSizeRoundedRect(const gfx::RectF& rect) {
333 return gfx::Rect(gfx::ToRoundedPoint(rect.origin()),
334 gfx::ToRoundedSize(rect.size()));
335}
336
Sammie Quon96c640d2023-09-01 22:44:54337void MoveFocusToView(OverviewFocusableView* target_view) {
Michele Fana5512322023-10-18 04:46:30338 auto* overview_session = OverviewController::Get()->overview_session();
Sammie Quon1ab58e272023-10-04 17:34:35339 CHECK(overview_session);
340
341 auto* focus_cycler = overview_session->focus_cycler();
Sammie Quon16a76272023-08-29 22:32:35342 CHECK(focus_cycler);
Yongshun Liu0c76bec2022-08-18 23:40:57343
Sammie Quon16a76272023-08-29 22:32:35344 focus_cycler->MoveFocusToView(target_view);
Yongshun Liu0c76bec2022-08-18 23:40:57345}
346
Sammie Quon277c6162023-10-25 03:12:59347void SetWindowsVisibleDuringItemDragging(const aura::Window::Windows& windows,
348 bool visible,
349 bool animate) {
350 float new_opacity = visible ? 1.f : 0.f;
Ali Hijazie63cbaf62023-12-20 19:29:35351 for (aura::Window* window : windows) {
Sammie Quon277c6162023-10-25 03:12:59352 ui::Layer* layer = window->layer();
353 if (layer->GetTargetOpacity() == new_opacity) {
354 continue;
355 }
356
357 if (animate) {
358 ScopedOverviewAnimationSettings settings(
359 OVERVIEW_ANIMATION_OPACITY_ON_WINDOW_DRAG, window);
360 layer->SetOpacity(new_opacity);
361 } else {
362 layer->SetOpacity(new_opacity);
363 }
364 }
365}
366
Sammie Quon83146debf2018-01-16 17:48:14367} // namespace ash