diff --git a/lib/app.dart b/lib/app.dart index a3b9008..ace6461 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -23,7 +23,7 @@ import 'api/api.dart'; import 'common/helper/system_helper.dart'; import 'common/io/rs_http.dart'; import 'common/rust/frb_generated.dart'; -import 'common/rust/api/rs_process.dart' as rs_process; +import 'common/rust/api/win32_api.dart' as win32; import 'data/app_version_data.dart'; import 'generated/no_l10n_strings.dart'; import 'ui/home/downloader/home_downloader_ui.dart'; @@ -158,7 +158,7 @@ class AppGlobalModel extends _$AppGlobalModel { } state = state.copyWith(deviceUUID: deviceUUID, appLocale: locale); } catch (e) { - await rs_process.setForegroundWindow(windowName: "SCToolBox"); + await win32.setForegroundWindow(windowName: "SCToolBox"); dPrint("exit: db is locking ..."); exit(0); } @@ -183,6 +183,7 @@ class AppGlobalModel extends _$AppGlobalModel { // init windows windowManager.waitUntilReadyToShow().then((_) async { + await windowManager.setTitle("SCToolBox"); await windowManager.setSize(const Size(1280, 810)); await windowManager.setMinimumSize(const Size(1280, 810)); await windowManager.setSkipTaskbar(false); diff --git a/lib/common/rust/api/rs_process.dart b/lib/common/rust/api/rs_process.dart index bb6bb14..12b38c4 100644 --- a/lib/common/rust/api/rs_process.dart +++ b/lib/common/rust/api/rs_process.dart @@ -23,10 +23,6 @@ Stream start( Future write({required int rsPid, required String data, dynamic hint}) => RustLib.instance.api.write(rsPid: rsPid, data: data, hint: hint); -Future setForegroundWindow({required String windowName, dynamic hint}) => - RustLib.instance.api - .setForegroundWindow(windowName: windowName, hint: hint); - class RsProcessStreamData { final RsProcessStreamDataType dataType; final String data; diff --git a/lib/common/rust/api/notify_api.dart b/lib/common/rust/api/win32_api.dart similarity index 78% rename from lib/common/rust/api/notify_api.dart rename to lib/common/rust/api/win32_api.dart index 0cb5c0d..91117da 100644 --- a/lib/common/rust/api/notify_api.dart +++ b/lib/common/rust/api/win32_api.dart @@ -18,3 +18,7 @@ Future sendNotify( appName: appName, appId: appId, hint: hint); + +Future setForegroundWindow({required String windowName, dynamic hint}) => + RustLib.instance.api + .setForegroundWindow(windowName: windowName, hint: hint); diff --git a/lib/common/rust/frb_generated.dart b/lib/common/rust/frb_generated.dart index abcfe60..db6f958 100644 --- a/lib/common/rust/frb_generated.dart +++ b/lib/common/rust/frb_generated.dart @@ -4,8 +4,8 @@ // 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/http_api.dart'; -import 'api/notify_api.dart'; import 'api/rs_process.dart'; +import 'api/win32_api.dart'; import 'dart:async'; import 'dart:convert'; import 'frb_generated.io.dart' if (dart.library.html) 'frb_generated.web.dart'; @@ -57,7 +57,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.0.0-dev.32'; @override - int get rustContentHash => -1186168522; + int get rustContentHash => 1453545208; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -83,6 +83,14 @@ abstract class RustLibApi extends BaseApi { Future setDefaultHeader( {required Map headers, dynamic hint}); + Stream start( + {required String executable, + required List arguments, + required String workingDirectory, + dynamic hint}); + + Future write({required int rsPid, required String data, dynamic hint}); + Future sendNotify( {String? summary, String? body, @@ -91,14 +99,6 @@ abstract class RustLibApi extends BaseApi { dynamic hint}); Future setForegroundWindow({required String windowName, dynamic hint}); - - Stream start( - {required String executable, - required List arguments, - required String workingDirectory, - dynamic hint}); - - Future write({required int rsPid, required String data, dynamic hint}); } class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @@ -212,60 +212,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["headers"], ); - @override - Future sendNotify( - {String? summary, - String? body, - String? appName, - String? appId, - dynamic hint}) { - return handler.executeNormal(NormalTask( - callFfi: (port_) { - var arg0 = cst_encode_opt_String(summary); - var arg1 = cst_encode_opt_String(body); - var arg2 = cst_encode_opt_String(appName); - var arg3 = cst_encode_opt_String(appId); - return wire.wire_send_notify(port_, arg0, arg1, arg2, arg3); - }, - codec: DcoCodec( - decodeSuccessData: dco_decode_unit, - decodeErrorData: dco_decode_AnyhowException, - ), - constMeta: kSendNotifyConstMeta, - argValues: [summary, body, appName, appId], - apiImpl: this, - hint: hint, - )); - } - - TaskConstMeta get kSendNotifyConstMeta => const TaskConstMeta( - debugName: "send_notify", - argNames: ["summary", "body", "appName", "appId"], - ); - - @override - Future setForegroundWindow({required String windowName, dynamic hint}) { - return handler.executeNormal(NormalTask( - callFfi: (port_) { - var arg0 = cst_encode_String(windowName); - return wire.wire_set_foreground_window(port_, arg0); - }, - codec: DcoCodec( - decodeSuccessData: dco_decode_bool, - decodeErrorData: dco_decode_AnyhowException, - ), - constMeta: kSetForegroundWindowConstMeta, - argValues: [windowName], - apiImpl: this, - hint: hint, - )); - } - - TaskConstMeta get kSetForegroundWindowConstMeta => const TaskConstMeta( - debugName: "set_foreground_window", - argNames: ["windowName"], - ); - @override Stream start( {required String executable, @@ -322,6 +268,60 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["rsPid", "data"], ); + @override + Future sendNotify( + {String? summary, + String? body, + String? appName, + String? appId, + dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + var arg0 = cst_encode_opt_String(summary); + var arg1 = cst_encode_opt_String(body); + var arg2 = cst_encode_opt_String(appName); + var arg3 = cst_encode_opt_String(appId); + return wire.wire_send_notify(port_, arg0, arg1, arg2, arg3); + }, + codec: DcoCodec( + decodeSuccessData: dco_decode_unit, + decodeErrorData: dco_decode_AnyhowException, + ), + constMeta: kSendNotifyConstMeta, + argValues: [summary, body, appName, appId], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kSendNotifyConstMeta => const TaskConstMeta( + debugName: "send_notify", + argNames: ["summary", "body", "appName", "appId"], + ); + + @override + Future setForegroundWindow({required String windowName, dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + var arg0 = cst_encode_String(windowName); + return wire.wire_set_foreground_window(port_, arg0); + }, + codec: DcoCodec( + decodeSuccessData: dco_decode_bool, + decodeErrorData: dco_decode_AnyhowException, + ), + constMeta: kSetForegroundWindowConstMeta, + argValues: [windowName], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kSetForegroundWindowConstMeta => const TaskConstMeta( + debugName: "set_foreground_window", + argNames: ["windowName"], + ); + @protected AnyhowException dco_decode_AnyhowException(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs diff --git a/lib/common/rust/frb_generated.io.dart b/lib/common/rust/frb_generated.io.dart index 2f05444..c4eb437 100644 --- a/lib/common/rust/frb_generated.io.dart +++ b/lib/common/rust/frb_generated.io.dart @@ -4,8 +4,8 @@ // 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/http_api.dart'; -import 'api/notify_api.dart'; import 'api/rs_process.dart'; +import 'api/win32_api.dart'; import 'dart:async'; import 'dart:convert'; import 'dart:ffi' as ffi; @@ -555,58 +555,6 @@ class RustLibWire implements BaseWire { late final _wire_set_default_header = _wire_set_default_headerPtr.asFunction< void Function(int, ffi.Pointer)>(); - void wire_send_notify( - int port_, - ffi.Pointer summary, - ffi.Pointer body, - ffi.Pointer app_name, - ffi.Pointer app_id, - ) { - return _wire_send_notify( - port_, - summary, - body, - app_name, - app_id, - ); - } - - late final _wire_send_notifyPtr = _lookup< - ffi.NativeFunction< - ffi.Void Function( - ffi.Int64, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer)>>( - 'frbgen_starcitizen_doctor_wire_send_notify'); - late final _wire_send_notify = _wire_send_notifyPtr.asFunction< - void Function( - int, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer)>(); - - void wire_set_foreground_window( - int port_, - ffi.Pointer window_name, - ) { - return _wire_set_foreground_window( - port_, - window_name, - ); - } - - late final _wire_set_foreground_windowPtr = _lookup< - ffi.NativeFunction< - ffi.Void Function( - ffi.Int64, ffi.Pointer)>>( - 'frbgen_starcitizen_doctor_wire_set_foreground_window'); - late final _wire_set_foreground_window = - _wire_set_foreground_windowPtr.asFunction< - void Function(int, ffi.Pointer)>(); - void wire_start( int port_, ffi.Pointer executable, @@ -660,6 +608,58 @@ class RustLibWire implements BaseWire { late final _wire_write = _wire_writePtr.asFunction< void Function(int, int, ffi.Pointer)>(); + void wire_send_notify( + int port_, + ffi.Pointer summary, + ffi.Pointer body, + ffi.Pointer app_name, + ffi.Pointer app_id, + ) { + return _wire_send_notify( + port_, + summary, + body, + app_name, + app_id, + ); + } + + late final _wire_send_notifyPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + ffi.Int64, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>( + 'frbgen_starcitizen_doctor_wire_send_notify'); + late final _wire_send_notify = _wire_send_notifyPtr.asFunction< + void Function( + int, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(); + + void wire_set_foreground_window( + int port_, + ffi.Pointer window_name, + ) { + return _wire_set_foreground_window( + port_, + window_name, + ); + } + + late final _wire_set_foreground_windowPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + ffi.Int64, ffi.Pointer)>>( + 'frbgen_starcitizen_doctor_wire_set_foreground_window'); + late final _wire_set_foreground_window = + _wire_set_foreground_windowPtr.asFunction< + void Function(int, ffi.Pointer)>(); + ffi.Pointer cst_new_box_autoadd_u_64( int value, ) { diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index 3e4002f..d7cb6db 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -16,8 +16,7 @@ import 'package:starcitizen_doctor/common/conf/url_conf.dart'; import 'package:starcitizen_doctor/common/helper/log_helper.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart'; import 'package:starcitizen_doctor/common/io/rs_http.dart'; -import 'package:starcitizen_doctor/common/rust/api/notify_api.dart' - as notify_api; +import 'package:starcitizen_doctor/common/rust/api/win32_api.dart' as win32; import 'package:starcitizen_doctor/common/utils/async.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart'; import 'package:starcitizen_doctor/common/utils/log.dart'; @@ -291,7 +290,7 @@ class HomeUIModel extends _$HomeUIModel { _appUpdateTimer?.cancel(); _appUpdateTimer = null; // 发送通知 - await notify_api.sendNotify( + await win32.sendNotify( summary: S.current.home_localization_new_version_available, body: S.current.home_localization_new_version_installed(updates.first), diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs index 6109034..4db21a5 100644 --- a/rust/src/api/mod.rs +++ b/rust/src/api/mod.rs @@ -4,4 +4,4 @@ pub mod http_api; pub mod rs_process; -pub mod notify_api; +pub mod win32_api; diff --git a/rust/src/api/notify_api.rs b/rust/src/api/notify_api.rs deleted file mode 100644 index 7f65e86..0000000 --- a/rust/src/api/notify_api.rs +++ /dev/null @@ -1,19 +0,0 @@ -use notify_rust::Notification; - -pub fn send_notify(summary: Option, body: Option, app_name: Option, app_id: Option) -> anyhow::Result<()> { - let mut n = Notification::new(); - if let Some(summary) = summary { - n.summary(&summary); - } - if let Some(body) = body { - n.body(&body); - } - if let Some(app_name) = app_name { - n.appname(&app_name); - } - if let Some(app_id) = app_id { - n.app_id(&app_id); - } - n.show()?; - Ok(()) -} \ No newline at end of file diff --git a/rust/src/api/rs_process.rs b/rust/src/api/rs_process.rs index 51309f3..5aacabf 100644 --- a/rust/src/api/rs_process.rs +++ b/rust/src/api/rs_process.rs @@ -9,9 +9,6 @@ use tokio::io::AsyncWriteExt; use tokio::io::BufReader; use tokio::process::ChildStdin; use tokio::sync::Mutex; -use windows::core::{HSTRING, PCWSTR}; -use windows::Win32::Foundation::HWND; -use windows::Win32::UI::WindowsAndMessaging; use crate::frb_generated::StreamSink; @@ -163,18 +160,4 @@ async fn _process_output( }; stream_sink.add(message).unwrap(); } -} - -pub fn set_foreground_window(window_name: &str) -> anyhow::Result { - let window_name_p: PCWSTR = PCWSTR(HSTRING::from(window_name).as_ptr()); - let h = unsafe { WindowsAndMessaging::FindWindowW(PCWSTR::null(), window_name_p) }; - if h == HWND::default() { - return Ok(false); - } - let sr = unsafe { WindowsAndMessaging::ShowWindow(h, WindowsAndMessaging::SW_RESTORE) }; - if !sr.as_bool() { - return Ok(false); - } - let r = unsafe { WindowsAndMessaging::SetForegroundWindow(h) }; - Ok(r.as_bool()) -} +} \ No newline at end of file diff --git a/rust/src/api/win32_api.rs b/rust/src/api/win32_api.rs new file mode 100644 index 0000000..7d3b940 --- /dev/null +++ b/rust/src/api/win32_api.rs @@ -0,0 +1,36 @@ +use notify_rust::Notification; +use windows::core::{HSTRING, PCWSTR}; +use windows::Win32::Foundation::HWND; +use windows::Win32::UI::WindowsAndMessaging; + +pub fn send_notify(summary: Option, body: Option, app_name: Option, app_id: Option) -> anyhow::Result<()> { + let mut n = Notification::new(); + if let Some(summary) = summary { + n.summary(&summary); + } + if let Some(body) = body { + n.body(&body); + } + if let Some(app_name) = app_name { + n.appname(&app_name); + } + if let Some(app_id) = app_id { + n.app_id(&app_id); + } + n.show()?; + Ok(()) +} + +pub fn set_foreground_window(window_name: &str) -> anyhow::Result { + let window_name_p: PCWSTR = PCWSTR(HSTRING::from(window_name).as_ptr()); + let h = unsafe { WindowsAndMessaging::FindWindowW(PCWSTR::null(), window_name_p) }; + if h == HWND::default() { + return Ok(false); + } + let sr = unsafe { WindowsAndMessaging::ShowWindow(h, WindowsAndMessaging::SW_RESTORE) }; + if !sr.as_bool() { + return Ok(false); + } + let r = unsafe { WindowsAndMessaging::SetForegroundWindow(h) }; + Ok(r.as_bool()) +} diff --git a/rust/src/frb_generated.io.rs b/rust/src/frb_generated.io.rs index 999958d..c6f90e5 100644 --- a/rust/src/frb_generated.io.rs +++ b/rust/src/frb_generated.io.rs @@ -204,25 +204,6 @@ pub extern "C" fn frbgen_starcitizen_doctor_wire_set_default_header( wire_set_default_header_impl(port_, headers) } -#[no_mangle] -pub extern "C" fn frbgen_starcitizen_doctor_wire_send_notify( - port_: i64, - summary: *mut wire_cst_list_prim_u_8_strict, - body: *mut wire_cst_list_prim_u_8_strict, - app_name: *mut wire_cst_list_prim_u_8_strict, - app_id: *mut wire_cst_list_prim_u_8_strict, -) { - wire_send_notify_impl(port_, summary, body, app_name, app_id) -} - -#[no_mangle] -pub extern "C" fn frbgen_starcitizen_doctor_wire_set_foreground_window( - port_: i64, - window_name: *mut wire_cst_list_prim_u_8_strict, -) { - wire_set_foreground_window_impl(port_, window_name) -} - #[no_mangle] pub extern "C" fn frbgen_starcitizen_doctor_wire_start( port_: i64, @@ -243,6 +224,25 @@ pub extern "C" fn frbgen_starcitizen_doctor_wire_write( wire_write_impl(port_, rs_pid, data) } +#[no_mangle] +pub extern "C" fn frbgen_starcitizen_doctor_wire_send_notify( + port_: i64, + summary: *mut wire_cst_list_prim_u_8_strict, + body: *mut wire_cst_list_prim_u_8_strict, + app_name: *mut wire_cst_list_prim_u_8_strict, + app_id: *mut wire_cst_list_prim_u_8_strict, +) { + wire_send_notify_impl(port_, summary, body, app_name, app_id) +} + +#[no_mangle] +pub extern "C" fn frbgen_starcitizen_doctor_wire_set_foreground_window( + port_: i64, + window_name: *mut wire_cst_list_prim_u_8_strict, +) { + wire_set_foreground_window_impl(port_, window_name) +} + #[no_mangle] pub extern "C" fn frbgen_starcitizen_doctor_cst_new_box_autoadd_u_64(value: u64) -> *mut u64 { flutter_rust_bridge::for_generated::new_leak_box_ptr(value) diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index 41a9628..f70fe87 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -31,7 +31,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueNom, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.32"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1186168522; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1453545208; // Section: executor @@ -139,57 +139,6 @@ fn wire_set_default_header_impl( }, ) } -fn wire_send_notify_impl( - port_: flutter_rust_bridge::for_generated::MessagePort, - summary: impl CstDecode>, - body: impl CstDecode>, - app_name: impl CstDecode>, - app_id: impl CstDecode>, -) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( - flutter_rust_bridge::for_generated::TaskInfo { - debug_name: "send_notify", - port: Some(port_), - mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, - }, - move || { - let api_summary = summary.cst_decode(); - let api_body = body.cst_decode(); - let api_app_name = app_name.cst_decode(); - let api_app_id = app_id.cst_decode(); - move |context| { - transform_result_dco((move || { - crate::api::notify_api::send_notify( - api_summary, - api_body, - api_app_name, - api_app_id, - ) - })()) - } - }, - ) -} -fn wire_set_foreground_window_impl( - port_: flutter_rust_bridge::for_generated::MessagePort, - window_name: impl CstDecode, -) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( - flutter_rust_bridge::for_generated::TaskInfo { - debug_name: "set_foreground_window", - port: Some(port_), - mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, - }, - move || { - let api_window_name = window_name.cst_decode(); - move |context| { - transform_result_dco((move || { - crate::api::rs_process::set_foreground_window(&api_window_name) - })()) - } - }, - ) -} fn wire_start_impl( port_: flutter_rust_bridge::for_generated::MessagePort, executable: impl CstDecode, @@ -259,6 +208,57 @@ fn wire_write_impl( }, ) } +fn wire_send_notify_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + summary: impl CstDecode>, + body: impl CstDecode>, + app_name: impl CstDecode>, + app_id: impl CstDecode>, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "send_notify", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let api_summary = summary.cst_decode(); + let api_body = body.cst_decode(); + let api_app_name = app_name.cst_decode(); + let api_app_id = app_id.cst_decode(); + move |context| { + transform_result_dco((move || { + crate::api::win32_api::send_notify( + api_summary, + api_body, + api_app_name, + api_app_id, + ) + })()) + } + }, + ) +} +fn wire_set_foreground_window_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + window_name: impl CstDecode, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "set_foreground_window", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let api_window_name = window_name.cst_decode(); + move |context| { + transform_result_dco((move || { + crate::api::win32_api::set_foreground_window(&api_window_name) + })()) + } + }, + ) +} // Section: dart2rust diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index a5ac2b8..f8453d2 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(0, 0); Win32Window::Size size(1280, 720); - if (!window.Create(L"SCToolBox", origin, size)) { + if (!window.Create(L"SCToolBox_init", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true);