diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto
index 090b378a2..d4601c0f9 100644
--- a/libs/hbb_common/protos/message.proto
+++ b/libs/hbb_common/protos/message.proto
@@ -284,7 +284,9 @@ enum ControlKey {
 }
 
 message KeyEvent {
+  // `down` indicates the key's state(down or up).
   bool down = 1;
+  // `press` indicates a click event(down and up).
   bool press = 2;
   oneof union {
     ControlKey control_key = 3;
diff --git a/src/client.rs b/src/client.rs
index 4ff2c6b52..9a050c1cb 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -2748,6 +2748,7 @@ fn _input_os_password(p: String, activate: bool, interface: impl Interface) {
         return;
     }
     let mut key_event = KeyEvent::new();
+    key_event.mode = KeyboardMode::Legacy.into();
     key_event.press = true;
     let mut msg_out = Message::new();
     key_event.set_seq(p);
diff --git a/src/keyboard.rs b/src/keyboard.rs
index 6c68dfa10..bc9ec8a77 100644
--- a/src/keyboard.rs
+++ b/src/keyboard.rs
@@ -417,6 +417,17 @@ pub fn is_modifier(key: &rdev::Key) -> bool {
     )
 }
 
+#[inline]
+pub fn is_modifier_code(evt: &KeyEvent) -> bool {
+    match evt.union {
+        Some(key_event::Union::Chr(code)) => {
+            let key = rdev::linux_key_from_code(code);
+            is_modifier(&key)
+        }
+        _ => false,
+    }
+}
+
 #[inline]
 pub fn is_numpad_rdev_key(key: &rdev::Key) -> bool {
     matches!(
@@ -869,24 +880,11 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Vec<KeyEv
     events
 }
 
+#[inline]
 pub fn map_keyboard_mode(_peer: &str, event: &Event, key_event: KeyEvent) -> Vec<KeyEvent> {
-    match _map_keyboard_mode(_peer, event, key_event) {
-        Some(key_event) => {
-            if _peer == OS_LOWER_LINUX {
-                if let EventType::KeyPress(k) = &event.event_type {
-                    #[cfg(target_os = "ios")]
-                    let try_workaround = true;
-                    #[cfg(not(target_os = "ios"))]
-                    let try_workaround = !is_modifier(k);
-                    if try_workaround {
-                        return try_workaround_linux_long_press(key_event);
-                    }
-                }
-            }
-            vec![key_event]
-        }
-        None => Vec::new(),
-    }
+    _map_keyboard_mode(_peer, event, key_event)
+        .map(|e| vec![e])
+        .unwrap_or_default()
 }
 
 fn _map_keyboard_mode(_peer: &str, event: &Event, mut key_event: KeyEvent) -> Option<KeyEvent> {
@@ -958,14 +956,6 @@ fn _map_keyboard_mode(_peer: &str, event: &Event, mut key_event: KeyEvent) -> Op
     Some(key_event)
 }
 
-// https://github.com/rustdesk/rustdesk/issues/6793
-#[inline]
-fn try_workaround_linux_long_press(key_event: KeyEvent) -> Vec<KeyEvent> {
-    let mut key_event_up = key_event.clone();
-    key_event_up.down = false;
-    vec![key_event, key_event_up]
-}
-
 #[cfg(not(any(target_os = "ios")))]
 fn try_fill_unicode(_peer: &str, event: &Event, key_event: &KeyEvent, events: &mut Vec<KeyEvent>) {
     match &event.unicode {
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 1aa7d7e8a..e1c564ce6 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -793,12 +793,13 @@ impl Connection {
                         handle_mouse(&msg, id);
                     }
                     MessageInput::Key((mut msg, press)) => {
-                        // todo: press and down have similar meanings.
-                        if press && msg.mode.enum_value() == Ok(KeyboardMode::Legacy) {
+                        // Set the press state to false, use `down` only in `handle_key()`.
+                        msg.press = false;
+                        if press {
                             msg.down = true;
                         }
                         handle_key(&msg);
-                        if press && msg.mode.enum_value() == Ok(KeyboardMode::Legacy) {
+                        if press {
                             msg.down = false;
                             handle_key(&msg);
                         }
@@ -1965,8 +1966,6 @@ impl Connection {
                 Some(message::Union::KeyEvent(..)) => {}
                 #[cfg(any(target_os = "android"))]
                 Some(message::Union::KeyEvent(mut me)) => {
-                    let is_press = (me.press || me.down) && !crate::is_modifier(&me);
-
                     let key = match me.mode.enum_value() {
                         Ok(KeyboardMode::Map) => {
                             Some(crate::keyboard::keycode_to_rdev_key(me.chr()))
@@ -1982,6 +1981,9 @@ impl Connection {
                     }
                     .filter(crate::keyboard::is_modifier);
 
+                    let is_press =
+                        (me.press || me.down) && !(crate::is_modifier(&me) || key.is_some());
+
                     if let Some(key) = key {
                         if is_press {
                             self.pressed_modifiers.insert(key);
@@ -2022,14 +2024,6 @@ impl Connection {
                         }
                         // https://github.com/rustdesk/rustdesk/issues/8633
                         MOUSE_MOVE_TIME.store(get_time(), Ordering::SeqCst);
-                        // handle all down as press
-                        // fix unexpected repeating key on remote linux, seems also fix abnormal alt/shift, which
-                        // make sure all key are released
-                        let is_press = if cfg!(target_os = "linux") {
-                            (me.press || me.down) && !crate::is_modifier(&me)
-                        } else {
-                            me.press
-                        };
 
                         let key = match me.mode.enum_value() {
                             Ok(KeyboardMode::Map) => {
@@ -2046,6 +2040,16 @@ impl Connection {
                         }
                         .filter(crate::keyboard::is_modifier);
 
+                        // handle all down as press
+                        // fix unexpected repeating key on remote linux, seems also fix abnormal alt/shift, which
+                        // make sure all key are released
+                        // https://github.com/rustdesk/rustdesk/issues/6793
+                        let is_press = if cfg!(target_os = "linux") {
+                            (me.press || me.down) && !(crate::is_modifier(&me) || key.is_some())
+                        } else {
+                            me.press
+                        };
+
                         if let Some(key) = key {
                             if is_press {
                                 self.pressed_modifiers.insert(key);