2026-01-17 22:06:01 +03:00
|
|
|
import 'dart:io';
|
2024-09-08 23:50:48 +03:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/services.dart';
|
2026-01-17 13:09:20 +03:00
|
|
|
import 'package:umbrix/bootstrap.dart';
|
|
|
|
|
import 'package:umbrix/core/model/environment.dart';
|
2023-07-06 17:18:41 +03:30
|
|
|
|
|
|
|
|
void main() async {
|
2026-01-17 22:06:01 +03:00
|
|
|
// Single instance check - BEFORE Flutter initialization
|
|
|
|
|
if (Platform.isLinux || Platform.isWindows) {
|
|
|
|
|
final lockFile = File('/tmp/umbrix.lock');
|
|
|
|
|
|
|
|
|
|
if (await lockFile.exists()) {
|
|
|
|
|
try {
|
|
|
|
|
final pidString = await lockFile.readAsString();
|
|
|
|
|
final pid = int.tryParse(pidString.trim());
|
|
|
|
|
|
|
|
|
|
if (pid != null) {
|
|
|
|
|
// Check if process is still alive
|
|
|
|
|
final result = await Process.run('ps', ['-p', pid.toString()]);
|
|
|
|
|
|
|
|
|
|
if (result.exitCode == 0) {
|
2026-01-18 05:56:12 +03:00
|
|
|
// Process alive - restore and focus existing window
|
2026-01-18 05:31:59 +03:00
|
|
|
try {
|
2026-01-18 05:56:12 +03:00
|
|
|
// Find window and restore from minimized state, then activate
|
|
|
|
|
final searchResult = await Process.run('xdotool', ['search', '--name', 'Umbrix']);
|
|
|
|
|
if (searchResult.exitCode == 0 && searchResult.stdout.toString().trim().isNotEmpty) {
|
|
|
|
|
final windowId = searchResult.stdout.toString().trim().split('\n').first;
|
|
|
|
|
// Restore from minimized/iconified state
|
|
|
|
|
await Process.run('xdotool', ['windowmap', windowId]);
|
|
|
|
|
await Process.run('xdotool', ['windowactivate', windowId]);
|
|
|
|
|
}
|
2026-01-18 05:31:59 +03:00
|
|
|
} catch (_) {
|
|
|
|
|
// xdotool not available, just exit
|
|
|
|
|
}
|
2026-01-17 22:06:01 +03:00
|
|
|
exit(0);
|
|
|
|
|
} else {
|
|
|
|
|
// Stale lock - remove it
|
|
|
|
|
await lockFile.delete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
try { await lockFile.delete(); } catch (_) {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create lock file with current PID
|
|
|
|
|
try {
|
|
|
|
|
await lockFile.create();
|
|
|
|
|
await lockFile.writeAsString(pid.toString());
|
|
|
|
|
} catch (_) {}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-06 17:18:41 +03:30
|
|
|
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
2024-09-08 23:50:48 +03:00
|
|
|
|
|
|
|
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
|
|
|
|
SystemChrome.setSystemUIOverlayStyle(
|
|
|
|
|
const SystemUiOverlayStyle(
|
|
|
|
|
statusBarColor: Colors.transparent,
|
|
|
|
|
systemNavigationBarColor: Colors.transparent,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
2023-09-12 15:22:58 +03:30
|
|
|
return lazyBootstrap(widgetsBinding, Environment.dev);
|
2023-07-06 17:18:41 +03:30
|
|
|
}
|