refact: flutter keyboard, map mode (#9160)

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou 2024-08-24 12:10:36 +08:00 committed by GitHub
parent 9d9741f18e
commit 1d416f6626
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 231 additions and 210 deletions

2
Cargo.lock generated
View File

@ -5187,7 +5187,7 @@ dependencies = [
[[package]] [[package]]
name = "rdev" name = "rdev"
version = "0.5.0-2" version = "0.5.0-2"
source = "git+https://github.com/rustdesk-org/rdev#b3434caee84c92412b45a2f655a15ac5dad33488" source = "git+https://github.com/rustdesk-org/rdev#d4c1759926d693ba269e2cb8cf9f87b13e424e4e"
dependencies = [ dependencies = [
"cocoa 0.24.1", "cocoa 0.24.1",
"core-foundation 0.9.4", "core-foundation 0.9.4",

View File

@ -34,8 +34,7 @@ class RawKeyFocusScope extends StatelessWidget {
canRequestFocus: true, canRequestFocus: true,
focusNode: focusNode, focusNode: focusNode,
onFocusChange: onFocusChange, onFocusChange: onFocusChange,
onKey: (FocusNode data, RawKeyEvent e) => onKeyEvent: (node, event) => inputModel.handleKeyEvent(event),
inputModel.handleRawKeyEvent(e),
child: child)); child: child));
} }
} }

View File

@ -181,6 +181,7 @@ class TextureModel {
} }
updateCurrentDisplay(int curDisplay) { updateCurrentDisplay(int curDisplay) {
if (isWeb) return;
final ffi = parent.target; final ffi = parent.target;
if (ffi == null) return; if (ffi == null) return;
tryCreateTexture(int idx) { tryCreateTexture(int idx) {

View File

@ -178,15 +178,15 @@ class PointerEventToRust {
} }
class ToReleaseKeys { class ToReleaseKeys {
RawKeyEvent? lastLShiftKeyEvent; KeyEvent? lastLShiftKeyEvent;
RawKeyEvent? lastRShiftKeyEvent; KeyEvent? lastRShiftKeyEvent;
RawKeyEvent? lastLCtrlKeyEvent; KeyEvent? lastLCtrlKeyEvent;
RawKeyEvent? lastRCtrlKeyEvent; KeyEvent? lastRCtrlKeyEvent;
RawKeyEvent? lastLAltKeyEvent; KeyEvent? lastLAltKeyEvent;
RawKeyEvent? lastRAltKeyEvent; KeyEvent? lastRAltKeyEvent;
RawKeyEvent? lastLCommandKeyEvent; KeyEvent? lastLCommandKeyEvent;
RawKeyEvent? lastRCommandKeyEvent; KeyEvent? lastRCommandKeyEvent;
RawKeyEvent? lastSuperKeyEvent; KeyEvent? lastSuperKeyEvent;
reset() { reset() {
lastLShiftKeyEvent = null; lastLShiftKeyEvent = null;
@ -200,67 +200,7 @@ class ToReleaseKeys {
lastSuperKeyEvent = null; lastSuperKeyEvent = null;
} }
updateKeyDown(LogicalKeyboardKey logicKey, RawKeyDownEvent e) { release(KeyEventResult Function(KeyEvent e) handleKeyEvent) {
if (e.isAltPressed) {
if (logicKey == LogicalKeyboardKey.altLeft) {
lastLAltKeyEvent = e;
} else if (logicKey == LogicalKeyboardKey.altRight) {
lastRAltKeyEvent = e;
}
} else if (e.isControlPressed) {
if (logicKey == LogicalKeyboardKey.controlLeft) {
lastLCtrlKeyEvent = e;
} else if (logicKey == LogicalKeyboardKey.controlRight) {
lastRCtrlKeyEvent = e;
}
} else if (e.isShiftPressed) {
if (logicKey == LogicalKeyboardKey.shiftLeft) {
lastLShiftKeyEvent = e;
} else if (logicKey == LogicalKeyboardKey.shiftRight) {
lastRShiftKeyEvent = e;
}
} else if (e.isMetaPressed) {
if (logicKey == LogicalKeyboardKey.metaLeft) {
lastLCommandKeyEvent = e;
} else if (logicKey == LogicalKeyboardKey.metaRight) {
lastRCommandKeyEvent = e;
} else if (logicKey == LogicalKeyboardKey.superKey) {
lastSuperKeyEvent = e;
}
}
}
updateKeyUp(LogicalKeyboardKey logicKey, RawKeyUpEvent e) {
if (e.isAltPressed) {
if (logicKey == LogicalKeyboardKey.altLeft) {
lastLAltKeyEvent = null;
} else if (logicKey == LogicalKeyboardKey.altRight) {
lastRAltKeyEvent = null;
}
} else if (e.isControlPressed) {
if (logicKey == LogicalKeyboardKey.controlLeft) {
lastLCtrlKeyEvent = null;
} else if (logicKey == LogicalKeyboardKey.controlRight) {
lastRCtrlKeyEvent = null;
}
} else if (e.isShiftPressed) {
if (logicKey == LogicalKeyboardKey.shiftLeft) {
lastLShiftKeyEvent = null;
} else if (logicKey == LogicalKeyboardKey.shiftRight) {
lastRShiftKeyEvent = null;
}
} else if (e.isMetaPressed) {
if (logicKey == LogicalKeyboardKey.metaLeft) {
lastLCommandKeyEvent = null;
} else if (logicKey == LogicalKeyboardKey.metaRight) {
lastRCommandKeyEvent = null;
} else if (logicKey == LogicalKeyboardKey.superKey) {
lastSuperKeyEvent = null;
}
}
}
release(KeyEventResult Function(RawKeyEvent e) handleRawKeyEvent) {
for (final key in [ for (final key in [
lastLShiftKeyEvent, lastLShiftKeyEvent,
lastRShiftKeyEvent, lastRShiftKeyEvent,
@ -273,10 +213,7 @@ class ToReleaseKeys {
lastSuperKeyEvent, lastSuperKeyEvent,
]) { ]) {
if (key != null) { if (key != null) {
handleRawKeyEvent(RawKeyUpEvent( handleKeyEvent(key);
data: key.data,
character: key.character,
));
} }
} }
} }
@ -339,49 +276,116 @@ class InputModel {
} }
} }
KeyEventResult handleRawKeyEvent(RawKeyEvent e) { void handleKeyDownEventModifiers(KeyEvent e) {
KeyUpEvent upEvent(e) => KeyUpEvent(
physicalKey: e.physicalKey,
logicalKey: e.logicalKey,
timeStamp: e.timeStamp,
);
if (e.logicalKey == LogicalKeyboardKey.altLeft) {
if (!alt) {
alt = true;
}
toReleaseKeys.lastLAltKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.altRight) {
if (!alt) {
alt = true;
}
toReleaseKeys.lastLAltKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.controlLeft) {
if (!ctrl) {
ctrl = true;
}
toReleaseKeys.lastLCtrlKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.controlRight) {
if (!ctrl) {
ctrl = true;
}
toReleaseKeys.lastRCtrlKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.shiftLeft) {
if (!shift) {
shift = true;
}
toReleaseKeys.lastLShiftKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.shiftRight) {
if (!shift) {
shift = true;
}
toReleaseKeys.lastRShiftKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.metaLeft) {
if (!command) {
command = true;
}
toReleaseKeys.lastLCommandKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.metaRight) {
if (!command) {
command = true;
}
toReleaseKeys.lastRCommandKeyEvent = upEvent(e);
} else if (e.logicalKey == LogicalKeyboardKey.superKey) {
if (!command) {
command = true;
}
toReleaseKeys.lastSuperKeyEvent = upEvent(e);
}
}
void handleKeyUpEventModifiers(KeyEvent e) {
if (e.logicalKey == LogicalKeyboardKey.altLeft) {
alt = false;
toReleaseKeys.lastLAltKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.altRight) {
alt = false;
toReleaseKeys.lastRAltKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.controlLeft) {
ctrl = false;
toReleaseKeys.lastLCtrlKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.controlRight) {
ctrl = false;
toReleaseKeys.lastRCtrlKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.shiftLeft) {
shift = false;
toReleaseKeys.lastLShiftKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.shiftRight) {
shift = false;
toReleaseKeys.lastRShiftKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.metaLeft) {
command = false;
toReleaseKeys.lastLCommandKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.metaRight) {
command = false;
toReleaseKeys.lastRCommandKeyEvent = null;
} else if (e.logicalKey == LogicalKeyboardKey.superKey) {
command = false;
toReleaseKeys.lastSuperKeyEvent = null;
}
}
KeyEventResult handleKeyEvent(KeyEvent e) {
if (isViewOnly) return KeyEventResult.handled; if (isViewOnly) return KeyEventResult.handled;
if ((isDesktop || isWebDesktop) && !isInputSourceFlutter) { if ((isDesktop || isWebDesktop) && !isInputSourceFlutter) {
return KeyEventResult.handled; return KeyEventResult.handled;
} }
if (isWindows || isLinux) {
final key = e.logicalKey; // Ignore meta keys. Because flutter window will loose focus if meta key is pressed.
if (e is RawKeyDownEvent) { if (e.physicalKey == PhysicalKeyboardKey.metaLeft ||
if (!e.repeat) { e.physicalKey == PhysicalKeyboardKey.metaRight) {
if (e.isAltPressed && !alt) { return KeyEventResult.handled;
alt = true;
} else if (e.isControlPressed && !ctrl) {
ctrl = true;
} else if (e.isShiftPressed && !shift) {
shift = true;
} else if (e.isMetaPressed && !command) {
command = true;
}
} }
toReleaseKeys.updateKeyDown(key, e);
} }
if (e is RawKeyUpEvent) {
if (key == LogicalKeyboardKey.altLeft ||
key == LogicalKeyboardKey.altRight) {
alt = false;
} else if (key == LogicalKeyboardKey.controlLeft ||
key == LogicalKeyboardKey.controlRight) {
ctrl = false;
} else if (key == LogicalKeyboardKey.shiftRight ||
key == LogicalKeyboardKey.shiftLeft) {
shift = false;
} else if (key == LogicalKeyboardKey.metaLeft ||
key == LogicalKeyboardKey.metaRight ||
key == LogicalKeyboardKey.superKey) {
command = false;
}
toReleaseKeys.updateKeyUp(key, e); if (e is KeyUpEvent) {
handleKeyUpEventModifiers(e);
} else if (e is KeyDownEvent) {
handleKeyDownEventModifiers(e);
} }
// * Currently mobile does not enable map mode // * Currently mobile does not enable map mode
if ((isDesktop || isWebDesktop) && keyboardMode == 'map') { if ((isDesktop || isWebDesktop)) {
mapKeyboardMode(e); // FIXME: e.character is wrong for dead keys, eg: ^ in de
newKeyboardMode(e.character ?? '', e.physicalKey.usbHidUsage & 0xFFFF,
// Show repeat event be converted to "release+press" events?
e is KeyDownEvent || e is KeyRepeatEvent);
} else { } else {
legacyKeyboardMode(e); legacyKeyboardMode(e);
} }
@ -389,42 +393,8 @@ class InputModel {
return KeyEventResult.handled; return KeyEventResult.handled;
} }
void mapKeyboardMode(RawKeyEvent e) { /// Send Key Event
int positionCode = -1; void newKeyboardMode(String character, int usbHid, bool down) {
int platformCode = -1;
bool down;
if (e.data is RawKeyEventDataMacOs) {
RawKeyEventDataMacOs newData = e.data as RawKeyEventDataMacOs;
positionCode = newData.keyCode;
platformCode = newData.keyCode;
} else if (e.data is RawKeyEventDataWindows) {
RawKeyEventDataWindows newData = e.data as RawKeyEventDataWindows;
positionCode = newData.scanCode;
platformCode = newData.keyCode;
} else if (e.data is RawKeyEventDataLinux) {
RawKeyEventDataLinux newData = e.data as RawKeyEventDataLinux;
// scanCode and keyCode of RawKeyEventDataLinux are incorrect.
// 1. scanCode means keycode
// 2. keyCode means keysym
positionCode = newData.scanCode;
platformCode = newData.keyCode;
} else if (e.data is RawKeyEventDataAndroid) {
RawKeyEventDataAndroid newData = e.data as RawKeyEventDataAndroid;
positionCode = newData.scanCode + 8;
platformCode = newData.keyCode;
} else {}
if (e is RawKeyDownEvent) {
down = true;
} else {
down = false;
}
inputRawKey(e.character ?? '', platformCode, positionCode, down);
}
/// Send raw Key Event
void inputRawKey(String name, int platformCode, int positionCode, bool down) {
const capslock = 1; const capslock = 1;
const numlock = 2; const numlock = 2;
const scrolllock = 3; const scrolllock = 3;
@ -443,27 +413,23 @@ class InputModel {
} }
bind.sessionHandleFlutterKeyEvent( bind.sessionHandleFlutterKeyEvent(
sessionId: sessionId, sessionId: sessionId,
name: name, character: character,
platformCode: platformCode, usbHid: usbHid,
positionCode: positionCode,
lockModes: lockModes, lockModes: lockModes,
downOrUp: down); downOrUp: down);
} }
void legacyKeyboardMode(RawKeyEvent e) { void legacyKeyboardMode(KeyEvent e) {
if (e is RawKeyDownEvent) { if (e is KeyDownEvent) {
if (e.repeat) { sendKey(e, down: true);
sendRawKey(e, press: true); } else if (e is KeyRepeatEvent) {
} else { sendKey(e, press: true);
sendRawKey(e, down: true); } else if (e is KeyUpEvent) {
} sendKey(e);
}
if (e is RawKeyUpEvent) {
sendRawKey(e);
} }
} }
void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) { void sendKey(KeyEvent e, {bool? down, bool? press}) {
// for maximum compatibility // for maximum compatibility
final label = physicalKeyMap[e.physicalKey.usbHidUsage] ?? final label = physicalKeyMap[e.physicalKey.usbHidUsage] ??
logicalKeyMap[e.logicalKey.keyId] ?? logicalKeyMap[e.logicalKey.keyId] ??
@ -566,7 +532,7 @@ class InputModel {
} }
void enterOrLeave(bool enter) { void enterOrLeave(bool enter) {
toReleaseKeys.release(handleRawKeyEvent); toReleaseKeys.release(handleKeyEvent);
_pointerMovedAfterEnter = false; _pointerMovedAfterEnter = false;
// Fix status // Fix status
@ -1164,15 +1130,15 @@ class InputModel {
// Simulate a key press event. // Simulate a key press event.
// `usbHidUsage` is the USB HID usage code of the key. // `usbHidUsage` is the USB HID usage code of the key.
Future<void> tapHidKey(int usbHidUsage) async { Future<void> tapHidKey(int usbHidUsage) async {
inputRawKey(kKeyFlutterKey, usbHidUsage, 0, true); newKeyboardMode(kKeyFlutterKey, usbHidUsage, true);
await Future.delayed(Duration(milliseconds: 100)); await Future.delayed(Duration(milliseconds: 100));
inputRawKey(kKeyFlutterKey, usbHidUsage, 0, false); newKeyboardMode(kKeyFlutterKey, usbHidUsage, false);
} }
Future<void> onMobileVolumeUp() async => Future<void> onMobileVolumeUp() async =>
await tapHidKey(PhysicalKeyboardKey.audioVolumeUp.usbHidUsage); await tapHidKey(PhysicalKeyboardKey.audioVolumeUp.usbHidUsage & 0xFFFF);
Future<void> onMobileVolumeDown() async => Future<void> onMobileVolumeDown() async =>
await tapHidKey(PhysicalKeyboardKey.audioVolumeDown.usbHidUsage); await tapHidKey(PhysicalKeyboardKey.audioVolumeDown.usbHidUsage & 0xFFFF);
Future<void> onMobilePower() async => Future<void> onMobilePower() async =>
await tapHidKey(PhysicalKeyboardKey.power.usbHidUsage); await tapHidKey(PhysicalKeyboardKey.power.usbHidUsage & 0xFFFF);
} }

View File

@ -23,6 +23,7 @@ sealed class EventToUI {
) = EventToUI_Rgba; ) = EventToUI_Rgba;
const factory EventToUI.texture( const factory EventToUI.texture(
int field0, int field0,
bool field1,
) = EventToUI_Texture; ) = EventToUI_Texture;
} }
@ -33,15 +34,19 @@ class EventToUI_Event implements EventToUI {
} }
class EventToUI_Rgba implements EventToUI { class EventToUI_Rgba implements EventToUI {
const EventToUI_Rgba(final int field0) : this.field = field0; const EventToUI_Rgba(final int field0) : field = field0;
final int field; final int field;
int get field0 => field; int get field0 => field;
} }
class EventToUI_Texture implements EventToUI { class EventToUI_Texture implements EventToUI {
const EventToUI_Texture(final int field0) : this.field = field0; const EventToUI_Texture(final int field0, final bool field1)
final int field; : f0 = field0,
int get field0 => field; f1 = field1;
final int f0;
final bool f1;
int get field0 => f0;
bool get field1 => f1;
} }
class RustdeskImpl { class RustdeskImpl {
@ -394,14 +399,20 @@ class RustdeskImpl {
Future<void> sessionHandleFlutterKeyEvent( Future<void> sessionHandleFlutterKeyEvent(
{required UuidValue sessionId, {required UuidValue sessionId,
required String name, required String character,
required int platformCode, required int usbHid,
required int positionCode,
required int lockModes, required int lockModes,
required bool downOrUp, required bool downOrUp,
dynamic hint}) { dynamic hint}) {
// TODO: map mode return Future(() => js.context.callMethod('setByName', [
throw UnimplementedError(); 'flutter_key_event',
jsonEncode({
'name': character,
'usb_hid': usbHid,
'lock_modes': lockModes,
if (downOrUp) 'down': 'true',
})
]));
} }
void sessionEnterOrLeave( void sessionEnterOrLeave(
@ -702,11 +713,11 @@ class RustdeskImpl {
} }
Future<String> mainGetAppName({dynamic hint}) { Future<String> mainGetAppName({dynamic hint}) {
throw UnimplementedError(); return Future.value(mainGetAppNameSync(hint: hint));
} }
String mainGetAppNameSync({dynamic hint}) { String mainGetAppNameSync({dynamic hint}) {
throw UnimplementedError(); return 'RustDesk';
} }
String mainUriPrefixSync({dynamic hint}) { String mainUriPrefixSync({dynamic hint}) {
@ -758,8 +769,9 @@ class RustdeskImpl {
} }
Future<bool> mainIsUsingPublicServer({dynamic hint}) { Future<bool> mainIsUsingPublicServer({dynamic hint}) {
return Future( return Future(() =>
() => js.context.callMethod('setByName', ["is_using_public_server"])); js.context.callMethod('getByName', ["is_using_public_server"]) ==
'true');
} }
Future<void> mainDiscover({dynamic hint}) { Future<void> mainDiscover({dynamic hint}) {
@ -1610,7 +1622,7 @@ class RustdeskImpl {
} }
bool mainIsOptionFixed({required String key, dynamic hint}) { bool mainIsOptionFixed({required String key, dynamic hint}) {
throw UnimplementedError(); return false;
} }
bool mainGetUseTextureRender({dynamic hint}) { bool mainGetUseTextureRender({dynamic hint}) {
@ -1650,5 +1662,36 @@ class RustdeskImpl {
throw UnimplementedError(); throw UnimplementedError();
} }
Future<String> getVoiceCallInputDevice({required bool isCm, dynamic hint}) {
throw UnimplementedError();
}
Future<void> setVoiceCallInputDevice(
{required bool isCm, required String device, dynamic hint}) {
throw UnimplementedError();
}
bool isPresetPasswordMobileOnly({dynamic hint}) {
throw UnimplementedError();
}
String mainGetBuildinOption({required String key, dynamic hint}) {
return '';
}
String installInstallOptions({dynamic hint}) {
throw UnimplementedError();
}
sessionRenameFile(
{required UuidValue sessionId,
required int actId,
required String path,
required String newName,
required bool isRemote,
dynamic hint}) {
throw UnimplementedError();
}
void dispose() {} void dispose() {}
} }

View File

@ -6,7 +6,7 @@ class TextureRgbaRenderer {
} }
Future<bool> closeTexture(int key) { Future<bool> closeTexture(int key) {
throw UnimplementedError(); return Future(() => true);
} }
Future<bool> onRgba( Future<bool> onRgba(

View File

@ -491,9 +491,8 @@ pub fn session_switch_display(is_desktop: bool, session_id: SessionID, value: Ve
pub fn session_handle_flutter_key_event( pub fn session_handle_flutter_key_event(
session_id: SessionID, session_id: SessionID,
name: String, character: String,
platform_code: i32, usb_hid: i32,
position_code: i32,
lock_modes: i32, lock_modes: i32,
down_or_up: bool, down_or_up: bool,
) { ) {
@ -501,9 +500,8 @@ pub fn session_handle_flutter_key_event(
let keyboard_mode = session.get_keyboard_mode(); let keyboard_mode = session.get_keyboard_mode();
session.handle_flutter_key_event( session.handle_flutter_key_event(
&keyboard_mode, &keyboard_mode,
&name, &character,
platform_code, usb_hid,
position_code,
lock_modes, lock_modes,
down_or_up, down_or_up,
); );

View File

@ -803,19 +803,18 @@ impl<T: InvokeUiSession> Session<T> {
pub fn handle_flutter_key_event( pub fn handle_flutter_key_event(
&self, &self,
keyboard_mode: &str, keyboard_mode: &str,
name: &str, character: &str,
platform_code: i32, usb_hid: i32,
position_code: i32,
lock_modes: i32, lock_modes: i32,
down_or_up: bool, down_or_up: bool,
) { ) {
if name == "flutter_key" { if character == "flutter_key" {
self._handle_key_flutter_simulation(keyboard_mode, platform_code, down_or_up); self._handle_key_flutter_simulation(keyboard_mode, usb_hid, down_or_up);
} else { } else {
self._handle_key_non_flutter_simulation( self._handle_key_non_flutter_simulation(
keyboard_mode, keyboard_mode,
platform_code, character,
position_code, usb_hid,
lock_modes, lock_modes,
down_or_up, down_or_up,
); );
@ -831,10 +830,10 @@ impl<T: InvokeUiSession> Session<T> {
) { ) {
// https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/keyboard_key.g.dart#L4356 // https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/keyboard_key.g.dart#L4356
let ctrl_key = match platform_code { let ctrl_key = match platform_code {
0x0007007f => Some(ControlKey::VolumeMute), 0x007f => Some(ControlKey::VolumeMute),
0x00070080 => Some(ControlKey::VolumeUp), 0x0080 => Some(ControlKey::VolumeUp),
0x00070081 => Some(ControlKey::VolumeDown), 0x0081 => Some(ControlKey::VolumeDown),
0x00070066 => Some(ControlKey::Power), 0x0066 => Some(ControlKey::Power),
_ => None, _ => None,
}; };
let Some(ctrl_key) = ctrl_key else { return }; let Some(ctrl_key) = ctrl_key else { return };
@ -851,22 +850,28 @@ impl<T: InvokeUiSession> Session<T> {
fn _handle_key_non_flutter_simulation( fn _handle_key_non_flutter_simulation(
&self, &self,
keyboard_mode: &str, keyboard_mode: &str,
platform_code: i32, character: &str,
position_code: i32, usb_hid: i32,
lock_modes: i32, lock_modes: i32,
down_or_up: bool, down_or_up: bool,
) { ) {
if position_code < 0 || platform_code < 0 { let key = rdev::usb_hid_key_from_code(usb_hid as _);
return;
} #[cfg(target_os = "windows")]
let platform_code: u32 = platform_code as _; let platform_code: u32 = rdev::win_code_from_key(key).unwrap_or(0);
let position_code: KeyCode = position_code as _; #[cfg(target_os = "windows")]
let position_code: KeyCode = rdev::win_scancode_from_key(key).unwrap_or(0) as _;
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let key = rdev::key_from_code(position_code) as rdev::Key; let position_code: KeyCode = rdev::code_from_key(key).unwrap_or(0) as _;
// Windows requires special handling #[cfg(not(any(target_os = "windows", target_os = "linux")))]
#[cfg(target_os = "windows")] let platform_code: u32 = position_code as _;
let key = rdev::get_win_key(platform_code, position_code); // For translate mode.
// We need to set the platform code (keysym) if is AltGr.
// https://github.com/rustdesk/rustdesk/blob/07cf1b4db5ef2f925efd3b16b87c33ce03c94809/src/keyboard.rs#L1029
// https://github.com/flutter/flutter/issues/153811
#[cfg(target_os = "linux")]
let platform_code: u32 = position_code as _;
let event_type = if down_or_up { let event_type = if down_or_up {
KeyPress(key) KeyPress(key)
@ -875,7 +880,16 @@ impl<T: InvokeUiSession> Session<T> {
}; };
let event = Event { let event = Event {
time: SystemTime::now(), time: SystemTime::now(),
unicode: None, unicode: if character.is_empty() {
None
} else {
Some(rdev::UnicodeInfo {
name: Some(character.to_string()),
unicode: character.encode_utf16().collect(),
// is_dead: is not correct here, because flutter cannot detect deadcode for now.
is_dead: false,
})
},
platform_code, platform_code,
position_code: position_code as _, position_code: position_code as _,
event_type, event_type,