0

Use the first child included in layout for sizing

When a view is removed, the parent view will ask to relayout before
removing the child view from their children lists. When the

When SimpleGridLayout attempts to cache the children view size, the
removed child view will technically still be in the list of children
views of the host view, but it will have a size 0 since it will be
removed.  To avoid the edge case where the first child view is removed
and a bad layout is calculated, take into consideration the first child
that will actually be included in the layout.

Bug: b:333338805
Change-Id: Iaeba771dbf08859584914cb5a6636cd558f050a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5446054
Commit-Queue: Ana Salazar <anasalazar@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1286625}
This commit is contained in:
Ana Salazar
2024-04-12 18:26:57 +00:00
committed by Chromium LUCI CQ
parent 5ebd3cf870
commit 436262b9aa
3 changed files with 75 additions and 2 deletions

@ -3485,6 +3485,7 @@ test("ash_unittests") {
"birch/birch_model_unittest.cc",
"birch/birch_ranker_unittest.cc",
"birch/birch_weather_provider_unittest.cc",
"bubble//simple_grid_layout_unittest.cc",
"bubble/bubble_event_filter_unittest.cc",
"bubble/bubble_utils_unittest.cc",
"capture_mode/capture_audio_mixing_unittests.cc",

@ -65,8 +65,14 @@ gfx::Size SimpleGridLayout::GetChildPreferredSize() const {
if (!host_view()->children().size())
return gfx::Size();
cached_child_preferred_size_ = host_view()->children()[0]->GetPreferredSize();
return *cached_child_preferred_size_;
for (views::View* child : host_view()->children()) {
if (IsChildIncludedInLayout(child)) {
cached_child_preferred_size_ = child->GetPreferredSize();
return *cached_child_preferred_size_;
}
}
return gfx::Size();
}
gfx::Size SimpleGridLayout::CalculatePreferredSize() const {

@ -0,0 +1,66 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/bubble/simple_grid_layout.h"
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_utils.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
namespace ash {
class SimpleGridLayoutTest : public testing::Test {
public:
void SetUp() override { host_ = std::make_unique<views::View>(); }
std::unique_ptr<views::View> host_;
};
TEST_F(SimpleGridLayoutTest, ChildIgnoredByLayout) {
// Create a SimpleGrid host view for 2 columns.
SimpleGridLayout* layout =
host_->SetLayoutManager(std::make_unique<SimpleGridLayout>(2, 0, 0));
// Add a child view of size 20 and verify that the Grid has a correct size.
views::StaticSizedView* v1 = host_->AddChildView(
std::make_unique<views::StaticSizedView>(gfx::Size(20, 20)));
EXPECT_EQ(gfx::Size(40, 20), layout->GetPreferredSize(host_.get()));
// Add a child view of size 10 and verify that the Grid assumes all views are
// size 20. as the first child.
views::StaticSizedView* v2 = host_->AddChildView(
std::make_unique<views::StaticSizedView>(gfx::Size(10, 10)));
EXPECT_EQ(gfx::Size(40, 20), layout->GetPreferredSize(host_.get()));
// Add a third child view of size 10 and verify that the grid is sozed
// correctly for 2 rows.
views::StaticSizedView* v3 = host_->AddChildView(
std::make_unique<views::StaticSizedView>(gfx::Size(10, 10)));
EXPECT_EQ(gfx::Size(40, 40), layout->GetPreferredSize(host_.get()));
// Set the first view to be ignored by layout. Expect the size to change
// accordingly to consider the child views sized at 10.
v1->SetProperty(views::kViewIgnoredByLayoutKey, true);
EXPECT_EQ(gfx::Size(20, 10), layout->GetPreferredSize(host_.get()));
// Layout the views. Verify the coordinates for all views.
views::test::RunScheduledLayout(host_.get());
EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v1->bounds());
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v2->bounds());
EXPECT_EQ(gfx::Rect(10, 0, 10, 10), v3->bounds());
// Change the host size view and run a layout again. Verify the layout did not
// changed.
host_->SetBounds(0, 0, 30, 30);
views::test::RunScheduledLayout(host_.get());
EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v1->bounds());
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v2->bounds());
EXPECT_EQ(gfx::Rect(10, 0, 10, 10), v3->bounds());
}
} // namespace ash