input_capture/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum InputCaptureError {
5    #[error("error creating input-capture: `{0}`")]
6    Create(#[from] CaptureCreationError),
7    #[error("error while capturing input: `{0}`")]
8    Capture(#[from] CaptureError),
9}
10
11#[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
12use std::io;
13#[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
14use wayland_client::{
15    backend::WaylandError,
16    globals::{BindError, GlobalError},
17    ConnectError, DispatchError,
18};
19
20#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
21use ashpd::desktop::ResponseError;
22
23#[cfg(target_os = "macos")]
24use core_graphics::base::CGError;
25
26#[derive(Debug, Error)]
27pub enum CaptureError {
28    #[error("activation stream closed unexpectedly")]
29    ActivationClosed,
30    #[error("libei stream was closed")]
31    EndOfStream,
32    #[error("io error: `{0}`")]
33    Io(#[from] std::io::Error),
34    #[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
35    #[error("libei error: `{0}`")]
36    Reis(#[from] reis::Error),
37    #[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
38    #[error(transparent)]
39    Portal(#[from] ashpd::Error),
40    #[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
41    #[error("libei disconnected - reason: `{0}`")]
42    Disconnected(String),
43    #[cfg(target_os = "macos")]
44    #[error("failed to warp mouse cursor: `{0}`")]
45    WarpCursor(CGError),
46    #[cfg(target_os = "macos")]
47    #[error("reset_mouse_position called without a connected client")]
48    ResetMouseWithoutClient,
49    #[cfg(target_os = "macos")]
50    #[error("core-graphics error: {0}")]
51    CoreGraphics(CGError),
52    #[cfg(target_os = "macos")]
53    #[error("unable to map key event: {0}")]
54    KeyMapError(i64),
55    #[cfg(target_os = "macos")]
56    #[error("Event tap disabled")]
57    EventTapDisabled,
58}
59
60#[derive(Debug, Error)]
61pub enum CaptureCreationError {
62    #[error("no backend available")]
63    NoAvailableBackend,
64    #[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
65    #[error("error creating input-capture-portal backend: `{0}`")]
66    Libei(#[from] LibeiCaptureCreationError),
67    #[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
68    #[error("error creating layer-shell capture backend: `{0}`")]
69    LayerShell(#[from] LayerShellCaptureCreationError),
70    #[cfg(all(unix, feature = "x11", not(target_os = "macos")))]
71    #[error("error creating x11 capture backend: `{0}`")]
72    X11(#[from] X11InputCaptureCreationError),
73    #[cfg(windows)]
74    #[error("error creating windows capture backend")]
75    Windows,
76    #[cfg(target_os = "macos")]
77    #[error("error creating macos capture backend: `{0}`")]
78    MacOS(#[from] MacosCaptureCreationError),
79}
80
81impl CaptureCreationError {
82    /// request was intentionally denied by the user
83    #[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
84    pub(crate) fn cancelled_by_user(&self) -> bool {
85        matches!(
86            self,
87            CaptureCreationError::Libei(LibeiCaptureCreationError::Ashpd(ashpd::Error::Response(
88                ResponseError::Cancelled
89            )))
90        )
91    }
92    #[cfg(not(all(unix, feature = "libei", not(target_os = "macos"))))]
93    pub(crate) fn cancelled_by_user(&self) -> bool {
94        false
95    }
96}
97
98#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
99#[derive(Debug, Error)]
100pub enum LibeiCaptureCreationError {
101    #[error("xdg-desktop-portal: `{0}`")]
102    Ashpd(#[from] ashpd::Error),
103}
104
105#[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
106#[derive(Debug, Error)]
107#[error("{protocol} protocol not supported: {inner}")]
108pub struct WaylandBindError {
109    inner: BindError,
110    protocol: &'static str,
111}
112
113#[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
114impl WaylandBindError {
115    pub(crate) fn new(inner: BindError, protocol: &'static str) -> Self {
116        Self { inner, protocol }
117    }
118}
119
120#[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))]
121#[derive(Debug, Error)]
122pub enum LayerShellCaptureCreationError {
123    #[error(transparent)]
124    Connect(#[from] ConnectError),
125    #[error(transparent)]
126    Global(#[from] GlobalError),
127    #[error(transparent)]
128    Wayland(#[from] WaylandError),
129    #[error(transparent)]
130    Bind(#[from] WaylandBindError),
131    #[error(transparent)]
132    Dispatch(#[from] DispatchError),
133    #[error(transparent)]
134    Io(#[from] io::Error),
135}
136
137#[cfg(all(unix, feature = "x11", not(target_os = "macos")))]
138#[derive(Debug, Error)]
139pub enum X11InputCaptureCreationError {
140    #[error("X11 input capture is not yet implemented :(")]
141    NotImplemented,
142}
143
144#[cfg(target_os = "macos")]
145#[derive(Debug, Error)]
146pub enum MacosCaptureCreationError {
147    #[error("event source creation failed!")]
148    EventSourceCreation,
149    #[cfg(target_os = "macos")]
150    #[error("event tap creation failed")]
151    EventTapCreation,
152    #[error("failed to set CG Cursor property")]
153    CGCursorProperty,
154    #[cfg(target_os = "macos")]
155    #[error("failed to get display ids: {0}")]
156    ActiveDisplays(CGError),
157}