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/material.dart';
 | 
				
			||||||
import 'package:flutter/services.dart';
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
import 'package:flutter_hbb/common/widgets/address_book.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
 | 
					  @protected
 | 
				
			||||||
  Future<MenuEntryBase<String>> _forceAlwaysRelayAction(String id) async {
 | 
					  Future<MenuEntryBase<String>> _forceAlwaysRelayAction(String id) async {
 | 
				
			||||||
    const option = 'force-always-relay';
 | 
					    const option = 'force-always-relay';
 | 
				
			||||||
@ -649,6 +667,9 @@ class RecentPeerCard extends BasePeerCard {
 | 
				
			|||||||
      menuItems.add(_rdpAction(context, peer.id));
 | 
					      menuItems.add(_rdpAction(context, peer.id));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    menuItems.add(_wolAction(peer.id));
 | 
					    menuItems.add(_wolAction(peer.id));
 | 
				
			||||||
 | 
					    if (Platform.isWindows) {
 | 
				
			||||||
 | 
					      menuItems.add(_createShortCutAction(peer.id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    menuItems.add(MenuEntryDivider());
 | 
					    menuItems.add(MenuEntryDivider());
 | 
				
			||||||
    menuItems.add(_renameAction(peer.id, false));
 | 
					    menuItems.add(_renameAction(peer.id, false));
 | 
				
			||||||
    menuItems.add(_removeAction(peer.id, () async {
 | 
					    menuItems.add(_removeAction(peer.id, () async {
 | 
				
			||||||
@ -681,6 +702,9 @@ class FavoritePeerCard extends BasePeerCard {
 | 
				
			|||||||
      menuItems.add(_rdpAction(context, peer.id));
 | 
					      menuItems.add(_rdpAction(context, peer.id));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    menuItems.add(_wolAction(peer.id));
 | 
					    menuItems.add(_wolAction(peer.id));
 | 
				
			||||||
 | 
					    if (Platform.isWindows) {
 | 
				
			||||||
 | 
					      menuItems.add(_createShortCutAction(peer.id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    menuItems.add(MenuEntryDivider());
 | 
					    menuItems.add(MenuEntryDivider());
 | 
				
			||||||
    menuItems.add(_renameAction(peer.id, false));
 | 
					    menuItems.add(_renameAction(peer.id, false));
 | 
				
			||||||
    menuItems.add(_removeAction(peer.id, () async {
 | 
					    menuItems.add(_removeAction(peer.id, () async {
 | 
				
			||||||
@ -715,6 +739,9 @@ class DiscoveredPeerCard extends BasePeerCard {
 | 
				
			|||||||
      menuItems.add(_rdpAction(context, peer.id));
 | 
					      menuItems.add(_rdpAction(context, peer.id));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    menuItems.add(_wolAction(peer.id));
 | 
					    menuItems.add(_wolAction(peer.id));
 | 
				
			||||||
 | 
					    if (Platform.isWindows) {
 | 
				
			||||||
 | 
					      menuItems.add(_createShortCutAction(peer.id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    menuItems.add(MenuEntryDivider());
 | 
					    menuItems.add(MenuEntryDivider());
 | 
				
			||||||
    menuItems.add(_removeAction(peer.id, () async {}));
 | 
					    menuItems.add(_removeAction(peer.id, () async {}));
 | 
				
			||||||
    return menuItems;
 | 
					    return menuItems;
 | 
				
			||||||
@ -740,6 +767,9 @@ class AddressBookPeerCard extends BasePeerCard {
 | 
				
			|||||||
      menuItems.add(_rdpAction(context, peer.id));
 | 
					      menuItems.add(_rdpAction(context, peer.id));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    menuItems.add(_wolAction(peer.id));
 | 
					    menuItems.add(_wolAction(peer.id));
 | 
				
			||||||
 | 
					    if (Platform.isWindows) {
 | 
				
			||||||
 | 
					      menuItems.add(_createShortCutAction(peer.id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    menuItems.add(MenuEntryDivider());
 | 
					    menuItems.add(MenuEntryDivider());
 | 
				
			||||||
    menuItems.add(_renameAction(peer.id, false));
 | 
					    menuItems.add(_renameAction(peer.id, false));
 | 
				
			||||||
    menuItems.add(_removeAction(peer.id, () async {}));
 | 
					    menuItems.add(_removeAction(peer.id, () async {}));
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,10 @@
 | 
				
			|||||||
use hbb_common::log;
 | 
					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>> {
 | 
					pub fn core_main() -> Option<Vec<String>> {
 | 
				
			||||||
    // https://docs.rs/flexi_logger/latest/flexi_logger/error_info/index.html#write
 | 
					    // 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
 | 
					    // 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]
 | 
					/// [Note]
 | 
				
			||||||
/// this is for invoke new connection from dbus.
 | 
					/// 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")]
 | 
					#[cfg(feature = "flutter")]
 | 
				
			||||||
fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<String>> {
 | 
					fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<String>> {
 | 
				
			||||||
    args.position(|element| {
 | 
					    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"))]
 | 
					    #[cfg(windows)]
 | 
				
			||||||
    return None;
 | 
					    {
 | 
				
			||||||
 | 
					        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)
 | 
					    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) {
 | 
					pub fn cm_send_chat(conn_id: i32, msg: String) {
 | 
				
			||||||
    crate::ui_cm_interface::send_chat(conn_id, msg);
 | 
					    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())
 | 
					        .chain(Some(0).into_iter())
 | 
				
			||||||
        .collect()
 | 
					        .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