diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 4b6cf2a62..67eb0234b 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -278,6 +278,8 @@ class _GeneralState extends State<_General> { _OptionCheckBox(context, 'Confirm before closing multiple tabs', 'enable-confirm-closing-tabs'), _OptionCheckBox(context, 'Adaptive Bitrate', 'enable-abr'), + if (Platform.isMacOS) + _OptionCheckBox(context, 'Swap control-command key', 'allow-swap-key'), if (Platform.isLinux) Tooltip( message: translate('software_render_tip'), diff --git a/memo.txt b/memo.txt new file mode 100644 index 000000000..da23ae423 --- /dev/null +++ b/memo.txt @@ -0,0 +1,104 @@ +#windows +python3 res/inline-sciter.py +cargo build --release --features inline,with_rc --target=aarch64-pc-windows-msvc -vv + +Push-Location flutter ; flutter pub get ; Pop-Location +~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart + +%comspec% /k "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" +rustup update +rustup target add aarch64-pc-windows-msvc +rustup target list + +reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug" /v Auto /t REG_DWORD /d 1 /f +reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\rustdesk.exe" /v Debugger /t REG_SZ /d "vsjitdebugger.exe" /f + +#macos +pushd flutter && flutter pub get && popd +~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart +./build.py --flutter +codesign --force --options runtime -s "Developer ID Application" --deep ./flutter/build/macos/Build/Products/Release/RustDesk.app -v +rm -r /Applications/RustDesk.app +cp -r ./flutter/build/macos/Build/Products/Release/RustDesk.app /Applications/RustDesk.app +open -n /Applications/RustDesk.app --args --server + +cargo bundle --release --features inline +cp libsciter.dylib target/release/bundle/osx/RustDesk.app/Contents/MacOS +mv target/release/bundle/osx/RustDesk.app/Contents/Resources/res/* target/release/bundle/osx/RustDesk.app/Contents/Resources +rm -rf target/release/bundle/osx/RustDesk.app/Contents/Resources/res +target/release/bundle/osx/RustDesk.app/Contents/Info.plist + LSUIElement + 1 + +python3 res/inline-sciter.py +cargo build --release --features inline +cp target/release/rustdesk ../Documents/RustDesk.app/Contents/MacOS/rustdesk +codesign -s "Developer ID Application" --force --options runtime ../Documents/RustDesk.app/Contents/MacOS/* +codesign -s "Developer ID Application" --force --options runtime ../Documents/RustDesk.app +rm -r /Applications/RustDesk.app +cp -r ../Documents/RustDesk.app /Applications/RustDesk.app + +csrutil disable +file target\release\rustdesk +sudo lsof -i -n -P | grep rustdesk // netstat +https://github.com/create-dmg/create-dmg +security find-identity -p basic -v + +#android +BINDGEN_EXTRA_CLANG_ARGS_aarch64_linux_android="--target=arm64-apple-macos --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" RUST_LOG=debug cargo ndk --platform 21 --target aarch64-linux-android rustc --lib --features flutter --release +cp target/aarch64-linux-android/release/liblibrustdesk.so flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so +pushd flutter; flutter build apk --target-platform android-arm64 --release; popd +adb install flutter/build/app/outputs/flutter-apk/app-release.apk + +sudo mount -t drvfs '\\192.168.111.10\Macintosh HD' /mnt/mac +cp target/aarch64-linux-android/debug/liblibrustdesk.so /mnt/mac/Users/sjpark/rustdesk/flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so + +adb logcat | grep LOG_SERVICE +adb emu kill + +sudo apt install build-essential +sudo apt install gcc-multilib + +#ios +flutter/ios/Runnder.xcworkspace/View/Navigators/Project/targets:Runner/Signing & Capability/Teams +cargo build --target aarch64-apple-ios --features flutter --release +pushd flutter; flutter build ios --release; popd +xcode/Window/Devices and Simulators/INSTALLED APPS + +xcrun simctl list +open -a Simulator --args -CurrentDeviceUDID 5D1C39DD-708B-41D3-B89A-3F0D9B8E42BF + +# rustdesk +cd C:\Users\sjpark\Documents\rustdesk +set VCPKG_ROOT=C:\Users\sjpark\Documents\vcpkg +set LIBCLANG_PATH=C:\Program Files\LLVM\bin + +# ring +set path=C:\Program Files\LLVM\bin;C:\Strawberry\perl\bin\;%path%; +.\target\tools\windows\nasm\nasm.exe +set RING_PREGENERATE_ASM=1 + +#dependencies +ring = { git = "https://github.com/sj6219/ring", branch = "0.16.20_alpha" } + + +adb shell dumpsys package com.carriez.flutter_hbb +objdump -T ~/rustdesk/target/aarch64-linux-android/release/liblibrustdesk.so + +cat /Users/sjpark/Library/Android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/11.0.5/lib/linux/aarch64/lldb-server | adb shell sh -c 'cat > /data/local/tmp/lldb-server && chmod 755 /data/local/tmp/lldb-server' +adb shell run-as com.carriez.flutter_hbb mkdir -p /data/data/com.carriez.flutter_hbb/lldb/bin/ +adb shell "cat /data/local/tmp/lldb-server | run-as com.carriez.flutter_hbb sh -c 'cat > /data/data/com.carriez.flutter_hbb/lldb/bin/lldb-server && chmod 755 /data/data/com.carriez.flutter_hbb/lldb/bin/lldb-server'" + +adb shell ps -e -o PID -o NAME | grep com.carriez.flutter_hbb +adb forward tcp:10086 tcp:10086 +adb shell run-as com.carriez.flutter_hbb /data/data/com.carriez.flutter_hbb/lldb/bin/lldb-server platform --listen "*:10086" --server + +/Users/sjpark/Library/Android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/darwin-x86_64/bin/lldb +platform select remote-android +platform connect connect://localhost:10086 +attach +b connection.rs:624 + +add-dsym /Users/sjpark/ndk-samples/hello-gl2/app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/libgl2jni.so +b gl_code.cpp:151 + diff --git a/src/flutter.rs b/src/flutter.rs index 2d7d3fb86..bee585d93 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -428,8 +428,10 @@ pub fn session_add( let session_id = get_session_id(id.to_owned()); LocalConfig::set_remote_id(&session_id); + let allow_swap_key = hbb_common::config::Config::get_option("allow-swap-key") == "Y"; let session: Session = Session { id: session_id.clone(), + allow_swap_key, ..Default::default() }; diff --git a/src/keyboard.rs b/src/keyboard.rs index 91480ba30..2764a4408 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -210,6 +210,53 @@ pub fn start_grab_loop() { if key == Key::CapsLock || key == Key::NumLock { return Some(event); } + #[cfg(target_os = "macos")] + let mut event = event; + #[cfg(target_os = "macos")] { + let mut allow_swap_key = false; + #[cfg(not(any(feature = "flutter", feature = "cli")))] + if let Some(session) = CUR_SESSION.lock().unwrap().as_ref() { + allow_swap_key = session.allow_swap_key; + } + #[cfg(feature = "flutter")] + if let Some(session) = SESSIONS + .read() + .unwrap() + .get(&*CUR_SESSION_ID.read().unwrap()) + { + allow_swap_key = session.allow_swap_key; + } + if allow_swap_key { + match event.event_type { + EventType::KeyPress( key) => { + let key = match key { + rdev::Key::ControlLeft => rdev::Key::MetaLeft, + rdev::Key::MetaLeft => rdev::Key::ControlLeft, + rdev::Key::ControlRight => rdev::Key::MetaLeft, + rdev::Key::MetaRight => rdev::Key::ControlLeft, + _ => key, + }; + event.event_type = EventType::KeyPress(key); + event.scan_code = rdev::macos_keycode_from_key(key).unwrap_or_default(); + event.code = event.scan_code as _; + } + EventType::KeyRelease(key) => { + let key = match key { + rdev::Key::ControlLeft => rdev::Key::MetaLeft, + rdev::Key::MetaLeft => rdev::Key::ControlLeft, + rdev::Key::ControlRight => rdev::Key::MetaLeft, + rdev::Key::MetaRight => rdev::Key::ControlLeft, + _ => key, + }; + event.event_type = EventType::KeyRelease(key); + event.scan_code = rdev::macos_keycode_from_key(key).unwrap_or_default(); + event.code = event.scan_code as _; + } + _ => {} + }; + }; + }; + let mut _keyboard_mode = KeyboardMode::Map; let scan_code = event.scan_code; diff --git a/src/server/connection.rs b/src/server/connection.rs index 9ce53c960..17d4e3768 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -539,6 +539,9 @@ impl Connection { #[cfg(not(any(target_os = "android", target_os = "ios")))] fn handle_input(receiver: std_mpsc::Receiver, tx: Sender) { + #[cfg(target_os = "macos")] + let allow_swap_key = hbb_common::config::Config::get_option("allow-swap-key") == "Y"; + let mut block_input_mode = false; #[cfg(target_os = "windows")] { @@ -551,9 +554,66 @@ impl Connection { match receiver.recv_timeout(std::time::Duration::from_millis(500)) { Ok(v) => match v { MessageInput::Mouse((msg, id)) => { + #[cfg(target_os = "macos")] + let msg = { + let mut msg = msg; + if allow_swap_key { + msg.modifiers = msg.modifiers.iter().map(|ck| { + let ck = ck.enum_value_or_default(); + let ck = match ck { + ControlKey::Control => ControlKey::Meta, + ControlKey::Meta => ControlKey::Control, + ControlKey::RControl => ControlKey::Meta, + ControlKey::RWin => ControlKey::Control, + _ => ck, + }; + hbb_common::protobuf::EnumOrUnknown::new(ck) + }).collect(); + } + msg + }; + handle_mouse(&msg, id); } MessageInput::Key((mut msg, press)) => { + #[cfg(target_os = "macos")] + if allow_swap_key { + if let Some(key_event::Union::ControlKey(ck)) = msg.union { + let ck = ck.enum_value_or_default(); + let ck = match ck { + ControlKey::Control => ControlKey::Meta, + ControlKey::Meta => ControlKey::Control, + ControlKey::RControl => ControlKey::Meta, + ControlKey::RWin => ControlKey::Control, + _ => ck, + }; + msg.set_control_key(ck); + } + msg.modifiers = msg.modifiers.iter().map(|ck| { + let ck = ck.enum_value_or_default(); + let ck = match ck { + ControlKey::Control => ControlKey::Meta, + ControlKey::Meta => ControlKey::Control, + ControlKey::RControl => ControlKey::Meta, + ControlKey::RWin => ControlKey::Control, + _ => ck, + }; + hbb_common::protobuf::EnumOrUnknown::new(ck) + }).collect(); + + let code = msg.chr(); + if code != 0 { + let key = rdev::key_from_code(code); + let key = match key { + rdev::Key::ControlLeft => rdev::Key::MetaLeft, + rdev::Key::MetaLeft => rdev::Key::ControlLeft, + rdev::Key::ControlRight => rdev::Key::MetaLeft, + rdev::Key::MetaRight => rdev::Key::ControlLeft, + _ => key, + }; + msg.set_chr(rdev::macos_keycode_from_key(key).unwrap_or_default()); + } + } // todo: press and down have similar meanings. if press && msg.mode.unwrap() == KeyboardMode::Legacy { msg.down = true; diff --git a/src/ui/index.tis b/src/ui/index.tis index ec2e0a748..20228ea03 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -214,6 +214,7 @@ class Enhancements: Reactor.Component { {has_hwcodec ?
  • {svg_checkmark}{translate("Hardware Codec")} (beta)
  • : ""}
  • {svg_checkmark}{translate("Adaptive Bitrate")} (beta)
  • {translate("Recording")}
  • + {is_osx ?
  • {svg_checkmark}{translate("Swap control-command key")}
  • : "" } ; } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 999b409e0..2d0d4d2c0 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -443,10 +443,12 @@ impl sciter::EventHandler for SciterSession { impl SciterSession { pub fn new(cmd: String, id: String, password: String, args: Vec) -> Self { + let allow_swap_key = hbb_common::config::Config::get_option("allow-swap-key") == "Y"; let session: Session = Session { id: id.clone(), password: password.clone(), args, + allow_swap_key, ..Default::default() }; diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index dc0e365ab..a0c4f06b0 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -36,6 +36,7 @@ pub struct Session { pub sender: Arc>>>, pub thread: Arc>>>, pub ui_handler: T, + pub allow_swap_key: bool, } impl Session { @@ -505,6 +506,15 @@ impl Session { shift: bool, command: bool, ) { + #[cfg(target_os = "macos")] + let (ctrl, command) = + if self.allow_swap_key { + (command, ctrl) + } + else { + (ctrl, command) + }; + #[allow(unused_mut)] let mut command = command; #[cfg(windows)]