Files
FlClash/lib/common/window.dart
T

98 lines
2.7 KiB
Dart
Raw Normal View History

2024-04-30 23:38:49 +08:00
import 'dart:io';
2024-10-27 16:59:23 +08:00
import 'package:fl_clash/common/common.dart';
2025-10-14 15:13:52 +08:00
import 'package:fl_clash/models/config.dart';
2024-04-30 23:38:49 +08:00
import 'package:flutter/material.dart';
2024-12-06 22:35:28 +08:00
import 'package:screen_retriever/screen_retriever.dart';
2024-04-30 23:38:49 +08:00
import 'package:window_manager/window_manager.dart';
class Window {
2025-12-16 11:23:09 +08:00
static Window? _instance;
Window._internal();
factory Window() {
_instance ??= Window._internal();
return _instance!;
}
Future<void> init(int version, WindowProps props) async {
2024-12-03 21:47:12 +08:00
final acquire = await singleInstanceLock.acquire();
if (!acquire) {
exit(0);
}
2025-06-07 01:48:34 +08:00
if (system.isWindows) {
protocol.register('clash');
protocol.register('clashmeta');
protocol.register('flclash');
}
2024-04-30 23:38:49 +08:00
await windowManager.ensureInitialized();
2025-10-14 15:13:52 +08:00
// kDebugMode ? Size(680, 580) :
2024-07-15 22:06:09 +08:00
WindowOptions windowOptions = WindowOptions(
2025-10-14 15:13:52 +08:00
size: props.size,
2025-03-12 17:15:31 +08:00
minimumSize: const Size(380, 400),
2024-04-30 23:38:49 +08:00
);
2025-06-07 01:48:34 +08:00
if (!system.isMacOS || version > 10) {
2024-09-08 21:21:21 +08:00
await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
2025-02-09 18:39:38 +08:00
}
2025-10-14 15:13:52 +08:00
await windowManager.setMaximizable(false);
await _windowPosition(props);
await windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.setPreventClose(true);
});
}
Future<void> _windowPosition(WindowProps props) async {
2025-06-07 01:48:34 +08:00
if (!system.isMacOS) {
2024-12-06 22:35:28 +08:00
final left = props.left ?? 0;
final top = props.top ?? 0;
final right = left + props.width;
final bottom = top + props.height;
if (left == 0 && top == 0) {
await windowManager.setAlignment(Alignment.center);
} else {
final displays = await screenRetriever.getAllDisplays();
2025-07-31 17:09:18 +08:00
final isPositionValid = displays.any((display) {
final displayBounds = Rect.fromLTWH(
display.visiblePosition!.dx,
display.visiblePosition!.dy,
display.size.width,
display.size.height,
2024-12-06 22:35:28 +08:00
);
2025-07-31 17:09:18 +08:00
return displayBounds.contains(Offset(left, top)) ||
displayBounds.contains(Offset(right, bottom));
});
if (isPositionValid) {
await windowManager.setPosition(Offset(left, top));
2024-12-06 22:35:28 +08:00
}
}
2024-09-08 21:21:21 +08:00
}
2024-04-30 23:38:49 +08:00
}
2025-06-07 01:48:34 +08:00
Future<void> show() async {
2025-02-09 18:39:38 +08:00
render?.resume();
2024-04-30 23:38:49 +08:00
await windowManager.show();
await windowManager.focus();
2024-09-08 21:21:21 +08:00
await windowManager.setSkipTaskbar(false);
}
2025-03-12 17:15:31 +08:00
Future<bool> get isVisible async {
final value = await windowManager.isVisible();
2025-06-07 01:48:34 +08:00
commonPrint.log('window visible check: $value');
2025-03-12 17:15:31 +08:00
return value;
2024-04-30 23:38:49 +08:00
}
2025-06-07 01:48:34 +08:00
Future<void> close() async {
2025-12-16 11:23:09 +08:00
await windowManager.close();
2024-04-30 23:38:49 +08:00
exit(0);
}
2025-06-07 01:48:34 +08:00
Future<void> hide() async {
2025-02-09 18:39:38 +08:00
render?.pause();
2024-04-30 23:38:49 +08:00
await windowManager.hide();
2024-09-08 21:21:21 +08:00
await windowManager.setSkipTaskbar(true);
2024-04-30 23:38:49 +08:00
}
}
final window = system.isDesktop ? Window() : null;