//! Internal Rust configuration API used by Jay's built-in TOML configuration //! implementation. #![allow( clippy::zero_prefixed_literal, clippy::manual_range_contains, clippy::uninlined_format_args, clippy::len_zero, clippy::single_char_pattern, clippy::single_char_add_str, clippy::single_match )] #![warn(unsafe_op_in_unsafe_fn)] #[expect(unused_imports)] use crate::input::Seat; use { crate::{ keyboard::ModifiedKeySym, protocol::WorkspaceSource, video::Connector, window::Window, }, serde::{Deserialize, Serialize}, std::{ fmt::{Debug, Display, Formatter}, time::Duration, }, }; #[macro_use] mod macros; #[doc(hidden)] pub mod _private; pub mod client; pub mod embedded; pub mod exec; pub mod input; pub mod io; pub mod keyboard; pub mod logging; pub mod protocol; pub mod status; pub mod tasks; pub mod theme; pub mod timer; pub mod video; pub mod window; pub mod workspace; pub mod xwayland; /// A planar direction. #[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq)] pub enum Direction { Left, Down, Up, Right, } /// A planar axis. #[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum Axis { Horizontal, Vertical, } impl Axis { /// Returns the axis orthogonal to `self`. pub fn other(self) -> Self { match self { Self::Horizontal => Self::Vertical, Self::Vertical => Self::Horizontal, } } } /// The curve used for tiled window animations. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct AnimationCurve(pub u32); impl AnimationCurve { pub const LINEAR: Self = Self(0); pub const EASE: Self = Self(1); pub const EASE_IN: Self = Self(2); pub const EASE_OUT: Self = Self(3); pub const EASE_IN_OUT: Self = Self(4); } /// The presentation style used for tiled window movement animations. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct AnimationStyle(pub u32); impl AnimationStyle { pub const PLAIN: Self = Self(0); pub const MULTIPHASE: Self = Self(1); } /// Exits the compositor. pub fn quit() { get!().quit() } /// Switches to a different VT. pub fn switch_to_vt(n: u32) { get!().switch_to_vt(n) } /// Reloads the configuration. /// /// If the configuration cannot be reloaded, this function has no effect. pub fn reload() { get!().reload() } /// Returns whether this execution of the configuration function is due to a reload. /// /// This can be used to decide whether the configuration should auto-start programs. pub fn is_reload() -> bool { get!(false).is_reload() } /// Sets whether new workspaces are captured by default. /// /// The default is `true`. pub fn set_default_workspace_capture(capture: bool) { get!().set_default_workspace_capture(capture) } /// Returns whether new workspaces are captured by default. pub fn get_default_workspace_capture() -> bool { get!(true).get_default_workspace_capture() } /// Toggles whether new workspaces are captured by default. pub fn toggle_default_workspace_capture() { let get = get!(); get.set_default_workspace_capture(!get.get_default_workspace_capture()); } /// A workspace. #[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)] pub struct Workspace(pub u64); impl Workspace { /// Returns whether this workspace existed at the time `Seat::get_workspace` was called. pub fn exists(self) -> bool { self.0 != 0 } /// Sets whether the workspaces is captured. /// /// The default is determined by `set_default_workspace_capture`. pub fn set_capture(self, capture: bool) { get!().set_workspace_capture(self, capture) } /// Returns whether the workspaces is captured. pub fn get_capture(self) -> bool { get!(true).get_workspace_capture(self) } /// Toggles whether the workspaces is captured. pub fn toggle_capture(self) { let get = get!(); get.set_workspace_capture(self, !get.get_workspace_capture(self)); } /// Moves this workspace to another output. /// /// This has no effect if the workspace is not currently being shown. pub fn move_to_output(self, output: Connector) { get!().move_to_output(WorkspaceSource::Explicit(self), output); } /// Returns the root container of this workspace. /// /// If no such container exists, [`Window::exists`] returns false. pub fn window(self) -> Window { get!(Window(0)).get_workspace_window(self) } /// Returns the connector that contains this workspace. /// /// If no such connector exists, [`Connector::exists`] returns false. pub fn connector(self) -> Connector { get!(Connector(0)).get_workspace_connector(self) } } /// Returns the workspace with the given name. /// /// Workspaces are identified by their name. Calling this function alone does not create the /// workspace if it doesn't already exist. pub fn get_workspace(name: &str) -> Workspace { get!(Workspace(0)).get_workspace(name) } /// A PCI ID. /// /// PCI IDs can be used to identify a hardware component. See the Debian [documentation][pci]. /// /// [pci]: https://wiki.debian.org/HowToIdentifyADevice/PCI #[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq, Default)] pub struct PciId { pub vendor: u32, pub model: u32, } impl Display for PciId { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{:04x}:{:04x}", self.vendor, self.model) } } /// Sets the callback to be called when the display goes idle. pub fn on_idle(f: F) { get!().on_idle(f) } /// Sets the callback to be called when all devices have been enumerated. /// /// This callback is only invoked once during the lifetime of the compositor. This is a /// good place to select the DRM device used for rendering. pub fn on_devices_enumerated(f: F) { get!().on_devices_enumerated(f) } /// Returns the Jay config directory. pub fn config_dir() -> String { get!().config_dir() } /// Returns all visible workspaces. pub fn workspaces() -> Vec { get!().workspaces() } /// Configures the idle timeout. /// /// `None` disables the timeout. /// /// The default is 10 minutes. pub fn set_idle(timeout: Option) { get!().set_idle(timeout.unwrap_or_default()) } /// Configures whether a key press turns monitors back on after `jay dpms off`. /// /// The default is `false`. pub fn set_key_press_enables_dpms(enabled: bool) { get!().set_key_press_enables_dpms(enabled) } /// Configures whether mouse movement turns monitors back on after `jay dpms off`. /// /// The default is `false`. pub fn set_mouse_move_enables_dpms(enabled: bool) { get!().set_mouse_move_enables_dpms(enabled) } /// Configures the idle grace period. /// /// The grace period starts after the idle timeout expires. During the grace period, the /// screen goes black but the displays are not yet disabled and the idle callback (set /// with [`on_idle`]) is not yet called. This is a purely visual effect to inform the user /// that the machine will soon go idle. /// /// The default is 5 seconds. pub fn set_idle_grace_period(timeout: Duration) { get!().set_idle_grace_period(timeout) } /// Enables or disables explicit sync. /// /// Calling this after the compositor has started has no effect. /// /// The default is `true`. pub fn set_explicit_sync_enabled(enabled: bool) { get!().set_explicit_sync_enabled(enabled); } /// Enables or disables dragging of tiles and workspaces. /// /// The default is `true`. pub fn set_ui_drag_enabled(enabled: bool) { get!().set_ui_drag_enabled(enabled); } /// Sets the distance at which ui dragging starts. /// /// The default is `10`. pub fn set_ui_drag_threshold(threshold: i32) { get!().set_ui_drag_threshold(threshold); } /// Enables or disables tiled window animations. /// /// The default is `false`. pub fn set_animations_enabled(enabled: bool) { get!().set_animations_enabled(enabled); } /// Sets the duration of tiled window animations in milliseconds. /// /// The default is `160`. pub fn set_animation_duration_ms(duration_ms: u32) { get!().set_animation_duration_ms(duration_ms); } /// Sets the curve used by tiled window animations. /// /// The default is [`AnimationCurve::EASE_OUT`]. pub fn set_animation_curve(curve: AnimationCurve) { get!().set_animation_curve(curve.0); } /// Sets the presentation style used for tiled window movement animations. /// /// The default is [`AnimationStyle::MULTIPHASE`]. pub fn set_animation_style(style: AnimationStyle) { get!().set_animation_style(style.0); } /// Sets a custom cubic-bezier curve used by tiled window animations. /// /// `x1` and `x2` must be between `0.0` and `1.0`. The curve starts at `(0, 0)` /// and ends at `(1, 1)`. pub fn set_animation_cubic_bezier(x1: f32, y1: f32, x2: f32, y2: f32) { get!().set_animation_cubic_bezier(x1, y1, x2, y2); } /// Enables or disables the color-management protocol. /// /// The default is `false`. /// /// Affected applications must be restarted for this to take effect. pub fn set_color_management_enabled(enabled: bool) { get!().set_color_management_enabled(enabled); } /// Sets whether floating windows are shown above fullscreen windows. /// /// The default is `false`. pub fn set_float_above_fullscreen(above: bool) { get!().set_float_above_fullscreen(above); } /// Gets whether floating windows are shown above fullscreen windows. pub fn get_float_above_fullscreen() -> bool { get!().get_float_above_fullscreen() } /// Toggles whether floating windows are shown above fullscreen windows. /// /// The default is `false`. pub fn toggle_float_above_fullscreen() { set_float_above_fullscreen(!get_float_above_fullscreen()) } /// Sets whether floating windows always show a pin icon. /// /// Clicking on the pin icon toggles the pin mode. See [`Seat::toggle_float_pinned`]. /// /// The icon is always shown if the window is pinned. This setting only affects unpinned /// windows. pub fn set_show_float_pin_icon(show: bool) { get!().set_show_float_pin_icon(show); } /// Sets whether the built-in bar is shown. /// /// The default is `true`. pub fn set_show_bar(show: bool) { get!().set_show_bar(show) } /// Returns whether the built-in bar is shown. pub fn get_show_bar() -> bool { get!(true).get_show_bar() } /// Toggles whether the built-in bar is shown. pub fn toggle_show_bar() { let get = get!(); get.set_show_bar(!get.get_show_bar()); } /// Sets whether title bars on windows are shown. /// /// The default is `true`. pub fn set_show_titles(show: bool) { get!().set_show_titles(show) } /// Returns whether title bars on windows are shown. pub fn get_show_titles() -> bool { get!(true).get_show_titles() } /// Toggles whether title bars on windows are shown. pub fn toggle_show_titles() { let get = get!(); get.set_show_titles(!get.get_show_titles()); } /// Sets whether title bars float above window content instead of being attached. /// /// When enabled, title bars are rendered on top of window content without consuming /// layout space. Window borders do not extend to include the title bar area. /// /// The default is `false`. pub fn set_floating_titles(floating: bool) { get!().set_floating_titles(floating) } /// Returns whether title bars float above window content. pub fn get_floating_titles() -> bool { get!(false).get_floating_titles() } /// Toggles whether title bars float above window content. pub fn toggle_floating_titles() { let get = get!(); get.set_floating_titles(!get.get_floating_titles()); } /// Sets the corner radius for window borders. /// /// A radius of 0 means square corners. The radius is in logical pixels. pub fn set_corner_radius(radius: f32) { get!().set_corner_radius(radius) } /// Returns the current corner radius for window borders. pub fn get_corner_radius() -> f32 { get!(0.0).get_corner_radius() } /// Enables or disables autotiling. /// /// When enabled, newly tiled windows alternate split orientation from the /// focused tiled window by splitting the focused tile along its largest axis. /// On an empty workspace, the first split uses the workspace output's largest /// axis. /// /// The default is `false`. pub fn set_autotile(enabled: bool) { get!().set_autotile(enabled) } /// Returns whether autotiling is enabled. pub fn get_autotile() -> bool { get!(false).get_autotile() } /// Sets the horizontal alignment of title text within tab buttons. /// /// - `"start"` — left-aligned (default) /// - `"center"` — centered /// - `"end"` — right-aligned pub fn set_tab_title_align(align: &str) { let val = match align { "center" => 1, "end" => 2, _ => 0, // start }; get!().set_tab_title_align(val) } /// Sets a callback to run when this config is unloaded. /// /// Only one callback can be set at a time. If another callback is already set, it will be /// dropped without being run. /// /// This function can be used to terminate threads and clear reference cycles. pub fn on_unload(f: impl FnOnce() + 'static) { get!().on_unload(f); } /// Enables or disables middle-click pasting. /// /// This has no effect on applications that are already running. /// /// The default is `true`. #[doc(alias("primary-selection", "primary_selection"))] pub fn set_middle_click_paste_enabled(enabled: bool) { get!().set_middle_click_paste_enabled(enabled); }