Repository navigation
build: Flutter 3.47.8, latest pub dependencies and tray_manager native API - #39
Merged
Merged
Conversation
Pins the latest stable SDK (Dart 3.13.7) in .fvmrc, both workflows and the READMEs, and activates FVM 4.3.2 in the shared setup action. The pinned SDK still satisfies the ^3.13.0 Dart constraint, so pubspec keeps it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pub upgrade --major-versions --tighten moves toastification to 3.2.2, crypto to 3.0.8, and transitively equatable to 3.0.0, shared_preferences_android to 2.5.4, shared_preferences_foundation to 2.6.1, vector_math to 2.4.4, vm_service to 15.4.0 and web to 1.1.2. Lower bounds now name the resolved versions, and material_color_utilities gets a real ^0.13.0 constraint instead of `any`. Still behind, because a dependency pins them: screen_retriever 0.3.0 (window_manager 0.5.2 requires ^0.2.2), cross_file 0.4.0 (file_selector platform packages), material_color_utilities 0.13.1 and test_api 0.7.15 (the Flutter SDK). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tray_manager 0.7 moved the 0.5.x API to a deprecated bridge (package:tray_manager/legacy.dart) that will be removed. The service now owns a nativeapi TrayIcon and builds its context menu from Menu/MenuItem, with a click listener per item. nativeapi calls are synchronous FFI, so the method-channel era scaffolding goes with the bridge: the serialized update queue, the per-call timeouts and the MissingPlugin/PlatformException latch. Support is asked once through TrayManager.isSupported, and right-click opens the menu natively at the cursor through ContextMenuTrigger.rightClicked. The unused refreshMenu is removed; rebuild and handleSystemResume no longer return futures. Behaviour kept from the bridge: replaced menus are disposed after the current event, check items re-assert their state after a click (GTK toggles them), the icon and menu are re-asserted every 20 seconds, and shutdown frees the icon before exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A private named parameter, `this._enableTunOnStartup`, keeps the public `enableTunOnStartup:` name for callers and clears the prefer_initializing_formals info from `flutter analyze`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Teardown deferred the menu's release to Timer.run, which never fires when exit(0) follows immediately (the elevation handoff). The exit-ordering crash shutdown() guards against needs every native tray handle released first, and teardown never runs inside a menu item's own callback, so free it now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #39 found that nativeapi opens the menu natively while Dart keeps running, so the 20 s tick (which cleared the menu signature) and any state change rebuilt the menu, swapped it in and freed the old one under an open menu: a use-after-free in the Windows menu loop, and on macOS a stale menu left attached to the status item with dead items. - One root menu now lives as long as its structure (the kind and key of each line). Labels, check marks and enabled states update in place, which is safe while the menu is on screen. - A structural rebuild, or rebuild() on resume/relaunch, that falls due while the menu reports itself open waits for its MenuClosedEvent. - The 20 s tick re-asserts only the icon, now including setVisible(true): the legacy setIcon ended with it, and it is what re-adds an icon the shell dropped (NIM_ADD) where the icon and tooltip setters cannot. - Replaced menus are freed right away. Item clicks reach Dart through NativeCallable.listener after the native callback returns, so the Timer.run deferral was unnecessary, and it could leave a replaced menu alive at exit. - material_color_utilities goes back to `any`: the Flutter SDK pins it, so a caret constraint would break `pub get` on the next SDK bump. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Second review of #39: in-place menu updates never reach Linux panels (only SetContextMenu republishes the D-Bus menu), cannot touch a Windows submenu line (it is registered under the submenu's handle), and the open/closed events they relied on arrive asynchronously, so the flag could lag behind the real menu, a click could be dropped when a deferred rebuild freed the menu on close, and a Linux panel that never reports "closed" could wedge it. - The trigger is ContextMenuTrigger.none; a TrayIconRightClickedEvent calls openContextMenu(), which blocks for as long as the menu is up on Windows (TrackPopupMenu) and macOS (performClick). _menuOpen is set and cleared synchronously around that call, so a rebuild falling due meanwhile always waits, and runs after the close once the click event has been delivered. - Every change rebuilds the whole menu again and publishes it with setContextMenu, which republishes it to Linux panels and covers submenu lines on Windows. The in-place update machinery is gone. - The menu replaced last stays alive until the next replacement, so a click already queued for it still finds its listener. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ext opening Third review of #39: - cnativeapi exports the Linux D-Bus menu only under a native trigger; with ContextMenuTrigger.none panels showed no menu at all. Linux keeps rightClicked (the panel draws its own copy, so there is no blocking menu loop to track) and skips the Dart-side open. - Two queued changes, or rebuild(), could free the menu a click was made in before that click was delivered. The menu shown by the latest opening now stays alive until the next opening, whichever path replaces it; a menu replaced without having been shown is freed at once, so nothing piles up. shutdown() frees both before exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fourth review of #39: the Linux panel keeps naming the old items until it has fetched the new layout, and nativeapi resolves those names to raw GTK widget pointers. Freeing a replaced menu at once left a short window where a click or property read could reach a destroyed widget, or a reused address. Replaced menus on Linux are now freed after a 10 s grace period, and at shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Review record. This repository has no automated reviewer, so the PR went through an independent code review (a separate agent that read the code and the tray_manager / nativeapi / cnativeapi 0.5.2 sources), repeated until clean:
Residual caveats: macOS relies on AppKit's 🤖 Generated with Claude Code |
acking-you
added a commit
to acking-you/proxy-everything
that referenced
this pull request
Oct 27, 2026
Proxy-UI/Proxy-UI-Flutter#39 (merge 7cd9408): Flutter 3.47.8, latest pub dependencies, and the tray moved to tray_manager's native API with the menu opened from Dart so it is never replaced or freed while on screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
acking-you
added a commit
to acking-you/proxy-everything
that referenced
this pull request
Oct 27, 2026
* build: upgrade the toolchain, dependencies and every submodule Toolchain - nightly-2026-01-26 -> nightly-2026-10-26 (rust-toolchain.toml and both CI workflows). rustfmt.toml needs nightly; the newer compiler also unblocks sysinfo 0.39 (cfg_select). - CI: docker/login-action v4.7.0, Windows fvm 4.1.0 -> 4.3.2. crates.io - sysinfo 0.38 -> 0.39, arc-swap 1.9.3, rustls 0.23.46, plist 1.10, plus a lockfile refresh (tokio 1.54.1, ureq 3.5, uuid 1.29, icu 2.4, ...). - lru dropped: nothing in the workspace uses it. proxy-core also drops ureq, kanal and async-broadcast, which only proxy-client/server use; anyhow is a Windows-only dependency of proxy-updater. Cargo's new unused_dependencies lint flagged all of these. - Held: libc =0.2.189 and with it parking_lot 0.12 (0.13 needs libc 0.2.191). nix 0.31.3 still fails on iOS against newer libc; the fix (nix#2821) is unreleased. - New lints: AtomicX::fetch_update -> try_update, as_chunks for fixed-size chunks, saturating_sub in proxy-tui's Up handling. Submodules - tun2proxy: upstream v0.8.6 merged; ArgProxy -> ProxyParameters. - ipstack: upstream main merged. - kanal: kanal-plus 0.2.1 (upstream main merged, branches 0.5). The parent now uses it as kanal-plus and patches crates.io kanal-plus to the same checkout, so uni-stream no longer pulls a second copy whose branches 0.3 no longer compiles on current nightlies. - uni-stream: dependencies upgraded, parking_lot replaced by std's RwLock. - rust-smallvec: upstream v2 (2.0.0-beta.3) merged; smallvec! is deprecated, so the header buffer is built with new + resize. It is now its own Cargo workspace, so it and better_mimalloc_rs join the exclude list like every other fork (both were implicit members until now). - better_mimalloc_rs: mimalloc_rust 0.1.52 merged, vendored mimalloc v2.5.2. - sysproxy-rs: macOS fixes landed on a branch, unmaintained interfaces crate replaced by nix's getifaddrs. - ui/flutter: Flutter 3.47.8, latest pub dependencies, tray on tray_manager's native API. quinn stays at quinn-proto 0.11.19 / quinn 0.11.12, its latest release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(windows): use as_chunks_mut for the icon's BGRA swap The new nightly's clippy (chunks_exact_to_as_chunks) rejects constant-size chunks_exact_mut under -D warnings. This Windows-only call site was not compiled on the platforms checked locally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(packet-tunnel): bind the loopback proxy before building Args Same shape as tun.rs; the inline form left rustfmt unable to lay out the map_err closure after the ProxyParameters rename. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * build: pin forks to their merged review fixes - deps/ipstack: acking-you/ipstack#5, receive window opens when the read buffer is smaller than the MTU. - deps/better_mimalloc_rs: acking-you/better_mimalloc_rs#2, vendored mimalloc exports mi_malloc_size and mi_malloc_usable_size without the override (upstream f46cacf6). - deps/kanal: acking-you/kanal#2 and #3, kanal-plus 0.2.2 with batch receives and sends sound when a waker panics. Each is the commit merged on the fork's default branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * build: pin the UI to its merged dependency upgrade Proxy-UI/Proxy-UI-Flutter#39 (merge 7cd9408): Flutter 3.47.8, latest pub dependencies, and the tray moved to tray_manager's native API with the menu opened from Dart so it is never replaced or freed while on screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upgrades the UI's SDK and dependencies to their latest releases and moves the tray to tray_manager's current API. Part of the dependency refresh in acking-you/proxy-everything; no native library change is needed.
What moved
.fvmrc,FLUTTER_VERSIONinci.yml/build.yaml, READMEssetup-fvm)any→^0.13.0Podfile.lockis not tracked)Tray:
tray_manager/legacy.dart→ nativeapilib/src/services/tray_service.dartno longer uses the deprecated 0.5-compatibletrayManager/MenuItembridge. nativeapi calls are synchronous, so the update queue, per-call timeouts andMissingPluginException/PlatformExceptionhandling are gone, along with the unusedrefreshMenu;rebuild()/handleSystemResume()no longer return futures. Kept: checkbox state re-assert after a click (GTK toggles on its own), the 20 s icon re-assert, rebuild on resume/relaunch, and freeing every native tray handle before exit (the menu is now released synchronously on teardown so an immediateexit(0)cannot find it alive). One behaviour difference: right-click opens the menu natively (ContextMenuTrigger.rightClicked) instead of Dart receiving the click and opening it.Held back
screen_retriever0.3.0: window_manager 0.5.2 (latest) requires^0.2.2.cross_file0.4.0: blocked by the file_selector platform packages.material_color_utilities0.13.1,test_api0.7.15: pinned by the Flutter SDK.Verified
fvm flutter analyze --no-fatal-infos: no issues (26 before, incl. the tray deprecations).fvm dart format --set-exit-if-changed lib/ test/: clean.fvm flutter test: 204 passed, 7 skipped. Packaging Python tests fromci.yml: pass.fvm flutter build macos --debug(throwaway bundle id) succeeded with the tray library and assets.Not verified
🤖 Generated with Claude Code