123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/frame/non_client_frame_view_ash.h"
- #include <memory>
- #include "ash/accelerators/accelerator_controller_impl.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/frame/header_view.h"
- #include "ash/frame/wide_frame_view.h"
- #include "ash/resources/vector_icons/vector_icons.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/style/ash_color_provider.h"
- #include "ash/style/dark_light_mode_controller_impl.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/test/test_widget_builder.h"
- #include "ash/wm/desks/desks_util.h"
- #include "ash/wm/overview/overview_controller.h"
- #include "ash/wm/splitview/split_view_controller.h"
- #include "ash/wm/tablet_mode/tablet_mode_controller.h"
- #include "ash/wm/window_state.h"
- #include "ash/wm/window_state_delegate.h"
- #include "ash/wm/window_util.h"
- #include "ash/wm/wm_event.h"
- #include "base/command_line.h"
- #include "base/containers/flat_set.h"
- #include "base/test/scoped_feature_list.h"
- #include "chromeos/constants/chromeos_features.h"
- #include "chromeos/ui/base/window_properties.h"
- #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h"
- #include "chromeos/ui/frame/default_frame_header.h"
- #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h"
- #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h"
- #include "chromeos/ui/vector_icons/vector_icons.h"
- #include "ui/aura/client/aura_constants.h"
- #include "ui/aura/window.h"
- #include "ui/aura/window_targeter.h"
- #include "ui/base/accelerators/accelerator.h"
- #include "ui/base/accelerators/test_accelerator_target.h"
- #include "ui/base/ui_base_features.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/test/draw_waiter_for_test.h"
- #include "ui/events/test/event_generator.h"
- #include "ui/gfx/geometry/rect.h"
- #include "ui/gfx/image/image_skia.h"
- #include "ui/gfx/image/image_unittest_util.h"
- #include "ui/gfx/vector_icon_types.h"
- #include "ui/views/widget/widget.h"
- #include "ui/views/widget/widget_delegate.h"
- #include "ui/views/window/caption_button_layout_constants.h"
- #include "ui/views/window/frame_caption_button.h"
- #include "ui/views/window/vector_icons/vector_icons.h"
- #include "ui/wm/core/window_util.h"
- namespace ash {
- using ::chromeos::DefaultFrameHeader;
- using ::chromeos::FrameCaptionButtonContainerView;
- using ::chromeos::ImmersiveFullscreenController;
- using ::chromeos::ImmersiveFullscreenControllerDelegate;
- using ::chromeos::ImmersiveFullscreenControllerTestApi;
- using ::chromeos::kFrameActiveColorKey;
- using ::chromeos::kFrameInactiveColorKey;
- using ::chromeos::kTrackDefaultFrameColors;
- // A views::WidgetDelegate which uses a NonClientFrameViewAsh.
- class NonClientFrameViewAshTestWidgetDelegate
- : public views::WidgetDelegateView {
- public:
- NonClientFrameViewAshTestWidgetDelegate() = default;
- NonClientFrameViewAshTestWidgetDelegate(
- const NonClientFrameViewAshTestWidgetDelegate&) = delete;
- NonClientFrameViewAshTestWidgetDelegate& operator=(
- const NonClientFrameViewAshTestWidgetDelegate&) = delete;
- ~NonClientFrameViewAshTestWidgetDelegate() override = default;
- std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
- views::Widget* widget) override {
- auto non_client_frame_view =
- std::make_unique<NonClientFrameViewAsh>(widget);
- non_client_frame_view_ = non_client_frame_view.get();
- return non_client_frame_view;
- }
- int GetNonClientFrameViewTopBorderHeight() {
- return non_client_frame_view_->NonClientTopBorderHeight();
- }
- NonClientFrameViewAsh* non_client_frame_view() const {
- return non_client_frame_view_;
- }
- HeaderView* header_view() const {
- return non_client_frame_view_->header_view_;
- }
- private:
- // Not owned.
- NonClientFrameViewAsh* non_client_frame_view_ = nullptr;
- };
- class TestWidgetConstraintsDelegate
- : public NonClientFrameViewAshTestWidgetDelegate {
- public:
- TestWidgetConstraintsDelegate() {
- SetCanMaximize(true);
- SetCanMinimize(true);
- }
- TestWidgetConstraintsDelegate(const TestWidgetConstraintsDelegate&) = delete;
- TestWidgetConstraintsDelegate& operator=(
- const TestWidgetConstraintsDelegate&) = delete;
- ~TestWidgetConstraintsDelegate() override = default;
- // views::View:
- gfx::Size GetMinimumSize() const override { return minimum_size_; }
- gfx::Size GetMaximumSize() const override { return maximum_size_; }
- views::View* GetContentsView() override {
- // Set this instance as the contents view so that the maximum and minimum
- // size constraints will be used.
- return this;
- }
- // views::WidgetDelegate:
- void set_minimum_size(const gfx::Size& min_size) { minimum_size_ = min_size; }
- void set_maximum_size(const gfx::Size& max_size) { maximum_size_ = max_size; }
- const gfx::Rect& GetFrameCaptionButtonContainerViewBounds() {
- return non_client_frame_view()
- ->GetFrameCaptionButtonContainerViewForTest()
- ->bounds();
- }
- void EndFrameCaptionButtonContainerViewAnimations() {
- FrameCaptionButtonContainerView::TestApi test(
- non_client_frame_view()->GetFrameCaptionButtonContainerViewForTest());
- test.EndAnimations();
- }
- int GetTitleBarHeight() const {
- return non_client_frame_view()->NonClientTopBorderHeight();
- }
- private:
- gfx::Size minimum_size_;
- gfx::Size maximum_size_;
- };
- using NonClientFrameViewAshTest = AshTestBase;
- // Verifies the client view is not placed at a y location of 0.
- TEST_F(NonClientFrameViewAshTest, ClientViewCorrectlyPlaced) {
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
- EXPECT_NE(0, widget->client_view()->bounds().y());
- }
- // Test that the height of the header is correct upon initially displaying
- // the widget.
- TEST_F(NonClientFrameViewAshTest, HeaderHeight) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- // The header should have enough room for the window controls. The
- // header/content separator line overlays the window controls.
- EXPECT_EQ(views::GetCaptionButtonLayoutSize(
- views::CaptionButtonLayoutSize::kNonBrowserCaption)
- .height(),
- delegate->non_client_frame_view()->GetHeaderView()->height());
- }
- // Regression test for https://crbug.com/839955
- TEST_F(NonClientFrameViewAshTest, ActiveStateOfButtonMatchesWidget) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- FrameCaptionButtonContainerView::TestApi test_api(
- delegate->non_client_frame_view()
- ->GetHeaderView()
- ->caption_button_container());
- widget->Show();
- EXPECT_TRUE(widget->IsActive());
- // The paint state doesn't change till the next paint.
- ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
- EXPECT_TRUE(test_api.size_button()->GetPaintAsActive());
- // Activate a different widget so the original one loses activation.
- std::unique_ptr<views::Widget> widget2 =
- CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
- widget2->Show();
- ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
- EXPECT_FALSE(widget->IsActive());
- EXPECT_FALSE(test_api.size_button()->GetPaintAsActive());
- }
- // Verify that NonClientFrameViewAsh returns the correct minimum and maximum
- // frame sizes when the client view does not specify any size constraints.
- TEST_F(NonClientFrameViewAshTest, NoSizeConstraints) {
- TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- gfx::Size min_frame_size = non_client_frame_view->GetMinimumSize();
- gfx::Size max_frame_size = non_client_frame_view->GetMaximumSize();
- EXPECT_EQ(delegate->GetTitleBarHeight(), min_frame_size.height());
- // A width and height constraint of 0 denotes unbounded.
- EXPECT_EQ(0, max_frame_size.width());
- EXPECT_EQ(0, max_frame_size.height());
- }
- // Verify that NonClientFrameViewAsh returns the correct minimum and maximum
- // frame sizes when the client view specifies size constraints.
- TEST_F(NonClientFrameViewAshTest, MinimumAndMaximumSize) {
- gfx::Size min_client_size(500, 500);
- gfx::Size max_client_size(800, 800);
- TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
- delegate->set_minimum_size(min_client_size);
- delegate->set_maximum_size(max_client_size);
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- gfx::Size min_frame_size = non_client_frame_view->GetMinimumSize();
- gfx::Size max_frame_size = non_client_frame_view->GetMaximumSize();
- EXPECT_EQ(min_client_size.width(), min_frame_size.width());
- EXPECT_EQ(max_client_size.width(), max_frame_size.width());
- EXPECT_EQ(min_client_size.height() + delegate->GetTitleBarHeight(),
- min_frame_size.height());
- EXPECT_EQ(max_client_size.height() + delegate->GetTitleBarHeight(),
- max_frame_size.height());
- }
- // Verify that NonClientFrameViewAsh updates the avatar icon based on the
- // avatar icon window property.
- TEST_F(NonClientFrameViewAshTest, AvatarIcon) {
- TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- EXPECT_FALSE(non_client_frame_view->GetAvatarIconViewForTest());
- // Avatar image becomes available.
- widget->GetNativeWindow()->SetProperty(
- aura::client::kAvatarIconKey,
- new gfx::ImageSkia(gfx::test::CreateImage(27, 27).AsImageSkia()));
- EXPECT_TRUE(non_client_frame_view->GetAvatarIconViewForTest());
- // Avatar image is gone; the ImageView for the avatar icon should be
- // removed.
- widget->GetNativeWindow()->ClearProperty(aura::client::kAvatarIconKey);
- EXPECT_FALSE(non_client_frame_view->GetAvatarIconViewForTest());
- }
- // Tests that a window is minimized, toggling tablet mode doesn't trigger
- // caption button update (https://crbug.com/822890).
- TEST_F(NonClientFrameViewAshTest, ToggleTabletModeOnMinimizedWindow) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- FrameCaptionButtonContainerView::TestApi test(
- delegate->non_client_frame_view()
- ->GetHeaderView()
- ->caption_button_container());
- widget->Maximize();
- // Restore icon for size button in maximized window state. Compare by name
- // because the address may not be the same for different build targets in the
- // component build.
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test.size_button()->icon_definition_for_test()->name);
- widget->Minimize();
- // Enter and exit tablet mode while the window is minimized.
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- // When unminimizing in non-tablet mode, size button should match with
- // maximized window state, which is restore icon.
- ::wm::Unminimize(widget->GetNativeWindow());
- EXPECT_TRUE(widget->IsMaximized());
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test.size_button()->icon_definition_for_test()->name);
- }
- // Verify that when in tablet mode with a maximized window, the height of the
- // header is zero.
- TEST_F(NonClientFrameViewAshTest, FrameHiddenInTabletModeForMaximizedWindows) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- widget->Maximize();
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- }
- // Verify that when in tablet mode with a non maximized window, the height of
- // the header is non zero.
- TEST_F(NonClientFrameViewAshTest,
- FrameShownInTabletModeForNonMaximizedWindows) {
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_EQ(views::GetCaptionButtonLayoutSize(
- views::CaptionButtonLayoutSize::kNonBrowserCaption)
- .height(),
- delegate->GetNonClientFrameViewTopBorderHeight());
- }
- // Verify that if originally in fullscreen mode, and enter tablet mode, the
- // height of the header remains zero.
- TEST_F(NonClientFrameViewAshTest,
- FrameRemainsHiddenInTabletModeWhenTogglingFullscreen) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- widget->SetFullscreen(true);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- }
- TEST_F(NonClientFrameViewAshTest, OpeningAppsInTabletMode) {
- auto* delegate = new TestWidgetConstraintsDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- widget->Maximize();
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- // Verify that after minimizing and showing the widget, the height of the
- // header is zero.
- widget->Minimize();
- widget->Show();
- EXPECT_TRUE(widget->IsMaximized());
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- // Verify that when we toggle maximize, the header is shown. For example,
- // maximized can be toggled in tablet mode by using the accessibility
- // keyboard.
- WMEvent event(WM_EVENT_TOGGLE_MAXIMIZE);
- WindowState::Get(widget->GetNativeWindow())->OnWMEvent(&event);
- EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- EXPECT_EQ(views::GetCaptionButtonLayoutSize(
- views::CaptionButtonLayoutSize::kNonBrowserCaption)
- .height(),
- delegate->GetNonClientFrameViewTopBorderHeight());
- }
- // Test if creating a new window in tablet mode uses maximzied state
- // and immersive mode.
- TEST_F(NonClientFrameViewAshTest, GetPreferredOnScreenHeightInTabletMaximzied) {
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- auto* delegate = new TestWidgetConstraintsDelegate;
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- auto* frame_view = static_cast<NonClientFrameViewAsh*>(
- widget->non_client_view()->frame_view());
- auto* header_view = frame_view->GetHeaderView();
- ASSERT_TRUE(widget->IsMaximized());
- EXPECT_TRUE(header_view->in_immersive_mode());
- static_cast<ImmersiveFullscreenControllerDelegate*>(header_view)
- ->SetVisibleFraction(0.5);
- // The height should be ~(33 *.5)
- EXPECT_NEAR(16, header_view->GetPreferredOnScreenHeight(), 1);
- static_cast<ImmersiveFullscreenControllerDelegate*>(header_view)
- ->SetVisibleFraction(0.0);
- EXPECT_EQ(0, header_view->GetPreferredOnScreenHeight());
- }
- // Verify windows that are minimized and then entered into tablet mode will have
- // no header when unminimized in tablet mode.
- TEST_F(NonClientFrameViewAshTest, MinimizedWindowsInTabletMode) {
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
- widget->GetNativeWindow()->SetProperty(
- aura::client::kResizeBehaviorKey,
- aura::client::kResizeBehaviorCanMaximize);
- widget->Maximize();
- widget->Minimize();
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- widget->Show();
- EXPECT_EQ(widget->non_client_view()->bounds(),
- widget->client_view()->bounds());
- }
- TEST_F(NonClientFrameViewAshTest, HeaderVisibilityInFullscreen) {
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- HeaderView* header_view = non_client_frame_view->GetHeaderView();
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- widget->SetFullscreen(true);
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- widget->SetFullscreen(false);
- widget->LayoutRootViewIfNecessary();
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- // Turn immersive off, and make sure that header view is invisible
- // in fullscreen.
- widget->SetFullscreen(true);
- ImmersiveFullscreenController::EnableForWidget(widget.get(), false);
- widget->LayoutRootViewIfNecessary();
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_FALSE(header_view->GetVisible());
- widget->SetFullscreen(false);
- widget->LayoutRootViewIfNecessary();
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- }
- namespace {
- class TestButtonModel : public chromeos::CaptionButtonModel {
- public:
- TestButtonModel() = default;
- TestButtonModel(const TestButtonModel&) = delete;
- TestButtonModel& operator=(const TestButtonModel&) = delete;
- ~TestButtonModel() override = default;
- void set_zoom_mode(bool zoom_mode) { zoom_mode_ = zoom_mode; }
- void SetVisible(views::CaptionButtonIcon type, bool visible) {
- if (visible)
- visible_buttons_.insert(type);
- else
- visible_buttons_.erase(type);
- }
- void SetEnabled(views::CaptionButtonIcon type, bool enabled) {
- if (enabled)
- enabled_buttons_.insert(type);
- else
- enabled_buttons_.erase(type);
- }
- // CaptionButtonModel::
- bool IsVisible(views::CaptionButtonIcon type) const override {
- return visible_buttons_.count(type);
- }
- bool IsEnabled(views::CaptionButtonIcon type) const override {
- return enabled_buttons_.count(type);
- }
- bool InZoomMode() const override { return zoom_mode_; }
- private:
- base::flat_set<views::CaptionButtonIcon> visible_buttons_;
- base::flat_set<views::CaptionButtonIcon> enabled_buttons_;
- bool zoom_mode_ = false;
- };
- } // namespace
- TEST_F(NonClientFrameViewAshTest, BackButton) {
- AcceleratorControllerImpl* controller =
- Shell::Get()->accelerator_controller();
- std::unique_ptr<TestButtonModel> model = std::make_unique<TestButtonModel>();
- TestButtonModel* model_ptr = model.get();
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(),
- gfx::Rect(0, 0, 400, 500));
- ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
- accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED);
- ui::TestAcceleratorTarget target_back_press;
- controller->Register({accelerator_back_press}, &target_back_press);
- ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
- accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED);
- ui::TestAcceleratorTarget target_back_release;
- controller->Register({accelerator_back_release}, &target_back_release);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- non_client_frame_view->SetCaptionButtonModel(std::move(model));
- HeaderView* header_view = non_client_frame_view->GetHeaderView();
- EXPECT_FALSE(header_view->GetBackButton());
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(header_view->GetBackButton());
- EXPECT_FALSE(header_view->GetBackButton()->GetEnabled());
- // Back button is disabled, so clicking on it should not should
- // generate back key sequence.
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->MoveMouseTo(
- header_view->GetBackButton()->GetBoundsInScreen().CenterPoint());
- generator->ClickLeftButton();
- EXPECT_EQ(0, target_back_press.accelerator_count());
- EXPECT_EQ(0, target_back_release.accelerator_count());
- model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_BACK, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(header_view->GetBackButton());
- EXPECT_TRUE(header_view->GetBackButton()->GetEnabled());
- // Back button is now enabled, so clicking on it should generate
- // back key sequence.
- generator->MoveMouseTo(
- header_view->GetBackButton()->GetBoundsInScreen().CenterPoint());
- generator->ClickLeftButton();
- EXPECT_EQ(1, target_back_press.accelerator_count());
- EXPECT_EQ(1, target_back_release.accelerator_count());
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, false);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_FALSE(header_view->GetBackButton());
- }
- // Make sure that client view occupies the entire window when the
- // frame is hidden.
- TEST_F(NonClientFrameViewAshTest, FrameVisibility) {
- NonClientFrameViewAshTestWidgetDelegate* delegate =
- new NonClientFrameViewAshTestWidgetDelegate;
- gfx::Rect window_bounds(10, 10, 200, 100);
- std::unique_ptr<views::Widget> widget = CreateTestWidget(
- delegate, desks_util::GetActiveDeskContainerId(), window_bounds);
- // The height is smaller by the top border height.
- gfx::Size client_bounds(200, 68);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());
- non_client_frame_view->SetFrameEnabled(false);
- widget->GetRootView()->Layout();
- EXPECT_EQ(gfx::Size(200, 100),
- widget->client_view()->GetLocalBounds().size());
- EXPECT_FALSE(non_client_frame_view->GetFrameEnabled());
- EXPECT_EQ(
- window_bounds,
- non_client_frame_view->GetClientBoundsForWindowBounds(window_bounds));
- non_client_frame_view->SetFrameEnabled(true);
- widget->GetRootView()->Layout();
- EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());
- EXPECT_TRUE(non_client_frame_view->GetFrameEnabled());
- EXPECT_EQ(32, delegate->GetNonClientFrameViewTopBorderHeight());
- EXPECT_EQ(
- gfx::Rect(gfx::Point(10, 42), client_bounds),
- non_client_frame_view->GetClientBoundsForWindowBounds(window_bounds));
- }
- TEST_F(NonClientFrameViewAshTest, CustomButtonModel) {
- std::unique_ptr<TestButtonModel> model = std::make_unique<TestButtonModel>();
- TestButtonModel* model_ptr = model.get();
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- non_client_frame_view->SetCaptionButtonModel(std::move(model));
- HeaderView* header_view = non_client_frame_view->GetHeaderView();
- FrameCaptionButtonContainerView::TestApi test_api(
- header_view->caption_button_container());
- // CLOSE button is always enabled.
- EXPECT_TRUE(test_api.close_button());
- EXPECT_FALSE(test_api.close_button()->GetVisible());
- EXPECT_TRUE(test_api.close_button()->GetEnabled());
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_CLOSE, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.close_button()->GetVisible());
- EXPECT_FALSE(test_api.minimize_button()->GetVisible());
- EXPECT_FALSE(test_api.size_button()->GetVisible());
- EXPECT_FALSE(test_api.menu_button()->GetVisible());
- // Back button
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(header_view->GetBackButton()->GetVisible());
- EXPECT_FALSE(header_view->GetBackButton()->GetEnabled());
- model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_BACK, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(header_view->GetBackButton()->GetEnabled());
- // size button
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.size_button()->GetVisible());
- EXPECT_FALSE(test_api.size_button()->GetEnabled());
- model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.size_button()->GetEnabled());
- // minimize button
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MINIMIZE, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.minimize_button()->GetVisible());
- EXPECT_FALSE(test_api.minimize_button()->GetEnabled());
- model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MINIMIZE, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.minimize_button()->GetEnabled());
- // menu button
- model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MENU, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.menu_button()->GetVisible());
- EXPECT_FALSE(test_api.menu_button()->GetEnabled());
- model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MENU, true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_TRUE(test_api.menu_button()->GetEnabled());
- // zoom button
- EXPECT_STREQ(views::kWindowControlMaximizeIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- model_ptr->set_zoom_mode(true);
- non_client_frame_view->SizeConstraintsChanged();
- widget->LayoutRootViewIfNecessary();
- EXPECT_STREQ(chromeos::kWindowControlZoomIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- widget->Maximize();
- EXPECT_STREQ(chromeos::kWindowControlDezoomIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- }
- TEST_F(NonClientFrameViewAshTest, WideFrame) {
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(),
- gfx::Rect(100, 0, 400, 500));
- NonClientFrameViewAsh* non_client_frame_view =
- delegate->non_client_frame_view();
- HeaderView* header_view = non_client_frame_view->GetHeaderView();
- widget->Maximize();
- std::unique_ptr<WideFrameView> wide_frame_view =
- std::make_unique<WideFrameView>(widget.get());
- wide_frame_view->GetWidget()->Show();
- HeaderView* wide_header_view = wide_frame_view->header_view();
- display::Screen* screen = display::Screen::GetScreen();
- const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
- gfx::Rect frame_bounds =
- wide_frame_view->GetWidget()->GetWindowBoundsInScreen();
- EXPECT_EQ(work_area.width(), frame_bounds.width());
- EXPECT_EQ(work_area.origin(), frame_bounds.origin());
- EXPECT_FALSE(header_view->should_paint());
- EXPECT_TRUE(wide_header_view->should_paint());
- // Test immersive.
- ImmersiveFullscreenController controller;
- wide_frame_view->Init(&controller);
- EXPECT_FALSE(wide_header_view->in_immersive_mode());
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- ImmersiveFullscreenController::EnableForWidget(widget.get(), true);
- EXPECT_TRUE(header_view->in_immersive_mode());
- EXPECT_TRUE(wide_header_view->in_immersive_mode());
- EXPECT_TRUE(header_view->GetVisible());
- // The height should be ~(33 *.5)
- wide_header_view->SetVisibleFraction(0.5);
- EXPECT_NEAR(16, wide_header_view->GetPreferredOnScreenHeight(), 1);
- // Make sure the frame can be revaled outside of the target window.
- EXPECT_FALSE(ImmersiveFullscreenControllerTestApi(&controller)
- .IsTopEdgeHoverTimerRunning());
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->MoveMouseTo(gfx::Point(10, 0));
- generator->MoveMouseBy(1, 0);
- EXPECT_TRUE(ImmersiveFullscreenControllerTestApi(&controller)
- .IsTopEdgeHoverTimerRunning());
- generator->MoveMouseTo(gfx::Point(10, 10));
- generator->MoveMouseBy(1, 0);
- EXPECT_FALSE(ImmersiveFullscreenControllerTestApi(&controller)
- .IsTopEdgeHoverTimerRunning());
- generator->MoveMouseTo(gfx::Point(600, 0));
- generator->MoveMouseBy(1, 0);
- EXPECT_TRUE(ImmersiveFullscreenControllerTestApi(&controller)
- .IsTopEdgeHoverTimerRunning());
- ImmersiveFullscreenController::EnableForWidget(widget.get(), false);
- EXPECT_FALSE(header_view->in_immersive_mode());
- EXPECT_FALSE(wide_header_view->in_immersive_mode());
- // visible fraction should be ignored in non immersive.
- wide_header_view->SetVisibleFraction(0.5);
- EXPECT_EQ(32, wide_header_view->GetPreferredOnScreenHeight());
- UpdateDisplay("1234x800");
- EXPECT_EQ(1234,
- wide_frame_view->GetWidget()->GetWindowBoundsInScreen().width());
- // Double Click
- EXPECT_TRUE(widget->IsMaximized());
- generator->MoveMouseToCenterOf(
- wide_header_view->GetWidget()->GetNativeWindow());
- generator->DoubleClickLeftButton();
- EXPECT_FALSE(widget->IsMaximized());
- }
- TEST_F(NonClientFrameViewAshTest, WideFrameButton) {
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(),
- gfx::Rect(100, 0, 400, 500));
- widget->Maximize();
- std::unique_ptr<WideFrameView> wide_frame_view =
- std::make_unique<WideFrameView>(widget.get());
- wide_frame_view->GetWidget()->Show();
- HeaderView* header_view = wide_frame_view->header_view();
- FrameCaptionButtonContainerView::TestApi test_api(
- header_view->caption_button_container());
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- widget->SetFullscreen(true);
- header_view->Layout();
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- {
- WMEvent event(WM_EVENT_PIN);
- WindowState::Get(widget->GetNativeWindow())->OnWMEvent(&event);
- header_view->Layout();
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- }
- {
- WMEvent event(WM_EVENT_TRUSTED_PIN);
- WindowState::Get(widget->GetNativeWindow())->OnWMEvent(&event);
- header_view->Layout();
- EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
- test_api.size_button()->icon_definition_for_test()->name);
- }
- }
- TEST_F(NonClientFrameViewAshTest, MoveFullscreenWideFrameBetweenDisplay) {
- UpdateDisplay("800x600, 1000x600");
- auto* screen = display::Screen::GetScreen();
- auto display_list = screen->GetAllDisplays();
- auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
- std::unique_ptr<views::Widget> widget =
- CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(),
- gfx::Rect(100, 0, 400, 500));
- widget->SetFullscreen(true);
- std::unique_ptr<WideFrameView> wide_frame_view =
- std::make_unique<WideFrameView>(widget.get());
- wide_frame_view->GetWidget()->Show();
- ASSERT_EQ(display_list[0].id(),
- screen->GetDisplayNearestWindow(widget->GetNativeWindow()).id());
- EXPECT_EQ(800,
- wide_frame_view->GetWidget()->GetWindowBoundsInScreen().width());
- window_util::MoveWindowToDisplay(widget->GetNativeWindow(),
- display_list[1].id());
- EXPECT_EQ(display_list[1].id(),
- screen->GetDisplayNearestWindow(widget->GetNativeWindow()).id());
- EXPECT_EQ(1000,
- wide_frame_view->GetWidget()->GetWindowBoundsInScreen().width());
- }
- namespace {
- class NonClientFrameViewAshFrameColorTest
- : public NonClientFrameViewAshTest,
- public testing::WithParamInterface<bool> {
- public:
- NonClientFrameViewAshFrameColorTest() = default;
- NonClientFrameViewAshFrameColorTest(
- const NonClientFrameViewAshFrameColorTest&) = delete;
- NonClientFrameViewAshFrameColorTest& operator=(
- const NonClientFrameViewAshFrameColorTest&) = delete;
- ~NonClientFrameViewAshFrameColorTest() override = default;
- };
- class TestWidgetDelegate : public TestWidgetConstraintsDelegate {
- public:
- TestWidgetDelegate(bool custom) : custom_(custom) {}
- TestWidgetDelegate(const TestWidgetDelegate&) = delete;
- TestWidgetDelegate& operator=(const TestWidgetDelegate&) = delete;
- ~TestWidgetDelegate() override = default;
- // views::WidgetDelegate:
- std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
- views::Widget* widget) override {
- if (custom_) {
- WindowState* window_state = WindowState::Get(widget->GetNativeWindow());
- window_state->SetDelegate(std::make_unique<WindowStateDelegate>());
- }
- return TestWidgetConstraintsDelegate::CreateNonClientFrameView(widget);
- }
- private:
- bool custom_;
- };
- } // namespace
- // Verify that NonClientFrameViewAsh updates the active color based on the
- // kFrameActiveColorKey window property.
- TEST_P(NonClientFrameViewAshFrameColorTest, kFrameActiveColorKey) {
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- SkColor active_color =
- widget->GetNativeWindow()->GetProperty(kFrameActiveColorKey);
- constexpr SkColor new_color = SK_ColorWHITE;
- EXPECT_NE(active_color, new_color);
- widget->GetNativeWindow()->SetProperty(kFrameActiveColorKey, new_color);
- active_color = widget->GetNativeWindow()->GetProperty(kFrameActiveColorKey);
- EXPECT_EQ(active_color, new_color);
- EXPECT_EQ(new_color,
- delegate->non_client_frame_view()->GetActiveFrameColorForTest());
- // Test that changing the property updates the caption button images.
- FrameCaptionButtonContainerView::TestApi test_api(
- delegate->non_client_frame_view()
- ->GetHeaderView()
- ->caption_button_container());
- ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
- gfx::ImageSkia original_icon_image = test_api.size_button()->icon_image();
- widget->GetNativeWindow()->SetProperty(kFrameActiveColorKey, SK_ColorBLACK);
- ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
- EXPECT_FALSE(original_icon_image.BackedBySameObjectAs(
- test_api.size_button()->icon_image()));
- }
- // Verify that NonClientFrameViewAsh updates the inactive color based on the
- // kFrameInactiveColorKey window property.
- TEST_P(NonClientFrameViewAshFrameColorTest, KFrameInactiveColor) {
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- SkColor active_color =
- widget->GetNativeWindow()->GetProperty(kFrameInactiveColorKey);
- constexpr SkColor new_color = SK_ColorWHITE;
- EXPECT_NE(active_color, new_color);
- widget->GetNativeWindow()->SetProperty(kFrameInactiveColorKey, new_color);
- active_color = widget->GetNativeWindow()->GetProperty(kFrameInactiveColorKey);
- EXPECT_EQ(active_color, new_color);
- EXPECT_EQ(new_color,
- delegate->non_client_frame_view()->GetInactiveFrameColorForTest());
- }
- // Verify that NonClientFrameViewAsh updates the active and inactive colors at
- // construction.
- TEST_P(NonClientFrameViewAshFrameColorTest, KFrameColorCtor) {
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- // Build the window, this implicit constructs the NonClientFrameView.
- constexpr SkColor non_default_color = SK_ColorWHITE;
- std::unique_ptr<views::Widget> widget =
- TestWidgetBuilder()
- .SetDelegate(delegate)
- .SetBounds(gfx::Rect())
- .SetParent(Shell::GetPrimaryRootWindow()->GetChildById(
- desks_util::GetActiveDeskContainerId()))
- .SetShow(true)
- .SetWindowProperty(kTrackDefaultFrameColors, false)
- .SetWindowProperty(kFrameActiveColorKey, non_default_color)
- .SetWindowProperty(kFrameInactiveColorKey, non_default_color)
- .BuildOwnsNativeWidget();
- // Check that the default color is different from the one used in the test.
- SkColor inactive_color =
- widget->GetNativeWindow()->GetProperty(kFrameInactiveColorKey);
- SkColor active_color =
- widget->GetNativeWindow()->GetProperty(kFrameActiveColorKey);
- EXPECT_EQ(active_color, non_default_color);
- EXPECT_EQ(inactive_color, non_default_color);
- EXPECT_EQ(delegate->non_client_frame_view()->GetInactiveFrameColorForTest(),
- non_default_color);
- EXPECT_EQ(delegate->non_client_frame_view()->GetActiveFrameColorForTest(),
- non_default_color);
- }
- // Verify that NonClientFrameViewAsh updates the active color based on the
- // kFrameActiveColorKey window property.
- TEST_P(NonClientFrameViewAshFrameColorTest, WideFrameInitialColor) {
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- widget->Maximize();
- aura::Window* window = widget->GetNativeWindow();
- SkColor active_color = window->GetProperty(kFrameActiveColorKey);
- SkColor inactive_color = window->GetProperty(kFrameInactiveColorKey);
- constexpr SkColor new_active_color = SK_ColorWHITE;
- constexpr SkColor new_inactive_color = SK_ColorBLACK;
- EXPECT_NE(active_color, new_active_color);
- EXPECT_NE(inactive_color, new_inactive_color);
- window->SetProperty(kFrameActiveColorKey, new_active_color);
- window->SetProperty(kFrameInactiveColorKey, new_inactive_color);
- std::unique_ptr<WideFrameView> wide_frame_view =
- std::make_unique<WideFrameView>(widget.get());
- HeaderView* wide_header_view = wide_frame_view->header_view();
- DefaultFrameHeader* header = wide_header_view->GetFrameHeader();
- EXPECT_EQ(new_active_color, header->active_frame_color_for_testing());
- EXPECT_EQ(new_inactive_color, header->inactive_frame_color_for_testing());
- }
- // Tests to make sure that the NonClientFrameViewAsh tracks default frame colors
- // for both light and dark mode.
- TEST_P(NonClientFrameViewAshFrameColorTest, DefaultFrameColorsDarkAndLight) {
- base::test::ScopedFeatureList scoped_feature_list(
- chromeos::features::kDarkLightMode);
- auto* color_provider = AshColorProvider::Get();
- auto* dark_light_mode_controller = DarkLightModeControllerImpl::Get();
- dark_light_mode_controller->OnActiveUserPrefServiceChanged(
- Shell::Get()->session_controller()->GetActivePrefService());
- ASSERT_TRUE(chromeos::features::IsDarkLightModeEnabled());
- const bool initial_dark_mode_status =
- dark_light_mode_controller->IsDarkModeEnabled();
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- aura::Window* window = widget->GetNativeWindow();
- const SkColor initial_active_default =
- color_provider->GetActiveDialogTitleBarColor();
- const SkColor initial_inactive_default =
- color_provider->GetInactiveDialogTitleBarColor();
- SkColor active_color = window->GetProperty(kFrameActiveColorKey);
- SkColor inactive_color = window->GetProperty(kFrameInactiveColorKey);
- EXPECT_EQ(initial_active_default, active_color);
- EXPECT_EQ(initial_inactive_default, inactive_color);
- // Switch the color mode
- dark_light_mode_controller->ToggleColorMode();
- ASSERT_NE(initial_dark_mode_status,
- dark_light_mode_controller->IsDarkModeEnabled());
- const SkColor active_default = color_provider->GetActiveDialogTitleBarColor();
- const SkColor inactive_default =
- color_provider->GetInactiveDialogTitleBarColor();
- active_color = window->GetProperty(kFrameActiveColorKey);
- inactive_color = window->GetProperty(kFrameInactiveColorKey);
- EXPECT_NE(initial_active_default, active_default);
- EXPECT_NE(initial_inactive_default, inactive_default);
- EXPECT_EQ(active_default, active_color);
- EXPECT_EQ(inactive_default, inactive_color);
- }
- // Tests to make sure that NonClientFrameViewAsh does not clobber custom frame
- // colors when the kTrackDefaultFrameColors property is set to false.
- TEST_P(NonClientFrameViewAshFrameColorTest,
- CanSetPersistentFrameColorsDarkAndLight) {
- base::test::ScopedFeatureList scoped_feature_list(
- chromeos::features::kDarkLightMode);
- auto* dark_light_mode_controller = DarkLightModeControllerImpl::Get();
- dark_light_mode_controller->OnActiveUserPrefServiceChanged(
- Shell::Get()->session_controller()->GetActivePrefService());
- ASSERT_TRUE(chromeos::features::IsDarkLightModeEnabled());
- const bool initial_dark_mode_status =
- dark_light_mode_controller->IsDarkModeEnabled();
- TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
- std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
- aura::Window* window = widget->GetNativeWindow();
- constexpr SkColor new_active_color = SK_ColorWHITE;
- constexpr SkColor new_inactive_color = SK_ColorBLACK;
- EXPECT_NE(new_active_color, window->GetProperty(kFrameActiveColorKey));
- EXPECT_NE(new_inactive_color, window->GetProperty(kFrameInactiveColorKey));
- window->SetProperty(kTrackDefaultFrameColors, false);
- window->SetProperty(kFrameActiveColorKey, new_active_color);
- window->SetProperty(kFrameInactiveColorKey, new_inactive_color);
- EXPECT_EQ(new_active_color, window->GetProperty(kFrameActiveColorKey));
- EXPECT_EQ(new_inactive_color, window->GetProperty(kFrameInactiveColorKey));
- // Switch the color mode.
- dark_light_mode_controller->ToggleColorMode();
- ASSERT_NE(initial_dark_mode_status,
- dark_light_mode_controller->IsDarkModeEnabled());
- EXPECT_EQ(new_active_color, window->GetProperty(kFrameActiveColorKey));
- EXPECT_EQ(new_inactive_color, window->GetProperty(kFrameInactiveColorKey));
- }
- // Run frame color tests with and without custom WindowStateDelegate.
- INSTANTIATE_TEST_SUITE_P(All,
- NonClientFrameViewAshFrameColorTest,
- testing::Bool());
- } // namespace ash
|