Merge pull request #2102 from Kingtous/master
feat: support create shortcut for peers
This commit is contained in:
		
						commit
						d9dfe2f715
					
				| @ -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<String> _createShortCutAction(String id) { | ||||
|     return MenuEntryButton<String>( | ||||
|       childBuilder: (TextStyle? style) => Text( | ||||
|         translate('Create Desktop Shortcut'), | ||||
|         style: style, | ||||
|       ), | ||||
|       proc: () { | ||||
|         bind.mainCreateShortcut(id: id); | ||||
|       }, | ||||
|       padding: menuPadding, | ||||
|       dismissOnClicked: true, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   @protected | ||||
|   Future<MenuEntryBase<String>> _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 {})); | ||||
|  | ||||
| @ -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<Vec<String>> { | ||||
|     // 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<Vec<String>> { | ||||
|     args.position(|element| { | ||||
| @ -249,6 +255,19 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<Strin | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     #[cfg(not(target_os = "linux"))] | ||||
|     return None; | ||||
|     #[cfg(windows)] | ||||
|     { | ||||
|         use winapi::um::winuser::WM_USER; | ||||
|         let uni_links = format!("rustdesk://connection/new/{}", peer_id); | ||||
|         let res = crate::platform::send_message_to_hnwd( | ||||
|             "FLUTTER_RUNNER_WIN32_WINDOW", | ||||
|             "RustDesk", | ||||
|             (WM_USER + 2) as _, // refered from unilinks desktop pub
 | ||||
|             uni_links.as_str(), | ||||
|             true | ||||
|         ); | ||||
|         return if res { None } else { Some(Vec::new()) }; | ||||
|     } | ||||
|     #[cfg(target_os = "macos")] | ||||
|     return Some(Vec::new()); | ||||
| } | ||||
|  | ||||
| @ -973,6 +973,11 @@ pub fn main_wol(id: String) { | ||||
|     crate::lan::send_wol(id) | ||||
| } | ||||
| 
 | ||||
| pub fn main_create_shortcut(_id: String) { | ||||
|     #[cfg(windows)] | ||||
|     create_shortcut(_id); | ||||
| } | ||||
| 
 | ||||
| pub fn cm_send_chat(conn_id: i32, msg: String) { | ||||
|     crate::ui_cm_interface::send_chat(conn_id, msg); | ||||
| } | ||||
|  | ||||
| @ -1646,3 +1646,39 @@ fn wide_string(s: &str) -> Vec<u16> { | ||||
|         .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; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user