use i_slint_core::items::MouseCursor;
use slint::{
SharedString,
platform::{Key, PointerEventButton},
};
use smithay_client_toolkit::{
reexports::{
client::{QueueHandle, protocol::wl_pointer},
protocols::wp::cursor_shape::v1::client::wp_cursor_shape_device_v1::Shape,
},
seat::{
keyboard::{KeyEvent, Keysym},
pointer::{PointerData, cursor_shape::CursorShapeManager},
},
};
use crate::wayland_adapter::SpellWin;
#[derive(Debug)]
pub(crate) struct PointerState {
pub(crate) pointer: Option<wl_pointer::WlPointer>,
pub(crate) pointer_data: Option<PointerData>,
pub(crate) cursor_shape: CursorShapeManager,
pub(crate) current_wayland_cursor: MouseCursor,
pub(crate) last_cursor_enter_serial: Option<u32>,
}
impl PointerState {
pub(crate) fn update_cursor(
&mut self,
mouse_cursor: MouseCursor,
queue: &QueueHandle<SpellWin>,
) {
if let Some(serial) = self.last_cursor_enter_serial
&& let Some(pointer) = self.pointer.as_ref()
&& mouse_cursor != self.current_wayland_cursor
{
if mouse_cursor == MouseCursor::None {
pointer.set_cursor(serial, None, 0, 0);
} else {
self.cursor_shape
.get_shape_device(pointer, queue)
.set_shape(serial, mouse_cursor_to_shape(mouse_cursor));
}
self.current_wayland_cursor = mouse_cursor;
}
}
}
const BTN_LEFT: u32 = 0x110;
const BTN_RIGHT: u32 = 0x111;
const BTN_MIDDLE: u32 = 0x112;
const BTN_SIDE: u32 = 0x113;
const BTN_EXTRA: u32 = 0x114;
const BTN_FORWARD: u32 = 0x115;
const BTN_BACK: u32 = 0x116;
pub(super) fn map_pointer_button(button: u32) -> PointerEventButton {
match button {
BTN_LEFT => PointerEventButton::Left,
BTN_RIGHT => PointerEventButton::Right,
BTN_MIDDLE => PointerEventButton::Middle,
BTN_SIDE | BTN_BACK => PointerEventButton::Back,
BTN_EXTRA | BTN_FORWARD => PointerEventButton::Forward,
_ => PointerEventButton::Other,
}
}
pub(super) fn mouse_cursor_to_shape(cursor: MouseCursor) -> Shape {
match cursor {
MouseCursor::Default => Shape::Default,
MouseCursor::Help => Shape::Help,
MouseCursor::Pointer => Shape::Pointer,
MouseCursor::Progress => Shape::Progress,
MouseCursor::Wait => Shape::Wait,
MouseCursor::Crosshair => Shape::Crosshair,
MouseCursor::Text => Shape::Text,
MouseCursor::Alias => Shape::Alias,
MouseCursor::Copy => Shape::Copy,
MouseCursor::Move => Shape::Move,
MouseCursor::NoDrop => Shape::NoDrop,
MouseCursor::NotAllowed => Shape::NotAllowed,
MouseCursor::Grab => Shape::Grab,
MouseCursor::Grabbing => Shape::Grabbing,
MouseCursor::ColResize => Shape::ColResize,
MouseCursor::RowResize => Shape::RowResize,
MouseCursor::NResize => Shape::NResize,
MouseCursor::EResize => Shape::EResize,
MouseCursor::SResize => Shape::SResize,
MouseCursor::WResize => Shape::WResize,
MouseCursor::NeResize => Shape::NeResize,
MouseCursor::NwResize => Shape::NwResize,
MouseCursor::SeResize => Shape::SeResize,
MouseCursor::SwResize => Shape::SwResize,
MouseCursor::EwResize => Shape::EwResize,
MouseCursor::NsResize => Shape::NsResize,
MouseCursor::NeswResize => Shape::NeswResize,
MouseCursor::NwseResize => Shape::NwseResize,
_ => Shape::Default,
}
}
pub(super) fn get_string(event: KeyEvent) -> SharedString {
let mut key: Option<Key> = None;
match event.keysym {
Keysym::BackSpace => key = Some(Key::Backspace),
Keysym::Tab => key = Some(Key::Tab),
Keysym::Return => key = Some(Key::Return),
Keysym::Escape => key = Some(Key::Escape),
Keysym::BackTab => key = Some(Key::Backtab),
Keysym::Delete => key = Some(Key::Delete),
Keysym::Shift_L => key = Some(Key::Shift),
Keysym::Shift_R => key = Some(Key::ShiftR),
Keysym::Control_L => key = Some(Key::Control),
Keysym::Control_R => key = Some(Key::ControlR),
Keysym::Alt_L => key = Some(Key::Alt),
Keysym::Alt_R => key = Some(Key::AltGr),
Keysym::Caps_Lock => key = Some(Key::CapsLock),
Keysym::Meta_L => key = Some(Key::Meta),
Keysym::Meta_R => key = Some(Key::MetaR),
Keysym::space => key = Some(Key::Space),
Keysym::Up | Keysym::uparrow => key = Some(Key::UpArrow),
Keysym::Down | Keysym::downarrow => key = Some(Key::DownArrow),
Keysym::Left | Keysym::leftarrow => key = Some(Key::LeftArrow),
Keysym::Right | Keysym::rightarrow => key = Some(Key::RightArrow),
Keysym::F1 => key = Some(Key::F1),
Keysym::F2 => key = Some(Key::F2),
Keysym::F3 => key = Some(Key::F3),
Keysym::F4 => key = Some(Key::F4),
Keysym::F5 => key = Some(Key::F5),
Keysym::F6 => key = Some(Key::F6),
Keysym::F7 => key = Some(Key::F7),
Keysym::F8 => key = Some(Key::F8),
Keysym::F9 => key = Some(Key::F9),
Keysym::F10 => key = Some(Key::F10),
Keysym::F11 => key = Some(Key::F11),
Keysym::F12 => key = Some(Key::F12),
Keysym::F13 => key = Some(Key::F13),
Keysym::F14 => key = Some(Key::F14),
Keysym::F15 => key = Some(Key::F15),
Keysym::F16 => key = Some(Key::F16),
Keysym::F17 => key = Some(Key::F17),
Keysym::F18 => key = Some(Key::F18),
Keysym::F19 => key = Some(Key::F19),
Keysym::F20 => key = Some(Key::F20),
Keysym::F21 => key = Some(Key::F21),
Keysym::F22 => key = Some(Key::F22),
Keysym::F23 => key = Some(Key::F23),
Keysym::F24 => key = Some(Key::F24),
Keysym::Insert => key = Some(Key::Insert),
Keysym::Home => key = Some(Key::Home),
Keysym::End => key = Some(Key::End),
Keysym::Page_Up => key = Some(Key::PageUp),
Keysym::Page_Down => key = Some(Key::PageDown),
Keysym::Scroll_Lock => key = Some(Key::ScrollLock),
Keysym::Pause => key = Some(Key::Pause),
Keysym::Sys_Req => key = Some(Key::SysReq),
Keysym::XF86_Stop => key = Some(Key::Stop),
Keysym::Menu => key = Some(Key::Menu),
_ => {}
}
if let Some(key) = key {
key.into()
} else {
SharedString::from(event.utf8.unwrap_or_default())
}
}