We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GTK animated widgets freeze until first resize
### Describe the bug

GTK Widgets that contain an "animated" component - e.g., Switch (the slide left/right animation) or an indeterminate ProgressBar (pulse animation) won't animate when the window is first drawn. However, if you resize the window, the animation will resume, including any historical state.

### Steps to reproduce

1. Run the toga_switch example.

Try to toggle the "initial state" button. The color of the switch will change, but the switch itself won't "slide".

Also worth note: The exterior border of the "change label" button is very slightly clipped.

2. Run the progressbar example

The indeterminate progress bar may not start. 

Toggle the Running Mode and Indeterminate Mode buttons. With sufficient toggling, you will eventually be able to cause the running indeterminate progress bar to stop animating.


### Expected behavior

Animated widgets should consistently render.

### Screenshots

_No response_

### Environment

- Operating System: Linux (any; tested on Fedora 36 and Ubuntu 22.04)
- Python version: 3.10 (but likely any)
- Software versions:
  - Toga: 0.3.0+; tested at 235ff2e, but anything after the landing of #1794 will show the problem


### Logs

```

```


### Additional context

The problem appears to be related to the GTK Container fixes introduced in #1794.

In both examples listed above, I have found that the *first* time I run examples after making a code change, it *sometimes* works. However, on second and subsequent runs, the problem reliably occurs. There may be a timing issue at play - maybe the slowdown of PYC recompilation is sufficient to mask event order problems?

A suboptimal fix: if the optimisation on L166 that only does a refresh() `if resized or self.needs_redraw` is removed (so a lot more refreshes are performed), the problem goes away

A partial fix: If `window` listens for the `window-state-event` signal, and marks the container dirty when that event occurs, the switch demo works. The switches on the progress bar demo are also fixed. However, the animation of the indeterminate progress bar *isn't* fixed (at least, not consistently)

This suggests that the issue is a signal that constitutes a "dirty" window, but isn't being treated as a dirty signal.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gtk/src/toga_gtk/container.py`
Content:
```
1 from .libs import Gdk, Gtk
2 
3 
4 class TogaContainer(Gtk.Fixed):
5     """A GTK container widget implementing Toga's layout.
6 
7     This is a GTK widget, with no Toga interface manifestation.
8     """
9 
10     def __init__(self):
11         super().__init__()
12         self._content = None
13         self.min_width = 100
14         self.min_height = 100
15 
16         # GDK/GTK always renders at 96dpi. When HiDPI mode is enabled, it is
17         # managed at the compositor level. See
18         # https://wiki.archlinux.org/index.php/HiDPI#GDK_3_(GTK_3) for details
19         self.dpi = 96
20         self.baseline_dpi = self.dpi
21 
22         # The dirty widgets are the set of widgets that are known to need
23         # re-hinting before any redraw occurs.
24         self._dirty_widgets = set()
25 
26         # A flag that can be used to explicitly flag that a redraw is required.
27         self.needs_redraw = True
28 
29     def make_dirty(self, widget=None):
30         """Mark the container (or a specific widget in the container) as dirty.
31 
32         :param widget: If provided, this widget will be rehinted before the next layout.
33         """
34         self.needs_redraw = True
35         if widget is not None:
36             self._dirty_widgets.add(widget)
37         self.queue_resize()
38 
39     @property
40     def width(self):
41         """The display width of the container.
42 
43         If the container doesn't have any content yet, the width is 0.
44         """
45         if self._content is None:
46             return 0
47         return self.get_allocated_width()
48 
49     @property
50     def height(self):
51         """The display height of the container.
52 
53         If the container doesn't have any content yet, the height is 0.
54         """
55         if self._content is None:
56             return 0
57         return self.get_allocated_height()
58 
59     @property
60     def content(self):
61         """The Toga implementation widget that is the root content of this
62         container.
63 
64         All children of the root content will also be added to the container as
65         a result of assigning content.
66 
67         If the container already has content, the old content will be replaced.
68         The old root content and all it's children will be removed from the
69         container.
70         """
71         return self._content
72 
73     @content.setter
74     def content(self, widget):
75         if self._content:
76             self._content.container = None
77 
78         self._content = widget
79         if widget:
80             widget.container = self
81 
82     def recompute(self):
83         """Rehint and re-layout the container's content, if necessary.
84 
85         Any widgets known to be dirty will be rehinted. The minimum
86         possible layout size for the container will also be recomputed.
87         """
88         if self._content and self.needs_redraw:
89             # If any of the widgets have been marked as dirty,
90             # recompute their bounds, and re-evaluate the minimum
91             # allowed size fo the layout.
92             while self._dirty_widgets:
93                 widget = self._dirty_widgets.pop()
94                 widget.rehint()
95 
96             # Compute the layout using a 0-size container
97             self._content.interface.style.layout(
98                 self._content.interface, TogaContainer()
99             )
100 
101             # print(" computed min layout", self._content.interface.layout)
102             self.min_width = self._content.interface.layout.width
103             self.min_height = self._content.interface.layout.height
104 
105     def do_get_preferred_width(self):
106         """Return (recomputing if necessary) the preferred width for the
107         container.
108 
109         The preferred size of the container is it's minimum size. This
110         preference will be overridden with the layout size when the layout is
111         applied.
112 
113         If the container does not yet have content, the minimum width is set to
114         0.
115         """
116         # print("GET PREFERRED WIDTH", self._content)
117         if self._content is None:
118             return 0, 0
119 
120         # Ensure we have an accurate min layout size
121         self.recompute()
122 
123         # The container will conform to the size of the allocation it is given,
124         # so the min and preferred size are the same.
125         return self.min_width, self.min_width
126 
127     def do_get_preferred_height(self):
128         """Return (recomputing if necessary) the preferred height for the
129         container.
130 
131         The preferred size of the container is it's minimum size. This
132         preference will be overridden with the layout size when the
133         layout is applied.
134 
135         If the container does not yet have content, the minimum height
136         is set to 0.
137         """
138         # print("GET PREFERRED HEIGHT", self._content)
139         if self._content is None:
140             return 0, 0
141 
142         # Ensure we have an accurate min layout size
143         self.recompute()
144 
145         # The container will conform to the size of the allocation it is given,
146         # so the min and preferred size are the same.
147         return self.min_height, self.min_height
148 
149     def do_size_allocate(self, allocation):
150         """Perform the actual layout for the widget, and all it's children.
151 
152         The container will assume whatever size it has been given by GTK -
153         usually the full space of the window that holds the container.
154         The layout will then be re-computed based on this new available size,
155         and that new geometry will be applied to all child widgets of the
156         container.
157         """
158         # print(self._content, f"Container layout {allocation.width}x{allocation.height} @ {allocation.x}x{allocation.y}")
159 
160         # The container will occupy the full space it has been allocated.
161         resized = (allocation.width, allocation.height) != (self.width, self.height)
162         self.set_allocation(allocation)
163 
164         # This function may be called in response to irrelevant events like button clicks,
165         # so only refresh if we really need to.
166         if self._content and (resized or self.needs_redraw):
167             # Re-evaluate the layout using the allocation size as the basis for geometry
168             # print("REFRESH LAYOUT", allocation.width, allocation.height)
169             self._content.interface.refresh()
170 
171             # WARNING! This is the list of children of the *container*, not
172             # the Toga widget. Toga maintains a tree of children; all nodes
173             # in that tree are direct children of the container.
174             for widget in self.get_children():
175                 if not widget.get_visible():
176                     # print("  not visible {widget.interface}")
177                     pass
178                 else:
179                     # Set the size of the child widget to the computed layout size.
180                     # print(f"  allocate child {widget.interface}: {widget.interface.layout}")
181                     widget_allocation = Gdk.Rectangle()
182                     widget_allocation.x = (
183                         widget.interface.layout.absolute_content_left + allocation.x
184                     )
185                     widget_allocation.y = (
186                         widget.interface.layout.absolute_content_top + allocation.y
187                     )
188                     widget_allocation.width = widget.interface.layout.content_width
189                     widget_allocation.height = widget.interface.layout.content_height
190 
191                     widget.size_allocate(widget_allocation)
192 
193         # The layout has been redrawn
194         self.needs_redraw = False
195
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gtk/src/toga_gtk/container.py b/gtk/src/toga_gtk/container.py
--- a/gtk/src/toga_gtk/container.py
+++ b/gtk/src/toga_gtk/container.py
@@ -161,12 +161,13 @@
         resized = (allocation.width, allocation.height) != (self.width, self.height)
         self.set_allocation(allocation)
 
-        # This function may be called in response to irrelevant events like button clicks,
-        # so only refresh if we really need to.
-        if self._content and (resized or self.needs_redraw):
-            # Re-evaluate the layout using the allocation size as the basis for geometry
-            # print("REFRESH LAYOUT", allocation.width, allocation.height)
-            self._content.interface.refresh()
+        if self._content:
+            # This function may be called in response to irrelevant events like button clicks,
+            # so only refresh if we really need to.
+            if resized or self.needs_redraw:
+                # Re-evaluate the layout using the allocation size as the basis for geometry
+                # print("REFRESH LAYOUT", allocation.width, allocation.height)
+                self._content.interface.refresh()
 
             # WARNING! This is the list of children of the *container*, not
             # the Toga widget. Toga maintains a tree of children; all nodes

{"golden_diff": "diff --git a/gtk/src/toga_gtk/container.py b/gtk/src/toga_gtk/container.py\n--- a/gtk/src/toga_gtk/container.py\n+++ b/gtk/src/toga_gtk/container.py\n@@ -161,12 +161,13 @@\n         resized = (allocation.width, allocation.height) != (self.width, self.height)\n         self.set_allocation(allocation)\n \n-        # This function may be called in response to irrelevant events like button clicks,\n-        # so only refresh if we really need to.\n-        if self._content and (resized or self.needs_redraw):\n-            # Re-evaluate the layout using the allocation size as the basis for geometry\n-            # print(\"REFRESH LAYOUT\", allocation.width, allocation.height)\n-            self._content.interface.refresh()\n+        if self._content:\n+            # This function may be called in response to irrelevant events like button clicks,\n+            # so only refresh if we really need to.\n+            if resized or self.needs_redraw:\n+                # Re-evaluate the layout using the allocation size as the basis for geometry\n+                # print(\"REFRESH LAYOUT\", allocation.width, allocation.height)\n+                self._content.interface.refresh()\n \n             # WARNING! This is the list of children of the *container*, not\n             # the Toga widget. Toga maintains a tree of children; all nodes\n", "issue": "GTK animated widgets freeze until first resize\n### Describe the bug\n\nGTK Widgets that contain an \"animated\" component - e.g., Switch (the slide left/right animation) or an indeterminate ProgressBar (pulse animation) won't animate when the window is first drawn. However, if you resize the window, the animation will resume, including any historical state.\n\n### Steps to reproduce\n\n1. Run the toga_switch example.\r\n\r\nTry to toggle the \"initial state\" button. The color of the switch will change, but the switch itself won't \"slide\".\r\n\r\nAlso worth note: The exterior border of the \"change label\" button is very slightly clipped.\r\n\r\n2. Run the progressbar example\r\n\r\nThe indeterminate progress bar may not start. \r\n\r\nToggle the Running Mode and Indeterminate Mode buttons. With sufficient toggling, you will eventually be able to cause the running indeterminate progress bar to stop animating.\r\n\n\n### Expected behavior\n\nAnimated widgets should consistently render.\n\n### Screenshots\n\n_No response_\n\n### Environment\n\n- Operating System: Linux (any; tested on Fedora 36 and Ubuntu 22.04)\r\n- Python version: 3.10 (but likely any)\r\n- Software versions:\r\n  - Toga: 0.3.0+; tested at 235ff2e, but anything after the landing of #1794 will show the problem\r\n\n\n### Logs\n\n```\r\n\r\n```\r\n\n\n### Additional context\n\nThe problem appears to be related to the GTK Container fixes introduced in #1794.\r\n\r\nIn both examples listed above, I have found that the *first* time I run examples after making a code change, it *sometimes* works. However, on second and subsequent runs, the problem reliably occurs. There may be a timing issue at play - maybe the slowdown of PYC recompilation is sufficient to mask event order problems?\r\n\r\nA suboptimal fix: if the optimisation on L166 that only does a refresh() `if resized or self.needs_redraw` is removed (so a lot more refreshes are performed), the problem goes away\r\n\r\nA partial fix: If `window` listens for the `window-state-event` signal, and marks the container dirty when that event occurs, the switch demo works. The switches on the progress bar demo are also fixed. However, the animation of the indeterminate progress bar *isn't* fixed (at least, not consistently)\r\n\r\nThis suggests that the issue is a signal that constitutes a \"dirty\" window, but isn't being treated as a dirty signal.\r\n\n", "before_files": [{"content": "from .libs import Gdk, Gtk\n\n\nclass TogaContainer(Gtk.Fixed):\n    \"\"\"A GTK container widget implementing Toga's layout.\n\n    This is a GTK widget, with no Toga interface manifestation.\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._content = None\n        self.min_width = 100\n        self.min_height = 100\n\n        # GDK/GTK always renders at 96dpi. When HiDPI mode is enabled, it is\n        # managed at the compositor level. See\n        # https://wiki.archlinux.org/index.php/HiDPI#GDK_3_(GTK_3) for details\n        self.dpi = 96\n        self.baseline_dpi = self.dpi\n\n        # The dirty widgets are the set of widgets that are known to need\n        # re-hinting before any redraw occurs.\n        self._dirty_widgets = set()\n\n        # A flag that can be used to explicitly flag that a redraw is required.\n        self.needs_redraw = True\n\n    def make_dirty(self, widget=None):\n        \"\"\"Mark the container (or a specific widget in the container) as dirty.\n\n        :param widget: If provided, this widget will be rehinted before the next layout.\n        \"\"\"\n        self.needs_redraw = True\n        if widget is not None:\n            self._dirty_widgets.add(widget)\n        self.queue_resize()\n\n    @property\n    def width(self):\n        \"\"\"The display width of the container.\n\n        If the container doesn't have any content yet, the width is 0.\n        \"\"\"\n        if self._content is None:\n            return 0\n        return self.get_allocated_width()\n\n    @property\n    def height(self):\n        \"\"\"The display height of the container.\n\n        If the container doesn't have any content yet, the height is 0.\n        \"\"\"\n        if self._content is None:\n            return 0\n        return self.get_allocated_height()\n\n    @property\n    def content(self):\n        \"\"\"The Toga implementation widget that is the root content of this\n        container.\n\n        All children of the root content will also be added to the container as\n        a result of assigning content.\n\n        If the container already has content, the old content will be replaced.\n        The old root content and all it's children will be removed from the\n        container.\n        \"\"\"\n        return self._content\n\n    @content.setter\n    def content(self, widget):\n        if self._content:\n            self._content.container = None\n\n        self._content = widget\n        if widget:\n            widget.container = self\n\n    def recompute(self):\n        \"\"\"Rehint and re-layout the container's content, if necessary.\n\n        Any widgets known to be dirty will be rehinted. The minimum\n        possible layout size for the container will also be recomputed.\n        \"\"\"\n        if self._content and self.needs_redraw:\n            # If any of the widgets have been marked as dirty,\n            # recompute their bounds, and re-evaluate the minimum\n            # allowed size fo the layout.\n            while self._dirty_widgets:\n                widget = self._dirty_widgets.pop()\n                widget.rehint()\n\n            # Compute the layout using a 0-size container\n            self._content.interface.style.layout(\n                self._content.interface, TogaContainer()\n            )\n\n            # print(\" computed min layout\", self._content.interface.layout)\n            self.min_width = self._content.interface.layout.width\n            self.min_height = self._content.interface.layout.height\n\n    def do_get_preferred_width(self):\n        \"\"\"Return (recomputing if necessary) the preferred width for the\n        container.\n\n        The preferred size of the container is it's minimum size. This\n        preference will be overridden with the layout size when the layout is\n        applied.\n\n        If the container does not yet have content, the minimum width is set to\n        0.\n        \"\"\"\n        # print(\"GET PREFERRED WIDTH\", self._content)\n        if self._content is None:\n            return 0, 0\n\n        # Ensure we have an accurate min layout size\n        self.recompute()\n\n        # The container will conform to the size of the allocation it is given,\n        # so the min and preferred size are the same.\n        return self.min_width, self.min_width\n\n    def do_get_preferred_height(self):\n        \"\"\"Return (recomputing if necessary) the preferred height for the\n        container.\n\n        The preferred size of the container is it's minimum size. This\n        preference will be overridden with the layout size when the\n        layout is applied.\n\n        If the container does not yet have content, the minimum height\n        is set to 0.\n        \"\"\"\n        # print(\"GET PREFERRED HEIGHT\", self._content)\n        if self._content is None:\n            return 0, 0\n\n        # Ensure we have an accurate min layout size\n        self.recompute()\n\n        # The container will conform to the size of the allocation it is given,\n        # so the min and preferred size are the same.\n        return self.min_height, self.min_height\n\n    def do_size_allocate(self, allocation):\n        \"\"\"Perform the actual layout for the widget, and all it's children.\n\n        The container will assume whatever size it has been given by GTK -\n        usually the full space of the window that holds the container.\n        The layout will then be re-computed based on this new available size,\n        and that new geometry will be applied to all child widgets of the\n        container.\n        \"\"\"\n        # print(self._content, f\"Container layout {allocation.width}x{allocation.height} @ {allocation.x}x{allocation.y}\")\n\n        # The container will occupy the full space it has been allocated.\n        resized = (allocation.width, allocation.height) != (self.width, self.height)\n        self.set_allocation(allocation)\n\n        # This function may be called in response to irrelevant events like button clicks,\n        # so only refresh if we really need to.\n        if self._content and (resized or self.needs_redraw):\n            # Re-evaluate the layout using the allocation size as the basis for geometry\n            # print(\"REFRESH LAYOUT\", allocation.width, allocation.height)\n            self._content.interface.refresh()\n\n            # WARNING! This is the list of children of the *container*, not\n            # the Toga widget. Toga maintains a tree of children; all nodes\n            # in that tree are direct children of the container.\n            for widget in self.get_children():\n                if not widget.get_visible():\n                    # print(\"  not visible {widget.interface}\")\n                    pass\n                else:\n                    # Set the size of the child widget to the computed layout size.\n                    # print(f\"  allocate child {widget.interface}: {widget.interface.layout}\")\n                    widget_allocation = Gdk.Rectangle()\n                    widget_allocation.x = (\n                        widget.interface.layout.absolute_content_left + allocation.x\n                    )\n                    widget_allocation.y = (\n                        widget.interface.layout.absolute_content_top + allocation.y\n                    )\n                    widget_allocation.width = widget.interface.layout.content_width\n                    widget_allocation.height = widget.interface.layout.content_height\n\n                    widget.size_allocate(widget_allocation)\n\n        # The layout has been redrawn\n        self.needs_redraw = False\n", "path": "gtk/src/toga_gtk/container.py"}], "after_files": [{"content": "from .libs import Gdk, Gtk\n\n\nclass TogaContainer(Gtk.Fixed):\n    \"\"\"A GTK container widget implementing Toga's layout.\n\n    This is a GTK widget, with no Toga interface manifestation.\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._content = None\n        self.min_width = 100\n        self.min_height = 100\n\n        # GDK/GTK always renders at 96dpi. When HiDPI mode is enabled, it is\n        # managed at the compositor level. See\n        # https://wiki.archlinux.org/index.php/HiDPI#GDK_3_(GTK_3) for details\n        self.dpi = 96\n        self.baseline_dpi = self.dpi\n\n        # The dirty widgets are the set of widgets that are known to need\n        # re-hinting before any redraw occurs.\n        self._dirty_widgets = set()\n\n        # A flag that can be used to explicitly flag that a redraw is required.\n        self.needs_redraw = True\n\n    def make_dirty(self, widget=None):\n        \"\"\"Mark the container (or a specific widget in the container) as dirty.\n\n        :param widget: If provided, this widget will be rehinted before the next layout.\n        \"\"\"\n        self.needs_redraw = True\n        if widget is not None:\n            self._dirty_widgets.add(widget)\n        self.queue_resize()\n\n    @property\n    def width(self):\n        \"\"\"The display width of the container.\n\n        If the container doesn't have any content yet, the width is 0.\n        \"\"\"\n        if self._content is None:\n            return 0\n        return self.get_allocated_width()\n\n    @property\n    def height(self):\n        \"\"\"The display height of the container.\n\n        If the container doesn't have any content yet, the height is 0.\n        \"\"\"\n        if self._content is None:\n            return 0\n        return self.get_allocated_height()\n\n    @property\n    def content(self):\n        \"\"\"The Toga implementation widget that is the root content of this\n        container.\n\n        All children of the root content will also be added to the container as\n        a result of assigning content.\n\n        If the container already has content, the old content will be replaced.\n        The old root content and all it's children will be removed from the\n        container.\n        \"\"\"\n        return self._content\n\n    @content.setter\n    def content(self, widget):\n        if self._content:\n            self._content.container = None\n\n        self._content = widget\n        if widget:\n            widget.container = self\n\n    def recompute(self):\n        \"\"\"Rehint and re-layout the container's content, if necessary.\n\n        Any widgets known to be dirty will be rehinted. The minimum\n        possible layout size for the container will also be recomputed.\n        \"\"\"\n        if self._content and self.needs_redraw:\n            # If any of the widgets have been marked as dirty,\n            # recompute their bounds, and re-evaluate the minimum\n            # allowed size fo the layout.\n            while self._dirty_widgets:\n                widget = self._dirty_widgets.pop()\n                widget.rehint()\n\n            # Compute the layout using a 0-size container\n            self._content.interface.style.layout(\n                self._content.interface, TogaContainer()\n            )\n\n            # print(\" computed min layout\", self._content.interface.layout)\n            self.min_width = self._content.interface.layout.width\n            self.min_height = self._content.interface.layout.height\n\n    def do_get_preferred_width(self):\n        \"\"\"Return (recomputing if necessary) the preferred width for the\n        container.\n\n        The preferred size of the container is it's minimum size. This\n        preference will be overridden with the layout size when the layout is\n        applied.\n\n        If the container does not yet have content, the minimum width is set to\n        0.\n        \"\"\"\n        # print(\"GET PREFERRED WIDTH\", self._content)\n        if self._content is None:\n            return 0, 0\n\n        # Ensure we have an accurate min layout size\n        self.recompute()\n\n        # The container will conform to the size of the allocation it is given,\n        # so the min and preferred size are the same.\n        return self.min_width, self.min_width\n\n    def do_get_preferred_height(self):\n        \"\"\"Return (recomputing if necessary) the preferred height for the\n        container.\n\n        The preferred size of the container is it's minimum size. This\n        preference will be overridden with the layout size when the\n        layout is applied.\n\n        If the container does not yet have content, the minimum height\n        is set to 0.\n        \"\"\"\n        # print(\"GET PREFERRED HEIGHT\", self._content)\n        if self._content is None:\n            return 0, 0\n\n        # Ensure we have an accurate min layout size\n        self.recompute()\n\n        # The container will conform to the size of the allocation it is given,\n        # so the min and preferred size are the same.\n        return self.min_height, self.min_height\n\n    def do_size_allocate(self, allocation):\n        \"\"\"Perform the actual layout for the widget, and all it's children.\n\n        The container will assume whatever size it has been given by GTK -\n        usually the full space of the window that holds the container.\n        The layout will then be re-computed based on this new available size,\n        and that new geometry will be applied to all child widgets of the\n        container.\n        \"\"\"\n        # print(self._content, f\"Container layout {allocation.width}x{allocation.height} @ {allocation.x}x{allocation.y}\")\n\n        # The container will occupy the full space it has been allocated.\n        resized = (allocation.width, allocation.height) != (self.width, self.height)\n        self.set_allocation(allocation)\n\n        if self._content:\n            # This function may be called in response to irrelevant events like button clicks,\n            # so only refresh if we really need to.\n            if resized or self.needs_redraw:\n                # Re-evaluate the layout using the allocation size as the basis for geometry\n                # print(\"REFRESH LAYOUT\", allocation.width, allocation.height)\n                self._content.interface.refresh()\n\n            # WARNING! This is the list of children of the *container*, not\n            # the Toga widget. Toga maintains a tree of children; all nodes\n            # in that tree are direct children of the container.\n            for widget in self.get_children():\n                if not widget.get_visible():\n                    # print(\"  not visible {widget.interface}\")\n                    pass\n                else:\n                    # Set the size of the child widget to the computed layout size.\n                    # print(f\"  allocate child {widget.interface}: {widget.interface.layout}\")\n                    widget_allocation = Gdk.Rectangle()\n                    widget_allocation.x = (\n                        widget.interface.layout.absolute_content_left + allocation.x\n                    )\n                    widget_allocation.y = (\n                        widget.interface.layout.absolute_content_top + allocation.y\n                    )\n                    widget_allocation.width = widget.interface.layout.content_width\n                    widget_allocation.height = widget.interface.layout.content_height\n\n                    widget.size_allocate(widget_allocation)\n\n        # The layout has been redrawn\n        self.needs_redraw = False\n", "path": "gtk/src/toga_gtk/container.py"}]}