From 41b0c77faa2d57a22cce8695672519617c53070a Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 14 Nov 2022 15:41:43 +0800 Subject: [PATCH 1/2] feat: support create shortcut for peers --- flutter/lib/common/widgets/peer_card.dart | 30 +++++++++++++++++++++++ src/core_main.rs | 10 ++++++-- src/flutter_ffi.rs | 5 ++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 5796c7d20..8df84af6c 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common/widgets/address_book.dart'; @@ -446,6 +448,22 @@ abstract class BasePeerCard extends StatelessWidget { ); } + /// Only avaliable on Windows. + @protected + MenuEntryBase _createShortCutAction(String id) { + return MenuEntryButton( + childBuilder: (TextStyle? style) => Text( + translate('Create Desktop Shortcut'), + style: style, + ), + proc: () { + bind.mainCreateShortcut(id: id); + }, + padding: menuPadding, + dismissOnClicked: true, + ); + } + @protected Future> _forceAlwaysRelayAction(String id) async { const option = 'force-always-relay'; @@ -649,6 +667,9 @@ class RecentPeerCard extends BasePeerCard { menuItems.add(_rdpAction(context, peer.id)); } menuItems.add(_wolAction(peer.id)); + if (Platform.isWindows) { + menuItems.add(_createShortCutAction(peer.id)); + } menuItems.add(MenuEntryDivider()); menuItems.add(_renameAction(peer.id, false)); menuItems.add(_removeAction(peer.id, () async { @@ -681,6 +702,9 @@ class FavoritePeerCard extends BasePeerCard { menuItems.add(_rdpAction(context, peer.id)); } menuItems.add(_wolAction(peer.id)); + if (Platform.isWindows) { + menuItems.add(_createShortCutAction(peer.id)); + } menuItems.add(MenuEntryDivider()); menuItems.add(_renameAction(peer.id, false)); menuItems.add(_removeAction(peer.id, () async { @@ -715,6 +739,9 @@ class DiscoveredPeerCard extends BasePeerCard { menuItems.add(_rdpAction(context, peer.id)); } menuItems.add(_wolAction(peer.id)); + if (Platform.isWindows) { + menuItems.add(_createShortCutAction(peer.id)); + } menuItems.add(MenuEntryDivider()); menuItems.add(_removeAction(peer.id, () async {})); return menuItems; @@ -740,6 +767,9 @@ class AddressBookPeerCard extends BasePeerCard { menuItems.add(_rdpAction(context, peer.id)); } menuItems.add(_wolAction(peer.id)); + if (Platform.isWindows) { + menuItems.add(_createShortCutAction(peer.id)); + } menuItems.add(MenuEntryDivider()); menuItems.add(_renameAction(peer.id, false)); menuItems.add(_removeAction(peer.id, () async {})); diff --git a/src/core_main.rs b/src/core_main.rs index d22d4e71b..39b13999e 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -1,6 +1,10 @@ use hbb_common::log; -// shared by flutter and sciter main function +/// shared by flutter and sciter main function +/// +/// [Note] +/// If it returns [`None`], then the process will terminate, and flutter gui will not be started. +/// If it returns [`Some`], then the process will continue, and flutter gui will be started. pub fn core_main() -> Option> { // https://docs.rs/flexi_logger/latest/flexi_logger/error_info/index.html#write // though async logger more efficient, but it also causes more problems, disable it for now @@ -223,6 +227,8 @@ fn import_config(path: &str) { /// /// [Note] /// this is for invoke new connection from dbus. +/// If it returns [`None`], then the process will terminate, and flutter gui will not be started. +/// If it returns [`Some`], then the process will continue, and flutter gui will be started. #[cfg(feature = "flutter")] fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option> { args.position(|element| { @@ -250,5 +256,5 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option Date: Mon, 14 Nov 2022 19:48:42 +0800 Subject: [PATCH 2/2] feat: implement --connect unilinks convert on windows --- src/core_main.rs | 17 +++++++++++++++-- src/platform/windows.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/core_main.rs b/src/core_main.rs index 39b13999e..443ef92ea 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -1,7 +1,7 @@ use hbb_common::log; /// shared by flutter and sciter main function -/// +/// /// [Note] /// If it returns [`None`], then the process will terminate, and flutter gui will not be started. /// If it returns [`Some`], then the process will continue, and flutter gui will be started. @@ -255,6 +255,19 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option Vec { .chain(Some(0).into_iter()) .collect() } + +/// send message to currently shown window +pub fn send_message_to_hnwd( + class_name: &str, + window_name: &str, + dw_data: usize, + data: &str, + show_window: bool, +) -> bool { + unsafe { + let class_name_utf16 = wide_string(class_name); + let window_name_utf16 = wide_string(window_name); + let window = FindWindowW(class_name_utf16.as_ptr(), window_name_utf16.as_ptr()); + if window.is_null() { + log::warn!("no such window {}:{}", class_name, window_name); + return false; + } + let mut data_struct = COPYDATASTRUCT::default(); + data_struct.dwData = dw_data; + let mut data_zero: String = data.chars().chain(Some('\0').into_iter()).collect(); + println!("send {:?}", data_zero); + data_struct.cbData = data_zero.len() as _; + data_struct.lpData = data_zero.as_mut_ptr() as _; + SendMessageW( + window, + WM_COPYDATA, + 0, + &data_struct as *const COPYDATASTRUCT as _, + ); + if show_window { + ShowWindow(window, SW_NORMAL); + SetForegroundWindow(window); + } + } + return true; +}