Skip to content

Commit

Permalink
Fix windows tray issues
Browse files Browse the repository at this point in the history
Optimize windows logic
  • Loading branch information
chen08209 committed Aug 25, 2024
1 parent c38a671 commit f6d9ed1
Show file tree
Hide file tree
Showing 24 changed files with 315 additions and 322 deletions.
5 changes: 4 additions & 1 deletion core/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/metacubex/mihomo/common/batch"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/component/sniffer"
"github.com/metacubex/mihomo/config"
"github.com/metacubex/mihomo/constant"
cp "github.com/metacubex/mihomo/constant/provider"
Expand Down Expand Up @@ -422,7 +423,9 @@ func overwriteConfig(targetConfig *config.RawConfig, patchConfig config.RawConfi
func patchConfig(general *config.General) {
log.Infoln("[Apply] patch")
route.ReStartServer(general.ExternalController)
tunnel.SetSniffing(general.Sniffing)
if sniffer.Dispatcher != nil {
tunnel.SetSniffing(general.Sniffing)
}
tunnel.SetFindProcessMode(general.FindProcessMode)
dialer.SetTcpConcurrent(general.TCPConcurrent)
dialer.DefaultInterface.Store(general.Interface)
Expand Down
63 changes: 35 additions & 28 deletions lib/common/launch.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:fl_clash/models/models.dart' hide Process;
import 'package:launch_at_startup/launch_at_startup.dart';

import 'constant.dart';
import 'system.dart';
import 'windows.dart';

class AutoLaunch {
static AutoLaunch? _instance;
Expand Down Expand Up @@ -34,6 +36,9 @@ class AutoLaunch {
}

Future<bool> enable() async {
if (Platform.isWindows) {
await windowsDisable();
}
return await launchAtStartup.enable();
}

Expand All @@ -51,45 +56,47 @@ class AutoLaunch {
return res.exitCode == 0;
}

windowsEnable() async {
await Process.run(
'schtasks',
[
'/Create',
'/SC',
'ONLOGON',
'/TN',
appName,
'/TR',
Platform.resolvedExecutable,
'/RL',
'HIGHEST',
'/F'
],
runInShell: true,
);
Future<bool> windowsEnable() async {
await disable();
return windows?.runas(
'schtasks',
[
'/Create',
'/SC',
'ONLOGON',
'/TN',
appName,
'/TR',
Platform.resolvedExecutable,
'/RL',
'HIGHEST',
'/F'
].join(" "),
) ??
false;
}

Future<bool> disable() async {
return await launchAtStartup.disable();
}

updateStatus(bool value) async {
final currentEnable =
Platform.isWindows ? await windowsIsEnable : await isEnable;
if (value == currentEnable) {
return;
}
if (Platform.isWindows) {
if (value) {
enable();
windowsEnable();
updateStatus(AutoLaunchState state) async {
final isOpenTun = state.isOpenTun;
final isAutoLaunch = state.isAutoLaunch;
if (Platform.isWindows && isOpenTun) {
if (await windowsIsEnable == isAutoLaunch) return;
if (isAutoLaunch) {
final isEnable = await windowsEnable();
if (!isEnable) {
enable();
}
} else {
windowsDisable();
}
return;
}
if (value == true) {
if (await isEnable == isAutoLaunch) return;
if (isAutoLaunch == true) {
enable();
} else {
disable();
Expand Down
9 changes: 7 additions & 2 deletions lib/common/picker.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:typed_data';

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

Future<String?> saveFile(String fileName,Uint8List bytes) async {
Future<String?> saveFile(String fileName, Uint8List bytes) async {
final path = await FilePicker.platform.saveFile(
fileName: fileName,
initialDirectory: await appPath.getDownloadDirPath(),
bytes: bytes,
bytes: Platform.isAndroid ? bytes : null,
);
if (!Platform.isAndroid && path != null) {
final file = await File(path).create(recursive: true);
await file.writeAsBytes(bytes);
}
return path;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/common/system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ class System {
bool get isDesktop =>
Platform.isWindows || Platform.isMacOS || Platform.isLinux;

get isAdmin async {
if (!Platform.isWindows) return false;
final result = await Process.run('net', ['session'], runInShell: true);
return result.exitCode == 0;
}

back() async {
await app?.moveTaskToBack();
await window?.hide();
Expand Down
5 changes: 3 additions & 2 deletions lib/common/windows.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Windows {
return _instance!;
}

void runAsAdministrator(String command, String arguments) async {
bool runas(String command, String arguments) {
final commandPtr = command.toNativeUtf16();
final argumentsPtr = arguments.toNativeUtf16();
final operationPtr = 'runas'.toNativeUtf16();
Expand Down Expand Up @@ -50,8 +50,9 @@ class Windows {
calloc.free(operationPtr);

if (result <= 32) {
throw Exception('Failed to launch $command with UAC');
return false;
}
return true;
}
}

Expand Down
11 changes: 9 additions & 2 deletions lib/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AppController {
late Function updateClashConfigDebounce;
late Function updateGroupDebounce;
late Function addCheckIpNumDebounce;
late Function applyProfileDebounce;

AppController(this.context) {
appState = context.read<AppState>();
Expand All @@ -34,6 +35,9 @@ class AppController {
updateClashConfigDebounce = debounce<Function()>(() async {
await updateClashConfig();
});
applyProfileDebounce = debounce<Function()>(() async {
await applyProfile(isPrue: true);
});
addCheckIpNumDebounce = debounce(() {
appState.checkIpNum++;
});
Expand All @@ -55,8 +59,7 @@ class AppController {
updateRunTime,
updateTraffic,
];
if (Platform.isAndroid) return;
await applyProfile(isPrue: true);
applyProfileDebounce();
} else {
await globalState.handleStop();
clashCore.resetTraffic();
Expand Down Expand Up @@ -367,6 +370,10 @@ class AppController {
);
}

showSnackBar(String message) {
globalState.showSnackBar(context, message: message);
}

addProfileFormURL(String url) async {
if (globalState.navigatorKey.currentState?.canPop() ?? false) {
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
Expand Down
4 changes: 2 additions & 2 deletions lib/fragments/profiles/profiles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class _ProfilesFragmentState extends State<ProfilesFragment> {
try {
await appController.updateProfile(profile);
if (profile.id == appController.config.currentProfile?.id) {
appController.applyProfile(isPrue: true);
appController.applyProfileDebounce();
}
} catch (e) {
messages.add("${profile.label ?? profile.id}: $e \n");
Expand Down Expand Up @@ -225,7 +225,7 @@ class ProfileItem extends StatelessWidget {
);
await appController.updateProfile(profile);
if (profile.id == appController.config.currentProfile?.id) {
appController.applyProfile(isPrue: true);
appController.applyProfileDebounce();
}
} catch (e) {
config.setProfile(
Expand Down
4 changes: 3 additions & 1 deletion lib/l10n/arb/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,7 @@
"tight": "Tight",
"standard": "Standard",
"loose": "Loose",
"profilesSort": "Profiles sort"
"profilesSort": "Profiles sort",
"start": "Start",
"stop": "Stop"
}
4 changes: 3 additions & 1 deletion lib/l10n/arb/intl_zh_CN.arb
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,7 @@
"tight": "宽松",
"standard": "标准",
"loose": "紧凑",
"profilesSort": "配置排序"
"profilesSort": "配置排序",
"start": "启动",
"stop": "暂停"
}
2 changes: 2 additions & 0 deletions lib/l10n/intl/messages_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,9 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("Sort"),
"source": MessageLookupByLibrary.simpleMessage("Source"),
"standard": MessageLookupByLibrary.simpleMessage("Standard"),
"start": MessageLookupByLibrary.simpleMessage("Start"),
"startVpn": MessageLookupByLibrary.simpleMessage("Staring VPN..."),
"stop": MessageLookupByLibrary.simpleMessage("Stop"),
"stopVpn": MessageLookupByLibrary.simpleMessage("Stopping VPN..."),
"style": MessageLookupByLibrary.simpleMessage("Style"),
"submit": MessageLookupByLibrary.simpleMessage("Submit"),
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/intl/messages_zh_CN.dart
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("排序"),
"source": MessageLookupByLibrary.simpleMessage("来源"),
"standard": MessageLookupByLibrary.simpleMessage("标准"),
"start": MessageLookupByLibrary.simpleMessage("启动"),
"startVpn": MessageLookupByLibrary.simpleMessage("正在启动VPN..."),
"stop": MessageLookupByLibrary.simpleMessage("暂停"),
"stopVpn": MessageLookupByLibrary.simpleMessage("正在停止VPN..."),
"style": MessageLookupByLibrary.simpleMessage("风格"),
"submit": MessageLookupByLibrary.simpleMessage("提交"),
Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/l10n.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Future<void> main() async {
clashCore.initMessage();
globalState.packageInfo = await PackageInfo.fromPlatform();
final config = await preferences.getConfig() ?? Config();
globalState.autoRun = config.autoRun;
final clashConfig = await preferences.getClashConfig() ?? ClashConfig();
await android?.init();
await window?.init(config.windowProps);
Expand Down
1 change: 1 addition & 0 deletions lib/models/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ class Config extends ChangeNotifier {
}
}

@JsonKey(defaultValue: false)
bool get showLabel => _showLabel;

set showLabel(bool value) {
Expand Down
4 changes: 3 additions & 1 deletion lib/models/generated/config.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f6d9ed1

Please sign in to comment.