diff --git a/local/recipes/wayland/redbear-compositor/source/src/main.rs b/local/recipes/wayland/redbear-compositor/source/src/main.rs index daa70ea6a2..fb63eccb7f 100644 --- a/local/recipes/wayland/redbear-compositor/source/src/main.rs +++ b/local/recipes/wayland/redbear-compositor/source/src/main.rs @@ -1233,6 +1233,27 @@ struct KeyboardEvent { time: u32, } +const MOD_SHIFT: u32 = 1 << 0; +const MOD_CAPS: u32 = 1 << 1; +const MOD_CTRL: u32 = 1 << 2; +const MOD_ALT: u32 = 1 << 3; +const MOD_MOD2: u32 = 1 << 4; +const MOD_MOD3: u32 = 1 << 5; +const MOD_LOGO: u32 = 1 << 6; +const MOD_MOD5: u32 = 1 << 7; + +const KEY_LEFT_SHIFT: u32 = 50; +const KEY_RIGHT_SHIFT: u32 = 62; +const KEY_LEFT_CTRL: u32 = 37; +const KEY_RIGHT_CTRL: u32 = 105; +const KEY_LEFT_ALT: u32 = 64; +const KEY_RIGHT_ALT: u32 = 108; +const KEY_LEFT_LOGO: u32 = 133; +const KEY_RIGHT_LOGO: u32 = 134; +const KEY_CAPS_LOCK: u32 = 66; +const KEY_NUM_LOCK: u32 = 77; +const KEY_MOD5: u32 = 116; + #[derive(Clone, Default)] struct KeyboardState { focused_surface: Option, @@ -1240,6 +1261,42 @@ struct KeyboardState { last_keycode: Option, last_state: Option, last_time: Option, + depressed: u32, + latched: u32, + locked: u32, + group: u32, +} + +impl KeyboardState { + fn modifier_bit_for_key(keycode: u32) -> Option { + match keycode { + k if k == KEY_LEFT_SHIFT || k == KEY_RIGHT_SHIFT => Some(MOD_SHIFT), + k if k == KEY_LEFT_CTRL || k == KEY_RIGHT_CTRL => Some(MOD_CTRL), + k if k == KEY_LEFT_ALT || k == KEY_RIGHT_ALT => Some(MOD_ALT), + k if k == KEY_LEFT_LOGO || k == KEY_RIGHT_LOGO => Some(MOD_LOGO), + KEY_CAPS_LOCK => Some(MOD_CAPS), + KEY_NUM_LOCK => Some(MOD_MOD2), + KEY_MOD5 => Some(MOD_MOD5), + _ => None, + } + } + + fn apply_modifier_event(&mut self, keycode: u32, pressed: bool) { + let Some(bit) = Self::modifier_bit_for_key(keycode) else { + return; + }; + if keycode == KEY_CAPS_LOCK || keycode == KEY_NUM_LOCK { + if pressed { + self.locked ^= bit; + } + return; + } + if pressed { + self.depressed |= bit; + } else { + self.depressed &= !bit; + } + } } #[derive(Clone, Default)] @@ -2848,6 +2905,20 @@ impl Compositor { keyboard_state.last_time = Some(time); keyboard_state.last_keycode = Some(keycode); keyboard_state.last_state = Some(state); + let pressed = state == 1; + keyboard_state.apply_modifier_event(keycode, pressed); + } + } else if opcode == WL_KEYBOARD_MODIFIERS { + if let (Some(depressed), Some(latched), Some(locked), Some(group)) = ( + read_payload_u32(payload, 1), + read_payload_u32(payload, 2), + read_payload_u32(payload, 3), + read_payload_u32(payload, 4), + ) { + keyboard_state.depressed = depressed; + keyboard_state.latched = latched; + keyboard_state.locked = locked; + keyboard_state.group = group; } } if let Some(event) = keyboard_state.pending_events.pop_front() { @@ -4057,11 +4128,15 @@ OBJECT_TYPE_WP_PRESENTATION_FEEDBACK => match opcode { { let mut msg = Vec::with_capacity(28); push_header(&mut msg, keyboard_id, WL_KEYBOARD_MODIFIERS, 20); + let (depressed, latched, locked, group) = { + let kb = self.keyboard_state.lock().unwrap(); + (kb.depressed, kb.latched, kb.locked, kb.group) + }; push_u32(&mut msg, self.next_serial()); - push_u32(&mut msg, 0); - push_u32(&mut msg, 0); - push_u32(&mut msg, 0); - push_u32(&mut msg, 0); + push_u32(&mut msg, depressed); + push_u32(&mut msg, latched); + push_u32(&mut msg, locked); + push_u32(&mut msg, group); self.write_event(client_id, stream, &msg, "wl_keyboard.modifiers")?; } Ok(()) @@ -4086,6 +4161,40 @@ OBJECT_TYPE_WP_PRESENTATION_FEEDBACK => match opcode { self.write_event(client_id, stream, &msg, "wl_keyboard.key") } + fn send_keyboard_modifiers( + &self, + client_id: u32, + stream: &mut UnixStream, + keyboard_id: u32, + ) -> Result<(), String> { + let (depressed, latched, locked, group) = { + let kb = self.keyboard_state.lock().unwrap(); + (kb.depressed, kb.latched, kb.locked, kb.group) + }; + let mut msg = Vec::with_capacity(28); + push_header(&mut msg, keyboard_id, WL_KEYBOARD_MODIFIERS, 20); + push_u32(&mut msg, self.next_serial()); + push_u32(&mut msg, depressed); + push_u32(&mut msg, latched); + push_u32(&mut msg, locked); + push_u32(&mut msg, group); + self.write_event(client_id, stream, &msg, "wl_keyboard.modifiers") + } + + fn set_modifier_state( + &self, + depressed: u32, + latched: u32, + locked: u32, + group: u32, + ) { + let mut kb = self.keyboard_state.lock().unwrap(); + kb.depressed = depressed; + kb.latched = latched; + kb.locked = locked; + kb.group = group; + } + fn send_zxdg_toplevel_decoration_configure( &self, client_id: u32,