wayland: implement wp_cursor_shap_manager_v1
This commit is contained in:
parent
af3b7b0868
commit
3acf0558a3
12 changed files with 452 additions and 60 deletions
166
src/cursor.rs
166
src/cursor.rs
|
|
@ -61,29 +61,77 @@ pub trait Cursor {
|
||||||
|
|
||||||
pub struct ServerCursors {
|
pub struct ServerCursors {
|
||||||
pub default: ServerCursorTemplate,
|
pub default: ServerCursorTemplate,
|
||||||
|
pub context_menu: ServerCursorTemplate,
|
||||||
|
pub help: ServerCursorTemplate,
|
||||||
pub pointer: ServerCursorTemplate,
|
pub pointer: ServerCursorTemplate,
|
||||||
pub resize_right: ServerCursorTemplate,
|
pub progress: ServerCursorTemplate,
|
||||||
pub resize_left: ServerCursorTemplate,
|
pub wait: ServerCursorTemplate,
|
||||||
pub resize_top: ServerCursorTemplate,
|
pub cell: ServerCursorTemplate,
|
||||||
pub resize_bottom: ServerCursorTemplate,
|
pub crosshair: ServerCursorTemplate,
|
||||||
pub resize_top_bottom: ServerCursorTemplate,
|
pub text: ServerCursorTemplate,
|
||||||
pub resize_left_right: ServerCursorTemplate,
|
pub vertical_text: ServerCursorTemplate,
|
||||||
pub resize_top_left: ServerCursorTemplate,
|
pub alias: ServerCursorTemplate,
|
||||||
pub resize_top_right: ServerCursorTemplate,
|
pub copy: ServerCursorTemplate,
|
||||||
pub resize_bottom_left: ServerCursorTemplate,
|
pub r#move: ServerCursorTemplate,
|
||||||
pub resize_bottom_right: ServerCursorTemplate,
|
pub no_drop: ServerCursorTemplate,
|
||||||
|
pub not_allowed: ServerCursorTemplate,
|
||||||
|
pub grab: ServerCursorTemplate,
|
||||||
|
pub grabbing: ServerCursorTemplate,
|
||||||
|
pub e_resize: ServerCursorTemplate,
|
||||||
|
pub n_resize: ServerCursorTemplate,
|
||||||
|
pub ne_resize: ServerCursorTemplate,
|
||||||
|
pub nw_resize: ServerCursorTemplate,
|
||||||
|
pub s_resize: ServerCursorTemplate,
|
||||||
|
pub se_resize: ServerCursorTemplate,
|
||||||
|
pub sw_resize: ServerCursorTemplate,
|
||||||
|
pub w_resize: ServerCursorTemplate,
|
||||||
|
pub ew_resize: ServerCursorTemplate,
|
||||||
|
pub ns_resize: ServerCursorTemplate,
|
||||||
|
pub nesw_resize: ServerCursorTemplate,
|
||||||
|
pub nwse_resize: ServerCursorTemplate,
|
||||||
|
pub col_resize: ServerCursorTemplate,
|
||||||
|
pub row_resize: ServerCursorTemplate,
|
||||||
|
pub all_scroll: ServerCursorTemplate,
|
||||||
|
pub zoom_in: ServerCursorTemplate,
|
||||||
|
pub zoom_out: ServerCursorTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, FromPrimitive)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, FromPrimitive)]
|
||||||
pub enum KnownCursor {
|
pub enum KnownCursor {
|
||||||
Default,
|
Default,
|
||||||
|
ContextMenu,
|
||||||
|
Help,
|
||||||
Pointer,
|
Pointer,
|
||||||
ResizeLeftRight,
|
Progress,
|
||||||
ResizeTopBottom,
|
Wait,
|
||||||
ResizeTopLeft,
|
Cell,
|
||||||
ResizeTopRight,
|
Crosshair,
|
||||||
ResizeBottomLeft,
|
Text,
|
||||||
ResizeBottomRight,
|
VerticalText,
|
||||||
|
Alias,
|
||||||
|
Copy,
|
||||||
|
Move,
|
||||||
|
NoDrop,
|
||||||
|
NotAllowed,
|
||||||
|
Grab,
|
||||||
|
Grabbing,
|
||||||
|
EResize,
|
||||||
|
NResize,
|
||||||
|
NeResize,
|
||||||
|
NwResize,
|
||||||
|
SResize,
|
||||||
|
SeResize,
|
||||||
|
SwResize,
|
||||||
|
WResize,
|
||||||
|
EwResize,
|
||||||
|
NsResize,
|
||||||
|
NeswResize,
|
||||||
|
NwseResize,
|
||||||
|
ColResize,
|
||||||
|
RowResize,
|
||||||
|
AllScroll,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerCursors {
|
impl ServerCursors {
|
||||||
|
|
@ -99,21 +147,42 @@ impl ServerCursors {
|
||||||
let theme = xcursor_theme.as_ref().map(|theme| BStr::new(theme.bytes()));
|
let theme = xcursor_theme.as_ref().map(|theme| BStr::new(theme.bytes()));
|
||||||
|
|
||||||
let load =
|
let load =
|
||||||
|name: &str| ServerCursorTemplate::load(name, theme, &scales, &sizes, &paths, ctx);
|
|names: &[&str]| ServerCursorTemplate::load(names, theme, &scales, &sizes, &paths, ctx);
|
||||||
Ok(Some(Self {
|
Ok(Some(Self {
|
||||||
default: load("left_ptr")?,
|
default: load(&["default", "left_ptr"])?,
|
||||||
pointer: load("hand2")?,
|
context_menu: load(&["context-menu"])?,
|
||||||
// default: load("left_ptr_watch")?,
|
help: load(&["help"])?,
|
||||||
resize_right: load("right_side")?,
|
pointer: load(&["pointer", "hand2", "hand1"])?,
|
||||||
resize_left: load("left_side")?,
|
progress: load(&["progress"])?,
|
||||||
resize_top: load("top_side")?,
|
wait: load(&["wait", "watch"])?,
|
||||||
resize_bottom: load("bottom_side")?,
|
cell: load(&["cell"])?,
|
||||||
resize_top_bottom: load("v_double_arrow")?,
|
crosshair: load(&["crosshair"])?,
|
||||||
resize_left_right: load("h_double_arrow")?,
|
text: load(&["text", "xterm"])?,
|
||||||
resize_top_left: load("top_left_corner")?,
|
vertical_text: load(&["vertical-text"])?,
|
||||||
resize_top_right: load("top_right_corner")?,
|
alias: load(&["alias"])?,
|
||||||
resize_bottom_left: load("bottom_left_corner")?,
|
copy: load(&["copy"])?,
|
||||||
resize_bottom_right: load("bottom_right_corner")?,
|
r#move: load(&["move"])?,
|
||||||
|
no_drop: load(&["no-drop"])?,
|
||||||
|
not_allowed: load(&["not-allowed"])?,
|
||||||
|
grab: load(&["grab"])?,
|
||||||
|
grabbing: load(&["grabbing"])?,
|
||||||
|
e_resize: load(&["e-resize", "right_side"])?,
|
||||||
|
w_resize: load(&["w-resize", "left_side"])?,
|
||||||
|
n_resize: load(&["n-resize", "top_side"])?,
|
||||||
|
s_resize: load(&["s-resize", "bottom_side"])?,
|
||||||
|
ns_resize: load(&["ns-resize", "v_double_arrow"])?,
|
||||||
|
ew_resize: load(&["ew-resize", "h_double_arrow"])?,
|
||||||
|
nw_resize: load(&["nw-resize", "top_left_corner"])?,
|
||||||
|
ne_resize: load(&["ne-resize", "top_right_corner"])?,
|
||||||
|
sw_resize: load(&["sw-resize", "bottom_left_corner"])?,
|
||||||
|
se_resize: load(&["se-resize", "bottom_right_corner"])?,
|
||||||
|
nesw_resize: load(&["nesw-resize"])?,
|
||||||
|
nwse_resize: load(&["nwse-resize"])?,
|
||||||
|
col_resize: load(&["col-resize"])?,
|
||||||
|
row_resize: load(&["row-resize"])?,
|
||||||
|
all_scroll: load(&["all-scroll", "grabbing"])?,
|
||||||
|
zoom_in: load(&["zoom-in"])?,
|
||||||
|
zoom_out: load(&["zoom-out"])?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -130,14 +199,14 @@ enum ServerCursorTemplateVariant {
|
||||||
|
|
||||||
impl ServerCursorTemplate {
|
impl ServerCursorTemplate {
|
||||||
fn load(
|
fn load(
|
||||||
name: &str,
|
names: &[&str],
|
||||||
theme: Option<&BStr>,
|
theme: Option<&BStr>,
|
||||||
scales: &[Scale],
|
scales: &[Scale],
|
||||||
sizes: &[u32],
|
sizes: &[u32],
|
||||||
paths: &[BString],
|
paths: &[BString],
|
||||||
ctx: &Rc<dyn GfxContext>,
|
ctx: &Rc<dyn GfxContext>,
|
||||||
) -> Result<Self, CursorError> {
|
) -> Result<Self, CursorError> {
|
||||||
match open_cursor(name, theme, scales, sizes, paths) {
|
match open_cursor(names, theme, scales, sizes, paths) {
|
||||||
Ok(cs) => {
|
Ok(cs) => {
|
||||||
if cs.images.len() == 1 {
|
if cs.images.len() == 1 {
|
||||||
let mut sizes = SmallMapMut::new();
|
let mut sizes = SmallMapMut::new();
|
||||||
|
|
@ -178,7 +247,7 @@ impl ServerCursorTemplate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Could not load cursor {}: {}", name, ErrorFmt(e));
|
log::warn!("Could not load cursor {:?}: {}", names, ErrorFmt(e));
|
||||||
let empty: [Cell<u8>; 4] = unsafe { MaybeUninit::zeroed().assume_init() };
|
let empty: [Cell<u8>; 4] = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||||
let mut img_sizes = SmallMapMut::new();
|
let mut img_sizes = SmallMapMut::new();
|
||||||
for scale in scales {
|
for scale in scales {
|
||||||
|
|
@ -399,20 +468,31 @@ struct OpenCursorResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_cursor(
|
fn open_cursor(
|
||||||
name: &str,
|
names: &[&str],
|
||||||
theme: Option<&BStr>,
|
theme: Option<&BStr>,
|
||||||
scales: &[Scale],
|
scales: &[Scale],
|
||||||
sizes: &[u32],
|
sizes: &[u32],
|
||||||
paths: &[BString],
|
paths: &[BString],
|
||||||
) -> Result<OpenCursorResult, CursorError> {
|
) -> Result<OpenCursorResult, CursorError> {
|
||||||
let name = name.as_bytes().as_bstr();
|
|
||||||
let mut file = None;
|
let mut file = None;
|
||||||
let mut themes_tested = AHashSet::new();
|
let mut pairs_tested = AHashSet::new();
|
||||||
if let Some(theme) = theme {
|
if let Some(theme) = theme {
|
||||||
file = open_cursor_file(&mut themes_tested, paths, theme, name);
|
for name in names {
|
||||||
|
let name = name.as_bytes().as_bstr();
|
||||||
|
file = open_cursor_file(&mut pairs_tested, paths, theme, name);
|
||||||
|
if file.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if file.is_none() {
|
if file.is_none() {
|
||||||
file = open_cursor_file(&mut themes_tested, paths, b"default".as_bstr(), name);
|
for name in names {
|
||||||
|
let name = name.as_bytes().as_bstr();
|
||||||
|
file = open_cursor_file(&mut pairs_tested, paths, b"default".as_bstr(), name);
|
||||||
|
if file.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let file = match file {
|
let file = match file {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
|
|
@ -422,13 +502,13 @@ fn open_cursor(
|
||||||
parser_cursor_file(&mut file, scales, sizes)
|
parser_cursor_file(&mut file, scales, sizes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_cursor_file(
|
fn open_cursor_file<'a>(
|
||||||
themes_tested: &mut AHashSet<BString>,
|
pairs_tested: &mut AHashSet<(BString, &'a BStr)>,
|
||||||
paths: &[BString],
|
paths: &[BString],
|
||||||
theme: &BStr,
|
theme: &BStr,
|
||||||
name: &BStr,
|
name: &'a BStr,
|
||||||
) -> Option<File> {
|
) -> Option<File> {
|
||||||
if !themes_tested.insert(theme.to_owned()) {
|
if !pairs_tested.insert((theme.to_owned(), name)) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if paths.is_empty() {
|
if paths.is_empty() {
|
||||||
|
|
@ -453,7 +533,7 @@ fn open_cursor_file(
|
||||||
}
|
}
|
||||||
if let Some(parents) = parents {
|
if let Some(parents) = parents {
|
||||||
for parent in parents {
|
for parent in parents {
|
||||||
if let Some(file) = open_cursor_file(themes_tested, paths, parent.as_bstr(), name) {
|
if let Some(file) = open_cursor_file(pairs_tested, paths, parent.as_bstr(), name) {
|
||||||
return Some(file);
|
return Some(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ use {
|
||||||
wl_shm::WlShmGlobal,
|
wl_shm::WlShmGlobal,
|
||||||
wl_subcompositor::WlSubcompositorGlobal,
|
wl_subcompositor::WlSubcompositorGlobal,
|
||||||
wl_surface::xwayland_shell_v1::XwaylandShellV1Global,
|
wl_surface::xwayland_shell_v1::XwaylandShellV1Global,
|
||||||
|
wp_cursor_shape_manager_v1::WpCursorShapeManagerV1Global,
|
||||||
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1Global,
|
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1Global,
|
||||||
wp_presentation::WpPresentationGlobal,
|
wp_presentation::WpPresentationGlobal,
|
||||||
wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1Global,
|
wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1Global,
|
||||||
|
|
@ -158,6 +159,7 @@ impl Globals {
|
||||||
add_singleton!(XwaylandShellV1Global);
|
add_singleton!(XwaylandShellV1Global);
|
||||||
add_singleton!(WpTearingControlManagerV1Global);
|
add_singleton!(WpTearingControlManagerV1Global);
|
||||||
add_singleton!(WpSinglePixelBufferManagerV1Global);
|
add_singleton!(WpSinglePixelBufferManagerV1Global);
|
||||||
|
add_singleton!(WpCursorShapeManagerV1Global);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_backend_singletons(&self, backend: &Rc<dyn Backend>) {
|
pub fn add_backend_singletons(&self, backend: &Rc<dyn Backend>) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ pub mod wl_shm;
|
||||||
pub mod wl_shm_pool;
|
pub mod wl_shm_pool;
|
||||||
pub mod wl_subcompositor;
|
pub mod wl_subcompositor;
|
||||||
pub mod wl_surface;
|
pub mod wl_surface;
|
||||||
|
pub mod wp_cursor_shape_device_v1;
|
||||||
|
pub mod wp_cursor_shape_manager_v1;
|
||||||
pub mod wp_fractional_scale_manager_v1;
|
pub mod wp_fractional_scale_manager_v1;
|
||||||
pub mod wp_presentation;
|
pub mod wp_presentation;
|
||||||
pub mod wp_presentation_feedback;
|
pub mod wp_presentation_feedback;
|
||||||
|
|
|
||||||
|
|
@ -784,13 +784,39 @@ impl WlSeatGlobal {
|
||||||
};
|
};
|
||||||
let tpl = match cursor {
|
let tpl = match cursor {
|
||||||
KnownCursor::Default => &cursors.default,
|
KnownCursor::Default => &cursors.default,
|
||||||
|
KnownCursor::ContextMenu => &cursors.context_menu,
|
||||||
|
KnownCursor::Help => &cursors.help,
|
||||||
KnownCursor::Pointer => &cursors.pointer,
|
KnownCursor::Pointer => &cursors.pointer,
|
||||||
KnownCursor::ResizeLeftRight => &cursors.resize_left_right,
|
KnownCursor::Progress => &cursors.progress,
|
||||||
KnownCursor::ResizeTopBottom => &cursors.resize_top_bottom,
|
KnownCursor::Wait => &cursors.wait,
|
||||||
KnownCursor::ResizeTopLeft => &cursors.resize_top_left,
|
KnownCursor::Cell => &cursors.cell,
|
||||||
KnownCursor::ResizeTopRight => &cursors.resize_top_right,
|
KnownCursor::Crosshair => &cursors.crosshair,
|
||||||
KnownCursor::ResizeBottomLeft => &cursors.resize_bottom_left,
|
KnownCursor::Text => &cursors.text,
|
||||||
KnownCursor::ResizeBottomRight => &cursors.resize_bottom_right,
|
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())));
|
self.set_cursor2(Some(tpl.instantiate(self.cursor_size.get())));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ impl WlPointer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if pointer_node.node_client_id() != Some(self.seat.client.id) {
|
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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// https://gitlab.freedesktop.org/wayland/wayland/-/issues/439
|
// https://gitlab.freedesktop.org/wayland/wayland/-/issues/439
|
||||||
|
|
|
||||||
136
src/ifs/wp_cursor_shape_device_v1.rs
Normal file
136
src/ifs/wp_cursor_shape_device_v1.rs
Normal 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);
|
||||||
119
src/ifs/wp_cursor_shape_manager_v1.rs
Normal file
119
src/ifs/wp_cursor_shape_manager_v1.rs
Normal 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);
|
||||||
|
|
@ -577,7 +577,7 @@ impl ContainerNode {
|
||||||
if y < title_height + 1 {
|
if y < title_height + 1 {
|
||||||
KnownCursor::Default
|
KnownCursor::Default
|
||||||
} else {
|
} else {
|
||||||
KnownCursor::ResizeLeftRight
|
KnownCursor::EwResize
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut cursor = KnownCursor::Default;
|
let mut cursor = KnownCursor::Default;
|
||||||
|
|
@ -585,7 +585,7 @@ impl ContainerNode {
|
||||||
let body = child.body.get();
|
let body = child.body.get();
|
||||||
if body.y1() > y {
|
if body.y1() > y {
|
||||||
if body.y1() - y > title_height + 1 {
|
if body.y1() - y > title_height + 1 {
|
||||||
cursor = KnownCursor::ResizeTopBottom
|
cursor = KnownCursor::NsResize
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -320,14 +320,14 @@ impl FloatNode {
|
||||||
let op_type = OP_TYPES[id];
|
let op_type = OP_TYPES[id];
|
||||||
let new_cursor = match op_type {
|
let new_cursor = match op_type {
|
||||||
OpType::Move => KnownCursor::Default,
|
OpType::Move => KnownCursor::Default,
|
||||||
OpType::ResizeLeft => KnownCursor::ResizeLeftRight,
|
OpType::ResizeLeft => KnownCursor::EwResize,
|
||||||
OpType::ResizeTop => KnownCursor::ResizeTopBottom,
|
OpType::ResizeTop => KnownCursor::NsResize,
|
||||||
OpType::ResizeRight => KnownCursor::ResizeLeftRight,
|
OpType::ResizeRight => KnownCursor::EwResize,
|
||||||
OpType::ResizeBottom => KnownCursor::ResizeTopBottom,
|
OpType::ResizeBottom => KnownCursor::NsResize,
|
||||||
OpType::ResizeTopLeft => KnownCursor::ResizeTopLeft,
|
OpType::ResizeTopLeft => KnownCursor::NwResize,
|
||||||
OpType::ResizeTopRight => KnownCursor::ResizeTopRight,
|
OpType::ResizeTopRight => KnownCursor::NeResize,
|
||||||
OpType::ResizeBottomLeft => KnownCursor::ResizeBottomLeft,
|
OpType::ResizeBottomLeft => KnownCursor::SwResize,
|
||||||
OpType::ResizeBottomRight => KnownCursor::ResizeBottomRight,
|
OpType::ResizeBottomRight => KnownCursor::SeResize,
|
||||||
};
|
};
|
||||||
seat_state.op_type = op_type;
|
seat_state.op_type = op_type;
|
||||||
if new_cursor != mem::replace(&mut seat_state.cursor, new_cursor) {
|
if new_cursor != mem::replace(&mut seat_state.cursor, new_cursor) {
|
||||||
|
|
|
||||||
9
wire/wp_cursor_shape_device_v1.txt
Normal file
9
wire/wp_cursor_shape_device_v1.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg destroy = 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
msg set_shape = 1 {
|
||||||
|
serial: u32,
|
||||||
|
shape: u32,
|
||||||
|
}
|
||||||
14
wire/wp_cursor_shape_manager_v1.txt
Normal file
14
wire/wp_cursor_shape_manager_v1.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg destroy = 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
msg get_pointer = 1 {
|
||||||
|
cursor_shape_device: id(wp_cursor_shape_device_v1),
|
||||||
|
pointer: id(wl_pointer),
|
||||||
|
}
|
||||||
|
|
||||||
|
msg get_tablet_tool_v2 = 2 {
|
||||||
|
cursor_shape_device: id(wp_cursor_shape_device_v1),
|
||||||
|
tablet_tool: id(zwp_tablet_tool_v2),
|
||||||
|
}
|
||||||
4
wire/zwp_tablet_tool_v2.txt
Normal file
4
wire/zwp_tablet_tool_v2.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg destroy = 1 {
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue