Add docs/superpowers/README.md as index for plans and specs. Add docs/references/flutter-upstream-bugs.md tracking 4 known Flutter framework workarounds.
5.0 KiB
Flutter Framework Upstream Bugs and Workarounds
Tracking document for Flutter framework issues that require Chanora-specific workarounds.
1. Flutter AdaptiveScaffold Discontinued
Flutter issue: flutter/flutter#162965
Impact: Chanora's adaptive 3-panel layout cannot use the built-in AdaptiveScaffold widget because it has been discontinued by the Flutter team. A custom breakpoint-based layout system was required.
Workaround: Chanora implements its own centralized breakpoint system with three layout classes (compact, medium, expanded) using a custom LayoutBuilder approach. The breakpoint constants and layout policy are documented in docs/ui-ux/adaptive-layout-platform-guide.md.
Relevant code:
- Design spec:
docs/superpowers/specs/2026-06-05-adaptive-3-panel-layout-design.md - Breakpoint thresholds follow Material 3 canonical breakpoints (600dp compact, 840dp medium, ≥1024dp expanded).
Status: Workaround in place. No Flutter fix expected; this is a permanent design divergence.
2. Flutter Lacks Native Audio Session Management
Flutter issue: No unified Flutter issue; this is a fundamental platform abstraction gap. Flutter's audioplayers and similar packages do not expose per-platform audio session lifecycle (iOS AVAudioSession, Android AudioFocus, macOS Core Audio).
Impact: Chanora must manage audio focus, interruption handling, and route changes natively on each platform and bridge them to Dart via MethodChannel.
Workaround: Chanora implements platform-specific audio lifecycle management:
| Platform | Native Implementation | Dart Bridge |
|---|---|---|
| iOS | AppDelegate.swift — AVAudioSession category/route/interruption observers |
chanora/ios_audio_lifecycle MethodChannel |
| Android | AndroidAudioFocusController.kt — AudioFocus request/abandon with OnAudioFocusChangeListener |
chanora/android_audio_lifecycle MethodChannel |
| macOS | MacOSAudioLifecycle — Core Audio HAL default-device and stream-format change observers |
chanora/macos_audio_lifecycle MethodChannel |
Relevant code:
- Dart dispatcher:
apps/chanora_flutter/lib/services/audio_lifecycle_service.dart - iOS native:
apps/chanora_flutter/ios/Runner/AppDelegate.swift - Android native:
apps/chanora_flutter/android/app/src/main/kotlin/app/chanora/chanora_flutter/AndroidAudioFocusController.kt - macOS native:
apps/chanora_flutter/macos/
Status: Ongoing. Each platform's MethodChannel handler catches and swallows errors from the Rust side to prevent exception propagation back through the platform framework (a Flutter restriction on MethodChannel handlers).
3. macOS Default-Device Change Not Exposed to Flutter
Flutter issue: No Flutter issue filed. Flutter's desktop audio support does not expose Core Audio HAL default-input/output device change notifications.
Impact: When the user changes the default audio device on macOS (e.g., plugging in headphones), the Chanora audio engine does not automatically rebind to the new device.
Workaround: The macOS MethodChannel (chanora/macos_audio_lifecycle) receives handleDefaultDeviceChange and handleConfigurationChange events from native Swift code, but the corresponding Rust-side FRB bridge function (macosDefaultDeviceChanged) is not yet exposed via flutter_rust_bridge. Events are captured and logged for observability only.
Relevant code:
apps/chanora_flutter/lib/services/audio_lifecycle_service.dart:150-157— macOS handler with TODO markersapps/chanora_flutter/lib/services/audio_lifecycle_service.dart:151—// TODO: call rust.macosDefaultDeviceChanged() once exposed
Status: Partial workaround. Requires flutter_rust_bridge update to expose the Rust function.
4. iOS Audio Session Activation Ordering
Flutter issue: No Flutter issue filed. Flutter does not provide a mechanism to coordinate audio session activation with network connection establishment.
Impact: On iOS, the AVAudioSession must be activated before the voice channel join RPC, and deactivated on failure. Without careful ordering, audio may be left in an active state after a failed join, or the session may not be active when the audio engine starts.
Workaround: Chanora implements an explicit ordering function joinVoiceChannelWithIosAudioSession that activates the iOS audio session, attempts the voice join, and deactivates on failure. A VoiceJoinSuccessPredicate allows callers to treat certain errors (e.g., "already in channel") as successful joins, keeping the audio session active.
Relevant code:
apps/chanora_flutter/lib/services/voice_join_ordering.dart— Full implementation- The
activateIosAudioSession/deactivateIosAudioSessioncallbacks are provided by the iOS native side viaAppDelegate.swift.
Status: Workaround in place. This is an inherent platform design requirement rather than a Flutter bug.