Skip to main content

a7n_platform/
permissions.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2
3//! macOS privacy permissions the daemon needs before it can share input.
4//!
5//! macOS grants these to the process that uses them, so they are checked and
6//! requested here, in the daemon, and not in any GUI.
7
8use std::fmt;
9
10#[cfg(target_os = "macos")]
11mod macos;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Permission {
15    Accessibility,
16    InputMonitoring,
17}
18
19impl Permission {
20    /// The label macOS shows in System Settings.
21    #[must_use]
22    pub fn name(self) -> &'static str {
23        match self {
24            Self::Accessibility => "Accessibility",
25            Self::InputMonitoring => "Input Monitoring",
26        }
27    }
28}
29
30impl fmt::Display for Permission {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        f.write_str(self.name())
33    }
34}
35
36#[derive(Debug, thiserror::Error)]
37pub enum PermissionError {
38    #[error("permissions are not managed on this platform")]
39    Unsupported,
40    #[error("cannot open the {0} pane in System Settings")]
41    OpenSettings(Permission),
42}
43
44/// Permissions still missing, checked live on every call; always empty off macOS.
45#[must_use]
46pub fn missing() -> Vec<Permission> {
47    #[cfg(target_os = "macos")]
48    return macos::missing();
49    #[cfg(not(target_os = "macos"))]
50    Vec::new()
51}
52
53/// Registers the daemon for `permission` and opens its System Settings pane.
54///
55/// # Errors
56///
57/// [`PermissionError::Unsupported`] off macOS, or
58/// [`PermissionError::OpenSettings`] when the pane cannot be opened.
59pub fn request(permission: Permission) -> Result<(), PermissionError> {
60    #[cfg(target_os = "macos")]
61    return macos::request(permission);
62    #[cfg(not(target_os = "macos"))]
63    {
64        let _ = permission;
65        Err(PermissionError::Unsupported)
66    }
67}