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:

committed by
Chromium LUCI CQ

parent
5ebd3cf870
commit
436262b9aa
@ -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 {
|
||||
|
66
ash/bubble/simple_grid_layout_unittest.cc
Normal file
66
ash/bubble/simple_grid_layout_unittest.cc
Normal file
@ -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
|
Reference in New Issue
Block a user