Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save rodydavis/76646f9f18e7543d9ff02860657f097a to your computer and use it in GitHub Desktop.

Select an option

Save rodydavis/76646f9f18e7543d9ff02860657f097a to your computer and use it in GitHub Desktop.
Flutter Multi Window with Shared State
// ignore_for_file: invalid_use_of_internal_member
import 'package:flutter/material.dart';
// ignore: implementation_imports
import 'package:flutter/src/widgets/_window.dart';
// Global shared state demonstrating the power of the single-isolate multi-view model.
// All windows instantly reflect this state without needing platform channels or IPC.
final ValueNotifier<int> sharedCounter = ValueNotifier<int>(0);
void main() {
WidgetsFlutterBinding.ensureInitialized();
runWidget(const MultiWindowOrchestrator());
}
class MyWindowDelegate extends RegularWindowControllerDelegate {
MyWindowDelegate({required this.onDestroy});
final VoidCallback onDestroy;
@override
void onWindowDestroyed() {
super.onWindowDestroyed();
onDestroy();
}
}
class MultiWindowOrchestrator extends StatefulWidget {
const MultiWindowOrchestrator({super.key});
@override
State<MultiWindowOrchestrator> createState() =>
_MultiWindowOrchestratorState();
}
class _MultiWindowOrchestratorState extends State<MultiWindowOrchestrator> {
final Map<int, RegularWindowController> _activeWindows = {};
int _windowIdCounter = 0;
@override
void initState() {
super.initState();
_spawnNewWindow(title: "Primary Application Workspace");
}
void _spawnNewWindow({required String title}) {
final int currentId = _windowIdCounter++;
final controller = RegularWindowController(
title: title,
preferredSize: const Size(1024, 768),
preferredConstraints: const BoxConstraints(minWidth: 800, minHeight: 600),
delegate: MyWindowDelegate(
onDestroy: () {
setState(() {
_activeWindows.remove(currentId);
});
},
),
);
setState(() {
_activeWindows[currentId] = controller;
});
}
@override
Widget build(BuildContext context) {
if (_activeWindows.isEmpty) {
return const SizedBox.shrink();
}
return ViewCollection(
views: _activeWindows.entries.map((entry) {
return RegularWindow(
key: ValueKey('window_${entry.key}'),
controller: entry.value,
child: AppView(
windowId: entry.key,
onSpawnRequested: () =>
_spawnNewWindow(title: "Secondary Workspace ${entry.key}"),
),
);
}).toList(),
);
}
}
class AppView extends StatefulWidget {
final int windowId;
final VoidCallback onSpawnRequested;
const AppView({
super.key,
required this.windowId,
required this.onSpawnRequested,
});
@override
State<AppView> createState() => _AppViewState();
}
class _AppViewState extends State<AppView> {
// Local state specific to this single window
int _localCounter = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text("Active View ID: ${widget.windowId}")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Welcome to Workspace ${widget.windowId}",
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 32),
// Demonstrating shared memory state across windows
ValueListenableBuilder<int>(
valueListenable: sharedCounter,
builder: (context, value, child) {
return Card(
elevation: 4,
color: Colors.blue.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
"Shared Global State",
style: Theme.of(context).textTheme.titleLarge,
),
Text(
"$value",
style: Theme.of(context).textTheme.displayMedium
?.copyWith(color: Colors.blue.shade800),
),
ElevatedButton.icon(
icon: const Icon(Icons.add),
label: const Text("Increment Shared"),
onPressed: () => sharedCounter.value++,
),
],
),
),
);
},
),
const SizedBox(height: 24),
// Demonstrating isolated local state for this specific window
Card(
elevation: 4,
color: Colors.green.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
"Local Window State",
style: Theme.of(context).textTheme.titleLarge,
),
Text(
"$_localCounter",
style: Theme.of(context).textTheme.displayMedium
?.copyWith(color: Colors.green.shade800),
),
ElevatedButton.icon(
icon: const Icon(Icons.add),
label: const Text("Increment Local"),
onPressed: () {
setState(() {
_localCounter++;
});
},
),
],
),
),
),
const SizedBox(height: 32),
ElevatedButton.icon(
icon: const Icon(Icons.open_in_new),
label: const Text("Spawn Secondary Window"),
onPressed: widget.onSpawnRequested,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 16,
),
textStyle: const TextStyle(fontSize: 16),
),
),
],
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment