snap-groups: Split out faster splitview toast
This moves the faster splitview dialog out of `no_windows_widget_` and to its own `faster_splitview_widget_` (previously `settings_widget_`). This widget contains a toast with a skip button and the settings button. Will refactor in follow-up CLs. Test: added Bug: b/323199185 Change-Id: I96eb80bcd87efd57d4b6ce8373d185bb0c0a11f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5255079 Reviewed-by: Ahmed Fakhry <afakhry@chromium.org> Commit-Queue: Sophie Wen <sophiewen@chromium.org> Cr-Commit-Position: refs/heads/main@{#1256513}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
1b061c2c74
commit
2df25b7f8a
@ -2460,8 +2460,14 @@ Style notes:
|
||||
<message name="IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility text read by screen readers for a closeable desk mini view when the close all feature is enabled.">
|
||||
Press Ctrl + W to combine with <ph name="DESK_NAME">$1<ex>Desk 1</ex></ph>. Press Ctrl + Shift + W to close desk and windows.
|
||||
</message>
|
||||
<message name="IDS_ASH_OVERVIEW_SETTINGS_BUTTON_LABEL" translateable="false" desc="The accessible name for the Overview Settings button during faster splitscreen setup.">
|
||||
Multitasking settings
|
||||
<message name="IDS_ASH_OVERVIEW_SETTINGS_BUTTON_LABEL" desc="The accessible name for the Overview Settings button during faster splitscreen setup.">
|
||||
Windows and desks settings
|
||||
</message>
|
||||
<message name="IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST" desc="The text for the Faster Splitscreen toast during faster splitscreen setup.">
|
||||
Choose a window for this side
|
||||
</message>
|
||||
<message name="IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST_SKIP" desc="The text for the Faster Splitscreen toast skip button.">
|
||||
Dismiss
|
||||
</message>
|
||||
<message name="IDS_ASH_OVERVIEW_WINDOW_CLOSING_A11Y_ALERT" desc="The accessibility alert read by screen readers to alert the user that a window in overview mode is closing.">
|
||||
Window <ph name="WINDOW_TITILE">$1<ex>1</ex></ph> closed.
|
||||
|
@ -0,0 +1 @@
|
||||
ce88f581202f4cf5a8a4e8d84558fe072fc8b9b7
|
@ -0,0 +1 @@
|
||||
3a66c9bf30160c6f3d1c69a5c7f2d5cd4d6a34df
|
@ -0,0 +1 @@
|
||||
96dc0a987229a1cc73b06b126d64275a913a4434
|
@ -25,6 +25,7 @@
|
||||
#include "ash/strings/grit/ash_strings.h"
|
||||
#include "ash/style/ash_color_id.h"
|
||||
#include "ash/style/icon_button.h"
|
||||
#include "ash/style/system_toast_style.h"
|
||||
#include "ash/system/toast/toast_manager_impl.h"
|
||||
#include "ash/wallpaper/wallpaper_controller_impl.h"
|
||||
#include "ash/wm/desks/default_desk_button.h"
|
||||
@ -98,6 +99,7 @@
|
||||
#include "ui/gfx/geometry/transform_util.h"
|
||||
#include "ui/gfx/geometry/vector2d_f.h"
|
||||
#include "ui/views/animation/animation_builder.h"
|
||||
#include "ui/views/highlight_border.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/wm/core/coordinate_conversion.h"
|
||||
@ -2032,16 +2034,17 @@ void OverviewGrid::UpdateNoWindowsWidget(bool no_items,
|
||||
// 2. In faster split screen setup, the `no_windows_widget_` show to indicate
|
||||
// either no windows available to pair or select a window to complete the
|
||||
// window layout.
|
||||
// TODO(b/307812315): Consider separating the widgets i.e. one
|
||||
// `no_windows_widget_` and one `faster_splitscreen_widget_`.
|
||||
const bool in_faster_split_screen_setup_session =
|
||||
window_util::IsInFasterSplitScreenSetupSession(root_window_);
|
||||
if ((!in_faster_split_screen_setup_session &&
|
||||
(!no_items || IsShowingSavedDeskLibrary())) ||
|
||||
// TODO(b/323199185): Move this to its own function.
|
||||
if (window_util::IsInFasterSplitScreenSetupSession(root_window_)) {
|
||||
UpdateFasterSplitViewWidget();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!no_items || IsShowingSavedDeskLibrary() ||
|
||||
overview_session_->enter_exit_overview_type() ==
|
||||
OverviewEnterExitType::kPine) {
|
||||
no_windows_widget_.reset();
|
||||
settings_widget_.reset();
|
||||
faster_splitview_widget_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2053,12 +2056,7 @@ void OverviewGrid::UpdateNoWindowsWidget(bool no_items,
|
||||
params.vertical_padding = kNoItemsIndicatorVerticalPaddingDp;
|
||||
params.rounding_dp = kNoItemsIndicatorRoundingDp;
|
||||
params.preferred_height = kNoItemsIndicatorHeightDp;
|
||||
if (in_faster_split_screen_setup_session) {
|
||||
params.message =
|
||||
no_items ? kFasterSplitScreenToastNoWindows : kFasterSplitScreenToast;
|
||||
} else {
|
||||
params.message = IDS_ASH_OVERVIEW_NO_RECENT_ITEMS;
|
||||
}
|
||||
params.message = IDS_ASH_OVERVIEW_NO_RECENT_ITEMS;
|
||||
|
||||
params.parent =
|
||||
root_window_->GetChildById(desks_util::GetActiveDeskContainerId());
|
||||
@ -2080,10 +2078,6 @@ void OverviewGrid::UpdateNoWindowsWidget(bool no_items,
|
||||
}
|
||||
|
||||
RefreshNoWindowsWidgetBounds(/*animate=*/false);
|
||||
|
||||
// This must be done after we set the no windows widget bounds.
|
||||
// TODO(b/323199185): Refactor all these UI component updates.
|
||||
UpdateSettingsButton();
|
||||
}
|
||||
|
||||
void OverviewGrid::RefreshNoWindowsWidgetBounds(bool animate) {
|
||||
@ -2092,25 +2086,6 @@ void OverviewGrid::RefreshNoWindowsWidgetBounds(bool animate) {
|
||||
|
||||
const gfx::Rect grid_bounds(GetGridEffectiveBounds());
|
||||
no_windows_widget_->SetBoundsCenteredIn(grid_bounds, animate);
|
||||
|
||||
if (window_util::IsInFasterSplitScreenSetupSession(root_window_)) {
|
||||
// If there are no windows, set it in the center of the grid.
|
||||
if (item_list_.empty()) {
|
||||
return;
|
||||
}
|
||||
// Position the widget under the bottom of the last overview item, but
|
||||
// centered horizontally.
|
||||
const gfx::RectF last_overview_item_bounds =
|
||||
item_list_.back()->target_bounds();
|
||||
const int center_x =
|
||||
no_windows_widget_->GetBoundsCenteredIn(grid_bounds).x();
|
||||
const gfx::Point available_origin(
|
||||
center_x,
|
||||
last_overview_item_bounds.bottom() + kFasterSplitScreenToastSpacingDp);
|
||||
no_windows_widget_->SetBounds(
|
||||
gfx::Rect(available_origin,
|
||||
no_windows_widget_->GetContentsView()->GetPreferredSize()));
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewGrid::RefreshGridBounds(bool animate) {
|
||||
@ -2447,12 +2422,6 @@ const SavedDeskLibraryView* OverviewGrid::GetSavedDeskLibraryView() const {
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
const IconButton* OverviewGrid::GetSettingsButtonForTesting() const {
|
||||
return settings_widget_ ? views::AsViewClass<IconButton>(
|
||||
settings_widget_->GetContentsView())
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void OverviewGrid::MaybeInitDesksWidget() {
|
||||
TRACE_EVENT0("ui", "OverviewGrid::MaybeInitDesksWidget");
|
||||
if (!desks_util::ShouldDesksBarBeCreated() || desks_widget_)
|
||||
@ -2930,47 +2899,86 @@ void OverviewGrid::CreateAndShowPine(const gfx::ImageSkia& pine_image) {
|
||||
OverviewController::Get()->OnPineWidgetShown();
|
||||
}
|
||||
|
||||
void OverviewGrid::OnSkipButtonPressed() {
|
||||
// Destroys `this`.
|
||||
// TODO(sophiewen): Consider adding another exit point metric.
|
||||
OverviewController::Get()->EndOverview(OverviewEndAction::kKeyEscapeOrBack);
|
||||
}
|
||||
|
||||
void OverviewGrid::OnSettingsButtonPressed() {
|
||||
// Opens the OS Settings page, which causes a window activation change and
|
||||
// `EndOverview()` and destroys `this`.
|
||||
Shell::Get()->shell_delegate()->OpenMultitaskingSettings();
|
||||
}
|
||||
|
||||
void OverviewGrid::UpdateSettingsButton() {
|
||||
void OverviewGrid::UpdateFasterSplitViewWidget() {
|
||||
if (!window_util::IsInFasterSplitScreenSetupSession(root_window_)) {
|
||||
// If we weren't started by partial overview, don't show the settings
|
||||
// button.
|
||||
// If we weren't started by faster splitview, don't show the widget.
|
||||
faster_splitview_widget_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!settings_widget_) {
|
||||
if (!faster_splitview_widget_) {
|
||||
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
|
||||
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
||||
params.parent = desks_util::GetActiveDeskContainerForRoot(root_window_);
|
||||
params.name = "OverviewSettingsWidget";
|
||||
params.name = "FasterSplitViewWidget";
|
||||
params.init_properties_container.SetProperty(kHideInDeskMiniViewKey, true);
|
||||
params.init_properties_container.SetProperty(kOverviewUiKey, true);
|
||||
settings_widget_ = std::make_unique<views::Widget>(std::move(params));
|
||||
faster_splitview_widget_ =
|
||||
std::make_unique<views::Widget>(std::move(params));
|
||||
auto* box_layout_view = faster_splitview_widget_->SetContentsView(
|
||||
std::make_unique<views::BoxLayoutView>());
|
||||
box_layout_view->SetOrientation(views::BoxLayout::Orientation::kHorizontal);
|
||||
box_layout_view->SetBetweenChildSpacing(kSettingsButtonSpacingDp);
|
||||
|
||||
box_layout_view->AddChildView(std::make_unique<SystemToastStyle>(
|
||||
base::BindRepeating(&OverviewGrid::OnSkipButtonPressed,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
l10n_util::GetStringUTF16(IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST),
|
||||
l10n_util::GetStringUTF16(
|
||||
IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST_SKIP)));
|
||||
|
||||
auto* settings_button =
|
||||
settings_widget_->SetContentsView(std::make_unique<IconButton>(
|
||||
box_layout_view->AddChildView(std::make_unique<IconButton>(
|
||||
base::BindRepeating(&OverviewGrid::OnSettingsButtonPressed,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
IconButton::Type::kLarge, &kOverviewSettingsIcon,
|
||||
IDS_ASH_OVERVIEW_SETTINGS_BUTTON_LABEL));
|
||||
|
||||
// TODO(b/323199185): Consider refactoring this from `SystemToastStyle`.
|
||||
const int toast_height = settings_button->GetPreferredSize().height();
|
||||
const float toast_corner_radius = toast_height / 2.0f;
|
||||
settings_button->SetBorder(std::make_unique<views::HighlightBorder>(
|
||||
toast_corner_radius,
|
||||
views::HighlightBorder::Type::kHighlightBorderOnShadow));
|
||||
settings_button->SetBackgroundColor(kColorAshShieldAndBase80);
|
||||
|
||||
faster_splitview_widget_->Show();
|
||||
}
|
||||
|
||||
// Align the settings button with the no windows widget.
|
||||
// TODO(b/323199185): Move the faster splitscreen toast to this widget.
|
||||
// TODO(b/323199185): UX needs to decide where to position this.
|
||||
|
||||
gfx::Rect centered_bounds(GetGridEffectiveBounds());
|
||||
const gfx::Size preferred_size =
|
||||
faster_splitview_widget_->GetContentsView()->GetPreferredSize();
|
||||
centered_bounds.ClampToCenteredSize(preferred_size);
|
||||
|
||||
// If there are no windows, set it in the center of the grid.
|
||||
if (item_list_.empty()) {
|
||||
faster_splitview_widget_->SetBounds(centered_bounds);
|
||||
return;
|
||||
}
|
||||
|
||||
// Position the widget under the bottom of the last overview item, but
|
||||
// centered horizontally.
|
||||
const gfx::RectF last_overview_item_bounds =
|
||||
item_list_.back()->target_bounds();
|
||||
centered_bounds.set_y(last_overview_item_bounds.bottom() +
|
||||
kFasterSplitScreenToastSpacingDp);
|
||||
faster_splitview_widget_->SetBounds(centered_bounds);
|
||||
|
||||
// TODO(b/323409897): Add a11y focus traversal and Chromevox support.
|
||||
CHECK(no_windows_widget_);
|
||||
const gfx::Rect no_windows_widget_bounds(
|
||||
no_windows_widget_->GetWindowBoundsInScreen());
|
||||
settings_widget_->SetBounds(
|
||||
gfx::Rect(no_windows_widget_bounds.right() + kSettingsButtonSpacingDp,
|
||||
no_windows_widget_bounds.y(), no_windows_widget_bounds.height(),
|
||||
no_windows_widget_bounds.height()));
|
||||
settings_widget_->Show();
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -41,7 +41,6 @@ class PresentationTimeRecorder;
|
||||
|
||||
namespace ash {
|
||||
|
||||
class IconButton;
|
||||
class LegacyDeskBarView;
|
||||
class OverviewDropTarget;
|
||||
class OverviewGridEventHandler;
|
||||
@ -474,7 +473,9 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver,
|
||||
const gfx::Rect bounds_for_testing() const { return bounds_; }
|
||||
float scroll_offset_for_testing() const { return scroll_offset_; }
|
||||
views::Widget* pine_widget_for_testing() const { return pine_widget_.get(); }
|
||||
const IconButton* GetSettingsButtonForTesting() const;
|
||||
views::Widget* faster_splitview_widget_for_testing() {
|
||||
return faster_splitview_widget_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class DesksTemplatesTest;
|
||||
@ -590,12 +591,15 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver,
|
||||
// instead.
|
||||
void CreateAndShowPine(const gfx::ImageSkia& pine_image);
|
||||
|
||||
// Called when the partial overview settings button is pressed.
|
||||
// Called when the faster splitview toast skip button is pressed.
|
||||
void OnSkipButtonPressed();
|
||||
|
||||
// Called when the faster splitview settings button is pressed.
|
||||
void OnSettingsButtonPressed();
|
||||
|
||||
// Updates the visibility of `settings_widget_`. The widget will only be shown
|
||||
// if automatic partial overview was started.
|
||||
void UpdateSettingsButton();
|
||||
// Updates the visibility of `faster_splitview_widget_`. The widget will
|
||||
// only be shown if faster splitview setup is in session.
|
||||
void UpdateFasterSplitViewWidget();
|
||||
|
||||
// The drop target is created when a window or overview item is being dragged,
|
||||
// and is destroyed when the drag ends or overview mode is ended. The drop
|
||||
@ -628,8 +632,9 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver,
|
||||
// The contents view of the above |desks_widget_| if created.
|
||||
raw_ptr<LegacyDeskBarView, DanglingUntriaged> desks_bar_view_ = nullptr;
|
||||
|
||||
// Faster splitscreen settings widget.
|
||||
std::unique_ptr<views::Widget> settings_widget_;
|
||||
// Widget that appears during faster splitview setup. Contains the faster
|
||||
// splitview toast and the overview settings button.
|
||||
std::unique_ptr<views::Widget> faster_splitview_widget_;
|
||||
|
||||
// True if the overview grid should animate when exiting overview mode. Note
|
||||
// even if it's true, it doesn't mean all window items in the grid should
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ash/screen_util.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/style/close_button.h"
|
||||
#include "ash/style/system_toast_style.h"
|
||||
#include "ash/system/toast/toast_manager_impl.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
#include "ash/test/ash_test_util.h"
|
||||
@ -175,8 +176,9 @@ SplitViewOverviewSession* VerifySplitViewOverviewSession(
|
||||
EXPECT_TRUE(work_area_bounds().Contains(expected_grid_bounds));
|
||||
|
||||
if (!Shell::Get()->IsInTabletMode() && faster_split_screen_setup) {
|
||||
EXPECT_TRUE(
|
||||
GetOverviewGridForRoot(window->GetRootWindow())->no_windows_widget());
|
||||
auto* overview_grid = GetOverviewGridForRoot(window->GetRootWindow());
|
||||
EXPECT_TRUE(overview_grid->faster_splitview_widget_for_testing());
|
||||
EXPECT_FALSE(overview_grid->no_windows_widget());
|
||||
}
|
||||
|
||||
return split_view_overview_session;
|
||||
@ -327,8 +329,9 @@ TEST_F(FasterSplitScreenTest, Basic) {
|
||||
|
||||
// Enter overview normally. Test no widget.
|
||||
ToggleOverview();
|
||||
EXPECT_FALSE(
|
||||
GetOverviewGridForRoot(w1->GetRootWindow())->no_windows_widget());
|
||||
auto* overview_grid = GetOverviewGridForRoot(w1->GetRootWindow());
|
||||
EXPECT_FALSE(overview_grid->no_windows_widget());
|
||||
EXPECT_FALSE(overview_grid->faster_splitview_widget_for_testing());
|
||||
}
|
||||
|
||||
TEST_F(FasterSplitScreenTest, CycleSnap) {
|
||||
@ -573,6 +576,25 @@ TEST_F(FasterSplitScreenTest, SkipPairingOnKeyEvent) {
|
||||
EXPECT_TRUE(Shell::Get()->window_cycle_controller()->IsCycling());
|
||||
}
|
||||
|
||||
TEST_F(FasterSplitScreenTest, SkipPairingToast) {
|
||||
std::unique_ptr<aura::Window> w1(CreateAppWindow());
|
||||
std::unique_ptr<aura::Window> w2(CreateAppWindow());
|
||||
SnapOneTestWindow(w1.get(), chromeos::WindowStateType::kPrimarySnapped);
|
||||
VerifySplitViewOverviewSession(w1.get());
|
||||
|
||||
auto* overview_grid = GetOverviewGridForRoot(w1->GetRootWindow());
|
||||
ASSERT_TRUE(overview_grid);
|
||||
auto* faster_splitview_widget =
|
||||
overview_grid->faster_splitview_widget_for_testing();
|
||||
ASSERT_TRUE(faster_splitview_widget);
|
||||
auto* toast_view = views::AsViewClass<SystemToastStyle>(
|
||||
faster_splitview_widget->GetContentsView()->children()[0]);
|
||||
ASSERT_TRUE(toast_view);
|
||||
LeftClickOn(toast_view->dismiss_button());
|
||||
|
||||
EXPECT_FALSE(OverviewController::Get()->InOverviewSession());
|
||||
}
|
||||
|
||||
TEST_F(FasterSplitScreenTest, DontStartPartialOverviewAfterSkippingPairing) {
|
||||
std::unique_ptr<aura::Window> w1(CreateAppWindow());
|
||||
std::unique_ptr<aura::Window> w2(CreateAppWindow());
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
#include "ui/events/test/event_generator.h"
|
||||
#include "ui/views/controls/button/button.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -76,7 +77,12 @@ IN_PROC_BROWSER_TEST_F(FasterSplitScreenBrowserTest, SnapWindowSettings) {
|
||||
auto* overview_grid =
|
||||
ash::OverviewController::Get()->overview_session()->GetGridWithRootWindow(
|
||||
window->GetRootWindow());
|
||||
auto* settings_button = overview_grid->GetSettingsButtonForTesting();
|
||||
ASSERT_TRUE(overview_grid);
|
||||
auto* faster_splitview_widget =
|
||||
overview_grid->faster_splitview_widget_for_testing();
|
||||
ASSERT_TRUE(faster_splitview_widget);
|
||||
auto* settings_button = views::AsViewClass<ash::IconButton>(
|
||||
faster_splitview_widget->GetContentsView()->children()[1]);
|
||||
ASSERT_TRUE(settings_button);
|
||||
|
||||
// Setup navigation observer to wait for the OS Settings page.
|
||||
|
Reference in New Issue
Block a user