Merge pull request #3121 from sj6219/sigma

allow swap key
This commit is contained in:
RustDesk 2023-02-28 15:28:35 +08:00 committed by GitHub
commit 5e06fc210b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 125 additions and 2 deletions

View File

@ -920,6 +920,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
disableClipboard(), disableClipboard(),
lockAfterSessionEnd(), lockAfterSessionEnd(),
privacyMode(), privacyMode(),
swapKey(),
]); ]);
} }
@ -1528,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

@ -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

@ -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> {