wayland: implement wlr-virtual-pointer-unstable-v1
This commit is contained in:
parent
942c090195
commit
548a2bf478
15 changed files with 437 additions and 4 deletions
|
|
@ -205,6 +205,7 @@ Jay supports the following wayland protocols:
|
||||||
| zwlr_layer_shell_v1 | 5 | No[^lsaccess] |
|
| zwlr_layer_shell_v1 | 5 | No[^lsaccess] |
|
||||||
| zwlr_output_manager_v1 | 4 | Yes |
|
| zwlr_output_manager_v1 | 4 | Yes |
|
||||||
| zwlr_screencopy_manager_v1 | 3 | Yes |
|
| zwlr_screencopy_manager_v1 | 3 | Yes |
|
||||||
|
| zwlr_virtual_pointer_manager_v1 | 2 | Yes |
|
||||||
| zwp_idle_inhibit_manager_v1 | 1 | |
|
| zwp_idle_inhibit_manager_v1 | 1 | |
|
||||||
| zwp_input_method_manager_v2 | 1 | Yes |
|
| zwp_input_method_manager_v2 | 1 | Yes |
|
||||||
| zwp_linux_dmabuf_v1 | 5 | |
|
| zwp_linux_dmabuf_v1 | 5 | |
|
||||||
|
|
|
||||||
|
|
@ -231,5 +231,7 @@ bitflags! {
|
||||||
pub const CC_HEAD_MANAGER = 1 << 13,
|
pub const CC_HEAD_MANAGER = 1 << 13,
|
||||||
/// Grants access to the `zwlr_gamma_control_manager_v1` global.
|
/// Grants access to the `zwlr_gamma_control_manager_v1` global.
|
||||||
pub const CC_GAMMA_CONTROL_MANAGER = 1 << 14,
|
pub const CC_GAMMA_CONTROL_MANAGER = 1 << 14,
|
||||||
|
/// Grants access to the `zwlr_virtual_pointer_manager_v1` global.
|
||||||
|
pub const CC_VIRTUAL_POINTER = 1 << 15,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ bitflags! {
|
||||||
CAP_FOREIGN_TOPLEVEL_MANAGER = 1 << 12,
|
CAP_FOREIGN_TOPLEVEL_MANAGER = 1 << 12,
|
||||||
CAP_HEAD_MANAGER = 1 << 13,
|
CAP_HEAD_MANAGER = 1 << 13,
|
||||||
CAP_GAMMA_CONTROL_MANAGER = 1 << 14,
|
CAP_GAMMA_CONTROL_MANAGER = 1 << 14,
|
||||||
|
CAP_VIRTUAL_POINTER_MANAGER = 1 << 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StaticText for ClientCapsEnum {
|
impl StaticText for ClientCapsEnum {
|
||||||
|
|
@ -87,6 +88,7 @@ impl StaticText for ClientCapsEnum {
|
||||||
ClientCapsEnum::CAP_FOREIGN_TOPLEVEL_MANAGER => "foreign-toplevel-manager",
|
ClientCapsEnum::CAP_FOREIGN_TOPLEVEL_MANAGER => "foreign-toplevel-manager",
|
||||||
ClientCapsEnum::CAP_HEAD_MANAGER => "head-manager",
|
ClientCapsEnum::CAP_HEAD_MANAGER => "head-manager",
|
||||||
ClientCapsEnum::CAP_GAMMA_CONTROL_MANAGER => "gamma-control-manager",
|
ClientCapsEnum::CAP_GAMMA_CONTROL_MANAGER => "gamma-control-manager",
|
||||||
|
ClientCapsEnum::CAP_VIRTUAL_POINTER_MANAGER => "virtual-pointer",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ use {
|
||||||
zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1Global,
|
zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1Global,
|
||||||
zwlr_layer_shell_v1::ZwlrLayerShellV1Global,
|
zwlr_layer_shell_v1::ZwlrLayerShellV1Global,
|
||||||
zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1Global,
|
zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1Global,
|
||||||
|
zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1Global,
|
||||||
zwp_idle_inhibit_manager_v1::ZwpIdleInhibitManagerV1Global,
|
zwp_idle_inhibit_manager_v1::ZwpIdleInhibitManagerV1Global,
|
||||||
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global,
|
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global,
|
||||||
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global,
|
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global,
|
||||||
|
|
@ -248,6 +249,7 @@ singletons! {
|
||||||
ZwpLinuxDmabufV1,
|
ZwpLinuxDmabufV1,
|
||||||
WpLinuxDrmSyncobjManagerV1,
|
WpLinuxDrmSyncobjManagerV1,
|
||||||
WpPresentation,
|
WpPresentation,
|
||||||
|
ZwlrVirtualPointerManagerV1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Globals {
|
pub struct Globals {
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,8 @@ pub mod zwlr_gamma_control_v1;
|
||||||
pub mod zwlr_layer_shell_v1;
|
pub mod zwlr_layer_shell_v1;
|
||||||
pub mod zwlr_screencopy_frame_v1;
|
pub mod zwlr_screencopy_frame_v1;
|
||||||
pub mod zwlr_screencopy_manager_v1;
|
pub mod zwlr_screencopy_manager_v1;
|
||||||
|
pub mod zwlr_virtual_pointer_manager_v1;
|
||||||
|
pub mod zwlr_virtual_pointer_v1;
|
||||||
pub mod zwp_idle_inhibit_manager_v1;
|
pub mod zwp_idle_inhibit_manager_v1;
|
||||||
pub mod zwp_linux_buffer_params_v1;
|
pub mod zwp_linux_buffer_params_v1;
|
||||||
pub mod zwp_linux_dmabuf_feedback_v1;
|
pub mod zwp_linux_dmabuf_feedback_v1;
|
||||||
|
|
|
||||||
|
|
@ -669,7 +669,7 @@ impl WlSeatGlobal {
|
||||||
self.cursor_moved(time_usec);
|
self.cursor_moved(time_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn motion_absolute_event(
|
pub fn motion_absolute_event(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
rect: Rect,
|
rect: Rect,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use {
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
const ROLE: u32 = 0;
|
const ROLE: u32 = 0;
|
||||||
|
|
||||||
pub(super) const RELEASED: u32 = 0;
|
pub const RELEASED: u32 = 0;
|
||||||
pub const PRESSED: u32 = 1;
|
pub const PRESSED: u32 = 1;
|
||||||
|
|
||||||
pub const VERTICAL_SCROLL: usize = 0;
|
pub const VERTICAL_SCROLL: usize = 0;
|
||||||
|
|
|
||||||
146
src/ifs/zwlr_virtual_pointer_manager_v1.rs
Normal file
146
src/ifs/zwlr_virtual_pointer_manager_v1.rs
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
client::{CAP_VIRTUAL_POINTER_MANAGER, Client, ClientCaps, ClientError},
|
||||||
|
globals::{Global, GlobalName},
|
||||||
|
ifs::zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1,
|
||||||
|
leaks::Tracker,
|
||||||
|
object::{Object, Version},
|
||||||
|
wire::{
|
||||||
|
WlOutputId, WlSeatId, ZwlrVirtualPointerManagerV1Id, ZwlrVirtualPointerV1Id,
|
||||||
|
zwlr_virtual_pointer_manager_v1::*,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
std::{ops::Deref, rc::Rc},
|
||||||
|
thiserror::Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ZwlrVirtualPointerManagerV1Global {
|
||||||
|
name: GlobalName,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrVirtualPointerManagerV1Global {
|
||||||
|
pub fn new(name: GlobalName) -> Self {
|
||||||
|
Self { name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_(
|
||||||
|
self: Rc<Self>,
|
||||||
|
id: ZwlrVirtualPointerManagerV1Id,
|
||||||
|
client: &Rc<Client>,
|
||||||
|
version: Version,
|
||||||
|
) -> Result<(), ZwlrVirtualPointerManagerV1Error> {
|
||||||
|
let obj = Rc::new(ZwlrVirtualPointerManagerV1 {
|
||||||
|
id,
|
||||||
|
client: client.clone(),
|
||||||
|
tracker: Default::default(),
|
||||||
|
version,
|
||||||
|
});
|
||||||
|
track!(client, obj);
|
||||||
|
client.add_client_obj(&obj)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global_base!(
|
||||||
|
ZwlrVirtualPointerManagerV1Global,
|
||||||
|
ZwlrVirtualPointerManagerV1,
|
||||||
|
ZwlrVirtualPointerManagerV1Error
|
||||||
|
);
|
||||||
|
|
||||||
|
simple_add_global!(ZwlrVirtualPointerManagerV1Global);
|
||||||
|
|
||||||
|
impl Global for ZwlrVirtualPointerManagerV1Global {
|
||||||
|
fn version(&self) -> u32 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn required_caps(&self) -> ClientCaps {
|
||||||
|
CAP_VIRTUAL_POINTER_MANAGER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ZwlrVirtualPointerManagerV1 {
|
||||||
|
pub id: ZwlrVirtualPointerManagerV1Id,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
pub version: Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrVirtualPointerManagerV1 {
|
||||||
|
fn create_virtual_pointer(
|
||||||
|
&self,
|
||||||
|
id: ZwlrVirtualPointerV1Id,
|
||||||
|
seat: WlSeatId,
|
||||||
|
output: WlOutputId,
|
||||||
|
) -> Result<(), ZwlrVirtualPointerManagerV1Error> {
|
||||||
|
let seat = if seat.is_some() {
|
||||||
|
self.client.lookup(seat)?.global.clone()
|
||||||
|
} else {
|
||||||
|
match self.client.state.seat_queue.last() {
|
||||||
|
None => return Err(ZwlrVirtualPointerManagerV1Error::NoSeat),
|
||||||
|
Some(s) => s.deref().clone(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let output = if output.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.client.lookup(output)?.global.clone())
|
||||||
|
};
|
||||||
|
let obj = Rc::new(ZwlrVirtualPointerV1 {
|
||||||
|
id,
|
||||||
|
client: self.client.clone(),
|
||||||
|
tracker: Default::default(),
|
||||||
|
version: self.version,
|
||||||
|
events: Default::default(),
|
||||||
|
seat,
|
||||||
|
output,
|
||||||
|
buttons: Default::default(),
|
||||||
|
});
|
||||||
|
track!(self.client, obj);
|
||||||
|
self.client.add_client_obj(&obj)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrVirtualPointerManagerV1RequestHandler for ZwlrVirtualPointerManagerV1 {
|
||||||
|
type Error = ZwlrVirtualPointerManagerV1Error;
|
||||||
|
|
||||||
|
fn create_virtual_pointer(
|
||||||
|
&self,
|
||||||
|
req: CreateVirtualPointer,
|
||||||
|
_slf: &Rc<Self>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
self.create_virtual_pointer(req.id, req.seat, WlOutputId::NONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_virtual_pointer_with_output(
|
||||||
|
&self,
|
||||||
|
req: CreateVirtualPointerWithOutput,
|
||||||
|
_slf: &Rc<Self>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
self.create_virtual_pointer(req.id, req.seat, req.output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
self = ZwlrVirtualPointerManagerV1;
|
||||||
|
version = self.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object for ZwlrVirtualPointerManagerV1 {}
|
||||||
|
|
||||||
|
simple_add_obj!(ZwlrVirtualPointerManagerV1);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZwlrVirtualPointerManagerV1Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("There are no seats")]
|
||||||
|
NoSeat,
|
||||||
|
}
|
||||||
|
efrom!(ZwlrVirtualPointerManagerV1Error, ClientError);
|
||||||
209
src/ifs/zwlr_virtual_pointer_v1.rs
Normal file
209
src/ifs/zwlr_virtual_pointer_v1.rs
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
backend::{AxisSource as BackendAxisSource, ButtonState, ScrollAxis},
|
||||||
|
client::{Client, ClientError},
|
||||||
|
fixed::Fixed,
|
||||||
|
ifs::{
|
||||||
|
wl_output::OutputGlobalOpt,
|
||||||
|
wl_seat::{
|
||||||
|
PX_PER_SCROLL, WlSeatGlobal,
|
||||||
|
wl_pointer::{self, CONTINUOUS, FINGER, PRESSED, RELEASED, WHEEL},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
leaks::Tracker,
|
||||||
|
object::{Object, Version},
|
||||||
|
utils::{copyhashmap::CopyHashMap, syncqueue::SyncQueue},
|
||||||
|
wire::{ZwlrVirtualPointerV1Id, zwlr_virtual_pointer_v1::*},
|
||||||
|
},
|
||||||
|
std::rc::Rc,
|
||||||
|
thiserror::Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ZwlrVirtualPointerV1 {
|
||||||
|
pub id: ZwlrVirtualPointerV1Id,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
pub version: Version,
|
||||||
|
pub events: SyncQueue<Event>,
|
||||||
|
pub seat: Rc<WlSeatGlobal>,
|
||||||
|
pub output: Option<Rc<OutputGlobalOpt>>,
|
||||||
|
pub buttons: CopyHashMap<u32, ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Event {
|
||||||
|
Motion(u32, Fixed, Fixed),
|
||||||
|
MotionAbsolute(u32, u32, u32, u32, u32),
|
||||||
|
Button(u32, u32, ButtonState),
|
||||||
|
Axis(u32, ScrollAxis, Fixed),
|
||||||
|
AxisSource(BackendAxisSource),
|
||||||
|
AxisStop(u32, ScrollAxis),
|
||||||
|
AxisDiscrete(u32, ScrollAxis, Fixed, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_axis(axis: u32) -> Result<ScrollAxis, ZwlrVirtualPointerV1Error> {
|
||||||
|
const VERTICAL_SCROLL: u32 = wl_pointer::VERTICAL_SCROLL as u32;
|
||||||
|
const HORIZONTAL_SCROLL: u32 = wl_pointer::HORIZONTAL_SCROLL as u32;
|
||||||
|
let axis = match axis {
|
||||||
|
VERTICAL_SCROLL => ScrollAxis::Vertical,
|
||||||
|
HORIZONTAL_SCROLL => ScrollAxis::Horizontal,
|
||||||
|
n => return Err(ZwlrVirtualPointerV1Error::UnknownAxis(n)),
|
||||||
|
};
|
||||||
|
Ok(axis)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrVirtualPointerV1 {
|
||||||
|
fn detach(&self) {
|
||||||
|
for (button, _) in self.buttons.lock().drain() {
|
||||||
|
let now = self.client.state.now_usec();
|
||||||
|
self.seat.button_event(now, button, ButtonState::Released);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrVirtualPointerV1RequestHandler for ZwlrVirtualPointerV1 {
|
||||||
|
type Error = ZwlrVirtualPointerV1Error;
|
||||||
|
|
||||||
|
fn motion(&self, req: Motion, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.events.push(Event::Motion(req.time, req.dx, req.dy));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn motion_absolute(&self, req: MotionAbsolute, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.events.push(Event::MotionAbsolute(
|
||||||
|
req.time,
|
||||||
|
req.x,
|
||||||
|
req.y,
|
||||||
|
req.x_extent,
|
||||||
|
req.y_extent,
|
||||||
|
));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button(&self, req: Button, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
let state = match req.state {
|
||||||
|
RELEASED => ButtonState::Released,
|
||||||
|
PRESSED => ButtonState::Pressed,
|
||||||
|
n => return Err(ZwlrVirtualPointerV1Error::UnknownButtonState(n)),
|
||||||
|
};
|
||||||
|
self.events.push(Event::Button(req.time, req.button, state));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn axis(&self, req: Axis, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.events
|
||||||
|
.push(Event::Axis(req.time, map_axis(req.axis)?, req.value));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame(&self, _req: Frame, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
fn ms_to_us(ms: u32) -> u64 {
|
||||||
|
ms as u64 * 1_000
|
||||||
|
}
|
||||||
|
let mut axis_time = None;
|
||||||
|
while let Some(ev) = self.events.pop() {
|
||||||
|
match ev {
|
||||||
|
Event::Motion(time, dx, dy) => {
|
||||||
|
self.seat.motion_event(ms_to_us(time), dx, dy, dx, dy);
|
||||||
|
}
|
||||||
|
Event::MotionAbsolute(time, x, y, x_max, y_max) => {
|
||||||
|
let x = x as f32 / x_max as f32;
|
||||||
|
let y = y as f32 / y_max as f32;
|
||||||
|
let rect = self
|
||||||
|
.output
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.get())
|
||||||
|
.map(|g| g.pos.get())
|
||||||
|
.unwrap_or_else(|| self.client.state.root.extents.get());
|
||||||
|
self.seat.motion_absolute_event(ms_to_us(time), rect, x, y);
|
||||||
|
}
|
||||||
|
Event::Button(time, button, state) => {
|
||||||
|
match state {
|
||||||
|
ButtonState::Released => self.buttons.remove(&button),
|
||||||
|
ButtonState::Pressed => self.buttons.set(button, ()),
|
||||||
|
};
|
||||||
|
self.seat.button_event(ms_to_us(time), button, state);
|
||||||
|
}
|
||||||
|
Event::Axis(time, axis, v) => {
|
||||||
|
axis_time = Some(time);
|
||||||
|
self.seat.axis_px(v, axis, false);
|
||||||
|
}
|
||||||
|
Event::AxisSource(source) => {
|
||||||
|
self.seat.axis_source(source);
|
||||||
|
}
|
||||||
|
Event::AxisStop(time, axis) => {
|
||||||
|
axis_time = Some(time);
|
||||||
|
self.seat.axis_stop(axis);
|
||||||
|
}
|
||||||
|
Event::AxisDiscrete(time, axis, value, discrete) => {
|
||||||
|
axis_time = Some(time);
|
||||||
|
self.seat.axis_px(value, axis, false);
|
||||||
|
self.seat
|
||||||
|
.axis_120(discrete.saturating_mul(120), axis, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(time) = axis_time {
|
||||||
|
self.seat.axis_frame(PX_PER_SCROLL, ms_to_us(time));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn axis_source(&self, req: AxisSource, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
let source = match req.axis_source {
|
||||||
|
WHEEL => BackendAxisSource::Wheel,
|
||||||
|
FINGER => BackendAxisSource::Finger,
|
||||||
|
CONTINUOUS => BackendAxisSource::Continuous,
|
||||||
|
n => return Err(ZwlrVirtualPointerV1Error::UnknownAxisSource(n)),
|
||||||
|
};
|
||||||
|
self.events.push(Event::AxisSource(source));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn axis_stop(&self, req: AxisStop, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.events
|
||||||
|
.push(Event::AxisStop(req.time, map_axis(req.axis)?));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn axis_discrete(&self, req: AxisDiscrete, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.events.push(Event::AxisDiscrete(
|
||||||
|
req.time,
|
||||||
|
map_axis(req.axis)?,
|
||||||
|
req.value,
|
||||||
|
req.discrete,
|
||||||
|
));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
self.detach();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
self = ZwlrVirtualPointerV1;
|
||||||
|
version = self.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object for ZwlrVirtualPointerV1 {
|
||||||
|
fn break_loops(&self) {
|
||||||
|
self.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_obj!(ZwlrVirtualPointerV1);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZwlrVirtualPointerV1Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Unknown button state {0}")]
|
||||||
|
UnknownButtonState(u32),
|
||||||
|
#[error("Unknown axis {0}")]
|
||||||
|
UnknownAxis(u32),
|
||||||
|
#[error("Unknown axis source {0}")]
|
||||||
|
UnknownAxisSource(u32),
|
||||||
|
}
|
||||||
|
efrom!(ZwlrVirtualPointerV1Error, ClientError);
|
||||||
|
|
@ -10,7 +10,7 @@ use {
|
||||||
CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER,
|
CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER,
|
||||||
CC_GAMMA_CONTROL_MANAGER, CC_HEAD_MANAGER, CC_IDLE_NOTIFIER, CC_INPUT_METHOD,
|
CC_GAMMA_CONTROL_MANAGER, CC_HEAD_MANAGER, CC_IDLE_NOTIFIER, CC_INPUT_METHOD,
|
||||||
CC_LAYER_SHELL, CC_SCREENCOPY, CC_SEAT_MANAGER, CC_SESSION_LOCK, CC_VIRTUAL_KEYBOARD,
|
CC_LAYER_SHELL, CC_SCREENCOPY, CC_SEAT_MANAGER, CC_SESSION_LOCK, CC_VIRTUAL_KEYBOARD,
|
||||||
CC_WORKSPACE_MANAGER, ClientCapabilities,
|
CC_VIRTUAL_POINTER, CC_WORKSPACE_MANAGER, ClientCapabilities,
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
@ -48,6 +48,7 @@ impl Parser for CapabilitiesParser {
|
||||||
"foreign-toplevel-manager" => CC_FOREIGN_TOPLEVEL_MANAGER,
|
"foreign-toplevel-manager" => CC_FOREIGN_TOPLEVEL_MANAGER,
|
||||||
"head-manager" => CC_HEAD_MANAGER,
|
"head-manager" => CC_HEAD_MANAGER,
|
||||||
"gamma-control-manager" => CC_GAMMA_CONTROL_MANAGER,
|
"gamma-control-manager" => CC_GAMMA_CONTROL_MANAGER,
|
||||||
|
"virtual-pointer" => CC_VIRTUAL_POINTER,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(
|
return Err(
|
||||||
CapabilitiesParserError::UnknownCapability(string.to_owned()).spanned(span),
|
CapabilitiesParserError::UnknownCapability(string.to_owned()).spanned(span),
|
||||||
|
|
|
||||||
|
|
@ -676,7 +676,8 @@
|
||||||
"workspace-manager",
|
"workspace-manager",
|
||||||
"foreign-toplevel-manager",
|
"foreign-toplevel-manager",
|
||||||
"head-manager",
|
"head-manager",
|
||||||
"gamma-control-manager"
|
"gamma-control-manager",
|
||||||
|
"virtual-pointer"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1066,6 +1066,10 @@ The string should have one of the following values:
|
||||||
|
|
||||||
Grants access to the `zwlr_gamma_control_manager_v1` global.
|
Grants access to the `zwlr_gamma_control_manager_v1` global.
|
||||||
|
|
||||||
|
- `virtual-pointer`:
|
||||||
|
|
||||||
|
Grants access to the `zwlr_virtual_pointer_manager_v1` global.
|
||||||
|
|
||||||
|
|
||||||
#### An array
|
#### An array
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4485,6 +4485,9 @@ ClientCapabilities:
|
||||||
- value: gamma-control-manager
|
- value: gamma-control-manager
|
||||||
description: |
|
description: |
|
||||||
Grants access to the `zwlr_gamma_control_manager_v1` global.
|
Grants access to the `zwlr_gamma_control_manager_v1` global.
|
||||||
|
- value: virtual-pointer
|
||||||
|
description: |
|
||||||
|
Grants access to the `zwlr_virtual_pointer_manager_v1` global.
|
||||||
- kind: array
|
- kind: array
|
||||||
description: An array of masks that are OR'd.
|
description: An array of masks that are OR'd.
|
||||||
items:
|
items:
|
||||||
|
|
|
||||||
13
wire/zwlr_virtual_pointer_manager_v1.txt
Normal file
13
wire/zwlr_virtual_pointer_manager_v1.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
request create_virtual_pointer {
|
||||||
|
seat: id(wl_seat),
|
||||||
|
id: id(zwlr_virtual_pointer_v1) (new),
|
||||||
|
}
|
||||||
|
|
||||||
|
request destroy (destructor, since = 1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
request create_virtual_pointer_with_output (since = 2) {
|
||||||
|
seat: id(wl_seat),
|
||||||
|
output: id(wl_output),
|
||||||
|
id: id(zwlr_virtual_pointer_v1) (new),
|
||||||
|
}
|
||||||
47
wire/zwlr_virtual_pointer_v1.txt
Normal file
47
wire/zwlr_virtual_pointer_v1.txt
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
request motion {
|
||||||
|
time: u32,
|
||||||
|
dx: fixed,
|
||||||
|
dy: fixed,
|
||||||
|
}
|
||||||
|
|
||||||
|
request motion_absolute {
|
||||||
|
time: u32,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
x_extent: u32,
|
||||||
|
y_extent: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
request button {
|
||||||
|
time: u32,
|
||||||
|
button: u32,
|
||||||
|
state: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
request axis {
|
||||||
|
time: u32,
|
||||||
|
axis: u32,
|
||||||
|
value: fixed,
|
||||||
|
}
|
||||||
|
|
||||||
|
request frame {
|
||||||
|
}
|
||||||
|
|
||||||
|
request axis_source {
|
||||||
|
axis_source: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
request axis_stop {
|
||||||
|
time: u32,
|
||||||
|
axis: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
request axis_discrete {
|
||||||
|
time: u32,
|
||||||
|
axis: u32,
|
||||||
|
value: fixed,
|
||||||
|
discrete: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
request destroy (destructor, since = 1) {
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue