Merge branch 'master' of https://github.com/rustdesk/rustdesk into android_start_on_boot

This commit is contained in:
csf 2023-03-01 00:22:40 +09:00
commit 761203e778
18 changed files with 180 additions and 40 deletions

View File

@ -18,7 +18,7 @@ on:
env: env:
LLVM_VERSION: "15.0.6" LLVM_VERSION: "15.0.6"
FLUTTER_VERSION: "3.7.0" FLUTTER_VERSION: "3.7.5"
# vcpkg version: 2022.05.10 # vcpkg version: 2022.05.10
# for multiarch gcc compatibility # for multiarch gcc compatibility
VCPKG_COMMIT_ID: "14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44" VCPKG_COMMIT_ID: "14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44"
@ -260,7 +260,7 @@ jobs:
job: job:
- { - {
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
os: ubuntu-18.04, os: ubuntu-20.04,
extra-build-args: "", extra-build-args: "",
} }
steps: steps:
@ -330,13 +330,13 @@ jobs:
- { - {
arch: x86_64, arch: x86_64,
target: aarch64-linux-android, target: aarch64-linux-android,
os: ubuntu-18.04, os: ubuntu-20.04,
extra-build-features: "", extra-build-features: "",
} }
# - { # - {
# arch: x86_64, # arch: x86_64,
# target: armv7-linux-androideabi, # target: armv7-linux-androideabi,
# os: ubuntu-18.04, # os: ubuntu-20.04,
# extra-build-features: "", # extra-build-features: "",
# } # }
steps: steps:
@ -907,19 +907,19 @@ jobs:
- { - {
arch: x86_64, arch: x86_64,
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
os: ubuntu-18.04, os: ubuntu-20.04,
extra-build-features: "", extra-build-features: "",
} }
- { - {
arch: x86_64, arch: x86_64,
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
os: ubuntu-18.04, os: ubuntu-20.04,
extra-build-features: "flatpak", extra-build-features: "flatpak",
} }
- { - {
arch: x86_64, arch: x86_64,
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
os: ubuntu-18.04, os: ubuntu-20.04,
extra-build-features: "appimage", extra-build-features: "appimage",
} }
# - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } # - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }

View File

@ -732,7 +732,7 @@ jobs:
x86_64) x86_64)
# no need mock on x86_64 # no need mock on x86_64
export VCPKG_ROOT=/opt/artifacts/vcpkg export VCPKG_ROOT=/opt/artifacts/vcpkg
cargo build --lib --features hwcodec,flutter,flutter_texture_render,${{ matrix.job.extra-build-features }} --release cargo build --lib --features hwcodec,flutter,${{ matrix.job.extra-build-features }} --release
;; ;;
esac esac
@ -900,7 +900,7 @@ jobs:
ln -s /usr/include /vcpkg/installed/arm64-linux/include ln -s /usr/include /vcpkg/installed/arm64-linux/include
export VCPKG_ROOT=/vcpkg export VCPKG_ROOT=/vcpkg
# disable hwcodec for compilation # disable hwcodec for compilation
cargo build --lib --features flutter,flutter_texture_render,${{ matrix.job.extra-build-features }} --release cargo build --lib --features flutter,${{ matrix.job.extra-build-features }} --release
;; ;;
armv7) armv7)
cp -r /opt/artifacts/vcpkg/installed/lib/* /usr/lib/arm-linux-gnueabihf/ cp -r /opt/artifacts/vcpkg/installed/lib/* /usr/lib/arm-linux-gnueabihf/
@ -910,7 +910,7 @@ jobs:
ln -s /usr/include /vcpkg/installed/arm-linux/include ln -s /usr/include /vcpkg/installed/arm-linux/include
export VCPKG_ROOT=/vcpkg export VCPKG_ROOT=/vcpkg
# disable hwcodec for compilation # disable hwcodec for compilation
cargo build --lib --features flutter,flutter_texture_render,${{ matrix.job.extra-build-features }} --release cargo build --lib --features flutter,${{ matrix.job.extra-build-features }} --release
;; ;;
esac esac

2
Cargo.lock generated
View File

@ -4656,7 +4656,7 @@ dependencies = [
[[package]] [[package]]
name = "rdev" name = "rdev"
version = "0.5.0-2" version = "0.5.0-2"
source = "git+https://github.com/fufesou/rdev#5b9fb5e42117f44e0ce0fe7cf2bddf270c75f1dc" source = "git+https://github.com/fufesou/rdev#25a99ce71ab42843ad253dd51e6a35e83e87a8a4"
dependencies = [ dependencies = [
"cocoa", "cocoa",
"core-foundation 0.9.3", "core-foundation 0.9.3",

View File

@ -315,13 +315,10 @@ def build_flutter_dmg(version, features):
# copy dylib # copy dylib
system2( system2(
"cp target/release/liblibrustdesk.dylib target/release/librustdesk.dylib") "cp target/release/liblibrustdesk.dylib target/release/librustdesk.dylib")
# ffi_bindgen_function_refactor()
# limitations from flutter rust bridge
system2('sed -i "" "s/char \*\*rustdesk_core_main(int \*args_len);//" flutter/macos/Runner/bridge_generated.h')
os.chdir('flutter') os.chdir('flutter')
system2('flutter build macos --release') system2('flutter build macos --release')
system2( system2(
"create-dmg rustdesk.dmg ./build/macos/Build/Products/Release/RustDesk.app") "create-dmg --volname \"RustDesk Installer\" --window-pos 200 120 --window-size 800 400 --icon-size 100 --app-drop-link 600 185 --icon RustDesk.app 200 190 --hide-extension RustDesk.app rustdesk.dmg ./build/macos/Build/Products/Release/RustDesk.app")
os.rename("rustdesk.dmg", f"../rustdesk-{version}.dmg") os.rename("rustdesk.dmg", f"../rustdesk-{version}.dmg")
os.chdir("..") os.chdir("..")

View File

@ -217,6 +217,9 @@ class MyTheme {
tabBarTheme: const TabBarTheme( tabBarTheme: const TabBarTheme(
labelColor: Colors.white70, labelColor: Colors.white70,
), ),
scrollbarTheme: ScrollbarThemeData(
thumbColor: MaterialStateProperty.all(Colors.grey[500])
),
splashColor: Colors.transparent, splashColor: Colors.transparent,
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
splashFactory: isDesktop ? NoSplash.splashFactory : null, splashFactory: isDesktop ? NoSplash.splashFactory : null,

View File

@ -19,7 +19,7 @@ import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
import '../../common/widgets/dialog.dart'; import '../../common/widgets/dialog.dart';
import '../../common/widgets/login.dart'; import '../../common/widgets/login.dart';
const double _kTabWidth = 235; const double _kTabWidth = 200;
const double _kTabHeight = 42; const double _kTabHeight = 42;
const double _kCardFixedWidth = 540; const double _kCardFixedWidth = 540;
const double _kCardLeftMargin = 15; const double _kCardLeftMargin = 15;

View File

@ -920,6 +920,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
disableClipboard(), disableClipboard(),
lockAfterSessionEnd(), lockAfterSessionEnd(),
privacyMode(), privacyMode(),
swapKey(),
]); ]);
} }
@ -953,12 +954,13 @@ class _DisplayMenuState extends State<_DisplayMenu> {
final canvasModel = widget.ffi.canvasModel; final canvasModel = widget.ffi.canvasModel;
final width = (canvasModel.getDisplayWidth() * canvasModel.scale + final width = (canvasModel.getDisplayWidth() * canvasModel.scale +
canvasModel.windowBorderWidth * 2) * CanvasModel.leftToEdge +
CanvasModel.rightToEdge) *
scale + scale +
magicWidth; magicWidth;
final height = (canvasModel.getDisplayHeight() * canvasModel.scale + final height = (canvasModel.getDisplayHeight() * canvasModel.scale +
canvasModel.tabBarHeight + CanvasModel.topToEdge +
canvasModel.windowBorderWidth * 2) * CanvasModel.bottomToEdge) *
scale + scale +
magicHeight; magicHeight;
double left = wndRect.left + (wndRect.width - width) / 2; double left = wndRect.left + (wndRect.width - width) / 2;
@ -1027,10 +1029,10 @@ class _DisplayMenuState extends State<_DisplayMenu> {
final canvasModel = widget.ffi.canvasModel; final canvasModel = widget.ffi.canvasModel;
final displayWidth = canvasModel.getDisplayWidth(); final displayWidth = canvasModel.getDisplayWidth();
final displayHeight = canvasModel.getDisplayHeight(); final displayHeight = canvasModel.getDisplayHeight();
final requiredWidth = displayWidth + final requiredWidth =
(canvasModel.tabBarHeight + canvasModel.windowBorderWidth * 2); CanvasModel.leftToEdge + displayWidth + CanvasModel.rightToEdge;
final requiredHeight = displayHeight + final requiredHeight =
(canvasModel.tabBarHeight + canvasModel.windowBorderWidth * 2); CanvasModel.topToEdge + displayHeight + CanvasModel.bottomToEdge;
return selfWidth > (requiredWidth * scale) && return selfWidth > (requiredWidth * scale) &&
selfHeight > (requiredHeight * scale); selfHeight > (requiredHeight * scale);
} }
@ -1527,6 +1529,23 @@ class _DisplayMenuState extends State<_DisplayMenu> {
ffi: widget.ffi, ffi: widget.ffi,
child: Text(translate('Privacy mode'))); child: Text(translate('Privacy mode')));
} }
swapKey() {
final visible = perms['keyboard'] != false &&
((Platform.isMacOS && pi.platform != kPeerPlatformMacOS) ||
(!Platform.isMacOS && pi.platform == kPeerPlatformMacOS));
if (!visible) return Offstage();
final option = 'allow_swap_key';
final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option);
return _CheckboxMenuButton(
value: value,
onChanged: (value) {
if (value == null) return;
bind.sessionToggleOption(id: widget.id, value: option);
},
ffi: widget.ffi,
child: Text(translate('Swap control-command key')));
}
} }
class _KeyboardMenu extends StatelessWidget { class _KeyboardMenu extends StatelessWidget {

View File

@ -14,6 +14,7 @@ class DesktopScrollWrapper extends StatelessWidget {
return ImprovedScrolling( return ImprovedScrolling(
scrollController: scrollController, scrollController: scrollController,
enableCustomMouseWheelScrolling: true, enableCustomMouseWheelScrolling: true,
// enableKeyboardScrolling: true, // strange behavior on mac
customMouseWheelScrollConfig: CustomMouseWheelScrollConfig( customMouseWheelScrollConfig: CustomMouseWheelScrollConfig(
scrollDuration: kDefaultScrollDuration, scrollDuration: kDefaultScrollDuration,
scrollCurve: Curves.linearToEaseOut, scrollCurve: Curves.linearToEaseOut,

View File

@ -458,10 +458,8 @@ class InputModel {
return; return;
} }
evt['type'] = type; evt['type'] = type;
if (isDesktop) { y -= CanvasModel.topToEdge;
y = y - stateGlobal.tabBarHeight - stateGlobal.windowBorderWidth.value; x -= CanvasModel.leftToEdge;
x -= stateGlobal.windowBorderWidth.value;
}
final canvasModel = parent.target!.canvasModel; final canvasModel = parent.target!.canvasModel;
final nearThr = 3; final nearThr = 3;
var nearRight = (canvasModel.size.width - x) < nearThr; var nearRight = (canvasModel.size.width - x) < nearThr;

View File

@ -727,12 +727,25 @@ class CanvasModel with ChangeNotifier {
double get scrollX => _scrollX; double get scrollX => _scrollX;
double get scrollY => _scrollY; double get scrollY => _scrollY;
static double get leftToEdge => (isDesktop || isWebDesktop)
? windowBorderWidth + kDragToResizeAreaPadding.left
: 0;
static double get rightToEdge => (isDesktop || isWebDesktop)
? windowBorderWidth + kDragToResizeAreaPadding.right
: 0;
static double get topToEdge => (isDesktop || isWebDesktop)
? tabBarHeight + windowBorderWidth + kDragToResizeAreaPadding.top
: 0;
static double get bottomToEdge => (isDesktop || isWebDesktop)
? windowBorderWidth + kDragToResizeAreaPadding.bottom
: 0;
updateViewStyle() async { updateViewStyle() async {
Size getSize() { Size getSize() {
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData.fromWindow(ui.window).size;
// If minimized, w or h may be negative here. // If minimized, w or h may be negative here.
double w = size.width - windowBorderWidth * 2; double w = size.width - leftToEdge - rightToEdge;
double h = size.height - tabBarHeight - windowBorderWidth * 2; double h = size.height - topToEdge - bottomToEdge;
return Size(w < 0 ? 0 : w, h < 0 ? 0 : h); return Size(w < 0 ? 0 : w, h < 0 ? 0 : h);
} }
@ -806,10 +819,14 @@ class CanvasModel with ChangeNotifier {
return parent.target?.ffiModel.display.height ?? defaultHeight; return parent.target?.ffiModel.display.height ?? defaultHeight;
} }
double get windowBorderWidth => stateGlobal.windowBorderWidth.value; static double get windowBorderWidth => stateGlobal.windowBorderWidth.value;
double get tabBarHeight => stateGlobal.tabBarHeight; static double get tabBarHeight => stateGlobal.tabBarHeight;
moveDesktopMouse(double x, double y) { moveDesktopMouse(double x, double y) {
if (size.width == 0 || size.height == 0) {
return;
}
// On mobile platforms, move the canvas with the cursor. // On mobile platforms, move the canvas with the cursor.
final dw = getDisplayWidth() * _scale; final dw = getDisplayWidth() * _scale;
final dh = getDisplayHeight() * _scale; final dh = getDisplayHeight() * _scale;

View File

@ -487,7 +487,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "Apple Development";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;

View File

@ -217,6 +217,8 @@ pub struct PeerConfig {
pub lock_after_session_end: LockAfterSessionEnd, pub lock_after_session_end: LockAfterSessionEnd,
#[serde(flatten)] #[serde(flatten)]
pub privacy_mode: PrivacyMode, pub privacy_mode: PrivacyMode,
#[serde(flatten)]
pub allow_swap_key: AllowSwapKey,
#[serde(default)] #[serde(default)]
pub port_forwards: Vec<(i32, String, i32)>, pub port_forwards: Vec<(i32, String, i32)>,
#[serde(default)] #[serde(default)]
@ -1060,6 +1062,8 @@ serde_field_bool!(
); );
serde_field_bool!(PrivacyMode, "privacy_mode", default_privacy_mode); serde_field_bool!(PrivacyMode, "privacy_mode", default_privacy_mode);
serde_field_bool!(AllowSwapKey, "allow_swap_key", default_swap_key);
#[derive(Debug, Default, Serialize, Deserialize, Clone)] #[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct LocalConfig { pub struct LocalConfig {
#[serde(default)] #[serde(default)]

View File

@ -1230,6 +1230,8 @@ impl LoginConfigHandler {
option.block_input = BoolOption::No.into(); option.block_input = BoolOption::No.into();
} else if name == "show-quality-monitor" { } else if name == "show-quality-monitor" {
config.show_quality_monitor.v = !config.show_quality_monitor.v; config.show_quality_monitor.v = !config.show_quality_monitor.v;
} else if name == "allow_swap_key" {
config.allow_swap_key.v = !config.allow_swap_key.v;
} else { } else {
let is_set = self let is_set = self
.options .options
@ -1383,6 +1385,8 @@ impl LoginConfigHandler {
self.config.disable_clipboard.v self.config.disable_clipboard.v
} else if name == "show-quality-monitor" { } else if name == "show-quality-monitor" {
self.config.show_quality_monitor.v self.config.show_quality_monitor.v
} else if name == "allow_swap_key" {
self.config.allow_swap_key.v
} else { } else {
!self.get_option(name).is_empty() !self.get_option(name).is_empty()
} }
@ -1807,6 +1811,7 @@ pub fn send_mouse(
if check_scroll_on_mac(mask, x, y) { if check_scroll_on_mac(mask, x, y) {
mouse_event.modifiers.push(ControlKey::Scroll.into()); mouse_event.modifiers.push(ControlKey::Scroll.into());
} }
interface.swap_modifier_mouse(&mut mouse_event);
msg_out.set_mouse_event(mouse_event); msg_out.set_mouse_event(mouse_event);
interface.send(Data::Message(msg_out)); interface.send(Data::Message(msg_out));
} }
@ -2033,6 +2038,7 @@ pub trait Interface: Send + Clone + 'static + Sized {
fn is_force_relay(&self) -> bool { fn is_force_relay(&self) -> bool {
self.get_login_config_handler().read().unwrap().force_relay self.get_login_config_handler().read().unwrap().force_relay
} }
fn swap_modifier_mouse(&self, _msg : &mut hbb_common::protos::message::MouseEvent) {}
} }
/// Data used by the client interface. /// Data used by the client interface.

View File

@ -39,8 +39,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("verification_tip", "A new device has been detected, and a verification code has been sent to the registered email address, enter the verification code to continue logging in."), ("verification_tip", "A new device has been detected, and a verification code has been sent to the registered email address, enter the verification code to continue logging in."),
("software_render_tip", "If you have an Nvidia graphics card and the remote window closes immediately after connecting, installing the nouveau driver and choosing to use software rendering may help. A software restart is required."), ("software_render_tip", "If you have an Nvidia graphics card and the remote window closes immediately after connecting, installing the nouveau driver and choosing to use software rendering may help. A software restart is required."),
("config_input", "In order to control remote desktop with keyboard, you need to grant RustDesk \"Input Monitoring\" permissions."), ("config_input", "In order to control remote desktop with keyboard, you need to grant RustDesk \"Input Monitoring\" permissions."),
("request_elevation_tip","You can also request elevation if there is someone on the remote side."), ("request_elevation_tip", "You can also request elevation if there is someone on the remote side."),
("wait_accept_uac_tip","Please wait for the remote user to accept the UAC dialog."), ("wait_accept_uac_tip", "Please wait for the remote user to accept the UAC dialog."),
("still_click_uac_tip", "Still requires the remote user to click OK on the UAC window of running RustDesk."), ("still_click_uac_tip", "Still requires the remote user to click OK on the UAC window of running RustDesk."),
("config_microphone", "In order to speak remotely, you need to grant RustDesk \"Record Audio\" permissions."), ("config_microphone", "In order to speak remotely, you need to grant RustDesk \"Record Audio\" permissions."),
("relay_hint_tip", "It may not be possible to connect directly, you can try to connect via relay. \nIn addition, if you want to use relay on your first try, you can add the \"/r\" suffix to the ID, or select the option \"Always connect via relay\" in the peer card."), ("relay_hint_tip", "It may not be possible to connect directly, you can try to connect via relay. \nIn addition, if you want to use relay on your first try, you can add the \"/r\" suffix to the ID, or select the option \"Always connect via relay\" in the peer card."),

View File

@ -458,6 +458,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Reconnect", "Reconectar"), ("Reconnect", "Reconectar"),
("Codec", "Códec"), ("Codec", "Códec"),
("Resolution", "Resolución"), ("Resolution", "Resolución"),
("No transfers in progress", ""), ("No transfers in progress", "No hay transferencias en curso"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -456,8 +456,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Stop voice call", "توقف تماس صوتی"), ("Stop voice call", "توقف تماس صوتی"),
("relay_hint_tip", " را به شناسه اضافه کنید یا گزینه \"همیشه از طریق رله متصل شوید\" را در کارت همتا انتخاب کنید. همچنین، اگر می‌خواهید فوراً از سرور رله استفاده کنید، می‌توانید پسوند \"/r\".\n اتصال مستقیم ممکن است امکان پذیر نباشد. در این صورت می توانید سعی کنید از طریق سرور رله متصل شوید"), ("relay_hint_tip", " را به شناسه اضافه کنید یا گزینه \"همیشه از طریق رله متصل شوید\" را در کارت همتا انتخاب کنید. همچنین، اگر می‌خواهید فوراً از سرور رله استفاده کنید، می‌توانید پسوند \"/r\".\n اتصال مستقیم ممکن است امکان پذیر نباشد. در این صورت می توانید سعی کنید از طریق سرور رله متصل شوید"),
("Reconnect", "اتصال مجدد"), ("Reconnect", "اتصال مجدد"),
("Codec", ""), ("Codec", "کدک"),
("Resolution", ""), ("Resolution", "وضوح"),
("No transfers in progress", ""), ("No transfers in progress", "هیچ انتقالی در حال انجام نیست"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -198,6 +198,7 @@ class Header: Reactor.Component {
{keyboard_enabled && clipboard_enabled ? <li #disable-clipboard .toggle-option><span>{svg_checkmark}</span>{translate('Disable clipboard')}</li> : ""} {keyboard_enabled && clipboard_enabled ? <li #disable-clipboard .toggle-option><span>{svg_checkmark}</span>{translate('Disable clipboard')}</li> : ""}
{keyboard_enabled ? <li #lock-after-session-end .toggle-option><span>{svg_checkmark}</span>{translate('Lock after session end')}</li> : ""} {keyboard_enabled ? <li #lock-after-session-end .toggle-option><span>{svg_checkmark}</span>{translate('Lock after session end')}</li> : ""}
{keyboard_enabled && pi.platform == "Windows" ? <li #privacy-mode><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""} {keyboard_enabled && pi.platform == "Windows" ? <li #privacy-mode><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""}
{keyboard_enabled && ((is_osx && pi.platform != "Mac OS") || (!is_osx && pi.platform == "Mac OS")) ? <li #allow_swap_key .toggle-option><span>{svg_checkmark}</span>{translate('Swap control-command key')}</li> : ""}
</menu> </menu>
</popup>; </popup>;
} }
@ -440,7 +441,7 @@ function toggleMenuState() {
for (var el in $$(menu#keyboard-options>li)) { for (var el in $$(menu#keyboard-options>li)) {
el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0); el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0);
} }
for (var id in ["show-remote-cursor", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end"]) { for (var id in ["show-remote-cursor", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end", "allow_swap_key"]) {
var el = self.select('#' + id); var el = self.select('#' + id);
if (el) { if (el) {
var value = handler.get_toggle_option(id); var value = handler.get_toggle_option(id);

View File

@ -373,10 +373,87 @@ impl<T: InvokeUiSession> Session<T> {
return "".to_owned(); return "".to_owned();
} }
pub fn swab_modifier_key(&self, msg: &mut KeyEvent) {
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
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 mut peer = self.peer_platform().to_lowercase();
peer.retain(|c| !c.is_whitespace());
let key = match peer.as_str() {
"windows" => {
let key = rdev::win_key_from_scancode(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,
};
rdev::win_scancode_from_key(key).unwrap_or_default()
}
"macos" => {
let key = rdev::macos_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,
};
rdev::macos_keycode_from_key(key).unwrap_or_default()
}
_ => {
let key = rdev::linux_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,
};
rdev::linux_keycode_from_key(key).unwrap_or_default()
}
};
msg.set_chr(key);
}
}
}
pub fn send_key_event(&self, evt: &KeyEvent) { pub fn send_key_event(&self, evt: &KeyEvent) {
// mode: legacy(0), map(1), translate(2), auto(3) // mode: legacy(0), map(1), translate(2), auto(3)
let mut msg = evt.clone();
self.swab_modifier_key(&mut msg);
let mut msg_out = Message::new(); let mut msg_out = Message::new();
msg_out.set_key_event(evt.clone()); msg_out.set_key_event(msg);
self.send(Data::Message(msg_out)); self.send(Data::Message(msg_out));
} }
@ -934,6 +1011,23 @@ impl<T: InvokeUiSession> Interface for Session<T> {
handle_test_delay(t, peer).await; handle_test_delay(t, peer).await;
} }
} }
fn swap_modifier_mouse(&self, msg : &mut hbb_common::protos::message::MouseEvent) {
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
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();
};
}
} }
impl<T: InvokeUiSession> Session<T> { impl<T: InvokeUiSession> Session<T> {