Skip to content

Commit f6d9ed1

Browse files
committed
Fix windows tray issues
Optimize windows logic
1 parent c38a671 commit f6d9ed1

24 files changed

+315
-322
lines changed

core/common.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/metacubex/mihomo/common/batch"
2222
"github.com/metacubex/mihomo/component/dialer"
2323
"github.com/metacubex/mihomo/component/resolver"
24+
"github.com/metacubex/mihomo/component/sniffer"
2425
"github.com/metacubex/mihomo/config"
2526
"github.com/metacubex/mihomo/constant"
2627
cp "github.com/metacubex/mihomo/constant/provider"
@@ -422,7 +423,9 @@ func overwriteConfig(targetConfig *config.RawConfig, patchConfig config.RawConfi
422423
func patchConfig(general *config.General) {
423424
log.Infoln("[Apply] patch")
424425
route.ReStartServer(general.ExternalController)
425-
tunnel.SetSniffing(general.Sniffing)
426+
if sniffer.Dispatcher != nil {
427+
tunnel.SetSniffing(general.Sniffing)
428+
}
426429
tunnel.SetFindProcessMode(general.FindProcessMode)
427430
dialer.SetTcpConcurrent(general.TCPConcurrent)
428431
dialer.DefaultInterface.Store(general.Interface)

lib/common/launch.dart

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import 'dart:async';
22
import 'dart:io';
3+
import 'package:fl_clash/models/models.dart' hide Process;
34
import 'package:launch_at_startup/launch_at_startup.dart';
45

56
import 'constant.dart';
67
import 'system.dart';
8+
import 'windows.dart';
79

810
class AutoLaunch {
911
static AutoLaunch? _instance;
@@ -34,6 +36,9 @@ class AutoLaunch {
3436
}
3537

3638
Future<bool> enable() async {
39+
if (Platform.isWindows) {
40+
await windowsDisable();
41+
}
3742
return await launchAtStartup.enable();
3843
}
3944

@@ -51,45 +56,47 @@ class AutoLaunch {
5156
return res.exitCode == 0;
5257
}
5358

54-
windowsEnable() async {
55-
await Process.run(
56-
'schtasks',
57-
[
58-
'/Create',
59-
'/SC',
60-
'ONLOGON',
61-
'/TN',
62-
appName,
63-
'/TR',
64-
Platform.resolvedExecutable,
65-
'/RL',
66-
'HIGHEST',
67-
'/F'
68-
],
69-
runInShell: true,
70-
);
59+
Future<bool> windowsEnable() async {
60+
await disable();
61+
return windows?.runas(
62+
'schtasks',
63+
[
64+
'/Create',
65+
'/SC',
66+
'ONLOGON',
67+
'/TN',
68+
appName,
69+
'/TR',
70+
Platform.resolvedExecutable,
71+
'/RL',
72+
'HIGHEST',
73+
'/F'
74+
].join(" "),
75+
) ??
76+
false;
7177
}
7278

7379
Future<bool> disable() async {
7480
return await launchAtStartup.disable();
7581
}
7682

77-
updateStatus(bool value) async {
78-
final currentEnable =
79-
Platform.isWindows ? await windowsIsEnable : await isEnable;
80-
if (value == currentEnable) {
81-
return;
82-
}
83-
if (Platform.isWindows) {
84-
if (value) {
85-
enable();
86-
windowsEnable();
83+
updateStatus(AutoLaunchState state) async {
84+
final isOpenTun = state.isOpenTun;
85+
final isAutoLaunch = state.isAutoLaunch;
86+
if (Platform.isWindows && isOpenTun) {
87+
if (await windowsIsEnable == isAutoLaunch) return;
88+
if (isAutoLaunch) {
89+
final isEnable = await windowsEnable();
90+
if (!isEnable) {
91+
enable();
92+
}
8793
} else {
8894
windowsDisable();
8995
}
9096
return;
9197
}
92-
if (value == true) {
98+
if (await isEnable == isAutoLaunch) return;
99+
if (isAutoLaunch == true) {
93100
enable();
94101
} else {
95102
disable();

lib/common/picker.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'dart:io';
12
import 'dart:typed_data';
23

34
import 'package:file_picker/file_picker.dart';
@@ -14,12 +15,16 @@ class Picker {
1415
return filePickerResult?.files.first;
1516
}
1617

17-
Future<String?> saveFile(String fileName,Uint8List bytes) async {
18+
Future<String?> saveFile(String fileName, Uint8List bytes) async {
1819
final path = await FilePicker.platform.saveFile(
1920
fileName: fileName,
2021
initialDirectory: await appPath.getDownloadDirPath(),
21-
bytes: bytes,
22+
bytes: Platform.isAndroid ? bytes : null,
2223
);
24+
if (!Platform.isAndroid && path != null) {
25+
final file = await File(path).create(recursive: true);
26+
await file.writeAsBytes(bytes);
27+
}
2328
return path;
2429
}
2530

lib/common/system.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class System {
1818
bool get isDesktop =>
1919
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
2020

21+
get isAdmin async {
22+
if (!Platform.isWindows) return false;
23+
final result = await Process.run('net', ['session'], runInShell: true);
24+
return result.exitCode == 0;
25+
}
26+
2127
back() async {
2228
await app?.moveTaskToBack();
2329
await window?.hide();

lib/common/windows.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Windows {
1515
return _instance!;
1616
}
1717

18-
void runAsAdministrator(String command, String arguments) async {
18+
bool runas(String command, String arguments) {
1919
final commandPtr = command.toNativeUtf16();
2020
final argumentsPtr = arguments.toNativeUtf16();
2121
final operationPtr = 'runas'.toNativeUtf16();
@@ -50,8 +50,9 @@ class Windows {
5050
calloc.free(operationPtr);
5151

5252
if (result <= 32) {
53-
throw Exception('Failed to launch $command with UAC');
53+
return false;
5454
}
55+
return true;
5556
}
5657
}
5758

lib/controller.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AppController {
2626
late Function updateClashConfigDebounce;
2727
late Function updateGroupDebounce;
2828
late Function addCheckIpNumDebounce;
29+
late Function applyProfileDebounce;
2930

3031
AppController(this.context) {
3132
appState = context.read<AppState>();
@@ -34,6 +35,9 @@ class AppController {
3435
updateClashConfigDebounce = debounce<Function()>(() async {
3536
await updateClashConfig();
3637
});
38+
applyProfileDebounce = debounce<Function()>(() async {
39+
await applyProfile(isPrue: true);
40+
});
3741
addCheckIpNumDebounce = debounce(() {
3842
appState.checkIpNum++;
3943
});
@@ -55,8 +59,7 @@ class AppController {
5559
updateRunTime,
5660
updateTraffic,
5761
];
58-
if (Platform.isAndroid) return;
59-
await applyProfile(isPrue: true);
62+
applyProfileDebounce();
6063
} else {
6164
await globalState.handleStop();
6265
clashCore.resetTraffic();
@@ -367,6 +370,10 @@ class AppController {
367370
);
368371
}
369372

373+
showSnackBar(String message) {
374+
globalState.showSnackBar(context, message: message);
375+
}
376+
370377
addProfileFormURL(String url) async {
371378
if (globalState.navigatorKey.currentState?.canPop() ?? false) {
372379
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);

lib/fragments/profiles/profiles.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class _ProfilesFragmentState extends State<ProfilesFragment> {
5252
try {
5353
await appController.updateProfile(profile);
5454
if (profile.id == appController.config.currentProfile?.id) {
55-
appController.applyProfile(isPrue: true);
55+
appController.applyProfileDebounce();
5656
}
5757
} catch (e) {
5858
messages.add("${profile.label ?? profile.id}: $e \n");
@@ -225,7 +225,7 @@ class ProfileItem extends StatelessWidget {
225225
);
226226
await appController.updateProfile(profile);
227227
if (profile.id == appController.config.currentProfile?.id) {
228-
appController.applyProfile(isPrue: true);
228+
appController.applyProfileDebounce();
229229
}
230230
} catch (e) {
231231
config.setProfile(

lib/l10n/arb/intl_en.arb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,7 @@
241241
"tight": "Tight",
242242
"standard": "Standard",
243243
"loose": "Loose",
244-
"profilesSort": "Profiles sort"
244+
"profilesSort": "Profiles sort",
245+
"start": "Start",
246+
"stop": "Stop"
245247
}

lib/l10n/arb/intl_zh_CN.arb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,7 @@
241241
"tight": "宽松",
242242
"standard": "标准",
243243
"loose": "紧凑",
244-
"profilesSort": "配置排序"
244+
"profilesSort": "配置排序",
245+
"start": "启动",
246+
"stop": "暂停"
245247
}

lib/l10n/intl/messages_en.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,9 @@ class MessageLookup extends MessageLookupByLibrary {
316316
"sort": MessageLookupByLibrary.simpleMessage("Sort"),
317317
"source": MessageLookupByLibrary.simpleMessage("Source"),
318318
"standard": MessageLookupByLibrary.simpleMessage("Standard"),
319+
"start": MessageLookupByLibrary.simpleMessage("Start"),
319320
"startVpn": MessageLookupByLibrary.simpleMessage("Staring VPN..."),
321+
"stop": MessageLookupByLibrary.simpleMessage("Stop"),
320322
"stopVpn": MessageLookupByLibrary.simpleMessage("Stopping VPN..."),
321323
"style": MessageLookupByLibrary.simpleMessage("Style"),
322324
"submit": MessageLookupByLibrary.simpleMessage("Submit"),

0 commit comments

Comments
 (0)