487 lines
13 KiB
Rust
487 lines
13 KiB
Rust
//! 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: FnMut() + 'static>(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: FnOnce() + 'static>(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<Workspace> {
|
|
get!().workspaces()
|
|
}
|
|
|
|
/// Configures the idle timeout.
|
|
///
|
|
/// `None` disables the timeout.
|
|
///
|
|
/// The default is 10 minutes.
|
|
pub fn set_idle(timeout: Option<Duration>) {
|
|
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);
|
|
}
|