From 51c205b1b8b7efca77ddef9df20dcd9e8076b2cd Mon Sep 17 00:00:00 2001 From: PythBuster <57115898+PythBuster@users.noreply.github.com> Date: Sat, 8 Aug 2026 21:46:33 +0200 Subject: [PATCH] fix: yield event loop after automatic UI updates Synchronous generator event handlers use `yield` as an explicit boundary for intermediate UI updates. Although auto-update queued the corresponding UI patch, `__auto_update()` did not actually suspend execution. The generator could therefore resume immediately, allowing blocking work such as `time.sleep()` to prevent the send loop from processing the queued update. Return whether `__auto_update()` updated a control and yield control to the event loop when it did. This ensures the send loop gets an opportunity to dispatch the UI patch before the handler continues, preserving the expected intermediate update behavior of `yield` and refreshing the UI after handler auto-updates. --- .../packages/flet/src/flet/messaging/session.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sdk/python/packages/flet/src/flet/messaging/session.py b/sdk/python/packages/flet/src/flet/messaging/session.py index c76093081b..fc2bb3a8da 100644 --- a/sdk/python/packages/flet/src/flet/messaging/session.py +++ b/sdk/python/packages/flet/src/flet/messaging/session.py @@ -554,13 +554,15 @@ async def after_event(self, control: BaseControl | None): """ # call auto-update if context.auto_update_enabled() and not context.was_update_called(): - await self.__auto_update(control) + if await self.__auto_update(control): + await asyncio.sleep(0) # yield to the event loop so the queued UI update can be sent. + context.reset_update_called() # unregister unreferenced services self.page._services.unregister_services() - async def __auto_update(self, control: BaseControl | None): + async def __auto_update(self, control: BaseControl | None) -> bool: """ Performs auto-update on the nearest eligible isolated ancestor. @@ -569,6 +571,9 @@ async def __auto_update(self, control: BaseControl | None): Args: control: Starting control for parent traversal. + + Returns: + `True` if a control was updated; otherwise, `False`. """ while control: if ( @@ -577,9 +582,11 @@ async def __auto_update(self, control: BaseControl | None): and self.__conn ): control.update() - break + return True control = control.parent + return False + def error(self, message: str): """ Sends a session-crashed message to the connected client.