Skip to content

Commit

Permalink
Merge pull request #237 from pentamassiv/wayland_log
Browse files Browse the repository at this point in the history
wayland: make it work a second time too
  • Loading branch information
pentamassiv authored Nov 1, 2023
2 parents 96d5fd2 + 3608b50 commit 9e02c6c
Showing 1 changed file with 108 additions and 54 deletions.
162 changes: 108 additions & 54 deletions src/linux/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,66 +103,88 @@ 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
let (virtual_keyboard, input_method, virtual_pointer) = (None, None, None);

let base_time = Instant::now();

let mut unused_keycodes = VecDeque::with_capacity(255 - 8 + 1); // All keycodes are unused when initialized
for n in 8..=255 {
unused_keycodes.push_back(n as Keycode);
}

// TODO: Double check this and adjust it
let (keysyms_per_keycode, keysyms) = (0, vec![]);
let keymap = KeyMap::new(8, 255, unused_keycodes, keysyms_per_keycode, keysyms);

let mut connection = Self {
keymap,
event_queue,
state,
virtual_keyboard,
input_method,
virtual_pointer,
base_time,
};

// Setup input method
let input_method = if let Some(seat) = state.seat.as_ref() {
state
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))
} else {
None
.map(|im_mgr| (im_mgr.get_input_method(seat, &qh, ()), 0));
};

// Setup virtual pointer
let virtual_pointer = state
self.virtual_pointer = self
.state
.pointer_manager
.as_ref()
.map(|vp_mgr| vp_mgr.create_virtual_pointer(state.seat.as_ref(), &qh, ()));
.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) = &state.kde_input {
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);
}

let base_time = Instant::now();

let mut unused_keycodes = VecDeque::with_capacity(255 - 8 + 1); // All keycodes are unused when initialized
for n in 8..=255 {
unused_keycodes.push_back(n as Keycode);
}

// TODO: Double check this and adjust it
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: {}",
self.virtual_keyboard.is_some(),
self.input_method.is_some(),
self.virtual_pointer.is_some(),
);

if virtual_keyboard.is_none() && input_method.is_none() && virtual_pointer.is_none() {
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(Self {
keymap,
event_queue,
state,
virtual_keyboard,
input_method,
virtual_pointer,
base_time,
})
Ok(())
}

/// Get the duration since the Keymap was created
Expand All @@ -183,12 +205,20 @@ 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()?;
// 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(());
}
Expand All @@ -200,8 +230,12 @@ 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()?;
// 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"))
Expand All @@ -212,6 +246,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 {
Expand All @@ -223,8 +258,12 @@ 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()?;
// 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(());
}
Expand All @@ -234,7 +273,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"))
Expand Down Expand Up @@ -263,6 +305,10 @@ impl Drop for Con {
if self.flush().is_err() {
error!("could not flush wayland queue");
}
trace!("wayland objects were destroyed");

// TODO: Change to flush()
let _ = self.event_queue.roundtrip(&mut self.state);
}
}

Expand Down Expand Up @@ -524,25 +570,25 @@ impl Drop for WaylandState {

impl KeyboardControllableNext for Con {
fn fast_text_entry(&mut self, text: &str) -> InputResult<Option<()>> {
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());
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)
}

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:?}");
if direction == Direction::Click || direction == Direction::Press {
let modifiers = self
.keymap
Expand All @@ -556,13 +602,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(())
}
}
Expand Down Expand Up @@ -604,12 +653,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
}
Expand All @@ -631,6 +682,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 => {
Expand All @@ -644,6 +696,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,
Expand Down Expand Up @@ -671,6 +724,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
}
Expand Down

0 comments on commit 9e02c6c

Please sign in to comment.