mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-01-14 04:00:27 +00:00
feat: update app_links
This commit is contained in:
parent
1d59acff2d
commit
a673f70862
41
lib/app.dart
41
lib/app.dart
@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_acrylic/flutter_acrylic.dart';
|
import 'package:flutter_acrylic/flutter_acrylic.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@ -24,6 +25,7 @@ import 'api/api.dart';
|
|||||||
import 'common/conf/url_conf.dart';
|
import 'common/conf/url_conf.dart';
|
||||||
import 'common/io/rs_http.dart';
|
import 'common/io/rs_http.dart';
|
||||||
import 'common/rust/frb_generated.dart';
|
import 'common/rust/frb_generated.dart';
|
||||||
|
import 'common/rust/api/applinks_api.dart' as applinks;
|
||||||
import 'common/rust/api/win32_api.dart' as win32;
|
import 'common/rust/api/win32_api.dart' as win32;
|
||||||
import 'data/app_version_data.dart';
|
import 'data/app_version_data.dart';
|
||||||
import 'generated/no_l10n_strings.dart';
|
import 'generated/no_l10n_strings.dart';
|
||||||
@ -125,6 +127,11 @@ class AppGlobalModel extends _$AppGlobalModel {
|
|||||||
await RSHttp.init();
|
await RSHttp.init();
|
||||||
dPrint("---- rust bridge init -----");
|
dPrint("---- rust bridge init -----");
|
||||||
|
|
||||||
|
// Register URL scheme
|
||||||
|
if ((!ConstConf.isMSE || kDebugMode) && Platform.isWindows) {
|
||||||
|
await _registerUrlScheme();
|
||||||
|
}
|
||||||
|
|
||||||
// init Hive
|
// init Hive
|
||||||
try {
|
try {
|
||||||
Hive.init("$applicationSupportDir/db");
|
Hive.init("$applicationSupportDir/db");
|
||||||
@ -166,16 +173,19 @@ class AppGlobalModel extends _$AppGlobalModel {
|
|||||||
windowManager.waitUntilReadyToShow().then((_) async {
|
windowManager.waitUntilReadyToShow().then((_) async {
|
||||||
await windowManager.setTitle("SCToolBox");
|
await windowManager.setTitle("SCToolBox");
|
||||||
await windowManager.setSkipTaskbar(false);
|
await windowManager.setSkipTaskbar(false);
|
||||||
await windowManager.show();
|
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
await Window.initialize();
|
|
||||||
await Window.hideWindowControls();
|
|
||||||
if (windowsDeviceInfo?.productName.contains("Windows 11") ?? false) {
|
if (windowsDeviceInfo?.productName.contains("Windows 11") ?? false) {
|
||||||
await Window.setEffect(effect: WindowEffect.acrylic);
|
// Apply acrylic effect before showing window
|
||||||
|
await Window.setEffect(effect: WindowEffect.acrylic, color: Colors.transparent, dark: true);
|
||||||
state = state.copyWith(windowsVersion: 11);
|
state = state.copyWith(windowsVersion: 11);
|
||||||
dPrint("---- Windows 11 Acrylic Effect init -----");
|
dPrint("---- Windows 11 Acrylic Effect applied -----");
|
||||||
|
} else {
|
||||||
|
state = state.copyWith(windowsVersion: 10);
|
||||||
|
await Window.setEffect(effect: WindowEffect.disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Show window after acrylic effect is applied
|
||||||
|
await windowManager.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
dPrint("---- Window init -----");
|
dPrint("---- Window init -----");
|
||||||
@ -318,6 +328,27 @@ class AppGlobalModel extends _$AppGlobalModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register sctoolbox:// URL scheme for non-MSE builds
|
||||||
|
Future<void> _registerUrlScheme() async {
|
||||||
|
try {
|
||||||
|
const scheme = "sctoolbox";
|
||||||
|
const appName = "SCToolBox";
|
||||||
|
final result = await applinks.registerApplinks(scheme: scheme, appName: appName);
|
||||||
|
if (result.success) {
|
||||||
|
if (result.wasModified) {
|
||||||
|
dPrint("URL scheme '$scheme' registered successfully: ${result.message}");
|
||||||
|
} else {
|
||||||
|
dPrint("URL scheme '$scheme' already registered: ${result.message}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dPrint("URL scheme '$scheme' registration check: ${result.message}");
|
||||||
|
// Even if check fails, the registration might have succeeded
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
dPrint("Failed to register URL scheme: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> _initAppDir() async {
|
Future<String> _initAppDir() async {
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
final userProfileDir = Platform.environment["USERPROFILE"];
|
final userProfileDir = Platform.environment["USERPROFILE"];
|
||||||
|
|||||||
@ -82,7 +82,7 @@ final class AppGlobalModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$appGlobalModelHash() => r'0e46d72594d94e2beb4d2ccb8616eb37facba288';
|
String _$appGlobalModelHash() => r'853586e6ce83942638f0971e08d7b9106a2e7186';
|
||||||
|
|
||||||
abstract class _$AppGlobalModel extends $Notifier<AppGlobalState> {
|
abstract class _$AppGlobalModel extends $Notifier<AppGlobalState> {
|
||||||
AppGlobalState build();
|
AppGlobalState build();
|
||||||
|
|||||||
68
lib/common/rust/api/applinks_api.dart
Normal file
68
lib/common/rust/api/applinks_api.dart
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `fmt`
|
||||||
|
|
||||||
|
/// Check if the URL scheme is already registered with the correct executable path
|
||||||
|
Future<ApplinksRegistrationResult> checkApplinksRegistration({
|
||||||
|
required String scheme,
|
||||||
|
}) => RustLib.instance.api.crateApiApplinksApiCheckApplinksRegistration(
|
||||||
|
scheme: scheme,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Register URL scheme in Windows registry
|
||||||
|
/// This will create or update the registry keys for the custom URL scheme
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `scheme` - The URL scheme to register (e.g., "sctoolbox")
|
||||||
|
/// * `app_name` - Optional application display name (e.g., "SCToolBox"). If provided,
|
||||||
|
/// the registry will show "URL:{app_name} Protocol" as the scheme description.
|
||||||
|
Future<ApplinksRegistrationResult> registerApplinks({
|
||||||
|
required String scheme,
|
||||||
|
String? appName,
|
||||||
|
}) => RustLib.instance.api.crateApiApplinksApiRegisterApplinks(
|
||||||
|
scheme: scheme,
|
||||||
|
appName: appName,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Unregister URL scheme from Windows registry
|
||||||
|
Future<ApplinksRegistrationResult> unregisterApplinks({
|
||||||
|
required String scheme,
|
||||||
|
}) =>
|
||||||
|
RustLib.instance.api.crateApiApplinksApiUnregisterApplinks(scheme: scheme);
|
||||||
|
|
||||||
|
/// Applinks URL scheme registration result
|
||||||
|
class ApplinksRegistrationResult {
|
||||||
|
/// Whether registration was successful
|
||||||
|
final bool success;
|
||||||
|
|
||||||
|
/// Detailed message about the operation
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
/// Whether the registry was modified (false if already configured correctly)
|
||||||
|
final bool wasModified;
|
||||||
|
|
||||||
|
const ApplinksRegistrationResult({
|
||||||
|
required this.success,
|
||||||
|
required this.message,
|
||||||
|
required this.wasModified,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
success.hashCode ^ message.hashCode ^ wasModified.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is ApplinksRegistrationResult &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
success == other.success &&
|
||||||
|
message == other.message &&
|
||||||
|
wasModified == other.wasModified;
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
import '../frb_generated.dart';
|
import '../frb_generated.dart';
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These functions are ignored because they are not marked as `pub`: `get_process_path`
|
||||||
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `fmt`, `fmt`
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `fmt`, `fmt`
|
||||||
|
|
||||||
Future<void> sendNotify({
|
Future<void> sendNotify({
|
||||||
@ -20,21 +21,27 @@ Future<void> sendNotify({
|
|||||||
appId: appId,
|
appId: appId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Get system memory size in GB
|
||||||
Future<BigInt> getSystemMemorySizeGb() =>
|
Future<BigInt> getSystemMemorySizeGb() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiGetSystemMemorySizeGb();
|
RustLib.instance.api.crateApiWin32ApiGetSystemMemorySizeGb();
|
||||||
|
|
||||||
|
/// Get number of logical processors
|
||||||
Future<int> getNumberOfLogicalProcessors() =>
|
Future<int> getNumberOfLogicalProcessors() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiGetNumberOfLogicalProcessors();
|
RustLib.instance.api.crateApiWin32ApiGetNumberOfLogicalProcessors();
|
||||||
|
|
||||||
|
/// Get all system information at once
|
||||||
Future<SystemInfo> getSystemInfo() =>
|
Future<SystemInfo> getSystemInfo() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiGetSystemInfo();
|
RustLib.instance.api.crateApiWin32ApiGetSystemInfo();
|
||||||
|
|
||||||
|
/// Get GPU info from registry (more accurate VRAM)
|
||||||
Future<String> getGpuInfoFromRegistry() =>
|
Future<String> getGpuInfoFromRegistry() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiGetGpuInfoFromRegistry();
|
RustLib.instance.api.crateApiWin32ApiGetGpuInfoFromRegistry();
|
||||||
|
|
||||||
|
/// Resolve shortcut (.lnk) file to get target path
|
||||||
Future<String> resolveShortcut({required String lnkPath}) =>
|
Future<String> resolveShortcut({required String lnkPath}) =>
|
||||||
RustLib.instance.api.crateApiWin32ApiResolveShortcut(lnkPath: lnkPath);
|
RustLib.instance.api.crateApiWin32ApiResolveShortcut(lnkPath: lnkPath);
|
||||||
|
|
||||||
|
/// Open file explorer and select file/folder
|
||||||
Future<void> openDirWithExplorer({
|
Future<void> openDirWithExplorer({
|
||||||
required String path,
|
required String path,
|
||||||
required bool isFile,
|
required bool isFile,
|
||||||
@ -58,16 +65,19 @@ Future<List<ProcessInfo>> getProcessListByName({required String processName}) =>
|
|||||||
processName: processName,
|
processName: processName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Kill processes by name
|
||||||
Future<int> killProcessByName({required String processName}) => RustLib
|
Future<int> killProcessByName({required String processName}) => RustLib
|
||||||
.instance
|
.instance
|
||||||
.api
|
.api
|
||||||
.crateApiWin32ApiKillProcessByName(processName: processName);
|
.crateApiWin32ApiKillProcessByName(processName: processName);
|
||||||
|
|
||||||
|
/// Get disk physical sector size for performance
|
||||||
Future<int> getDiskPhysicalSectorSize({required String driveLetter}) => RustLib
|
Future<int> getDiskPhysicalSectorSize({required String driveLetter}) => RustLib
|
||||||
.instance
|
.instance
|
||||||
.api
|
.api
|
||||||
.crateApiWin32ApiGetDiskPhysicalSectorSize(driveLetter: driveLetter);
|
.crateApiWin32ApiGetDiskPhysicalSectorSize(driveLetter: driveLetter);
|
||||||
|
|
||||||
|
/// Create a desktop shortcut
|
||||||
Future<void> createDesktopShortcut({
|
Future<void> createDesktopShortcut({
|
||||||
required String targetPath,
|
required String targetPath,
|
||||||
required String shortcutName,
|
required String shortcutName,
|
||||||
@ -76,12 +86,14 @@ Future<void> createDesktopShortcut({
|
|||||||
shortcutName: shortcutName,
|
shortcutName: shortcutName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Run a program with admin privileges (UAC)
|
||||||
Future<void> runAsAdmin({required String program, required String args}) =>
|
Future<void> runAsAdmin({required String program, required String args}) =>
|
||||||
RustLib.instance.api.crateApiWin32ApiRunAsAdmin(
|
RustLib.instance.api.crateApiWin32ApiRunAsAdmin(
|
||||||
program: program,
|
program: program,
|
||||||
args: args,
|
args: args,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Start a program (without waiting)
|
||||||
Future<void> startProcess({
|
Future<void> startProcess({
|
||||||
required String program,
|
required String program,
|
||||||
required List<String> args,
|
required List<String> args,
|
||||||
@ -90,12 +102,15 @@ Future<void> startProcess({
|
|||||||
args: args,
|
args: args,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Check if NVME patch is applied
|
||||||
Future<bool> checkNvmePatchStatus() =>
|
Future<bool> checkNvmePatchStatus() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiCheckNvmePatchStatus();
|
RustLib.instance.api.crateApiWin32ApiCheckNvmePatchStatus();
|
||||||
|
|
||||||
|
/// Add NVME patch to registry
|
||||||
Future<void> addNvmePatch() =>
|
Future<void> addNvmePatch() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiAddNvmePatch();
|
RustLib.instance.api.crateApiWin32ApiAddNvmePatch();
|
||||||
|
|
||||||
|
/// Remove NVME patch from registry
|
||||||
Future<void> removeNvmePatch() =>
|
Future<void> removeNvmePatch() =>
|
||||||
RustLib.instance.api.crateApiWin32ApiRemoveNvmePatch();
|
RustLib.instance.api.crateApiWin32ApiRemoveNvmePatch();
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
|
import 'api/applinks_api.dart';
|
||||||
import 'api/asar_api.dart';
|
import 'api/asar_api.dart';
|
||||||
import 'api/downloader_api.dart';
|
import 'api/downloader_api.dart';
|
||||||
import 'api/http_api.dart';
|
import 'api/http_api.dart';
|
||||||
@ -72,7 +73,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
String get codegenVersion => '2.11.1';
|
String get codegenVersion => '2.11.1';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => -1903117367;
|
int get rustContentHash => -351025706;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig =
|
static const kDefaultExternalLibraryLoaderConfig =
|
||||||
ExternalLibraryLoaderConfig(
|
ExternalLibraryLoaderConfig(
|
||||||
@ -85,6 +86,9 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
abstract class RustLibApi extends BaseApi {
|
abstract class RustLibApi extends BaseApi {
|
||||||
Future<void> crateApiWin32ApiAddNvmePatch();
|
Future<void> crateApiWin32ApiAddNvmePatch();
|
||||||
|
|
||||||
|
Future<ApplinksRegistrationResult>
|
||||||
|
crateApiApplinksApiCheckApplinksRegistration({required String scheme});
|
||||||
|
|
||||||
Future<bool> crateApiWin32ApiCheckNvmePatchStatus();
|
Future<bool> crateApiWin32ApiCheckNvmePatchStatus();
|
||||||
|
|
||||||
Future<void> crateApiOrtApiClearAllModels();
|
Future<void> crateApiOrtApiClearAllModels();
|
||||||
@ -268,6 +272,11 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
|
|
||||||
Future<void> crateApiUnp4KApiP4KOpen({required String p4KPath});
|
Future<void> crateApiUnp4KApiP4KOpen({required String p4KPath});
|
||||||
|
|
||||||
|
Future<ApplinksRegistrationResult> crateApiApplinksApiRegisterApplinks({
|
||||||
|
required String scheme,
|
||||||
|
String? appName,
|
||||||
|
});
|
||||||
|
|
||||||
Future<void> crateApiWin32ApiRemoveNvmePatch();
|
Future<void> crateApiWin32ApiRemoveNvmePatch();
|
||||||
|
|
||||||
Future<String> crateApiWin32ApiResolveShortcut({required String lnkPath});
|
Future<String> crateApiWin32ApiResolveShortcut({required String lnkPath});
|
||||||
@ -320,6 +329,10 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
|
|
||||||
Future<void> crateApiOrtApiUnloadTranslationModel({required String modelKey});
|
Future<void> crateApiOrtApiUnloadTranslationModel({required String modelKey});
|
||||||
|
|
||||||
|
Future<ApplinksRegistrationResult> crateApiApplinksApiUnregisterApplinks({
|
||||||
|
required String scheme,
|
||||||
|
});
|
||||||
|
|
||||||
Future<WebViewConfiguration> crateApiWebviewApiWebViewConfigurationDefault();
|
Future<WebViewConfiguration> crateApiWebviewApiWebViewConfigurationDefault();
|
||||||
|
|
||||||
Future<WebViewNavigationState>
|
Future<WebViewNavigationState>
|
||||||
@ -411,6 +424,36 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
TaskConstMeta get kCrateApiWin32ApiAddNvmePatchConstMeta =>
|
TaskConstMeta get kCrateApiWin32ApiAddNvmePatchConstMeta =>
|
||||||
const TaskConstMeta(debugName: "add_nvme_patch", argNames: []);
|
const TaskConstMeta(debugName: "add_nvme_patch", argNames: []);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ApplinksRegistrationResult>
|
||||||
|
crateApiApplinksApiCheckApplinksRegistration({required String scheme}) {
|
||||||
|
return handler.executeNormal(
|
||||||
|
NormalTask(
|
||||||
|
callFfi: (port_) {
|
||||||
|
var arg0 = cst_encode_String(scheme);
|
||||||
|
return wire
|
||||||
|
.wire__crate__api__applinks_api__check_applinks_registration(
|
||||||
|
port_,
|
||||||
|
arg0,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
codec: DcoCodec(
|
||||||
|
decodeSuccessData: dco_decode_applinks_registration_result,
|
||||||
|
decodeErrorData: dco_decode_AnyhowException,
|
||||||
|
),
|
||||||
|
constMeta: kCrateApiApplinksApiCheckApplinksRegistrationConstMeta,
|
||||||
|
argValues: [scheme],
|
||||||
|
apiImpl: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskConstMeta get kCrateApiApplinksApiCheckApplinksRegistrationConstMeta =>
|
||||||
|
const TaskConstMeta(
|
||||||
|
debugName: "check_applinks_registration",
|
||||||
|
argNames: ["scheme"],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> crateApiWin32ApiCheckNvmePatchStatus() {
|
Future<bool> crateApiWin32ApiCheckNvmePatchStatus() {
|
||||||
return handler.executeNormal(
|
return handler.executeNormal(
|
||||||
@ -1987,6 +2030,39 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
TaskConstMeta get kCrateApiUnp4KApiP4KOpenConstMeta =>
|
TaskConstMeta get kCrateApiUnp4KApiP4KOpenConstMeta =>
|
||||||
const TaskConstMeta(debugName: "p4k_open", argNames: ["p4KPath"]);
|
const TaskConstMeta(debugName: "p4k_open", argNames: ["p4KPath"]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ApplinksRegistrationResult> crateApiApplinksApiRegisterApplinks({
|
||||||
|
required String scheme,
|
||||||
|
String? appName,
|
||||||
|
}) {
|
||||||
|
return handler.executeNormal(
|
||||||
|
NormalTask(
|
||||||
|
callFfi: (port_) {
|
||||||
|
var arg0 = cst_encode_String(scheme);
|
||||||
|
var arg1 = cst_encode_opt_String(appName);
|
||||||
|
return wire.wire__crate__api__applinks_api__register_applinks(
|
||||||
|
port_,
|
||||||
|
arg0,
|
||||||
|
arg1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
codec: DcoCodec(
|
||||||
|
decodeSuccessData: dco_decode_applinks_registration_result,
|
||||||
|
decodeErrorData: dco_decode_AnyhowException,
|
||||||
|
),
|
||||||
|
constMeta: kCrateApiApplinksApiRegisterApplinksConstMeta,
|
||||||
|
argValues: [scheme, appName],
|
||||||
|
apiImpl: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskConstMeta get kCrateApiApplinksApiRegisterApplinksConstMeta =>
|
||||||
|
const TaskConstMeta(
|
||||||
|
debugName: "register_applinks",
|
||||||
|
argNames: ["scheme", "appName"],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> crateApiWin32ApiRemoveNvmePatch() {
|
Future<void> crateApiWin32ApiRemoveNvmePatch() {
|
||||||
return handler.executeNormal(
|
return handler.executeNormal(
|
||||||
@ -2369,6 +2445,36 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
argNames: ["modelKey"],
|
argNames: ["modelKey"],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ApplinksRegistrationResult> crateApiApplinksApiUnregisterApplinks({
|
||||||
|
required String scheme,
|
||||||
|
}) {
|
||||||
|
return handler.executeNormal(
|
||||||
|
NormalTask(
|
||||||
|
callFfi: (port_) {
|
||||||
|
var arg0 = cst_encode_String(scheme);
|
||||||
|
return wire.wire__crate__api__applinks_api__unregister_applinks(
|
||||||
|
port_,
|
||||||
|
arg0,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
codec: DcoCodec(
|
||||||
|
decodeSuccessData: dco_decode_applinks_registration_result,
|
||||||
|
decodeErrorData: dco_decode_AnyhowException,
|
||||||
|
),
|
||||||
|
constMeta: kCrateApiApplinksApiUnregisterApplinksConstMeta,
|
||||||
|
argValues: [scheme],
|
||||||
|
apiImpl: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskConstMeta get kCrateApiApplinksApiUnregisterApplinksConstMeta =>
|
||||||
|
const TaskConstMeta(
|
||||||
|
debugName: "unregister_applinks",
|
||||||
|
argNames: ["scheme"],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<WebViewConfiguration> crateApiWebviewApiWebViewConfigurationDefault() {
|
Future<WebViewConfiguration> crateApiWebviewApiWebViewConfigurationDefault() {
|
||||||
return handler.executeNormal(
|
return handler.executeNormal(
|
||||||
@ -2869,6 +2975,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return raw as String;
|
return raw as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ApplinksRegistrationResult dco_decode_applinks_registration_result(
|
||||||
|
dynamic raw,
|
||||||
|
) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
final arr = raw as List<dynamic>;
|
||||||
|
if (arr.length != 3)
|
||||||
|
throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
|
||||||
|
return ApplinksRegistrationResult(
|
||||||
|
success: dco_decode_bool(arr[0]),
|
||||||
|
message: dco_decode_String(arr[1]),
|
||||||
|
wasModified: dco_decode_bool(arr[2]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
bool dco_decode_bool(dynamic raw) {
|
bool dco_decode_bool(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@ -3347,6 +3468,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return utf8.decoder.convert(inner);
|
return utf8.decoder.convert(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ApplinksRegistrationResult sse_decode_applinks_registration_result(
|
||||||
|
SseDeserializer deserializer,
|
||||||
|
) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
var var_success = sse_decode_bool(deserializer);
|
||||||
|
var var_message = sse_decode_String(deserializer);
|
||||||
|
var var_wasModified = sse_decode_bool(deserializer);
|
||||||
|
return ApplinksRegistrationResult(
|
||||||
|
success: var_success,
|
||||||
|
message: var_message,
|
||||||
|
wasModified: var_wasModified,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
bool sse_decode_bool(SseDeserializer deserializer) {
|
bool sse_decode_bool(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@ -4047,6 +4183,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
|
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_applinks_registration_result(
|
||||||
|
ApplinksRegistrationResult self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_bool(self.success, serializer);
|
||||||
|
sse_encode_String(self.message, serializer);
|
||||||
|
sse_encode_bool(self.wasModified, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_bool(bool self, SseSerializer serializer) {
|
void sse_encode_bool(bool self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
|
import 'api/applinks_api.dart';
|
||||||
import 'api/asar_api.dart';
|
import 'api/asar_api.dart';
|
||||||
import 'api/downloader_api.dart';
|
import 'api/downloader_api.dart';
|
||||||
import 'api/http_api.dart';
|
import 'api/http_api.dart';
|
||||||
@ -39,6 +40,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw);
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ApplinksRegistrationResult dco_decode_applinks_registration_result(
|
||||||
|
dynamic raw,
|
||||||
|
);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
bool dco_decode_bool(dynamic raw);
|
bool dco_decode_bool(dynamic raw);
|
||||||
|
|
||||||
@ -216,6 +222,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer);
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ApplinksRegistrationResult sse_decode_applinks_registration_result(
|
||||||
|
SseDeserializer deserializer,
|
||||||
|
);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
bool sse_decode_bool(SseDeserializer deserializer);
|
bool sse_decode_bool(SseDeserializer deserializer);
|
||||||
|
|
||||||
@ -672,6 +683,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
return raw.toSigned(64).toInt();
|
return raw.toSigned(64).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void cst_api_fill_to_wire_applinks_registration_result(
|
||||||
|
ApplinksRegistrationResult apiObj,
|
||||||
|
wire_cst_applinks_registration_result wireObj,
|
||||||
|
) {
|
||||||
|
wireObj.success = cst_encode_bool(apiObj.success);
|
||||||
|
wireObj.message = cst_encode_String(apiObj.message);
|
||||||
|
wireObj.was_modified = cst_encode_bool(apiObj.wasModified);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void cst_api_fill_to_wire_box_autoadd_rsi_launcher_asar_data(
|
void cst_api_fill_to_wire_box_autoadd_rsi_launcher_asar_data(
|
||||||
RsiLauncherAsarData apiObj,
|
RsiLauncherAsarData apiObj,
|
||||||
@ -946,6 +967,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer);
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_applinks_registration_result(
|
||||||
|
ApplinksRegistrationResult self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_bool(bool self, SseSerializer serializer);
|
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||||
|
|
||||||
@ -1227,6 +1254,33 @@ class RustLibWire implements BaseWire {
|
|||||||
_wire__crate__api__win32_api__add_nvme_patchPtr
|
_wire__crate__api__win32_api__add_nvme_patchPtr
|
||||||
.asFunction<void Function(int)>();
|
.asFunction<void Function(int)>();
|
||||||
|
|
||||||
|
void wire__crate__api__applinks_api__check_applinks_registration(
|
||||||
|
int port_,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> scheme,
|
||||||
|
) {
|
||||||
|
return _wire__crate__api__applinks_api__check_applinks_registration(
|
||||||
|
port_,
|
||||||
|
scheme,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _wire__crate__api__applinks_api__check_applinks_registrationPtr =
|
||||||
|
_lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Int64,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
)
|
||||||
|
>
|
||||||
|
>(
|
||||||
|
'frbgen_starcitizen_doctor_wire__crate__api__applinks_api__check_applinks_registration',
|
||||||
|
);
|
||||||
|
late final _wire__crate__api__applinks_api__check_applinks_registration =
|
||||||
|
_wire__crate__api__applinks_api__check_applinks_registrationPtr
|
||||||
|
.asFunction<
|
||||||
|
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
||||||
|
>();
|
||||||
|
|
||||||
void wire__crate__api__win32_api__check_nvme_patch_status(int port_) {
|
void wire__crate__api__win32_api__check_nvme_patch_status(int port_) {
|
||||||
return _wire__crate__api__win32_api__check_nvme_patch_status(port_);
|
return _wire__crate__api__win32_api__check_nvme_patch_status(port_);
|
||||||
}
|
}
|
||||||
@ -2453,6 +2507,40 @@ class RustLibWire implements BaseWire {
|
|||||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
void wire__crate__api__applinks_api__register_applinks(
|
||||||
|
int port_,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> scheme,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> app_name,
|
||||||
|
) {
|
||||||
|
return _wire__crate__api__applinks_api__register_applinks(
|
||||||
|
port_,
|
||||||
|
scheme,
|
||||||
|
app_name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _wire__crate__api__applinks_api__register_applinksPtr =
|
||||||
|
_lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Int64,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
)
|
||||||
|
>
|
||||||
|
>(
|
||||||
|
'frbgen_starcitizen_doctor_wire__crate__api__applinks_api__register_applinks',
|
||||||
|
);
|
||||||
|
late final _wire__crate__api__applinks_api__register_applinks =
|
||||||
|
_wire__crate__api__applinks_api__register_applinksPtr
|
||||||
|
.asFunction<
|
||||||
|
void Function(
|
||||||
|
int,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
)
|
||||||
|
>();
|
||||||
|
|
||||||
void wire__crate__api__win32_api__remove_nvme_patch(int port_) {
|
void wire__crate__api__win32_api__remove_nvme_patch(int port_) {
|
||||||
return _wire__crate__api__win32_api__remove_nvme_patch(port_);
|
return _wire__crate__api__win32_api__remove_nvme_patch(port_);
|
||||||
}
|
}
|
||||||
@ -2467,9 +2555,9 @@ class RustLibWire implements BaseWire {
|
|||||||
|
|
||||||
void wire__crate__api__win32_api__resolve_shortcut(
|
void wire__crate__api__win32_api__resolve_shortcut(
|
||||||
int port_,
|
int port_,
|
||||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> _lnk_path,
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> lnk_path,
|
||||||
) {
|
) {
|
||||||
return _wire__crate__api__win32_api__resolve_shortcut(port_, _lnk_path);
|
return _wire__crate__api__win32_api__resolve_shortcut(port_, lnk_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _wire__crate__api__win32_api__resolve_shortcutPtr =
|
late final _wire__crate__api__win32_api__resolve_shortcutPtr =
|
||||||
@ -2799,6 +2887,30 @@ class RustLibWire implements BaseWire {
|
|||||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
void wire__crate__api__applinks_api__unregister_applinks(
|
||||||
|
int port_,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> scheme,
|
||||||
|
) {
|
||||||
|
return _wire__crate__api__applinks_api__unregister_applinks(port_, scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _wire__crate__api__applinks_api__unregister_applinksPtr =
|
||||||
|
_lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Int64,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
)
|
||||||
|
>
|
||||||
|
>(
|
||||||
|
'frbgen_starcitizen_doctor_wire__crate__api__applinks_api__unregister_applinks',
|
||||||
|
);
|
||||||
|
late final _wire__crate__api__applinks_api__unregister_applinks =
|
||||||
|
_wire__crate__api__applinks_api__unregister_applinksPtr
|
||||||
|
.asFunction<
|
||||||
|
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
||||||
|
>();
|
||||||
|
|
||||||
void wire__crate__api__webview_api__web_view_configuration_default(
|
void wire__crate__api__webview_api__web_view_configuration_default(
|
||||||
int port_,
|
int port_,
|
||||||
) {
|
) {
|
||||||
@ -3721,6 +3833,16 @@ final class wire_cst_list_web_view_event extends ffi.Struct {
|
|||||||
external int len;
|
external int len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class wire_cst_applinks_registration_result extends ffi.Struct {
|
||||||
|
@ffi.Bool()
|
||||||
|
external bool success;
|
||||||
|
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> message;
|
||||||
|
|
||||||
|
@ffi.Bool()
|
||||||
|
external bool was_modified;
|
||||||
|
}
|
||||||
|
|
||||||
final class wire_cst_download_global_stat extends ffi.Struct {
|
final class wire_cst_download_global_stat extends ffi.Struct {
|
||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int download_speed;
|
external int download_speed;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
|
import 'package:flutter_acrylic/flutter_acrylic.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||||
@ -36,10 +37,16 @@ Future<void> main(List<String> args) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initWindow() async {
|
Future<void> _initWindow() async {
|
||||||
|
// Initialize flutter_acrylic before runApp (same as official example)
|
||||||
|
await Window.initialize();
|
||||||
|
await Window.hideWindowControls();
|
||||||
await windowManager.setTitleBarStyle(TitleBarStyle.hidden, windowButtonVisibility: false);
|
await windowManager.setTitleBarStyle(TitleBarStyle.hidden, windowButtonVisibility: false);
|
||||||
await windowManager.setSize(const Size(1280, 810));
|
await windowManager.setSize(const Size(1280, 810));
|
||||||
await windowManager.setMinimumSize(const Size(1280, 810));
|
await windowManager.setMinimumSize(const Size(1280, 810));
|
||||||
await windowManager.center(animate: true);
|
await windowManager.center(animate: true);
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
await Window.setEffect(effect: WindowEffect.transparent, color: Colors.transparent, dark: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends HookConsumerWidget with WindowListener {
|
class App extends HookConsumerWidget with WindowListener {
|
||||||
|
|||||||
@ -44,7 +44,7 @@ final class PartyRoomProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$partyRoomHash() => r'3247b6ea5482a8938f118c2d0d6f9ecf2e55fba7';
|
String _$partyRoomHash() => r'446e4cc88be96c890f8e676c6faf0e4d3b33a529';
|
||||||
|
|
||||||
/// PartyRoom Provider
|
/// PartyRoom Provider
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ final class Unp4kCModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$unp4kCModelHash() => r'68c24d50113e9e734ae8d277f65999bbef05dc05';
|
String _$unp4kCModelHash() => r'6713e8e95e2bec1adcb36b63f6c6f9240a5959be';
|
||||||
|
|
||||||
abstract class _$Unp4kCModel extends $Notifier<Unp4kcState> {
|
abstract class _$Unp4kCModel extends $Notifier<Unp4kcState> {
|
||||||
Unp4kcState build();
|
Unp4kcState build();
|
||||||
|
|||||||
@ -59,7 +59,7 @@ final class AuthUIModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$authUIModelHash() => r'cef2bc3fecb2c52e507fa24bc352b4553d918a38';
|
String _$authUIModelHash() => r'485bf56e488ba01cd1371131e6d92077c76176df';
|
||||||
|
|
||||||
final class AuthUIModelFamily extends $Family
|
final class AuthUIModelFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
@ -42,7 +42,7 @@ final class LocalizationUIModelProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$localizationUIModelHash() =>
|
String _$localizationUIModelHash() =>
|
||||||
r'7b398d3b2ddd306ff8f328be39f28200fe8bf49e';
|
r'34bfb83eb271b16d24a10219bbf86fc4b873f9aa';
|
||||||
|
|
||||||
abstract class _$LocalizationUIModel extends $Notifier<LocalizationUIState> {
|
abstract class _$LocalizationUIModel extends $Notifier<LocalizationUIState> {
|
||||||
LocalizationUIState build();
|
LocalizationUIState build();
|
||||||
|
|||||||
@ -41,7 +41,7 @@ final class SettingsUIModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$settingsUIModelHash() => r'c448be241a29891e90d8f17bef9e7f61d66c05be';
|
String _$settingsUIModelHash() => r'302b8ce09601218c28c0cf2bd133f1749ec471dc';
|
||||||
|
|
||||||
abstract class _$SettingsUIModel extends $Notifier<SettingsUIState> {
|
abstract class _$SettingsUIModel extends $Notifier<SettingsUIState> {
|
||||||
SettingsUIState build();
|
SettingsUIState build();
|
||||||
|
|||||||
@ -41,7 +41,7 @@ final class ToolsUIModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$toolsUIModelHash() => r'2b0c851c677a03a88c02f6f9d146624d505e974f';
|
String _$toolsUIModelHash() => r'85ccd6ff3fe9622f9d2bfbf3c8385fd8c9363e7e';
|
||||||
|
|
||||||
abstract class _$ToolsUIModel extends $Notifier<ToolsUIState> {
|
abstract class _$ToolsUIModel extends $Notifier<ToolsUIState> {
|
||||||
ToolsUIState build();
|
ToolsUIState build();
|
||||||
|
|||||||
400
rust/src/api/applinks_api.rs
Normal file
400
rust/src/api/applinks_api.rs
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
/// Applinks URL scheme registration result
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ApplinksRegistrationResult {
|
||||||
|
/// Whether registration was successful
|
||||||
|
pub success: bool,
|
||||||
|
/// Detailed message about the operation
|
||||||
|
pub message: String,
|
||||||
|
/// Whether the registry was modified (false if already configured correctly)
|
||||||
|
pub was_modified: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the URL scheme is already registered with the correct executable path
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn check_applinks_registration(scheme: String) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
use windows::core::{HSTRING, PCWSTR};
|
||||||
|
use windows::Win32::System::Registry::{
|
||||||
|
RegCloseKey, RegOpenKeyExW, RegQueryValueExW, HKEY_CURRENT_USER, KEY_READ,
|
||||||
|
REG_VALUE_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
let app_path = env::current_exe()
|
||||||
|
.map_err(|e| anyhow::anyhow!("Failed to get current executable path: {}", e))?
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let expected_command = format!("\"{}\" \"%1\"", app_path);
|
||||||
|
let protocol_key_path = format!("Software\\Classes\\{}", scheme);
|
||||||
|
let command_key_path = format!("{}\\shell\\open\\command", protocol_key_path);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Check if URL Protocol value exists
|
||||||
|
let mut protocol_key = std::mem::zeroed();
|
||||||
|
let protocol_key_hstring = HSTRING::from(&protocol_key_path);
|
||||||
|
|
||||||
|
if RegOpenKeyExW(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
PCWSTR(protocol_key_hstring.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
KEY_READ,
|
||||||
|
&mut protocol_key,
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!("URL scheme '{}' is not registered", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check URL Protocol value
|
||||||
|
let url_protocol_name = HSTRING::from("URL Protocol");
|
||||||
|
let mut data_type: REG_VALUE_TYPE = REG_VALUE_TYPE::default();
|
||||||
|
let mut data_size: u32 = 0;
|
||||||
|
|
||||||
|
if RegQueryValueExW(
|
||||||
|
protocol_key,
|
||||||
|
PCWSTR(url_protocol_name.as_ptr()),
|
||||||
|
None,
|
||||||
|
Some(&mut data_type),
|
||||||
|
None,
|
||||||
|
Some(&mut data_size),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(protocol_key);
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!("URL Protocol value not found for scheme '{}'", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = RegCloseKey(protocol_key);
|
||||||
|
|
||||||
|
// Check command key
|
||||||
|
let mut command_key = std::mem::zeroed();
|
||||||
|
let command_key_hstring = HSTRING::from(&command_key_path);
|
||||||
|
|
||||||
|
if RegOpenKeyExW(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
PCWSTR(command_key_hstring.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
KEY_READ,
|
||||||
|
&mut command_key,
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!("Command key not found for scheme '{}'", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read command value (default value with empty name)
|
||||||
|
let empty_name = HSTRING::from("");
|
||||||
|
let mut data_size: u32 = 0;
|
||||||
|
|
||||||
|
if RegQueryValueExW(
|
||||||
|
command_key,
|
||||||
|
PCWSTR(empty_name.as_ptr()),
|
||||||
|
None,
|
||||||
|
Some(&mut data_type),
|
||||||
|
None,
|
||||||
|
Some(&mut data_size),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
|| data_size == 0
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(command_key);
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!("Command value not found for scheme '{}'", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the actual command value
|
||||||
|
let mut buffer: Vec<u8> = vec![0; data_size as usize];
|
||||||
|
if RegQueryValueExW(
|
||||||
|
command_key,
|
||||||
|
PCWSTR(empty_name.as_ptr()),
|
||||||
|
None,
|
||||||
|
Some(&mut data_type),
|
||||||
|
Some(buffer.as_mut_ptr()),
|
||||||
|
Some(&mut data_size),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(command_key);
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!("Failed to read command value for scheme '{}'", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = RegCloseKey(command_key);
|
||||||
|
|
||||||
|
// Convert buffer to string (UTF-16 to UTF-8)
|
||||||
|
let command_value = String::from_utf16_lossy(
|
||||||
|
&buffer
|
||||||
|
.chunks_exact(2)
|
||||||
|
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
||||||
|
.take_while(|&c| c != 0)
|
||||||
|
.collect::<Vec<u16>>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Compare with expected command (case-insensitive for path)
|
||||||
|
if command_value.to_lowercase() == expected_command.to_lowercase() {
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: true,
|
||||||
|
message: format!("URL scheme '{}' is already registered correctly", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!(
|
||||||
|
"URL scheme '{}' is registered but with different path. Current: '{}', Expected: '{}'",
|
||||||
|
scheme, command_value, expected_command
|
||||||
|
),
|
||||||
|
was_modified: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
pub fn check_applinks_registration(scheme: String) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!(
|
||||||
|
"URL scheme registration check is not supported on this platform for scheme '{}'",
|
||||||
|
scheme
|
||||||
|
),
|
||||||
|
was_modified: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register URL scheme in Windows registry
|
||||||
|
/// This will create or update the registry keys for the custom URL scheme
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `scheme` - The URL scheme to register (e.g., "sctoolbox")
|
||||||
|
/// * `app_name` - Optional application display name (e.g., "SCToolBox"). If provided,
|
||||||
|
/// the registry will show "URL:{app_name} Protocol" as the scheme description.
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn register_applinks(scheme: String, app_name: Option<String>) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
use windows::core::{HSTRING, PCWSTR};
|
||||||
|
use windows::Win32::System::Registry::{
|
||||||
|
RegCloseKey, RegCreateKeyExW, RegSetValueExW, HKEY_CURRENT_USER, KEY_WRITE,
|
||||||
|
REG_CREATE_KEY_DISPOSITION, REG_OPTION_NON_VOLATILE, REG_SZ,
|
||||||
|
};
|
||||||
|
|
||||||
|
// First check if already registered correctly
|
||||||
|
let check_result = check_applinks_registration(scheme.clone())?;
|
||||||
|
if check_result.success {
|
||||||
|
return Ok(check_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
let app_path = env::current_exe()
|
||||||
|
.map_err(|e| anyhow::anyhow!("Failed to get current executable path: {}", e))?
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let command_value = format!("\"{}\" \"%1\"", app_path);
|
||||||
|
let protocol_key_path = format!("Software\\Classes\\{}", scheme);
|
||||||
|
let command_key_path = format!("{}\\shell\\open\\command", protocol_key_path);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Create protocol key
|
||||||
|
let mut protocol_key = std::mem::zeroed();
|
||||||
|
let protocol_key_hstring = HSTRING::from(&protocol_key_path);
|
||||||
|
let mut disposition: REG_CREATE_KEY_DISPOSITION = REG_CREATE_KEY_DISPOSITION::default();
|
||||||
|
|
||||||
|
if RegCreateKeyExW(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
PCWSTR(protocol_key_hstring.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
PCWSTR::null(),
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
KEY_WRITE,
|
||||||
|
None,
|
||||||
|
&mut protocol_key,
|
||||||
|
Some(&mut disposition),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Failed to create registry key '{}'",
|
||||||
|
protocol_key_path
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default value (display name) if app_name is provided
|
||||||
|
if let Some(ref name) = app_name {
|
||||||
|
let display_name = format!("URL:{} Protocol", name);
|
||||||
|
let empty_name = HSTRING::from("");
|
||||||
|
let display_name_bytes: Vec<u8> = display_name
|
||||||
|
.encode_utf16()
|
||||||
|
.chain(std::iter::once(0))
|
||||||
|
.flat_map(|c| c.to_le_bytes())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if RegSetValueExW(
|
||||||
|
protocol_key,
|
||||||
|
PCWSTR(empty_name.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
REG_SZ,
|
||||||
|
Some(&display_name_bytes),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(protocol_key);
|
||||||
|
return Err(anyhow::anyhow!("Failed to set display name value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set URL Protocol value (empty string)
|
||||||
|
let url_protocol_name = HSTRING::from("URL Protocol");
|
||||||
|
let empty_value: [u8; 2] = [0, 0]; // Empty UTF-16 string
|
||||||
|
|
||||||
|
if RegSetValueExW(
|
||||||
|
protocol_key,
|
||||||
|
PCWSTR(url_protocol_name.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
REG_SZ,
|
||||||
|
Some(&empty_value),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(protocol_key);
|
||||||
|
return Err(anyhow::anyhow!("Failed to set URL Protocol value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = RegCloseKey(protocol_key);
|
||||||
|
|
||||||
|
// Create command key
|
||||||
|
let mut command_key = std::mem::zeroed();
|
||||||
|
let command_key_hstring = HSTRING::from(&command_key_path);
|
||||||
|
|
||||||
|
if RegCreateKeyExW(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
PCWSTR(command_key_hstring.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
PCWSTR::null(),
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
KEY_WRITE,
|
||||||
|
None,
|
||||||
|
&mut command_key,
|
||||||
|
Some(&mut disposition),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Failed to create command key '{}'",
|
||||||
|
command_key_path
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set command value
|
||||||
|
let empty_name = HSTRING::from("");
|
||||||
|
let command_bytes: Vec<u8> = command_value
|
||||||
|
.encode_utf16()
|
||||||
|
.chain(std::iter::once(0))
|
||||||
|
.flat_map(|c| c.to_le_bytes())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if RegSetValueExW(
|
||||||
|
command_key,
|
||||||
|
PCWSTR(empty_name.as_ptr()),
|
||||||
|
Some(0),
|
||||||
|
REG_SZ,
|
||||||
|
Some(&command_bytes),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
let _ = RegCloseKey(command_key);
|
||||||
|
return Err(anyhow::anyhow!("Failed to set command value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = RegCloseKey(command_key);
|
||||||
|
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: true,
|
||||||
|
message: format!(
|
||||||
|
"Successfully registered URL scheme '{}' with command '{}'",
|
||||||
|
scheme, command_value
|
||||||
|
),
|
||||||
|
was_modified: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
pub fn register_applinks(scheme: String, _app_name: Option<String>) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!(
|
||||||
|
"URL scheme registration is not supported on this platform for scheme '{}'",
|
||||||
|
scheme
|
||||||
|
),
|
||||||
|
was_modified: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unregister URL scheme from Windows registry
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn unregister_applinks(scheme: String) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
use windows::core::{HSTRING, PCWSTR};
|
||||||
|
use windows::Win32::System::Registry::{RegDeleteTreeW, HKEY_CURRENT_USER};
|
||||||
|
|
||||||
|
let protocol_key_path = format!("Software\\Classes\\{}", scheme);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let protocol_key_hstring = HSTRING::from(&protocol_key_path);
|
||||||
|
|
||||||
|
let result = RegDeleteTreeW(HKEY_CURRENT_USER, PCWSTR(protocol_key_hstring.as_ptr()));
|
||||||
|
|
||||||
|
if result.is_err() {
|
||||||
|
// Check if the key doesn't exist (not an error in this case)
|
||||||
|
let error_code = result.0 as u32;
|
||||||
|
if error_code == 2 {
|
||||||
|
// ERROR_FILE_NOT_FOUND
|
||||||
|
return Ok(ApplinksRegistrationResult {
|
||||||
|
success: true,
|
||||||
|
message: format!("URL scheme '{}' was not registered", scheme),
|
||||||
|
was_modified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Failed to delete registry key '{}': error code {}",
|
||||||
|
protocol_key_path,
|
||||||
|
error_code
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: true,
|
||||||
|
message: format!("Successfully unregistered URL scheme '{}'", scheme),
|
||||||
|
was_modified: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
pub fn unregister_applinks(scheme: String) -> anyhow::Result<ApplinksRegistrationResult> {
|
||||||
|
Ok(ApplinksRegistrationResult {
|
||||||
|
success: false,
|
||||||
|
message: format!(
|
||||||
|
"URL scheme unregistration is not supported on this platform for scheme '{}'",
|
||||||
|
scheme
|
||||||
|
),
|
||||||
|
was_modified: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Do not put code in `mod.rs`, but put in e.g. `simple.rs`.
|
// Do not put code in `mod.rs`, but put in e.g. `simple.rs`.
|
||||||
//
|
//
|
||||||
|
pub mod applinks_api;
|
||||||
pub mod http_api;
|
pub mod http_api;
|
||||||
pub mod rs_process;
|
pub mod rs_process;
|
||||||
pub mod win32_api;
|
pub mod win32_api;
|
||||||
|
|||||||
@ -37,7 +37,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
|||||||
default_rust_auto_opaque = RustAutoOpaqueNom,
|
default_rust_auto_opaque = RustAutoOpaqueNom,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1903117367;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -351025706;
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
||||||
@ -66,6 +66,30 @@ fn wire__crate__api__win32_api__add_nvme_patch_impl(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
fn wire__crate__api__applinks_api__check_applinks_registration_impl(
|
||||||
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
|
scheme: impl CstDecode<String>,
|
||||||
|
) {
|
||||||
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||||
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
|
debug_name: "check_applinks_registration",
|
||||||
|
port: Some(port_),
|
||||||
|
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||||
|
},
|
||||||
|
move || {
|
||||||
|
let api_scheme = scheme.cst_decode();
|
||||||
|
move |context| {
|
||||||
|
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
|
||||||
|
(move || {
|
||||||
|
let output_ok =
|
||||||
|
crate::api::applinks_api::check_applinks_registration(api_scheme)?;
|
||||||
|
Ok(output_ok)
|
||||||
|
})(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
fn wire__crate__api__win32_api__check_nvme_patch_status_impl(
|
fn wire__crate__api__win32_api__check_nvme_patch_status_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
) {
|
) {
|
||||||
@ -1462,6 +1486,32 @@ fn wire__crate__api__unp4k_api__p4k_open_impl(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
fn wire__crate__api__applinks_api__register_applinks_impl(
|
||||||
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
|
scheme: impl CstDecode<String>,
|
||||||
|
app_name: impl CstDecode<Option<String>>,
|
||||||
|
) {
|
||||||
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||||
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
|
debug_name: "register_applinks",
|
||||||
|
port: Some(port_),
|
||||||
|
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||||
|
},
|
||||||
|
move || {
|
||||||
|
let api_scheme = scheme.cst_decode();
|
||||||
|
let api_app_name = app_name.cst_decode();
|
||||||
|
move |context| {
|
||||||
|
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
|
||||||
|
(move || {
|
||||||
|
let output_ok =
|
||||||
|
crate::api::applinks_api::register_applinks(api_scheme, api_app_name)?;
|
||||||
|
Ok(output_ok)
|
||||||
|
})(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
fn wire__crate__api__win32_api__remove_nvme_patch_impl(
|
fn wire__crate__api__win32_api__remove_nvme_patch_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
) {
|
) {
|
||||||
@ -1485,7 +1535,7 @@ fn wire__crate__api__win32_api__remove_nvme_patch_impl(
|
|||||||
}
|
}
|
||||||
fn wire__crate__api__win32_api__resolve_shortcut_impl(
|
fn wire__crate__api__win32_api__resolve_shortcut_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
_lnk_path: impl CstDecode<String>,
|
lnk_path: impl CstDecode<String>,
|
||||||
) {
|
) {
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||||
flutter_rust_bridge::for_generated::TaskInfo {
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
@ -1494,11 +1544,11 @@ fn wire__crate__api__win32_api__resolve_shortcut_impl(
|
|||||||
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
let api__lnk_path = _lnk_path.cst_decode();
|
let api_lnk_path = lnk_path.cst_decode();
|
||||||
move |context| {
|
move |context| {
|
||||||
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
|
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
|
||||||
(move || {
|
(move || {
|
||||||
let output_ok = crate::api::win32_api::resolve_shortcut(api__lnk_path)?;
|
let output_ok = crate::api::win32_api::resolve_shortcut(api_lnk_path)?;
|
||||||
Ok(output_ok)
|
Ok(output_ok)
|
||||||
})(),
|
})(),
|
||||||
)
|
)
|
||||||
@ -1788,6 +1838,29 @@ fn wire__crate__api__ort_api__unload_translation_model_impl(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
fn wire__crate__api__applinks_api__unregister_applinks_impl(
|
||||||
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
|
scheme: impl CstDecode<String>,
|
||||||
|
) {
|
||||||
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||||
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
|
debug_name: "unregister_applinks",
|
||||||
|
port: Some(port_),
|
||||||
|
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||||
|
},
|
||||||
|
move || {
|
||||||
|
let api_scheme = scheme.cst_decode();
|
||||||
|
move |context| {
|
||||||
|
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
|
||||||
|
(move || {
|
||||||
|
let output_ok = crate::api::applinks_api::unregister_applinks(api_scheme)?;
|
||||||
|
Ok(output_ok)
|
||||||
|
})(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
fn wire__crate__api__webview_api__web_view_configuration_default_impl(
|
fn wire__crate__api__webview_api__web_view_configuration_default_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
) {
|
) {
|
||||||
@ -2296,6 +2369,20 @@ impl SseDecode for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode for crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
|
let mut var_success = <bool>::sse_decode(deserializer);
|
||||||
|
let mut var_message = <String>::sse_decode(deserializer);
|
||||||
|
let mut var_wasModified = <bool>::sse_decode(deserializer);
|
||||||
|
return crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
success: var_success,
|
||||||
|
message: var_message,
|
||||||
|
was_modified: var_wasModified,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for bool {
|
impl SseDecode for bool {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@ -2940,6 +3027,28 @@ fn pde_ffi_dispatcher_sync_impl(
|
|||||||
|
|
||||||
// Section: rust2dart
|
// Section: rust2dart
|
||||||
|
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
impl flutter_rust_bridge::IntoDart for crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
|
[
|
||||||
|
self.success.into_into_dart().into_dart(),
|
||||||
|
self.message.into_into_dart().into_dart(),
|
||||||
|
self.was_modified.into_into_dart().into_dart(),
|
||||||
|
]
|
||||||
|
.into_dart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
|
||||||
|
for crate::api::applinks_api::ApplinksRegistrationResult
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl flutter_rust_bridge::IntoIntoDart<crate::api::applinks_api::ApplinksRegistrationResult>
|
||||||
|
for crate::api::applinks_api::ApplinksRegistrationResult
|
||||||
|
{
|
||||||
|
fn into_into_dart(self) -> crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
impl flutter_rust_bridge::IntoDart for crate::api::unp4k_api::DcbRecordItem {
|
impl flutter_rust_bridge::IntoDart for crate::api::unp4k_api::DcbRecordItem {
|
||||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
@ -3416,6 +3525,15 @@ impl SseEncode for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode for crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
<bool>::sse_encode(self.success, serializer);
|
||||||
|
<String>::sse_encode(self.message, serializer);
|
||||||
|
<bool>::sse_encode(self.was_modified, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for bool {
|
impl SseEncode for bool {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
@ -3978,6 +4096,18 @@ mod io {
|
|||||||
String::from_utf8(vec).unwrap()
|
String::from_utf8(vec).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<crate::api::applinks_api::ApplinksRegistrationResult>
|
||||||
|
for wire_cst_applinks_registration_result
|
||||||
|
{
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
crate::api::applinks_api::ApplinksRegistrationResult {
|
||||||
|
success: self.success.cst_decode(),
|
||||||
|
message: self.message.cst_decode(),
|
||||||
|
was_modified: self.was_modified.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<bool> for *mut bool {
|
impl CstDecode<bool> for *mut bool {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
fn cst_decode(self) -> bool {
|
fn cst_decode(self) -> bool {
|
||||||
@ -4321,6 +4451,20 @@ mod io {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl NewWithNullPtr for wire_cst_applinks_registration_result {
|
||||||
|
fn new_with_null_ptr() -> Self {
|
||||||
|
Self {
|
||||||
|
success: Default::default(),
|
||||||
|
message: core::ptr::null_mut(),
|
||||||
|
was_modified: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for wire_cst_applinks_registration_result {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new_with_null_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl NewWithNullPtr for wire_cst_dcb_record_item {
|
impl NewWithNullPtr for wire_cst_dcb_record_item {
|
||||||
fn new_with_null_ptr() -> Self {
|
fn new_with_null_ptr() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -4557,6 +4701,14 @@ mod io {
|
|||||||
wire__crate__api__win32_api__add_nvme_patch_impl(port_)
|
wire__crate__api__win32_api__add_nvme_patch_impl(port_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__applinks_api__check_applinks_registration(
|
||||||
|
port_: i64,
|
||||||
|
scheme: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
) {
|
||||||
|
wire__crate__api__applinks_api__check_applinks_registration_impl(port_, scheme)
|
||||||
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__check_nvme_patch_status(
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__check_nvme_patch_status(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
@ -5042,6 +5194,15 @@ mod io {
|
|||||||
wire__crate__api__unp4k_api__p4k_open_impl(port_, p4k_path)
|
wire__crate__api__unp4k_api__p4k_open_impl(port_, p4k_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__applinks_api__register_applinks(
|
||||||
|
port_: i64,
|
||||||
|
scheme: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
app_name: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
) {
|
||||||
|
wire__crate__api__applinks_api__register_applinks_impl(port_, scheme, app_name)
|
||||||
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__remove_nvme_patch(
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__remove_nvme_patch(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
@ -5052,9 +5213,9 @@ mod io {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__resolve_shortcut(
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__win32_api__resolve_shortcut(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
_lnk_path: *mut wire_cst_list_prim_u_8_strict,
|
lnk_path: *mut wire_cst_list_prim_u_8_strict,
|
||||||
) {
|
) {
|
||||||
wire__crate__api__win32_api__resolve_shortcut_impl(port_, _lnk_path)
|
wire__crate__api__win32_api__resolve_shortcut_impl(port_, lnk_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
@ -5154,6 +5315,14 @@ mod io {
|
|||||||
wire__crate__api__ort_api__unload_translation_model_impl(port_, model_key)
|
wire__crate__api__ort_api__unload_translation_model_impl(port_, model_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__applinks_api__unregister_applinks(
|
||||||
|
port_: i64,
|
||||||
|
scheme: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
) {
|
||||||
|
wire__crate__api__applinks_api__unregister_applinks_impl(port_, scheme)
|
||||||
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__webview_api__web_view_configuration_default(
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__webview_api__web_view_configuration_default(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
@ -5467,6 +5636,13 @@ mod io {
|
|||||||
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
|
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_applinks_registration_result {
|
||||||
|
success: bool,
|
||||||
|
message: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
was_modified: bool,
|
||||||
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct wire_cst_dcb_record_item {
|
pub struct wire_cst_dcb_record_item {
|
||||||
|
|||||||
@ -90,7 +90,7 @@ BEGIN
|
|||||||
BLOCK "040904e4"
|
BLOCK "040904e4"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "com.xkeyc.tools.starcitizen.doctor" "\0"
|
VALUE "CompanyName", "com.xkeyc.tools.starcitizen.doctor" "\0"
|
||||||
VALUE "FileDescription", "starcitizen_doctor" "\0"
|
VALUE "FileDescription", "SCToolBox" "\0"
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
||||||
VALUE "InternalName", "starcitizen_doctor" "\0"
|
VALUE "InternalName", "starcitizen_doctor" "\0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2023 com.xkeyc.tools.starcitizen.doctor. All rights reserved." "\0"
|
VALUE "LegalCopyright", "Copyright (C) 2023 com.xkeyc.tools.starcitizen.doctor. All rights reserved." "\0"
|
||||||
|
|||||||
@ -34,9 +34,10 @@ bool FlutterWindow::OnCreate() {
|
|||||||
});
|
});
|
||||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
||||||
|
|
||||||
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
// Window display is now controlled by Dart layer via windowManager.show()
|
||||||
this->Show();
|
// flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
||||||
});
|
// this->Show();
|
||||||
|
// });
|
||||||
|
|
||||||
// Flutter can complete the first frame before the "show window" callback is
|
// Flutter can complete the first frame before the "show window" callback is
|
||||||
// registered. The following call ensures a frame is pending to ensure the
|
// registered. The following call ensures a frame is pending to ensure the
|
||||||
|
|||||||
@ -150,7 +150,9 @@ bool Win32Window::Create(const std::wstring& title,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Win32Window::Show() {
|
bool Win32Window::Show() {
|
||||||
return ShowWindow(window_handle_, SW_SHOWNORMAL);
|
// Use SW_SHOWNOACTIVATE to avoid stealing focus from other windows
|
||||||
|
// This is consistent with bitsdojo_window behavior used in flutter_acrylic example
|
||||||
|
return ShowWindow(window_handle_, SW_SHOWNOACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user