import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:umbrix/bootstrap.dart'; import 'package:umbrix/core/model/environment.dart'; final lockFile = File('/tmp/umbrix.lock'); Future _activateExistingWindow() async { // Try to activate existing window via wmctrl try { final result = await Process.run('wmctrl', ['-a', 'Umbrix']); if (result.exitCode == 0) return; } catch (e) { // wmctrl not available, try xdotool try { await Process.run('xdotool', ['search', '--name', 'Umbrix', 'windowactivate']); } catch (e) { // No window activation possible } } } void _cleanupLockFile() { try { if (lockFile.existsSync()) { lockFile.deleteSync(); } } catch (e) { // Ignore cleanup errors } } void main() async { // Single instance check - BEFORE Flutter initialization if (Platform.isLinux || Platform.isWindows) { if (await lockFile.exists()) { // Check if process is still alive try { final pidString = await lockFile.readAsString(); final pid = int.tryParse(pidString.trim()); if (pid != null) { final result = await Process.run('ps', ['-p', pid.toString()]); if (result.exitCode != 0) { // Process dead, remove stale lock await lockFile.delete(); } else { // Process alive - activate window and exit await _activateExistingWindow(); exit(0); } } } catch (e) { // Error reading lock, remove it try { await lockFile.delete(); } catch (e) {} } } // Create lock file try { await lockFile.create(); await lockFile.writeAsString(pid.toString()); } catch (e) { // If can't create, continue anyway } } final widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, systemNavigationBarColor: Colors.transparent, ), ); return lazyBootstrap(widgetsBinding, Environment.dev); }