Skip to content

Fix Linux desktop client flavor and cache, and warn about extensions the client lacks - #7030

Open
ndonkoHenri wants to merge 11 commits into
flet-1.1.0from
fix/linux-desktop-client-flavor
Open

ndonkoHenri wants to merge 11 commits into
flet-1.1.0from
fix/linux-desktop-client-flavor

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the Linux desktop client problems behind #5311 and #6265: a stale client reused after an OS upgrade, and a desktop_flavor setting that was ignored depending on where the app was started from. It also makes Flet say what's wrong instead of failing silently: it warns when the app uses an extension the client doesn't include, on every desktop platform, and gives install hints when the Linux client can't load a shared library.

1. Linux client cache is per distro (#5311)

Each Linux client build links its distro's libmpv (libmpv.so.1 on Debian 10/11 and Ubuntu 20.04/22.04, libmpv.so.2 on Debian 12 and Ubuntu 24.04). The cache folder only had the flavor and version in its name, ~/.flet/client/flet-desktop-{flavor}-{version}. After an OS upgrade, or after changing FLET_LINUX_DISTRO, Flet reused the build for the previous distro, and the full client then failed to start with libmpv.so.1: cannot open shared object file (Linux Mint 21 → 22.1 in #5311).

The folder is now flet-desktop-{flavor}-{distro}-{version}, so a different distro gets its own download. The system glibc version is cached with functools.cache (not the build picked from it, so tests can still vary it).

2. desktop_flavor is read from the app's project (#6265)

[tool.flet].desktop_flavor was only read from the pyproject.toml of the current working directory. With this layout:

music-app/
├── pyproject.toml   # [tool.flet] desktop_flavor = "full"
└── src/main.py      # uses ft.Audio
Started with Before After
cd music-app && flet run full full
cd ~ && flet run projects/music-app light, Audio.play() times out full
cd music-app/src && python main.py (or an IDE's Run) light full

Now:

  • flet run reads the nearest pyproject.toml at or above the script and exports its desktop_flavor as FLET_DESKTOP_FLAVOR for the client it opens, unless that variable is already set. The client is opened from the flet run process, whose working directory is where flet run was started, so the variable is how the setting reaches it.
  • flet_desktop itself (used by python main.py / ft.run()) checks the current directory first, then the nearest pyproject.toml at or above sys.argv[0].
  • That nearest file may belong to an enclosing project (a monorepo root, say). If it can't be read or parsed, it's ignored; before, flet run died with a TOMLDecodeError.
  • flet pack apps use only FLET_DESKTOP_FLAVOR. A frozen app is a file, so the script lookup treated its folder as a project. A pyproject.toml near the app, or in the folder it was started from, could pick a flavor other than the bundled one and make it download a vanilla client instead of using its own (patched icon and metadata).

FLET_DESKTOP_FLAVOR still wins over all of the above. Resolution order: env var → pyproject.toml in the current directory → nearest one at or above the script → light on Linux, full elsewhere.

3. Warning when the client doesn't include an extension the app uses

With the light Linux client, Audio calls time out with Timeout waiting for invoke method listener and Video shows Unknown control: Video, with nothing pointing at the client (#6121, #6265). The same happens on any platform with a third-party extension that the prebuilt client doesn't contain. Flet now logs, for example:

The light Flet desktop client doesn't include the flet_audio extension (from flet-audio) the app uses, so its controls show as unknown controls and its services don't respond. If the full client includes it, set FLET_DESKTOP_FLAVOR=full or desktop_flavor = "full" under [tool.flet] in pyproject.toml: https://flet.dev/docs/getting-started/installation#linux

For other clients the second sentence suggests building a client with flet build and starting the app from the project folder.

How it works (flet_desktop/__init__.py, __warn_missing_extensions, called right after the client is cached on Windows, macOS and Linux):

  1. What the client contains. A release client's AOT snapshot (lib/libapp.so, data/app.so, App.framework/App) keeps a package:<name>/ URI for every Dart library compiled into it. The snapshot is scanned once and the package names are stored in a .extensions file in the client's cache folder. The file is only trusted if it lists flet; otherwise the snapshot is scanned again.
  2. What's installed. Extensions install flutter/<package>/pubspec.yaml into site-packages. If every such folder on sys.path is in the client's list (the usual case), the check ends here, in about 1 ms.
  3. What's missing and used. Otherwise the installed distributions' RECORDs map each missing Flutter package to the Python modules it ships (for editable installs, a flutter/<package> folder next to a <package> module counts). An extension is reported only if the app imports one of those modules: either it's already in sys.modules, or the app's .py files import it, found by parsing them with ast (venvs, hidden folders, build, dist, node_modules and symlinked folders are skipped). Under flet run the app runs in a separate process, so run.py passes the script's folder as app_dir. This scan takes ~140 ms and only runs when an installed extension is missing from the client.

An installed but unused extension gives no warning. Any error in the check is logged at debug level and never stops the app.

The helpers that flet pack already used for this (get_client_extensions, find_installed_extensions, find_imported_modules, …) move from flet_cli/__pyinstaller/extensions.py to flet_desktop/extensions.py, so both share them. flet pack and its tests only change their import.

4. Hint when the Linux client can't load a library (#2823)

When the client exits with status 127 (the dynamic loader couldn't load a shared library), flet run and ft.run() now log that a library could not be loaded (the loader's own error only names the library). With the full flavor, where libmpv or GStreamer is the usual cause, the hint gives the apt install command for them and suggests FLET_DESKTOP_FLAVOR=light for apps that need none of the full client's extra extensions; otherwise it says to install the system package that provides the library.

5. Load the reinstalled flet-desktop after a version-mismatch reinstall

ensure_flet_desktop_package_installed() imports flet_desktop to compare versions and reinstalls it on a mismatch, but the old modules stayed in sys.modules. The first launch after upgrading flet then ran the replaced package. The flet_desktop modules are now dropped and import caches invalidated after the reinstall.

Docs

  • Video (Linux section): the light client doesn't include Video; the full client needs libmpv and GStreamer, with the runtime package names for Debian/Ubuntu by release, Fedora, openSUSE and Rocky/AlmaLinux 9 (which needs FLET_LINUX_DISTRO=debian12). The old advice to symlink libmpv.so to libmpv.so.1 is removed; libmpv-dev is only needed by flet build linux.
  • Audio page and flet-audio / flet-video READMEs: same light/full explanation and packages.
  • Installation (Linux, desktop flavor): installing system libraries doesn't add audio or video to the light client; Flet picks the build by glibc version; the new warning.
  • Environment variables: new FLET_LINUX_DISTRO section with the build → glibc → architectures → libmpv table; FLET_DESKTOP_FLAVOR documents where the setting is read from; each build is cached in its own folder.
  • CHANGELOG: two bug fixes (Issue with Flet Framework After Upgrading to Linux Mint 22.1: Missing libmpv.so.1 #5311, bug: Flet_Audio: Song never gets Loaded #6265) and two improvements (the extension warning, the exit-127 hint).

Testing

Case Result
light client, flet run warning logged; play() times out as before
light client, python main.py warning logged
FLET_DESKTOP_FLAVOR=full no warning; audio plays
light client, flet-audio installed but not imported no warning

The .extensions files were written on first launch (144 packages for the full client, 135 for the light one) and read on later ones.

Fixes #5311
Fixes #6265

Summary by Sourcery

Improve desktop client selection and diagnostics across platforms, with distro-aware Linux caching, project-aware flavor resolution, and actionable warnings for missing extensions and libraries.

New Features:

  • Warn when an app uses desktop extensions that are not included in the selected client, with platform-appropriate guidance for resolving the mismatch.
  • Provide Linux startup diagnostics and package installation hints when the desktop client cannot load required shared libraries.

Bug Fixes:

  • Prevent Linux desktop clients built for different distributions from sharing a cache entry after OS or distro-selection changes.
  • Resolve desktop flavor settings from the app project when launching from another directory or directly through Python.
  • Ensure the freshly installed flet-desktop package is loaded after a version-mismatch reinstall.

Enhancements:

  • Share desktop extension discovery utilities between client warnings and packaged-client validation.
  • Cache detected client extension metadata and system glibc information to reduce repeated inspection.

Documentation:

  • Update Linux installation, audio, video, environment-variable, and package guidance for desktop flavors, runtime dependencies, distro selection, and extension diagnostics.

ensure_flet_desktop_package_installed() imports flet_desktop to compare
versions, reinstalls on a mismatch, and left the old module in
sys.modules. The first launch after upgrading flet then imported the
replaced package. Drop the flet_desktop modules and invalidate the
import caches after the reinstall.
…roblems

- Name the Linux client cache dir flet-desktop-{flavor}-{distro}-{version}.
  Each distro build links that distro's libmpv soname, so a client cached
  before an OS upgrade or a FLET_LINUX_DISTRO change is no longer reused.
- After the client exits, log install hints when the dynamic loader could
  not start it (exit status 127).
- Warn when the Linux default light client is used while flet-audio or
  flet-video is installed, since it has neither extension.
- Read [tool.flet].desktop_flavor from the started script's project too,
  and export it as FLET_DESKTOP_FLAVOR from flet run, so starting the app
  from another directory keeps the project's flavor.
A frozen executable is a file, so the started-script lookup treated the
folder of a flet pack app as a project and could select a flavor other
than the bundled one, which made the app download a vanilla client.
Skip that lookup in frozen apps.
…ipt in flet run

flet run only read [tool.flet].desktop_flavor from the script's own
folder, so a script in a project subfolder, run from outside the
project, opened the light client. Use the nearest pyproject.toml at or
above the script.
…ads the flavor

The nearest pyproject.toml at or above the script may belong to an
enclosing project. If it can't be read or parsed, flet run died with a
TOMLDecodeError before starting the app; now it is ignored.
A flet pack app also read the pyproject.toml of the directory it was
started from, so starting it inside a project with desktop_flavor =
"full" swapped its bundled light client for a downloaded full one.
Caching the build id hid glibc changes from the artifact tests, which vary the detected version per case.
The check reads the client's extensions from its AOT snapshot, caches them in the client's folder and compares them with the extensions the app imports, so it covers every extension and platform instead of only Audio and Video with the light Linux client. The extension helpers move from flet-cli to flet-desktop to be shared with flet pack. The exit-127 hint names libmpv and GStreamer only for the full flavor.
@sourcery-ai

sourcery-ai Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Sorry @ndonkoHenri, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 9 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Deploying flet-website-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 504dd02
Status: ✅  Deploy successful!
Preview URL: https://738931ae.flet-website-v2.pages.dev
Branch Preview URL: https://fix-linux-desktop-client-fla.flet-website-v2.pages.dev

View logs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Flet_Audio: Song never gets Loaded Issue with Flet Framework After Upgrading to Linux Mint 22.1: Missing libmpv.so.1

1 participant