From 316a3aac97c8797631dbf54bbcc9d2c6c01bffd2 Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Tue, 24 Oct 2023 02:07:45 +0200 Subject: [PATCH 1/6] wayland: Added more logging --- src/linux/wayland.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index 9b78d981..3e138a5c 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -148,6 +148,13 @@ impl Con { let (keysyms_per_keycode, keysyms) = (0, vec![]); let keymap = KeyMap::new(8, 255, unused_keycodes, keysyms_per_keycode, keysyms); + trace!( + "protocols available\nvirtual_keyboard: {}\ninput_method: {}\nvirtual_pointer: {}", + virtual_keyboard.is_some(), + input_method.is_some(), + virtual_pointer.is_some(), + ); + if virtual_keyboard.is_none() && input_method.is_none() && virtual_pointer.is_none() { return Err(NewConError::EstablishCon( "no protocol available to simulate input", @@ -183,10 +190,12 @@ impl Con { let keycode = keycode - 8; // Adjust by 8 due to the xkb/xwayland requirements if direction == Direction::Press || direction == Direction::Click { + trace!("vk.key({time}, {keycode}, 1)"); vk.key(time, keycode, 1); self.flush()?; } if direction == Direction::Release || direction == Direction::Click { + trace!("vk.key({time}, {keycode}, 0)"); vk.key(time, keycode, 0); self.flush()?; } @@ -200,6 +209,7 @@ impl Con { fn send_modifier_event(&mut self, modifiers: ModifierBitflag) -> InputResult<()> { if let Some(vk) = &self.virtual_keyboard { is_alive(vk)?; + trace!("vk.modifiers({modifiers}, 0, 0, 0)"); vk.modifiers(modifiers, 0, 0, 0); self.flush()?; return Ok(()); @@ -212,6 +222,7 @@ impl Con { /// # Errors /// TODO fn apply_keymap(&mut self) -> InputResult<()> { + trace!("apply_keymap(&mut self)"); if let Some(vk) = &self.virtual_keyboard { is_alive(vk)?; let Ok(keymap_res) = self.keymap.regenerate() else { @@ -223,6 +234,7 @@ impl Con { // There should always be a file at this point so unwrapping is fine // here if let Some(keymap_size) = keymap_res { + trace!("update wayland keymap"); vk.keymap(1, self.keymap.file.as_ref().unwrap().as_fd(), keymap_size); self.flush()?; } @@ -526,6 +538,7 @@ impl KeyboardControllableNext for Con { fn fast_text_entry(&mut self, text: &str) -> InputResult> { if let Some((im, serial)) = &mut self.input_method { is_alive(im)?; + trace!("fast text input with imput_method protocol"); im.commit_string(text.to_string()); im.commit(*serial); *serial = serial.wrapping_add(1); @@ -543,6 +556,7 @@ impl KeyboardControllableNext for Con { // Send the events to the compositor if let Ok(modifier) = Modifier::try_from(key) { + trace!("it is a modifier: {modifier:?}"); if direction == Direction::Click || direction == Direction::Press { let modifiers = self .keymap @@ -604,12 +618,14 @@ impl MouseControllableNext for Con { if direction == Direction::Press || direction == Direction::Click { let time = self.get_time(); + trace!("vp.button({time}, {button}, wl_pointer::ButtonState::Pressed)"); vp.button(time, button, wl_pointer::ButtonState::Pressed); vp.frame(); // TODO: Check if this is needed } if direction == Direction::Release || direction == Direction::Click { let time = self.get_time(); + trace!("vp.button({time}, {button}, wl_pointer::ButtonState::Released)"); vp.button(time, button, wl_pointer::ButtonState::Released); vp.frame(); // TODO: Check if this is needed } @@ -631,6 +647,7 @@ impl MouseControllableNext for Con { let time = self.get_time(); match coordinate { Coordinate::Relative => { + trace!("vp.motion({time}, {x}, {y})"); vp.motion(time, x as f64, y as f64); } Coordinate::Absolute => { @@ -644,6 +661,7 @@ impl MouseControllableNext for Con { "the absolute coordinates cannot be negative", )); }; + trace!("vp.motion_absolute({time}, {x}, {y}, u32::MAX, u32::MAX)"); vp.motion_absolute( time, x, @@ -671,6 +689,7 @@ impl MouseControllableNext for Con { Axis::Horizontal => wl_pointer::Axis::HorizontalScroll, Axis::Vertical => wl_pointer::Axis::VerticalScroll, }; + trace!("vp.axis(time, axis, length.into())"); vp.axis(time, axis, length.into()); vp.frame(); // TODO: Check if this is needed } From 7e940c8ef1313b41d32ff2dd0be4f281a620bb14 Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Tue, 24 Oct 2023 02:15:53 +0200 Subject: [PATCH 2/6] wayland: Do not attempt to map modifiers --- src/linux/wayland.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index 3e138a5c..0742a024 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -549,11 +549,6 @@ impl KeyboardControllableNext for Con { } fn enter_key(&mut self, key: Key, direction: Direction) -> InputResult<()> { - let keycode = self.keymap.key_to_keycode(&(), key)?; - - // Apply the new keymap if there were any changes - self.apply_keymap()?; - // Send the events to the compositor if let Ok(modifier) = Modifier::try_from(key) { trace!("it is a modifier: {modifier:?}"); @@ -570,13 +565,16 @@ impl KeyboardControllableNext for Con { self.send_modifier_event(modifiers)?; } } else { + let keycode = self.keymap.key_to_keycode(&(), key)?; + + // Apply the new keymap if there were any changes + self.apply_keymap()?; self.send_key_event(keycode, direction)?; + // Let the keymap know that the key was held/no longer held + // This is important to avoid unmapping held keys + self.keymap.enter_key(keycode, direction); } - // Let the keymap know that the key was held/no longer held - // This is important to avoid unmapping held keys - self.keymap.enter_key(keycode, direction); - Ok(()) } } From 87104e87cb4c7a06c14f76f35d34edda6d56e97c Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Tue, 24 Oct 2023 02:29:55 +0200 Subject: [PATCH 3/6] wayland: apply the keymap immediately after establishing the connection --- src/linux/wayland.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index 0742a024..e097200f 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -160,8 +160,7 @@ impl Con { "no protocol available to simulate input", )); } - - Ok(Self { + let mut connection = Self { keymap, event_queue, state, @@ -169,7 +168,12 @@ impl Con { input_method, virtual_pointer, base_time, - }) + }; + + if connection.apply_keymap().is_err() { + return Err(NewConError::EstablishCon("unable to apply the keymap")); + }; + Ok(connection) } /// Get the duration since the Keymap was created From b5f88b29a3d76eca7ee1454ed6781150744ec876 Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Tue, 24 Oct 2023 15:57:13 +0200 Subject: [PATCH 4/6] wayland: added trace and changed fast_text fn --- src/linux/wayland.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index e097200f..2ee7a67d 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -250,7 +250,10 @@ impl Con { /// Flush the Wayland queue fn flush(&self) -> InputResult<()> { match self.event_queue.flush() { - Ok(()) => Ok(()), + Ok(()) => { + trace!("flushed event queue"); + Ok(()) + } Err(e) => { error!("{:?}", e); Err(InputError::Simulate("could not flush wayland queue")) @@ -279,6 +282,7 @@ impl Drop for Con { if self.flush().is_err() { error!("could not flush wayland queue"); } + trace!("wayland objects were destroyed"); } } @@ -540,7 +544,7 @@ impl Drop for WaylandState { impl KeyboardControllableNext for Con { fn fast_text_entry(&mut self, text: &str) -> InputResult> { - if let Some((im, serial)) = &mut self.input_method { + if let Some((im, serial)) = self.input_method.as_mut() { is_alive(im)?; trace!("fast text input with imput_method protocol"); im.commit_string(text.to_string()); From d12dbca5e0a4f14420f85369ac4baf3e13c04159 Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Wed, 25 Oct 2023 04:19:00 +0200 Subject: [PATCH 5/6] Do a roundtrip instead of flushing --- src/linux/wayland.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index 2ee7a67d..6f677ef7 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -196,12 +196,18 @@ impl Con { if direction == Direction::Press || direction == Direction::Click { trace!("vk.key({time}, {keycode}, 1)"); vk.key(time, keycode, 1); - self.flush()?; + // TODO: Change to flush() + if self.event_queue.roundtrip(&mut self.state).is_err() { + return Err(InputError::Simulate("The roundtrip on Wayland failed")); + } } if direction == Direction::Release || direction == Direction::Click { trace!("vk.key({time}, {keycode}, 0)"); vk.key(time, keycode, 0); - self.flush()?; + // TODO: Change to flush() + if self.event_queue.roundtrip(&mut self.state).is_err() { + return Err(InputError::Simulate("The roundtrip on Wayland failed")); + } } return Ok(()); } @@ -215,7 +221,10 @@ impl Con { is_alive(vk)?; trace!("vk.modifiers({modifiers}, 0, 0, 0)"); vk.modifiers(modifiers, 0, 0, 0); - self.flush()?; + // TODO: Change to flush() + if self.event_queue.roundtrip(&mut self.state).is_err() { + return Err(InputError::Simulate("The roundtrip on Wayland failed")); + } return Ok(()); } Err(InputError::Simulate("no way to enter modifier")) @@ -240,7 +249,10 @@ impl Con { if let Some(keymap_size) = keymap_res { trace!("update wayland keymap"); vk.keymap(1, self.keymap.file.as_ref().unwrap().as_fd(), keymap_size); - self.flush()?; + // TODO: Change to flush() + if self.event_queue.roundtrip(&mut self.state).is_err() { + return Err(InputError::Simulate("The roundtrip on Wayland failed")); + } } return Ok(()); } @@ -283,6 +295,9 @@ impl Drop for Con { error!("could not flush wayland queue"); } trace!("wayland objects were destroyed"); + + // TODO: Change to flush() + let _ = self.event_queue.roundtrip(&mut self.state); } } @@ -550,7 +565,10 @@ impl KeyboardControllableNext for Con { im.commit_string(text.to_string()); im.commit(*serial); *serial = serial.wrapping_add(1); - self.flush()?; + // TODO: Change to flush() + if self.event_queue.roundtrip(&mut self.state).is_err() { + return Err(InputError::Simulate("The roundtrip on Wayland failed")); + } return Ok(Some(())); } Ok(None) From 3608b5017c7b016bfdb8220f1590a2fc3495a8ee Mon Sep 17 00:00:00 2001 From: pentamassiv Date: Wed, 1 Nov 2023 21:55:13 +0100 Subject: [PATCH 6/6] wayland: Move intitializing the protocols to a different function --- src/linux/wayland.rs | 101 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/src/linux/wayland.rs b/src/linux/wayland.rs index 6f677ef7..34cf7118 100644 --- a/src/linux/wayland.rs +++ b/src/linux/wayland.rs @@ -103,39 +103,7 @@ impl Con { return Err(NewConError::EstablishCon("wayland roundtrip not possible")); }; - // Setup virtual keyboard - let virtual_keyboard = if let Some(seat) = state.seat.as_ref() { - state - .keyboard_manager - .as_ref() - .map(|vk_mgr| vk_mgr.create_virtual_keyboard(seat, &qh, ())) - } else { - None - }; - - // Setup input method - let input_method = if let Some(seat) = state.seat.as_ref() { - state - .im_manager - .as_ref() - .map(|im_mgr| (im_mgr.get_input_method(seat, &qh, ()), 0)) - } else { - None - }; - - // Setup virtual pointer - let virtual_pointer = state - .pointer_manager - .as_ref() - .map(|vp_mgr| vp_mgr.create_virtual_pointer(state.seat.as_ref(), &qh, ())); - - // Try to authenticate for the KDE Fake Input protocol - // TODO: Get this protocol to work - if let Some(kde_input) = &state.kde_input { - let application = "enigo".to_string(); - let reason = "enter keycodes or move the mouse".to_string(); - kde_input.authenticate(application, reason); - } + let (virtual_keyboard, input_method, virtual_pointer) = (None, None, None); let base_time = Instant::now(); @@ -148,18 +116,6 @@ impl Con { let (keysyms_per_keycode, keysyms) = (0, vec![]); let keymap = KeyMap::new(8, 255, unused_keycodes, keysyms_per_keycode, keysyms); - trace!( - "protocols available\nvirtual_keyboard: {}\ninput_method: {}\nvirtual_pointer: {}", - virtual_keyboard.is_some(), - input_method.is_some(), - virtual_pointer.is_some(), - ); - - if virtual_keyboard.is_none() && input_method.is_none() && virtual_pointer.is_none() { - return Err(NewConError::EstablishCon( - "no protocol available to simulate input", - )); - } let mut connection = Self { keymap, event_queue, @@ -170,12 +126,67 @@ impl Con { base_time, }; + connection.init_protocols()?; + if connection.apply_keymap().is_err() { return Err(NewConError::EstablishCon("unable to apply the keymap")); }; Ok(connection) } + /// Try to set up all the protocols. An error is returned, if no protocol is + /// available + fn init_protocols(&mut self) -> Result<(), NewConError> { + let qh = self.event_queue.handle(); + + if let Some(seat) = self.state.seat.as_ref() { + // Setup virtual keyboard + self.virtual_keyboard = self + .state + .keyboard_manager + .as_ref() + .map(|vk_mgr| vk_mgr.create_virtual_keyboard(seat, &qh, ())); + // Setup input method + self.input_method = self + .state + .im_manager + .as_ref() + .map(|im_mgr| (im_mgr.get_input_method(seat, &qh, ()), 0)); + }; + + // Setup virtual pointer + self.virtual_pointer = self + .state + .pointer_manager + .as_ref() + .map(|vp_mgr| vp_mgr.create_virtual_pointer(self.state.seat.as_ref(), &qh, ())); + + // Try to authenticate for the KDE Fake Input protocol + // TODO: Get this protocol to work + if let Some(kde_input) = &self.state.kde_input { + let application = "enigo".to_string(); + let reason = "enter keycodes or move the mouse".to_string(); + kde_input.authenticate(application, reason); + } + + trace!( + "protocols available\nvirtual_keyboard: {}\ninput_method: {}\nvirtual_pointer: {}", + self.virtual_keyboard.is_some(), + self.input_method.is_some(), + self.virtual_pointer.is_some(), + ); + + if self.virtual_keyboard.is_none() + && self.input_method.is_none() + && self.virtual_pointer.is_none() + { + return Err(NewConError::EstablishCon( + "no protocol available to simulate input", + )); + } + Ok(()) + } + /// Get the duration since the Keymap was created fn get_time(&self) -> u32 { let duration = self.base_time.elapsed();