1
0
Fork 0
forked from wry/wry

wayland: implement wp_cursor_shap_manager_v1

This commit is contained in:
Julian Orth 2024-02-08 14:13:18 +01:00
parent af3b7b0868
commit 3acf0558a3
12 changed files with 452 additions and 60 deletions

View file

@ -784,13 +784,39 @@ impl WlSeatGlobal {
};
let tpl = match cursor {
KnownCursor::Default => &cursors.default,
KnownCursor::ContextMenu => &cursors.context_menu,
KnownCursor::Help => &cursors.help,
KnownCursor::Pointer => &cursors.pointer,
KnownCursor::ResizeLeftRight => &cursors.resize_left_right,
KnownCursor::ResizeTopBottom => &cursors.resize_top_bottom,
KnownCursor::ResizeTopLeft => &cursors.resize_top_left,
KnownCursor::ResizeTopRight => &cursors.resize_top_right,
KnownCursor::ResizeBottomLeft => &cursors.resize_bottom_left,
KnownCursor::ResizeBottomRight => &cursors.resize_bottom_right,
KnownCursor::Progress => &cursors.progress,
KnownCursor::Wait => &cursors.wait,
KnownCursor::Cell => &cursors.cell,
KnownCursor::Crosshair => &cursors.crosshair,
KnownCursor::Text => &cursors.text,
KnownCursor::VerticalText => &cursors.vertical_text,
KnownCursor::Alias => &cursors.alias,
KnownCursor::Copy => &cursors.copy,
KnownCursor::Move => &cursors.r#move,
KnownCursor::NoDrop => &cursors.no_drop,
KnownCursor::NotAllowed => &cursors.not_allowed,
KnownCursor::Grab => &cursors.grab,
KnownCursor::Grabbing => &cursors.grabbing,
KnownCursor::EResize => &cursors.e_resize,
KnownCursor::NResize => &cursors.n_resize,
KnownCursor::NeResize => &cursors.ne_resize,
KnownCursor::NwResize => &cursors.nw_resize,
KnownCursor::SResize => &cursors.s_resize,
KnownCursor::SeResize => &cursors.se_resize,
KnownCursor::SwResize => &cursors.sw_resize,
KnownCursor::WResize => &cursors.w_resize,
KnownCursor::EwResize => &cursors.ew_resize,
KnownCursor::NsResize => &cursors.ns_resize,
KnownCursor::NeswResize => &cursors.nesw_resize,
KnownCursor::NwseResize => &cursors.nwse_resize,
KnownCursor::ColResize => &cursors.col_resize,
KnownCursor::RowResize => &cursors.row_resize,
KnownCursor::AllScroll => &cursors.all_scroll,
KnownCursor::ZoomIn => &cursors.zoom_in,
KnownCursor::ZoomOut => &cursors.zoom_out,
};
self.set_cursor2(Some(tpl.instantiate(self.cursor_size.get())));
}

View file

@ -197,7 +197,7 @@ impl WlPointer {
}
};
if pointer_node.node_client_id() != Some(self.seat.client.id) {
log::warn!("ignoring wl_pointer.set_cursor (2)");
// log::warn!("ignoring wl_pointer.set_cursor (2)");
return Ok(());
}
// https://gitlab.freedesktop.org/wayland/wayland/-/issues/439

View file

@ -0,0 +1,136 @@
use {
crate::{
client::{Client, ClientError},
cursor::KnownCursor,
ifs::wl_seat::WlSeatGlobal,
leaks::Tracker,
object::Object,
utils::buffd::{MsgParser, MsgParserError},
wire::{wp_cursor_shape_device_v1::*, WpCursorShapeDeviceV1Id},
},
std::rc::Rc,
thiserror::Error,
};
const DEFAULT: u32 = 1;
const CONTEXT_MENU: u32 = 2;
const HELP: u32 = 3;
const POINTER: u32 = 4;
const PROGRESS: u32 = 5;
const WAIT: u32 = 6;
const CELL: u32 = 7;
const CROSSHAIR: u32 = 8;
const TEXT: u32 = 9;
const VERTICAL_TEXT: u32 = 10;
const ALIAS: u32 = 11;
const COPY: u32 = 12;
const MOVE: u32 = 13;
const NO_DROP: u32 = 14;
const NOT_ALLOWED: u32 = 15;
const GRAB: u32 = 16;
const GRABBING: u32 = 17;
const E_RESIZE: u32 = 18;
const N_RESIZE: u32 = 19;
const NE_RESIZE: u32 = 20;
const NW_RESIZE: u32 = 21;
const S_RESIZE: u32 = 22;
const SE_RESIZE: u32 = 23;
const SW_RESIZE: u32 = 24;
const W_RESIZE: u32 = 25;
const EW_RESIZE: u32 = 26;
const NS_RESIZE: u32 = 27;
const NESW_RESIZE: u32 = 28;
const NWSE_RESIZE: u32 = 29;
const COL_RESIZE: u32 = 30;
const ROW_RESIZE: u32 = 31;
const ALL_SCROLL: u32 = 32;
const ZOOM_IN: u32 = 33;
const ZOOM_OUT: u32 = 34;
pub struct WpCursorShapeDeviceV1 {
pub id: WpCursorShapeDeviceV1Id,
pub client: Rc<Client>,
pub seat: Rc<WlSeatGlobal>,
pub tracker: Tracker<Self>,
}
impl WpCursorShapeDeviceV1 {
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeDeviceV1Error> {
let _req: Destroy = self.client.parse(self, parser)?;
self.client.remove_obj(self)?;
Ok(())
}
fn set_shape(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeDeviceV1Error> {
let req: SetShape = self.client.parse(self, parser)?;
let cursor = match req.shape {
DEFAULT => KnownCursor::Default,
CONTEXT_MENU => KnownCursor::ContextMenu,
HELP => KnownCursor::Help,
POINTER => KnownCursor::Pointer,
PROGRESS => KnownCursor::Progress,
WAIT => KnownCursor::Wait,
CELL => KnownCursor::Cell,
CROSSHAIR => KnownCursor::Crosshair,
TEXT => KnownCursor::Text,
VERTICAL_TEXT => KnownCursor::VerticalText,
ALIAS => KnownCursor::Alias,
COPY => KnownCursor::Copy,
MOVE => KnownCursor::Move,
NO_DROP => KnownCursor::NoDrop,
NOT_ALLOWED => KnownCursor::NotAllowed,
GRAB => KnownCursor::Grab,
GRABBING => KnownCursor::Grabbing,
E_RESIZE => KnownCursor::EResize,
N_RESIZE => KnownCursor::NResize,
NE_RESIZE => KnownCursor::NeResize,
NW_RESIZE => KnownCursor::NwResize,
S_RESIZE => KnownCursor::SResize,
SE_RESIZE => KnownCursor::SeResize,
SW_RESIZE => KnownCursor::SwResize,
W_RESIZE => KnownCursor::WResize,
EW_RESIZE => KnownCursor::EwResize,
NS_RESIZE => KnownCursor::NsResize,
NESW_RESIZE => KnownCursor::NeswResize,
NWSE_RESIZE => KnownCursor::NwseResize,
COL_RESIZE => KnownCursor::ColResize,
ROW_RESIZE => KnownCursor::RowResize,
ALL_SCROLL => KnownCursor::AllScroll,
ZOOM_IN => KnownCursor::ZoomIn,
ZOOM_OUT => KnownCursor::ZoomOut,
_ => return Err(WpCursorShapeDeviceV1Error::UnknownShape(req.shape)),
};
let pointer_node = match self.seat.pointer_node() {
Some(n) => n,
_ => return Ok(()),
};
if pointer_node.node_client_id() != Some(self.client.id) {
return Ok(());
}
self.seat.set_known_cursor(cursor);
Ok(())
}
}
object_base! {
self = WpCursorShapeDeviceV1;
DESTROY => destroy,
SET_SHAPE => set_shape,
}
impl Object for WpCursorShapeDeviceV1 {}
simple_add_obj!(WpCursorShapeDeviceV1);
#[derive(Debug, Error)]
pub enum WpCursorShapeDeviceV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
#[error("Parsing failed")]
MsgParserError(#[source] Box<MsgParserError>),
#[error("Shape {0} is unknown")]
UnknownShape(u32),
}
efrom!(WpCursorShapeDeviceV1Error, ClientError);
efrom!(WpCursorShapeDeviceV1Error, MsgParserError);

View file

@ -0,0 +1,119 @@
use {
crate::{
client::{Client, ClientError},
globals::{Global, GlobalName},
ifs::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1,
leaks::Tracker,
object::Object,
utils::buffd::{MsgParser, MsgParserError},
wire::{wp_cursor_shape_manager_v1::*, WpCursorShapeManagerV1Id},
},
std::rc::Rc,
thiserror::Error,
};
pub struct WpCursorShapeManagerV1Global {
pub name: GlobalName,
}
impl WpCursorShapeManagerV1Global {
pub fn new(name: GlobalName) -> Self {
Self { name }
}
fn bind_(
self: Rc<Self>,
id: WpCursorShapeManagerV1Id,
client: &Rc<Client>,
version: u32,
) -> Result<(), WpCursorShapeManagerV1Error> {
let mgr = Rc::new(WpCursorShapeManagerV1 {
id,
client: client.clone(),
tracker: Default::default(),
version,
});
track!(client, mgr);
client.add_client_obj(&mgr)?;
Ok(())
}
}
global_base!(
WpCursorShapeManagerV1Global,
WpCursorShapeManagerV1,
WpCursorShapeManagerV1Error
);
simple_add_global!(WpCursorShapeManagerV1Global);
impl Global for WpCursorShapeManagerV1Global {
fn singleton(&self) -> bool {
true
}
fn version(&self) -> u32 {
1
}
}
pub struct WpCursorShapeManagerV1 {
pub id: WpCursorShapeManagerV1Id,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub version: u32,
}
impl WpCursorShapeManagerV1 {
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeManagerV1Error> {
let _req: Destroy = self.client.parse(self, parser)?;
self.client.remove_obj(self)?;
Ok(())
}
fn get_pointer(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeManagerV1Error> {
let req: GetPointer = self.client.parse(self, parser)?;
let pointer = self.client.lookup(req.pointer)?;
let device = Rc::new(WpCursorShapeDeviceV1 {
id: req.cursor_shape_device,
client: self.client.clone(),
seat: pointer.seat.global.clone(),
tracker: Default::default(),
});
track!(self.client, device);
self.client.add_client_obj(&device)?;
Ok(())
}
fn get_tablet_tool_v2(
&self,
parser: MsgParser<'_, '_>,
) -> Result<(), WpCursorShapeManagerV1Error> {
let _req: GetTabletToolV2 = self.client.parse(self, parser)?;
Err(WpCursorShapeManagerV1Error::TabletToolNotSupported)
}
}
object_base! {
self = WpCursorShapeManagerV1;
DESTROY => destroy,
GET_POINTER => get_pointer,
GET_TABLET_TOOL_V2 => get_tablet_tool_v2,
}
impl Object for WpCursorShapeManagerV1 {}
simple_add_obj!(WpCursorShapeManagerV1);
#[derive(Debug, Error)]
pub enum WpCursorShapeManagerV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
#[error("Parsing failed")]
MsgParserError(#[source] Box<MsgParserError>),
#[error("This compositor does not support tablet tools")]
TabletToolNotSupported,
}
efrom!(WpCursorShapeManagerV1Error, ClientError);
efrom!(WpCursorShapeManagerV1Error, MsgParserError);