#![allow(dead_code)]
use crate::render::AppState;
use wayland_client::{
QueueHandle,
protocol::{wl_output, wl_pointer},
};
use wayland_protocols_wlr::virtual_pointer::v1::client::{
zwlr_virtual_pointer_manager_v1, zwlr_virtual_pointer_v1,
};
pub enum MouseButton {
Left,
Right,
Middle,
}
pub enum ScrollDirection {
Up,
Down,
Left,
Right,
}
pub struct VirtualPointer {
pointer: zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1,
}
impl VirtualPointer {
pub fn new(
manager: &zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1,
output: Option<&wl_output::WlOutput>,
qhandle: &QueueHandle<AppState>,
) -> Self {
let pointer = if output.is_some() {
manager.create_virtual_pointer_with_output(None, output, qhandle, ())
} else {
manager.create_virtual_pointer(None, qhandle, ())
};
Self { pointer }
}
pub fn move_to(&self, x: i32, y: i32, screen_w: i32, screen_h: i32) {
let time = 0;
self.pointer
.motion_absolute(time, x as u32, y as u32, screen_w as u32, screen_h as u32);
self.pointer.frame();
}
pub fn move_by(&self, dx: f64, dy: f64) {
let time = 0;
self.pointer.motion(time, dx, dy);
self.pointer.frame();
}
pub fn click(&self, button: MouseButton) {
let btn_code = match button {
MouseButton::Left => 0x110, MouseButton::Right => 0x111, MouseButton::Middle => 0x112, };
let time = 0;
self.pointer
.button(time, btn_code, wl_pointer::ButtonState::Pressed);
self.pointer.frame();
std::thread::sleep(std::time::Duration::from_millis(50));
self.pointer
.button(time, btn_code, wl_pointer::ButtonState::Released);
self.pointer.frame();
}
pub fn scroll(&self, direction: ScrollDirection, distance: i32) {
let time = 0;
let axis = match direction {
ScrollDirection::Up | ScrollDirection::Down => wl_pointer::Axis::VerticalScroll,
ScrollDirection::Left | ScrollDirection::Right => wl_pointer::Axis::HorizontalScroll,
};
let value = match direction {
ScrollDirection::Up | ScrollDirection::Left => -distance,
ScrollDirection::Down | ScrollDirection::Right => distance,
};
self.pointer.axis(time, axis, value as f64);
self.pointer.frame();
}
pub fn drag_to(
&self,
start_x: i32,
start_y: i32,
end_x: i32,
end_y: i32,
screen_w: i32,
screen_h: i32,
) {
self.move_to(start_x, start_y, screen_w, screen_h);
std::thread::sleep(std::time::Duration::from_millis(50));
self.pointer
.button(0, 0x110, wl_pointer::ButtonState::Pressed);
self.pointer.frame();
std::thread::sleep(std::time::Duration::from_millis(50));
self.move_to(end_x, end_y, screen_w, screen_h);
std::thread::sleep(std::time::Duration::from_millis(50));
self.pointer
.button(0, 0x110, wl_pointer::ButtonState::Released);
self.pointer.frame();
}
}