diff --git a/shell/platform/linux/BUILD.gn b/shell/platform/linux/BUILD.gn index 4c1cbc4a75dea..7fa53d241bd9d 100644 --- a/shell/platform/linux/BUILD.gn +++ b/shell/platform/linux/BUILD.gn @@ -224,6 +224,7 @@ executable("flutter_linux_unittests") { "fl_texture_registrar_test.cc", "fl_value_test.cc", "fl_view_accessible_test.cc", + "fl_view_test.cc", "testing/fl_test.cc", "testing/mock_binary_messenger.cc", "testing/mock_binary_messenger_response_handle.cc", diff --git a/shell/platform/linux/fl_view.cc b/shell/platform/linux/fl_view.cc index 5229d4d9f391f..c6ccf567740e7 100644 --- a/shell/platform/linux/fl_view.cc +++ b/shell/platform/linux/fl_view.cc @@ -724,6 +724,26 @@ static void fl_view_get_preferred_height(GtkWidget* widget, } } +static void size_allocate_child(FlView* view, + FlViewChild* child, + GtkAllocation* allocation) { + GtkAllocation child_allocation = child->geometry; + GtkRequisition child_requisition; + gtk_widget_get_preferred_size(child->widget, &child_requisition, NULL); + + if (!gtk_widget_get_has_window(GTK_WIDGET(view))) { + child_allocation.x += allocation->x; + child_allocation.y += allocation->y; + } + + if (child_allocation.width == 0 && child_allocation.height == 0) { + child_allocation.width = allocation->width; + child_allocation.height = allocation->height; + } + + gtk_widget_size_allocate(child->widget, &child_allocation); +} + // Implements GtkWidget::size-allocate. static void fl_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation) { @@ -746,21 +766,7 @@ static void fl_view_size_allocate(GtkWidget* widget, continue; } - GtkAllocation child_allocation = child->geometry; - GtkRequisition child_requisition; - gtk_widget_get_preferred_size(child->widget, &child_requisition, NULL); - - if (!gtk_widget_get_has_window(widget)) { - child_allocation.x += allocation->x; - child_allocation.y += allocation->y; - } - - if (child_allocation.width == 0 && child_allocation.height == 0) { - child_allocation.width = allocation->width; - child_allocation.height = allocation->height; - } - - gtk_widget_size_allocate(child->widget, &child_allocation); + size_allocate_child(self, child, allocation); } GtkAllocation event_box_allocation = { @@ -978,6 +984,9 @@ void fl_view_add_widget(FlView* view, } void fl_view_end_frame(FlView* view) { + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(view), &allocation); + for (GList* pending_child = view->pending_children_list; pending_child; pending_child = pending_child->next) { FlViewChild* pending_view_child = @@ -991,6 +1000,7 @@ void fl_view_end_frame(FlView* view) { } else { // newly added child gtk_widget_set_parent(pending_view_child->widget, GTK_WIDGET(view)); + size_allocate_child(view, pending_view_child, &allocation); } } diff --git a/shell/platform/linux/fl_view_test.cc b/shell/platform/linux/fl_view_test.cc new file mode 100644 index 0000000000000..7f5199860d714 --- /dev/null +++ b/shell/platform/linux/fl_view_test.cc @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Included first as it collides with the X11 headers. +#include "gtest/gtest.h" + +#include "flutter/shell/platform/linux/fl_view_private.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h" +#include "flutter/shell/platform/linux/testing/fl_test.h" + +struct FlViewTest : ::testing::Test { + static void SetUpTestSuite() { gtk_init(nullptr, nullptr); } +}; + +TEST_F(FlViewTest, SizeAllocate) { + g_autoptr(FlDartProject) project = fl_dart_project_new(); + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + + GtkAllocation allocation = {0, 0, 320, 240}; + gtk_widget_size_allocate(GTK_WIDGET(view), &allocation); + + fl_view_begin_frame(view); + + GtkWidget* child = gtk_label_new(nullptr); + fl_view_add_widget(view, child, nullptr); + + fl_view_end_frame(view); + + GtkAllocation child_allocation; + gtk_widget_get_allocation(child, &child_allocation); + EXPECT_EQ(child_allocation.x, 0); + EXPECT_EQ(child_allocation.y, 0); + EXPECT_EQ(child_allocation.width, 320); + EXPECT_EQ(child_allocation.height, 240); + + allocation = {0, 0, 321, 239}; + gtk_widget_size_allocate(GTK_WIDGET(view), &allocation); + + gtk_widget_get_allocation(child, &child_allocation); + EXPECT_EQ(child_allocation.x, 0); + EXPECT_EQ(child_allocation.y, 0); + EXPECT_EQ(child_allocation.width, 321); + EXPECT_EQ(child_allocation.height, 239); + + gtk_widget_destroy(GTK_WIDGET(view)); +}