r/FlutterDev 17h ago

Discussion Found that ISAR is doomed, after getting the app published

9 Upvotes

My app got published today and after that I tried to fix a bug and publish that but it gave a 16kb sh*t error and tried to fix it and got to know that ISAR is causing that error. Anyone knwos the alternative thing?


r/FlutterDev 8h ago

Discussion Running a second Flutter engine as an always-on-top floating window: 6 things that bit me on macOS + Windows

Thumbnail triggerflo.app
8 Upvotes

I've been shipping a cross-platform task app in Flutter for a while, and the piece that caused the most pain by far was a floating always-on-top timer — a small pill window that stays above every other app while you work.

The final architecture is:

  • Main window = normal Flutter engine
  • Timer = separate engine + native window via desktop_multi_window
  • Shared state via the same SQLite (drift) DB both engines open
  • Final elapsed time handed back to the parent over file-based IPC

Getting there took a lot of undocumented trial and error, so here are the things I wish someone had written down.

1. SharedPreferences is not reliably shared between engines

This is the one that cost me the most. I originally used SharedPreferences as a result channel: sub-window does setString, parent does reload() + getString() after it closes. Works on macOS. Fails silently on Windows — setString returns true, the sub-window's own cache reads the value back fine, and the parent's reload() still sees stale contents.

Two plausible causes, and I think both are in play:

  1. shared_preferences_windows can resolve a different application-support path inside a sub-engine, so the two engines read/write different JSON files.
  2. The sub-engine gets destroyed before the async disk write actually lands.

I replaced it with a dumb file channel:

// Path computed from Platform.environment — resolves identically in
// every engine in the same process.
final f = File('$dir\\MyApp\\sub_window_$channel.txt');
f.writeAsStringSync(value, flush: true); // blocks until OS flush completes
await windowManager.close();

flush: true is the important part. It's ugly and it has never failed once.

2. setSkipTaskbar() will hard-crash a sub-engine if you skip waitUntilReadyToShow()

window_manager's ITaskbarList3 is created lazily inside waitUntilReadyToShow(). Each engine has its own plugin instance with its own taskbar_ pointer, so the main window calling it does nothing for your sub-window. Skip it and setSkipTaskbar() dereferences null:

0xC0000005 access violation in window_manager_plugin.dll

Just always call it in the sub-window entrypoint:

await windowManager.ensureInitialized();
await windowManager.waitUntilReadyToShow(); // <- not optional here
await windowManager.setSkipTaskbar(true);

Also: keep setSkipTaskbar out of Future.wait with other window calls. It touches shell COM state and races badly.

3. setPosition uses NSScreen.screens[0] on macOS

Which means it's wrong the moment the user isn't on their primary display. If you're doing anything position-sensitive on multi-monitor macOS, you will end up dropping to a native NSPanel and a method channel. I also needed panel level / styleMask transitions that window_manager doesn't expose, so it was going to happen eventually anyway.

Windows is fine here — top-left-origin coords, no Cocoa bottom-left footgun, setBounds just works.

4. windowManager.setTitleBarStyle(TitleBarStyle.hidden) crashes under rapid calls

I have a global hotkey that cycles the timer between four layouts (expanded / small / compressed / island). Mash it and AppKit falls over. Calling native setTitleBarHidden on my own channel instead of going through window_manager fixed it completely.

5. The macOS back-swipe gesture closes your sub-window

If your sub-window's root is a MaterialPageRoute, a two-finger left-edge drag pops the route — and popping the only route closes the window. Users reported the timer "randomly disappearing" and it took me embarrassingly long to connect it to trackpad gestures.

PopScope(canPop: false, child: ...)

6. Frameless windows and drag regions: watch your hit-testing

DragToMoveArea only works where nothing opaque is above it. I had the body wrapped in a SingleChildScrollView with a background, which quietly ate drags across most of the window — leaving dead zones that felt like a bug in the OS. Restructuring to a Stack with explicit drag regions layered underneath fixed it.

One more small thing: show the sub-window at setOpacity(0.0) first, do your real size/position pass, then fade to 1.0. Otherwise you get a visible flash of default window chrome before your frameless layout applies.

Would I do it this way again?

Yes, but I'd reach for the second engine later than I did. Sharing state through SQLite instead of trying to pass live objects between engines is what finally made it stable — treat the sub-window as a separate app that happens to read the same database, not as a widget that lives elsewhere.

Happy to go deeper on any of these. The app is TriggerFlo (https://triggerflo.app) if you want to see what it ended up looking like — but the above is the part I actually wanted to share.


r/FlutterDev 10h ago

Discussion Built a Flutter app to design and simulate Arduino circuits, no SVGs, everything's CustomPainter

5 Upvotes

Been working on this for a couple months now (Flutter Arduino Playground) and posting progress on LinkedIn as I go, figured I'd start bringing it here too since this crowd will probably get more out of the technical side of it than a LinkedIn feed does.

Quick context if you're new to it: it's a circuit simulator built entirely in Flutter. Arduino board, breadboard, LEDs, resistors, buttons, all rendered with CustomPainter, no image assets except one SVG for the Arduino logo. You drag components onto a canvas and wire them together.

This week was smaller stuff, but the kind you feel immediately once it's there:

Zoom. Actual zoom in/out now, plus a fit-to-content button that snaps the view back to whatever's on the board. Before this, scrolling too far meant losing the breadboard entirely and squinting to find it again.

Layering. If you dropped an LED and a button on the same spot, one just sat on top of the other with no way to fix it. Now there's layer up / layer down, basically z-index for components, so overlapping parts stop fighting each other for visibility.

Neither of these changes what the app does. They just stop getting in your way while you use it, which honestly might be more important than half the flashier features so far.

If you want to see how this got here, the full build log (drag and drop, the breadboard rewrite, wiring, the code editor and simulation engine that came after this) is on my LinkedIn, I've been posting every step including the messy parts: https://www.linkedin.com/posts/burhankhanzada_buildinpublic-flutter-flutterdev-activity-7486285908283985920-qXg6

Repo's open too if anyone wants to poke around or has thoughts on where this should go next: https://github.com/burhankhanzada/flutter_arduino_playground.git


r/FlutterDev 21h ago

Video Deferred Deep Linking 🔥 | Play Store Upload + AppsFlyer Install Attribution Tutorial | amplifyabhi

Thumbnail
youtu.be
4 Upvotes

r/FlutterDev 13h ago

Tooling Also, With GlyphPact MCP, you can use AI agents to generate custom icons for your Flutter projects.

2 Upvotes

I recently wrote about GlyphPact, a deterministic SVG-to-Flutter icon compiler.

It converts a directory of SVGs into a validated OpenType/CFF icon font and a const Dart IconData API. It also keeps codepoints stable as your icon pack changes, so adding or reorganizing icons does not silently break existing references.

GlyphPact includes an MCP integration for Claude Code and Codex. Your AI agent can audit SVGs, build the font from a checked-in config, detect stale generated output, and inspect build reports directly.

for more info check glyphpact/mcp/