From 9ae6857ec6f0b9bf4475ba12b7baec5231779506 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 19 Nov 2025 09:50:31 -0800 Subject: [PATCH 1/5] Refactor window control to fix app start with a hidden window Moved window logic from controls/window.dart to services/window.dart, converting WindowControl to WindowService and updating its integration. Updated page and core extension to use the new service, removed window overlay from view, and adjusted backend and related code to support the refactor. This change improves separation of concerns by treating window management as a service rather than a UI control. --- packages/flet/lib/src/controls/page.dart | 79 ++++-- packages/flet/lib/src/controls/view.dart | 4 - packages/flet/lib/src/flet_backend.dart | 9 +- .../flet/lib/src/flet_core_extension.dart | 6 +- .../src/{controls => services}/window.dart | 256 ++++++++---------- 5 files changed, 182 insertions(+), 172 deletions(-) rename packages/flet/lib/src/{controls => services}/window.dart (60%) diff --git a/packages/flet/lib/src/controls/page.dart b/packages/flet/lib/src/controls/page.dart index 7edb16519f..7a3c7ec1ce 100644 --- a/packages/flet/lib/src/controls/page.dart +++ b/packages/flet/lib/src/controls/page.dart @@ -20,6 +20,7 @@ import '../models/page_design.dart'; import '../routing/route_parser.dart'; import '../routing/route_state.dart'; import '../routing/router_delegate.dart'; +import '../services/service_binding.dart'; import '../services/service_registry.dart'; import '../utils/device_info.dart'; import '../utils/locale.dart'; @@ -57,6 +58,9 @@ class _PageControlState extends State with WidgetsBindingObserver { late final AppLifecycleListener _appLifecycleListener; ServiceRegistry? _pageServices; ServiceRegistry? _userServices; + String? _userServicesUid; + ServiceBinding? _windowService; + Control? _windowControl; bool? _prevOnKeyboardEvent; bool _keyboardHandlerSubscribed = false; String? _prevViewRoutes; @@ -95,12 +99,15 @@ class _PageControlState extends State with WidgetsBindingObserver { _attachKeyboardListenerIfNeeded(); widget.control.addInvokeMethodListener(_invokeMethod); + widget.control.addListener(_onPageControlChanged); + _ensureServiceRegistries(); } @override void didChangeDependencies() { debugPrint("Page.didChangeDependencies: ${widget.control.id}"); super.didChangeDependencies(); + _ensureServiceRegistries(); _loadFontsIfNeeded(FletBackend.of(context)); } @@ -109,26 +116,7 @@ class _PageControlState extends State with WidgetsBindingObserver { debugPrint("Page.didUpdateWidget: ${widget.control.id}"); super.didUpdateWidget(oldWidget); _updateMultiViews(); - - // page services - _pageServices ??= ServiceRegistry( - control: widget.control, - propertyName: "_services", - backend: FletBackend.of(context)); - - // user services - var userServicesControl = widget.control.child("_user_services"); - if (userServicesControl != null) { - if (_userServices == null || - _userServices?.control.internals?["uid"] != - userServicesControl.internals?["uid"]) { - _userServices = ServiceRegistry( - control: userServicesControl, - propertyName: "_services", - backend: FletBackend.of(context)); - } - } - + _ensureServiceRegistries(); _attachKeyboardListenerIfNeeded(); _loadFontsIfNeeded(FletBackend.of(context)); } @@ -148,9 +136,60 @@ class _PageControlState extends State with WidgetsBindingObserver { HardwareKeyboard.instance.removeHandler(_handleKeyDown); } widget.control.removeInvokeMethodListener(_invokeMethod); + widget.control.removeListener(_onPageControlChanged); + _pageServices?.dispose(); + _userServices?.dispose(); + _windowService?.dispose(); super.dispose(); } + void _onPageControlChanged() { + _ensureServiceRegistries(); + } + + void _ensureServiceRegistries() { + if (!mounted) { + return; + } + var backend = FletBackend.of(context); + + _pageServices ??= ServiceRegistry( + control: widget.control, + propertyName: "_services", + backend: backend); + + var userServicesControl = widget.control.child("_user_services"); + if (userServicesControl != null) { + var uid = userServicesControl.internals?["uid"]; + if (_userServices == null || _userServicesUid != uid) { + _userServices?.dispose(); + _userServices = ServiceRegistry( + control: userServicesControl, + propertyName: "_services", + backend: backend); + _userServicesUid = uid; + } + } else if (_userServices != null) { + _userServices?.dispose(); + _userServices = null; + _userServicesUid = null; + } + + var windowControl = widget.control.child("window", visibleOnly: false); + if (windowControl != null) { + if (!identical(windowControl, _windowControl)) { + _windowService?.dispose(); + _windowService = + ServiceBinding(control: windowControl, backend: backend); + _windowControl = windowControl; + } + } else if (_windowService != null) { + _windowService?.dispose(); + _windowService = null; + _windowControl = null; + } + } + Future _invokeMethod(String name, dynamic args) async { debugPrint("Page.$name($args)"); diff --git a/packages/flet/lib/src/controls/view.dart b/packages/flet/lib/src/controls/view.dart index 41ec0d01f9..10e215d6d7 100644 --- a/packages/flet/lib/src/controls/view.dart +++ b/packages/flet/lib/src/controls/view.dart @@ -168,10 +168,6 @@ class _ViewControlState extends State { overlayWidgets.add(PageMedia(view: widget.control.parent)); } - var windowControl = control.parent?.get("window"); - if (windowControl != null && isRootView && isDesktopPlatform()) { - overlayWidgets.add(ControlWidget(control: windowControl)); - } } Widget body = Stack(children: [ diff --git a/packages/flet/lib/src/flet_backend.dart b/packages/flet/lib/src/flet_backend.dart index a8c74faf27..48c792b8eb 100644 --- a/packages/flet/lib/src/flet_backend.dart +++ b/packages/flet/lib/src/flet_backend.dart @@ -186,12 +186,14 @@ class FletBackend extends ChangeNotifier { _registerClient(); } catch (e) { debugPrint("Error connecting to Flet backend: $e"); + rethrow; error = e.toString(); _onDisconnect(); } } _registerClient() { + debugPrint("Registering web client: $page"); _send( Message( action: MessageAction.registerClient, @@ -211,7 +213,7 @@ class FletBackend extends ChangeNotifier { "width": page.get("width"), "height": page.get("height"), "platform": page.get("platform"), - "window": page.child("window")!.toMap(), + "window": page.child("window", visibleOnly: false)!.toMap(), "media": page.get("media"), }).toMap()), unbuffered: true); @@ -333,7 +335,7 @@ class FletBackend extends ChangeNotifier { if (isDesktopPlatform()) { var windowState = await getWindowState(); debugPrint("Window state updated: $windowState"); - var window = page.child("window")!; + var window = page.child("window", visibleOnly: false)!; updateControl(window.id, windowState.toMap()); triggerControlEvent(window, "event", {"type": "resized"}); } @@ -470,8 +472,7 @@ class FletBackend extends ChangeNotifier { var template = appErrorMessage ?? defaultAppErrorMessageTemplate; final lines = const LineSplitter().convert(rawError); final message = lines.isNotEmpty ? lines.first : ""; - final details = - lines.length > 1 ? lines.sublist(1).join("\n") : ""; + final details = lines.length > 1 ? lines.sublist(1).join("\n") : ""; template = template.replaceAll("{message}", message); if (details.isEmpty) { template = template.replaceAll(RegExp(r'(\r?\n)*\{details\}'), ""); diff --git a/packages/flet/lib/src/flet_core_extension.dart b/packages/flet/lib/src/flet_core_extension.dart index 17e0868ff5..5903641677 100644 --- a/packages/flet/lib/src/flet_core_extension.dart +++ b/packages/flet/lib/src/flet_core_extension.dart @@ -101,7 +101,6 @@ import 'controls/time_picker.dart'; import 'controls/transparent_pointer.dart'; import 'controls/vertical_divider.dart'; import 'controls/view.dart'; -import 'controls/window.dart'; import 'controls/window_drag_area.dart'; import 'flet_extension.dart'; import 'flet_service.dart'; @@ -116,6 +115,7 @@ import 'services/shared_preferences.dart'; import 'services/storage_paths.dart'; import 'services/tester.dart'; import 'services/url_launcher.dart'; +import 'services/window.dart'; import 'utils/cupertino_icons.dart'; import 'utils/material_icons.dart'; @@ -355,8 +355,6 @@ class FletCoreExtension extends FletExtension { return VerticalDividerControl(key: key, control: control); case "View": return ViewControl(key: key, control: control); - case "Window": - return WindowControl(key: key, control: control); case "WindowDragArea": return WindowDragAreaControl(key: key, control: control); default: @@ -383,6 +381,8 @@ class FletCoreExtension extends FletExtension { return SemanticsServiceControl(control: control); case "StoragePaths": return StoragePaths(control: control); + case "Window": + return WindowService(control: control); case "Tester": return TesterService(control: control); case "UrlLauncher": diff --git a/packages/flet/lib/src/controls/window.dart b/packages/flet/lib/src/services/window.dart similarity index 60% rename from packages/flet/lib/src/controls/window.dart rename to packages/flet/lib/src/services/window.dart index df68368d62..9ba9731ed4 100644 --- a/packages/flet/lib/src/controls/window.dart +++ b/packages/flet/lib/src/services/window.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:window_manager/window_manager.dart'; import '../flet_backend.dart'; -import '../models/control.dart'; +import '../flet_service.dart'; import '../utils/alignment.dart'; import '../utils/colors.dart'; import '../utils/desktop.dart'; @@ -13,17 +13,8 @@ import '../utils/platform.dart'; import '../utils/theme.dart'; import '../utils/window.dart'; -class WindowControl extends StatefulWidget { - final Control control; - - WindowControl({Key? key, required this.control}) - : super(key: key ?? ValueKey("control_${control.id}")); - - @override - State createState() => _WindowControlState(); -} - -class _WindowControlState extends State with WindowListener { +class WindowService extends FletService with WindowListener { + final Completer _initWindowStateCompleter = Completer(); String? _title; Color? _bgColor; double? _width; @@ -58,128 +49,129 @@ class _WindowControlState extends State with WindowListener { bool? _skipTaskBar; double? _progressBar; bool? _ignoreMouseEvents; - final Completer _initWindowStateCompleter = Completer(); + bool _listenersAttached = false; + + WindowService({required super.control}); @override - void initState() { - debugPrint("Window.initState()"); - super.initState(); + void init() { + super.init(); + if (!isDesktopPlatform()) { + return; + } + debugPrint("WindowService(${control.id}).init"); _initWindowState(); } Future _initWindowState() async { - final windowState = await getWindowState(); - _width = windowState.width; - _height = windowState.height; - _top = windowState.top; - _left = windowState.left; - _opacity = windowState.opacity; - _minimizable = windowState.minimizable; - _maximizable = windowState.maximizable; - _fullScreen = windowState.fullScreen; - _resizable = windowState.resizable; - _alwaysOnTop = windowState.alwaysOnTop; - _preventClose = windowState.preventClose; - _minimized = windowState.minimized; - _maximized = windowState.maximized; - _visible = windowState.visible; - _focused = windowState.focused; - _skipTaskBar = windowState.skipTaskBar; - - // bind listeners - windowManager.addListener(this); - widget.control.addInvokeMethodListener(_invokeMethod); - - if (!_initWindowStateCompleter.isCompleted) { - _initWindowStateCompleter.complete(); - } - } + try { + final windowState = await getWindowState(); + _width = windowState.width; + _height = windowState.height; + _top = windowState.top; + _left = windowState.left; + _opacity = windowState.opacity; + _minimizable = windowState.minimizable; + _maximizable = windowState.maximizable; + _fullScreen = windowState.fullScreen; + _resizable = windowState.resizable; + _alwaysOnTop = windowState.alwaysOnTop; + _preventClose = windowState.preventClose; + _minimized = windowState.minimized; + _maximized = windowState.maximized; + _visible = windowState.visible; + _focused = windowState.focused; + _skipTaskBar = windowState.skipTaskBar; + + if (!_listenersAttached) { + windowManager.addListener(this); + control.addInvokeMethodListener(_invokeMethod); + _listenersAttached = true; + } - @override - void didChangeDependencies() { - debugPrint("Window.didChangeDependencies: ${widget.control.id}"); - super.didChangeDependencies(); - _updateWindowAfterInit(); - } + if (!_initWindowStateCompleter.isCompleted) { + _initWindowStateCompleter.complete(); + } - @override - void dispose() { - debugPrint("Window.dispose()"); - windowManager.removeListener(this); - widget.control.addInvokeMethodListener(_invokeMethod); - super.dispose(); + _scheduleWindowUpdate(); + } catch (e) { + debugPrint("Error initializing window state: $e"); + } } @override - void didUpdateWidget(covariant WindowControl oldWidget) { - debugPrint("Window.didUpdateWidget: ${widget.control.id}"); - super.didUpdateWidget(oldWidget); - _updateWindowAfterInit(); + void update() { + if (!isDesktopPlatform()) { + return; + } + _scheduleWindowUpdate(); } - void _updateWindowAfterInit() { - var backend = FletBackend.of(context); + void _scheduleWindowUpdate() { if (_initWindowStateCompleter.isCompleted) { - _updateWindow(backend); + unawaited(_updateWindow(control.backend)); } else { - _initWindowStateCompleter.future.then((_) { - _updateWindow(backend); - }); + _initWindowStateCompleter.future + .then((_) => _updateWindow(control.backend)); } } - void _updateWindow(FletBackend backend) async { + Future _updateWindow(FletBackend backend) async { + if (!isDesktopPlatform()) { + return; + } try { - var title = widget.control.parent!.getString("title"); - var bgColor = widget.control.getColor("bgcolor", context); - var width = widget.control.getDouble("width"); - var height = widget.control.getDouble("height"); - var minWidth = widget.control.getDouble("min_width"); - var minHeight = widget.control.getDouble("min_height"); - var maxWidth = widget.control.getDouble("max_width"); - var maxHeight = widget.control.getDouble("max_height"); - var top = widget.control.getDouble("top"); - var left = widget.control.getDouble("left"); - var fullScreen = widget.control.getBool("full_screen"); - var minimized = widget.control.getBool("minimized"); - var maximized = widget.control.getBool("maximized"); - var alignment = widget.control.getAlignment("alignment"); - var badgeLabel = widget.control.getString("badge_label"); - var icon = widget.control.getString("icon"); - var hasShadow = widget.control.getBool("shadow"); - var opacity = widget.control.getDouble("opacity"); - var aspectRatio = widget.control.getDouble("aspect_ratio"); - var brightness = widget.control.getBrightness("brightness"); - var minimizable = widget.control.getBool("minimizable"); - var maximizable = widget.control.getBool("maximizable"); - var alwaysOnTop = widget.control.getBool("always_on_top"); - var alwaysOnBottom = widget.control.getBool("always_on_bottom"); - var resizable = widget.control.getBool("resizable"); - var movable = widget.control.getBool("movable"); - var preventClose = widget.control.getBool("prevent_close"); - var titleBarHidden = widget.control.getBool("title_bar_hidden"); + var parent = control.parent; + if (parent == null) { + return; + } + var title = parent.getString("title"); + var bgColor = control.getColor("bgcolor", null); + var width = control.getDouble("width"); + var height = control.getDouble("height"); + var minWidth = control.getDouble("min_width"); + var minHeight = control.getDouble("min_height"); + var maxWidth = control.getDouble("max_width"); + var maxHeight = control.getDouble("max_height"); + var top = control.getDouble("top"); + var left = control.getDouble("left"); + var fullScreen = control.getBool("full_screen"); + var minimized = control.getBool("minimized"); + var maximized = control.getBool("maximized"); + var alignment = control.getAlignment("alignment"); + var badgeLabel = control.getString("badge_label"); + var icon = control.getString("icon"); + var hasShadow = control.getBool("shadow"); + var opacity = control.getDouble("opacity"); + var aspectRatio = control.getDouble("aspect_ratio"); + var brightness = control.getBrightness("brightness"); + var minimizable = control.getBool("minimizable"); + var maximizable = control.getBool("maximizable"); + var alwaysOnTop = control.getBool("always_on_top"); + var alwaysOnBottom = control.getBool("always_on_bottom"); + var resizable = control.getBool("resizable"); + var movable = control.getBool("movable"); + var preventClose = control.getBool("prevent_close"); + var titleBarHidden = control.getBool("title_bar_hidden"); var titleBarButtonsHidden = - widget.control.getBool("title_bar_buttons_hidden", false)!; - var visible = widget.control.getBool("visible"); - var focused = widget.control.getBool("focused"); - var skipTaskBar = widget.control.getBool("skip_task_bar"); - var frameless = widget.control.getBool("frameless"); - var progressBar = widget.control.getDouble("progress_bar"); - var ignoreMouseEvents = widget.control.getBool("ignore_mouse_events"); - - // title + control.getBool("title_bar_buttons_hidden", false)!; + var visible = control.getBool("visible"); + var focused = control.getBool("focused"); + var skipTaskBar = control.getBool("skip_task_bar"); + var frameless = control.getBool("frameless"); + var progressBar = control.getDouble("progress_bar"); + var ignoreMouseEvents = control.getBool("ignore_mouse_events"); + if (title != null && title != _title) { - setWindowTitle(title); + await setWindowTitle(title); _title = title; } - // bgColor if (bgColor != null && bgColor != _bgColor) { - setWindowBackgroundColor(bgColor); + await setWindowBackgroundColor(bgColor); _bgColor = bgColor; } - // size if ((width != null || height != null) && (width != _width || height != _height) && fullScreen != true && @@ -190,7 +182,6 @@ class _WindowControlState extends State with WindowListener { _height = height; } - // min size if ((minWidth != null || minHeight != null) && (minWidth != _minWidth || minHeight != _minHeight)) { await setWindowMinSize(minWidth, minHeight); @@ -198,7 +189,6 @@ class _WindowControlState extends State with WindowListener { _minHeight = minHeight; } - // max size if ((maxWidth != null || maxHeight != null) && (maxWidth != _maxWidth || maxHeight != _maxHeight)) { await setWindowMaxSize(maxWidth, maxHeight); @@ -206,7 +196,6 @@ class _WindowControlState extends State with WindowListener { _maxHeight = maxHeight; } - // position if ((top != null || left != null) && (top != _top || left != _left) && fullScreen != true && @@ -217,31 +206,26 @@ class _WindowControlState extends State with WindowListener { _left = left; } - // opacity if (opacity != null && opacity != _opacity) { await setWindowOpacity(opacity); _opacity = opacity; } - // aspectRatio if (aspectRatio != null && aspectRatio != _aspectRatio) { await setWindowAspectRatio(aspectRatio); _aspectRatio = aspectRatio; } - // brightness if (brightness != null && brightness != _brightness) { await setWindowBrightness(brightness); _brightness = brightness; } - // minimizable if (minimizable != null && minimizable != _minimizable) { await setWindowMinimizability(minimizable); _minimizable = minimizable; } - // minimized if (minimized != _minimized) { if (minimized == true) { await minimizeWindow(); @@ -251,13 +235,11 @@ class _WindowControlState extends State with WindowListener { _minimized = minimized; } - // maximizable if (maximizable != null && maximizable != _maximizable) { await setWindowMaximizability(maximizable); _maximizable = maximizable; } - // maximized if (maximized != _maximized) { if (maximized == true) { await maximizeWindow(); @@ -267,76 +249,64 @@ class _WindowControlState extends State with WindowListener { _maximized = maximized; } - // alignment if (alignment != null && alignment != _alignment) { await setWindowAlignment(alignment); _alignment = alignment; } - // badge label if (badgeLabel != null && badgeLabel != _badgeLabel) { await setWindowBadgeLabel(badgeLabel); _badgeLabel = badgeLabel; } - // icon if (icon != null && icon != _icon) { var iconAssetSrc = backend.getAssetSource(icon); await setWindowIcon(iconAssetSrc.path); _icon = icon; } - // has shadow if (hasShadow != null && hasShadow != _hasShadow) { await setWindowShadow(hasShadow); _hasShadow = hasShadow; } - // resizable if (resizable != null && resizable != _resizable) { await setWindowResizability(resizable); _resizable = resizable; } - // movable if (movable != null && movable != _movable) { await setWindowMovability(movable); _movable = movable; } - // full screen if (fullScreen != null && fullScreen != _fullScreen) { await setWindowFullScreen(fullScreen); _fullScreen = fullScreen; } - // always on top if (alwaysOnTop != null && alwaysOnTop != _alwaysOnTop) { await setWindowAlwaysOnTop(alwaysOnTop); _alwaysOnTop = alwaysOnTop; } - // always on bottom if (alwaysOnBottom != null && alwaysOnBottom != _alwaysOnBottom) { await setWindowAlwaysOnBottom(alwaysOnBottom); _alwaysOnBottom = alwaysOnBottom; } - // prevent close if (preventClose != null && preventClose != _preventClose) { await setWindowPreventClose(preventClose); _preventClose = preventClose; } - // title bar hidden if (titleBarHidden != null && titleBarHidden != _titleBarHidden) { await setWindowTitleBarVisibility( titleBarHidden, titleBarButtonsHidden); _titleBarHidden = titleBarHidden; } - // visible - if (visible != _visible) { + if (visible != null && visible != _visible) { if (visible == true) { await showWindow(); } else { @@ -345,8 +315,7 @@ class _WindowControlState extends State with WindowListener { _visible = visible; } - // focused - if (focused != _focused) { + if (focused != null && focused != _focused) { if (focused == true) { await focusWindow(); } else { @@ -355,25 +324,21 @@ class _WindowControlState extends State with WindowListener { _focused = focused; } - // frameless if (frameless != null && frameless != _frameless && frameless == true) { await setWindowFrameless(); _frameless = frameless; } - // progress bar if (progressBar != null && progressBar != _progressBar) { await setWindowProgressBar(progressBar); _progressBar = progressBar; } - // skip task bar if (skipTaskBar != null && skipTaskBar != _skipTaskBar) { await setWindowSkipTaskBar(skipTaskBar); _skipTaskBar = skipTaskBar; } - // ignore mouse events if (ignoreMouseEvents != null && ignoreMouseEvents != _ignoreMouseEvents) { await setIgnoreMouseEvents(ignoreMouseEvents); @@ -411,18 +376,28 @@ class _WindowControlState extends State with WindowListener { } break; default: - throw Exception("Unknown method ${widget.control.type}.$name"); + throw Exception("Unknown method Window.$name"); } } @override - Widget build(BuildContext context) { - return const SizedBox.shrink(); + void dispose() { + if (_listenersAttached) { + windowManager.removeListener(this); + control.removeInvokeMethodListener(_invokeMethod); + _listenersAttached = false; + } + super.dispose(); } @override void onWindowEvent(String eventName) { - if (["resize", "resized", "move"].contains(eventName)) return; + if (!isDesktopPlatform()) { + return; + } + if (["resize", "resized", "move"].contains(eventName)) { + return; + } getWindowState().then((state) { _width = state.width; _height = state.height; @@ -441,8 +416,7 @@ class _WindowControlState extends State with WindowListener { _focused = state.focused; _skipTaskBar = state.skipTaskBar; - // notify - widget.control.backend.onWindowEvent(eventName, state); + control.backend.onWindowEvent(eventName, state); }); } } From 30b1e4efd54cf7d062ffa9a90b601d8a1be1e536 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 19 Nov 2025 09:57:27 -0800 Subject: [PATCH 2/5] Add usage instructions and startup message to example Added comments explaining how to run the example with the --hidden option using `flet run`. Also added a print statement to notify that the window is hidden on start and will show after 3 seconds. --- sdk/python/examples/controls/page/window_hidden_on_start.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sdk/python/examples/controls/page/window_hidden_on_start.py b/sdk/python/examples/controls/page/window_hidden_on_start.py index 5c85a796ae..0ce72c4198 100644 --- a/sdk/python/examples/controls/page/window_hidden_on_start.py +++ b/sdk/python/examples/controls/page/window_hidden_on_start.py @@ -1,9 +1,15 @@ +# +# Use -n (--hidden) option to run this example with `flet run` command: +# +# flet run -n examples/controls/page/window_hidden_on_start.py +# import asyncio import flet as ft async def main(page: ft.Page): + print("Window is hidden on start. Will show after 3 seconds...") page.add(ft.Text("Hello!")) await asyncio.sleep(3) page.window.visible = True From 30a1e1a0c3e6a16ce35504fccab3c7f5b12a8b81 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 19 Nov 2025 12:37:34 -0800 Subject: [PATCH 3/5] Refactor time picker tests and add window resize example Refactored material time picker integration tests for improved clarity and consistency, updating dialog creation and page update order. Added a new example for window resizing in desktop apps. Updated golden image and other related test files. --- .../examples/controls/page/window_resize.py | 19 ++++++++ .../controls/material/test_time_picker.py | 46 ++++++++++-------- .../examples/core/test_shader_mask.py | 19 +++++--- .../cupertino/test_cupertino_action_sheet.py | 7 +-- .../macos/context_menu/programmatic_open.png | Bin 14717 -> 13732 bytes .../examples/material/test_context_menu.py | 1 + .../examples/material/test_time_picker.py | 14 +++--- 7 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 sdk/python/examples/controls/page/window_resize.py diff --git a/sdk/python/examples/controls/page/window_resize.py b/sdk/python/examples/controls/page/window_resize.py new file mode 100644 index 0000000000..d54f7ba3d2 --- /dev/null +++ b/sdk/python/examples/controls/page/window_resize.py @@ -0,0 +1,19 @@ +import flet as ft + + +def main(page: ft.Page): + if page.window.width is None or page.window.height is None: + page.add(ft.Text("Window size can be changed only in desktop apps.")) + return + + width = 400 + height = 300 + + chrome_width = page.window.width - page.width + chrome_height = page.window.height - page.height + page.window.width = width + chrome_width + page.window.height = height + chrome_height + page.window.update() + + +ft.run(main) diff --git a/sdk/python/packages/flet/integration_tests/controls/material/test_time_picker.py b/sdk/python/packages/flet/integration_tests/controls/material/test_time_picker.py index efacbda781..a85c807ae0 100644 --- a/sdk/python/packages/flet/integration_tests/controls/material/test_time_picker.py +++ b/sdk/python/packages/flet/integration_tests/controls/material/test_time_picker.py @@ -17,18 +17,20 @@ def flet_app(flet_app_function): async def test_basic(flet_app: ftt.FletTestApp, request): flet_app.page.enable_screenshots = True flet_app.resize_page(600, 450) - - time_picker = ft.TimePicker( - confirm_text="Confirm", - error_invalid_text="Time out of range", - help_text="Pick your time slot", - value=datetime.time(hour=19, minute=30), - hour_format=ft.TimePickerHourFormat.H24, - ) - flet_app.page.show_dialog(time_picker) flet_app.page.update() await flet_app.tester.pump_and_settle() + flet_app.page.show_dialog( + ft.TimePicker( + confirm_text="Confirm", + error_invalid_text="Time out of range", + help_text="Pick your time slot", + value=datetime.time(hour=19, minute=30), + hour_format=ft.TimePickerHourFormat.H24, + ) + ) + + await flet_app.tester.pump_and_settle() flet_app.assert_screenshot( request.node.name, await flet_app.page.take_screenshot( @@ -41,13 +43,16 @@ async def test_basic(flet_app: ftt.FletTestApp, request): async def test_hour_format_12(flet_app: ftt.FletTestApp, request): flet_app.page.enable_screenshots = True flet_app.resize_page(600, 450) + flet_app.page.update() + await flet_app.tester.pump_and_settle() - time_picker = ft.TimePicker( - value=datetime.time(hour=19, minute=30), - hour_format=ft.TimePickerHourFormat.H12, + flet_app.page.show_dialog( + ft.TimePicker( + value=datetime.time(hour=19, minute=30), + hour_format=ft.TimePickerHourFormat.H12, + ) ) - flet_app.page.show_dialog(time_picker) - flet_app.page.update() + await flet_app.tester.pump_and_settle() flet_app.assert_screenshot( request.node.name, @@ -61,13 +66,16 @@ async def test_hour_format_12(flet_app: ftt.FletTestApp, request): async def test_hour_format_24(flet_app: ftt.FletTestApp, request): flet_app.page.enable_screenshots = True flet_app.resize_page(600, 450) + flet_app.page.update() + await flet_app.tester.pump_and_settle() - time_picker = ft.TimePicker( - value=datetime.time(hour=19, minute=30), - hour_format=ft.TimePickerHourFormat.H24, + flet_app.page.show_dialog( + ft.TimePicker( + value=datetime.time(hour=19, minute=30), + hour_format=ft.TimePickerHourFormat.H24, + ) ) - flet_app.page.show_dialog(time_picker) - flet_app.page.update() + await flet_app.tester.pump_and_settle() flet_app.assert_screenshot( request.node.name, diff --git a/sdk/python/packages/flet/integration_tests/examples/core/test_shader_mask.py b/sdk/python/packages/flet/integration_tests/examples/core/test_shader_mask.py index dc2476dbd2..6d340f1ff7 100644 --- a/sdk/python/packages/flet/integration_tests/examples/core/test_shader_mask.py +++ b/sdk/python/packages/flet/integration_tests/examples/core/test_shader_mask.py @@ -12,6 +12,12 @@ @pytest.mark.asyncio(loop_scope="function") async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): flet_app_function.page.theme_mode = ft.ThemeMode.LIGHT + + img = ft.Image( + src_base64="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", + height=300, + fit=ft.BoxFit.FILL, + ) sm = ft.ShaderMask( blend_mode=ft.BlendMode.MULTIPLY, shader=ft.LinearGradient( @@ -20,17 +26,16 @@ async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): colors=[ft.Colors.WHITE, ft.Colors.BLACK], tile_mode=ft.GradientTileMode.CLAMP, ), - content=ft.Image( - src_base64="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", - height=300, - fit=ft.BoxFit.FILL, - ), + content=img, ) flet_app_function.page.enable_screenshots = True flet_app_function.resize_page(300, 320) - flet_app_function.page.add(sm) flet_app_function.page.update() - await flet_app_function.tester.pump_and_settle(duration=ft.Duration(seconds=1)) + await flet_app_function.tester.pump_and_settle() + + flet_app_function.page.add(sm) + await flet_app_function.tester.pump_and_settle() + await flet_app_function.tester.pump(1000) flet_app_function.assert_screenshot( "test_image_for_docs", await flet_app_function.page.take_screenshot( diff --git a/sdk/python/packages/flet/integration_tests/examples/cupertino/test_cupertino_action_sheet.py b/sdk/python/packages/flet/integration_tests/examples/cupertino/test_cupertino_action_sheet.py index c7aea65ff2..e26374bbd4 100644 --- a/sdk/python/packages/flet/integration_tests/examples/cupertino/test_cupertino_action_sheet.py +++ b/sdk/python/packages/flet/integration_tests/examples/cupertino/test_cupertino_action_sheet.py @@ -10,6 +10,9 @@ async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): page.theme_mode = ft.ThemeMode.LIGHT page.enable_screenshots = True flet_app_function.resize_page(400, 400) + page.update() + await flet_app_function.tester.pump_and_settle() + sheet = ft.CupertinoActionSheet( title=ft.Text("Choose an option"), message=ft.Text("Select what you would like to do."), @@ -20,12 +23,10 @@ async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): cancel=ft.CupertinoActionSheetAction(content=ft.Text("Cancel")), ) page.add(sheet) - page.update() await flet_app_function.tester.pump_and_settle() flet_app_function.assert_screenshot( - "test_image_for_docs", + request.node.name, await flet_app_function.page.take_screenshot( pixel_ratio=flet_app_function.screenshots_pixel_ratio ), ) - page.update() diff --git a/sdk/python/packages/flet/integration_tests/examples/material/golden/macos/context_menu/programmatic_open.png b/sdk/python/packages/flet/integration_tests/examples/material/golden/macos/context_menu/programmatic_open.png index 1f516099d487b9a9fcb672a85a5db6d589e42aa0..c8e2c77ec6cb4d675ecbe3b91145869da7c092b2 100644 GIT binary patch literal 13732 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 literal 14717 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 Date: Wed, 19 Nov 2025 14:23:08 -0800 Subject: [PATCH 4/5] Fix test flakiness in test_basic by updating page state Added explicit page update and await pump_and_settle before opening the time picker in test_basic. This ensures the page is fully rendered and stable before interaction, reducing test flakiness. --- .../integration_tests/examples/material/test_time_picker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/python/packages/flet/integration_tests/examples/material/test_time_picker.py b/sdk/python/packages/flet/integration_tests/examples/material/test_time_picker.py index cb48c34378..de7cae659d 100644 --- a/sdk/python/packages/flet/integration_tests/examples/material/test_time_picker.py +++ b/sdk/python/packages/flet/integration_tests/examples/material/test_time_picker.py @@ -42,12 +42,13 @@ async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): async def test_basic(flet_app_function: ftt.FletTestApp): flet_app_function.page.enable_screenshots = True flet_app_function.resize_page(600, 400) + flet_app_function.page.update() + await flet_app_function.tester.pump_and_settle() # open picker await flet_app_function.tester.tap( await flet_app_function.tester.find_by_icon(ft.Icons.TIME_TO_LEAVE) ) - flet_app_function.page.update() await flet_app_function.tester.pump_and_settle() flet_app_function.assert_screenshot( From 7c4528cdcbff9b0959952b72445c18fa2038d949 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 19 Nov 2025 17:58:29 -0800 Subject: [PATCH 5/5] Remove rethrow in backend connection error handler Eliminated the rethrow statement in the FletBackend connection error handler to prevent exceptions from propagating and to handle errors more gracefully. --- packages/flet/lib/src/flet_backend.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/flet/lib/src/flet_backend.dart b/packages/flet/lib/src/flet_backend.dart index 48c792b8eb..088ffcc273 100644 --- a/packages/flet/lib/src/flet_backend.dart +++ b/packages/flet/lib/src/flet_backend.dart @@ -186,7 +186,6 @@ class FletBackend extends ChangeNotifier { _registerClient(); } catch (e) { debugPrint("Error connecting to Flet backend: $e"); - rethrow; error = e.toString(); _onDisconnect(); }