Skip to content

Commit 490e19a

Browse files
committed
Add debug statements [skip ci]
1 parent 4e0271f commit 490e19a

File tree

5 files changed

+154
-37
lines changed

5 files changed

+154
-37
lines changed

core/src/toga/style/applicator.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@ def widget(self) -> Widget:
4040

4141
def refresh(self) -> None:
4242
# print("RE-EVALUATE LAYOUT", self.widget)
43+
print("[DEBUG Applicator] refresh called")
4344
self.widget.refresh()
4445

4546
def set_bounds(self) -> None:
4647
# print(" APPLY LAYOUT", self.widget, self.widget.layout)
48+
print(
49+
f"[DEBUG Applicator] set_bounds called "
50+
f"{self.widget} with layout {self.widget.layout}"
51+
)
4752
self.widget._impl.set_bounds(
4853
self.widget.layout.absolute_content_left,
4954
self.widget.layout.absolute_content_top,

gtk/src/toga_gtk/container.py

Lines changed: 121 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
class TogaContainerLayoutManager(Gtk.LayoutManager):
1919
def __init__(self):
2020
super().__init__()
21+
print("[DEBUG CONTAINER] TogaContainerLayoutManager initialized")
2122

2223
def do_get_request_mode(self, container):
24+
print(f"[DEBUG CONTAINER] Getting request mode for container {container}")
2325
return Gtk.SizeRequestMode.CONSTANT_SIZE
2426

2527
def do_measure(self, container, orientation, for_size):
@@ -30,19 +32,42 @@ def do_measure(self, container, orientation, for_size):
3032
3133
If the container does not yet have content, the minimum size is set to 0x0.
3234
"""
33-
# print("GET PREFERRED SIZE", self._content)
35+
orient_name = (
36+
"HORIZONTAL"
37+
if orientation == Gtk.Orientation.HORIZONTAL
38+
else "VERTICAL"
39+
)
40+
print(
41+
f"[DEBUG CONTAINER] Measuring container: orientation={orient_name}, "
42+
f"for_size={for_size}"
43+
)
44+
3445
if container._content is None:
46+
print(
47+
"[DEBUG CONTAINER] Container has no content, returning 0, 0, -1, -1"
48+
)
3549
return 0, 0, -1, -1
3650

3751
# Ensure we have an accurate min layout size
52+
print("[DEBUG CONTAINER] Recomputing container layout for measurement")
3853
container.recompute()
3954

4055
# The container will conform to the size of the allocation it is given,
4156
# so the min and preferred size are the same.
4257
if orientation == Gtk.Orientation.HORIZONTAL:
43-
return container.min_width, container.min_width, -1, -1
58+
result = container.min_width, container.min_width, -1, -1
59+
print(
60+
f"[DEBUG CONTAINER] Horizontal measure result: "
61+
f"min={result[0]}, nat={result[1]}"
62+
)
63+
return result
4464
elif orientation == Gtk.Orientation.VERTICAL:
45-
return container.min_height, container.min_height, -1, -1
65+
result = container.min_height, container.min_height, -1, -1
66+
print(
67+
f"[DEBUG CONTAINER] Vertical measure result: "
68+
f"min={result[0]}, nat={result[1]}"
69+
)
70+
return result
4671
return None
4772

4873
def do_allocate(self, container, width, height, baseline):
@@ -53,35 +78,52 @@ def do_allocate(self, container, width, height, baseline):
5378
layout will then be re-computed based on this new available size, and
5479
that new geometry will be applied to all child widgets of the container.
5580
"""
56-
# print(widget._content, f"Container layout {width}x{height} @ 0x0")
81+
print(
82+
f"[DEBUG CONTAINER] Allocating container: "
83+
f"width={width}, height={height}, baseline={baseline}"
84+
)
5785

5886
if container._content:
5987
current_width = container.width
6088
current_height = container.height
6189
resized = (width, height) != (current_width, current_height)
6290

91+
print(
92+
f"[DEBUG CONTAINER] Current container size: "
93+
f"{current_width}x{current_height}, "
94+
f"resized={resized}, needs_redraw={container.needs_redraw}"
95+
)
96+
6397
if resized or container.needs_redraw:
64-
# print("REFRESH LAYOUT", width, height)
98+
print(f"[DEBUG CONTAINER] Refreshing layout to {width}x{height}")
6599
container._content.interface.style.layout(container)
66100
container.min_width = container._content.interface.layout.min_width
67101
container.min_height = (
68102
container._content.interface.layout.min_height
69103
)
104+
print(
105+
f"[DEBUG CONTAINER] New min size: "
106+
f"{container.min_width}x{container.min_height}"
107+
)
70108

71109
# WARNING! This is the list of children of the *container*, not
72110
# the Toga widget. Toga maintains a tree of children; all nodes
73111
# in that tree are direct children of the container.
74112

75113
# Process each child widget
114+
print("[DEBUG CONTAINER] Allocating children:")
115+
child_count = 0
76116
child_widget = container.get_first_child()
77117
while child_widget is not None:
118+
child_count += 1
78119
if child_widget.get_visible():
79120
# Set the allocation of the child widget to the computed
80121
# layout size.
81-
# print(
82-
# f" allocate child {child_widget.interface}: "
83-
# "{child_widget.interface.layout}"
84-
# )
122+
print(
123+
f"[DEBUG CONTAINER] Child {child_count}: "
124+
f"{getattr(child_widget, 'interface', 'unknown')}"
125+
)
126+
85127
child_widget_allocation = Gdk.Rectangle()
86128
child_widget_allocation.x = (
87129
child_widget.interface.layout.absolute_content_left
@@ -95,11 +137,31 @@ def do_allocate(self, container, width, height, baseline):
95137
child_widget_allocation.height = (
96138
child_widget.interface.layout.content_height
97139
)
140+
141+
print(
142+
f"[DEBUG CONTAINER] Allocating at "
143+
f"({child_widget_allocation.x},"
144+
f"{child_widget_allocation.y}) "
145+
f"size {child_widget_allocation.width}x"
146+
f"{child_widget_allocation.height}"
147+
)
98148
child_widget.size_allocate(child_widget_allocation, -1)
149+
else:
150+
print(
151+
f"[DEBUG CONTAINER] Child {child_count}: "
152+
f"{getattr(child_widget, 'interface', 'unknown')} "
153+
f"(not visible)"
154+
)
99155
child_widget = child_widget.get_next_sibling()
100156

157+
print(f"[DEBUG CONTAINER] Allocated {child_count} children")
158+
101159
# The layout has been redrawn
102160
container.needs_redraw = False
161+
print(
162+
"[DEBUG CONTAINER] Allocation complete, "
163+
"container.needs_redraw set to False"
164+
)
103165

104166
class TogaContainer(Gtk.Box):
105167
"""A GTK container widget implementing Toga's layout.
@@ -109,11 +171,13 @@ class TogaContainer(Gtk.Box):
109171

110172
def __init__(self):
111173
super().__init__()
174+
print("[DEBUG CONTAINER] TogaContainer initialized")
112175

113176
# Because we don't have access to the existing layout manager, we must
114177
# create our custom layout manager class.
115178
layout_manager = TogaContainerLayoutManager()
116179
self.set_layout_manager(layout_manager)
180+
print("[DEBUG CONTAINER] Custom layout manager set")
117181

118182
self._content = None
119183
self.min_width = 100
@@ -128,8 +192,14 @@ def __init__(self):
128192

129193
# A flag that can be used to explicitly flag that a redraw is required.
130194
self.needs_redraw = True
195+
print(
196+
f"[DEBUG CONTAINER] Initial state: "
197+
f"min_size={self.min_width}x{self.min_height}, dpi={self.dpi}, "
198+
f"needs_redraw={self.needs_redraw}"
199+
)
131200

132201
def refreshed(self):
202+
print("[DEBUG CONTAINER] Container refreshed called")
133203
pass
134204

135205
def make_dirty(self, widget=None):
@@ -140,7 +210,16 @@ def make_dirty(self, widget=None):
140210
self.needs_redraw = True
141211
if widget is not None:
142212
self._dirty_widgets.add(widget)
213+
print(
214+
f"[DEBUG CONTAINER] Widget {widget} marked as dirty, "
215+
f"dirty count: {len(self._dirty_widgets)}"
216+
)
217+
else:
218+
print(
219+
"[DEBUG CONTAINER] Container marked as dirty (no specific widget)"
220+
)
143221
self.queue_resize()
222+
print("[DEBUG CONTAINER] Resize queued")
144223

145224
@property
146225
def width(self):
@@ -149,11 +228,13 @@ def width(self):
149228
If the container doesn't have any content yet, the width is 0.
150229
"""
151230
if self._content is None:
231+
print("[DEBUG CONTAINER] width property: No content, returning 0")
152232
return 0
153233

154234
if self._dirty_widgets and self.needs_redraw:
155235
self.recompute()
156236
width = self.get_width()
237+
print(f"[DEBUG CONTAINER] width property: returning {width}")
157238
return width
158239

159240
@property
@@ -163,11 +244,13 @@ def height(self):
163244
If the container doesn't have any content yet, the height is 0.
164245
"""
165246
if self._content is None:
247+
print("[DEBUG CONTAINER] height property: No content, returning 0")
166248
return 0
167249

168250
if self._dirty_widgets and self.needs_redraw:
169251
self.recompute()
170252
height = self.get_height()
253+
print(f"[DEBUG CONTAINER] height property: returning {height}")
171254
return height
172255

173256
@property
@@ -185,14 +268,20 @@ def content(self):
185268

186269
@content.setter
187270
def content(self, widget):
271+
print(f"[DEBUG CONTAINER] Setting container content to {widget}")
188272
if self._content:
273+
print(f"[DEBUG CONTAINER] Removing old content {self._content}")
189274
self._content.container = None
190275

191276
self._content = widget
192277
if widget:
278+
print(
279+
f"[DEBUG CONTAINER] Setting container reference on widget {widget}"
280+
)
193281
widget.container = self
194282
self.make_dirty(widget)
195283
else:
284+
print("[DEBUG CONTAINER] No new content, marking container as dirty")
196285
self.make_dirty()
197286

198287
def recompute(self):
@@ -201,19 +290,42 @@ def recompute(self):
201290
Any widgets known to be dirty will be rehinted. The minimum possible
202291
layout size for the container will also be recomputed.
203292
"""
293+
print(
294+
f"[DEBUG CONTAINER] recompute() called. Has content: "
295+
f"{self._content is not None}, "
296+
f"Dirty widgets: {len(self._dirty_widgets)}"
297+
)
204298
if self._content and self._dirty_widgets:
205299
# If any of the widgets have been marked as dirty,
206300
# recompute their bounds, and re-evaluate the minimum
207301
# allowed size for the layout.
302+
print(
303+
f"[DEBUG CONTAINER] Rehinting "
304+
f"{len(self._dirty_widgets)} dirty widgets"
305+
)
208306
while self._dirty_widgets:
209307
widget = self._dirty_widgets.pop()
308+
print(f"[DEBUG CONTAINER] Rehinting widget {widget}")
210309
widget.rehint()
211310

212311
# Recompute the layout
312+
print("[DEBUG CONTAINER] Recomputing layout for content")
213313
self._content.interface.style.layout(self)
214314

315+
old_min_width = self.min_width
316+
old_min_height = self.min_height
215317
self.min_width = self._content.interface.layout.min_width
216318
self.min_height = self._content.interface.layout.min_height
319+
print(
320+
f"[DEBUG CONTAINER] Min size updated: "
321+
f"{old_min_width}x{old_min_height} -> "
322+
f"{self.min_width}x{self.min_height}"
323+
)
324+
else:
325+
print(
326+
"[DEBUG CONTAINER] No content or no dirty widgets, "
327+
"skipping recompute"
328+
)
217329

218330
else: # pragma: no-cover-if-gtk4
219331

gtk/src/toga_gtk/widgets/textinput.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,18 @@ def rehint(self):
105105
)
106106
self.interface.intrinsic.height = height[1]
107107
else: # pragma: no-cover-if-gtk3
108-
# print(
109-
# "REHINT",
110-
# self,
111-
# self.native.get_preferred_size()[0].width,
112-
# self.native.get_preferred_size()[0].height,
113-
# )
108+
print(
109+
"[DEBUG TextInput] REHINT",
110+
self,
111+
self.native.get_preferred_size()[1].width,
112+
self.native.get_preferred_size()[1].height,
113+
)
114114
min_size, size = self.native.get_preferred_size()
115115

116116
self.interface.intrinsic.width = at_least(
117-
max(size.width, self.interface._MIN_WIDTH)
117+
max(min_size.width, self.interface._MIN_WIDTH)
118118
)
119-
self.interface.intrinsic.height = size.height
119+
self.interface.intrinsic.height = min_size.height
120120

121121
def set_error(self, error_message):
122122
self.native.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "error")

gtk/tests_backend/probe.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import asyncio
2-
import contextlib
32

43
import toga
54
from toga_gtk.libs import GTK_VERSION, GLib, Gtk
@@ -9,32 +8,21 @@ class BaseProbe:
98

109
async def redraw(self, message=None, delay=0):
1110
"""Request a redraw of the app, waiting until that redraw has completed."""
11+
print(f"[DEBUG REDRAW] Redraw called with message: {message}, delay: {delay}")
1212
if (
1313
hasattr(self, "native")
1414
and self.native
1515
and hasattr(self.native, "queue_draw")
1616
):
17+
print(
18+
f"[DEBUG REDRAW] Native widget available, "
19+
f"calling queue_draw on {self.native}"
20+
)
1721
self.native.queue_draw()
1822

19-
if frame_clock := self.native.get_frame_clock():
20-
handler_id = None
21-
with contextlib.suppress(asyncio.TimeoutError):
22-
redraw_complete = asyncio.Future()
23-
24-
def on_after_paint(*args):
25-
if not redraw_complete.done():
26-
redraw_complete.set_result(True)
27-
return False
28-
29-
handler_id = frame_clock.connect("after-paint", on_after_paint)
30-
31-
await asyncio.wait_for(redraw_complete, 0.05)
32-
if handler_id is not None:
33-
with contextlib.suppress(SystemError):
34-
frame_clock.disconnect(handler_id)
35-
36-
# Process events to ensure the UI is fully updated
37-
for _ in range(15):
23+
print("[DEBUG REDRAW] Processing events to ensure UI is fully updated")
24+
events_processed = 0
25+
for i in range(15):
3826
if GTK_VERSION < (4, 0, 0):
3927
if Gtk.events_pending():
4028
Gtk.main_iteration_do(blocking=False)
@@ -43,12 +31,20 @@ def on_after_paint(*args):
4331
else:
4432
context = GLib.main_context_default()
4533
if context.pending():
34+
print(f"[DEBUG REDRAW] GTK4: Processing context iteration {i+1}")
4635
context.iteration(may_block=False)
36+
events_processed += 1
4737
else:
38+
print(
39+
f"[DEBUG REDRAW] GTK4: "
40+
f"No more events pending after {events_processed} iterations"
41+
)
4842
break
4943

5044
# Always yield to let GTK catch up
45+
print("[DEBUG REDRAW] Yielding control with asyncio.sleep(0)")
5146
await asyncio.sleep(0)
47+
print("[DEBUG REDRAW] Redraw method complete")
5248

5349
if toga.App.app.run_slow:
5450
delay = max(1, delay)

0 commit comments

Comments
 (0)