2023-08-29 13:49:41 -07:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
|
|
2025-10-16 18:53:57 +02:00
|
|
|
use cosmic_config::{CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry};
|
2023-08-29 13:49:41 -07:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-12-20 16:52:44 -08:00
|
|
|
use std::collections::HashMap;
|
2023-08-29 13:49:41 -07:00
|
|
|
|
2025-08-20 16:49:08 +02:00
|
|
|
use crate::input::TouchpadOverride;
|
|
|
|
|
|
2023-08-29 13:49:41 -07:00
|
|
|
pub mod input;
|
2025-08-19 16:51:37 -04:00
|
|
|
#[cfg(feature = "output")]
|
2025-01-31 14:13:33 -08:00
|
|
|
pub mod output;
|
2023-09-07 13:28:08 -07:00
|
|
|
pub mod workspace;
|
2023-08-29 13:49:41 -07:00
|
|
|
|
2025-08-26 19:32:35 -04:00
|
|
|
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
|
|
|
pub struct EdidProduct {
|
|
|
|
|
pub manufacturer: [char; 3],
|
|
|
|
|
pub product: u16,
|
|
|
|
|
pub serial: Option<u32>,
|
|
|
|
|
pub manufacture_week: i32,
|
|
|
|
|
pub manufacture_year: i32,
|
|
|
|
|
pub model_year: Option<i32>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "libdisplay-info")]
|
|
|
|
|
impl From<libdisplay_info::edid::VendorProduct> for EdidProduct {
|
|
|
|
|
fn from(vp: libdisplay_info::edid::VendorProduct) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
manufacturer: vp.manufacturer,
|
|
|
|
|
product: vp.product,
|
|
|
|
|
serial: vp.serial,
|
|
|
|
|
manufacture_week: vp.manufacture_week,
|
|
|
|
|
manufacture_year: vp.manufacture_year,
|
|
|
|
|
model_year: vp.model_year,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-12 05:35:22 -08:00
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
|
|
|
|
pub struct KeyboardConfig {
|
|
|
|
|
/// Boot state for numlock
|
|
|
|
|
pub numlock_state: NumlockState,
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-17 08:30:47 -08:00
|
|
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
2025-02-12 05:35:22 -08:00
|
|
|
pub enum NumlockState {
|
|
|
|
|
BootOn,
|
|
|
|
|
#[default]
|
|
|
|
|
BootOff,
|
|
|
|
|
LastBoot,
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-09 16:43:19 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2025-12-08 18:21:58 +01:00
|
|
|
pub struct AppearanceConfig {
|
|
|
|
|
pub clip_floating_windows: bool,
|
|
|
|
|
pub clip_tiled_windows: bool,
|
|
|
|
|
pub shadow_tiled_windows: bool,
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-09 16:43:19 +01:00
|
|
|
impl Default for AppearanceConfig {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
AppearanceConfig {
|
|
|
|
|
clip_floating_windows: true,
|
|
|
|
|
clip_tiled_windows: true,
|
|
|
|
|
shadow_tiled_windows: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 14:25:18 -05:00
|
|
|
#[derive(Clone, Debug, PartialEq, CosmicConfigEntry)]
|
|
|
|
|
#[version = 1]
|
2023-12-20 16:52:44 -08:00
|
|
|
pub struct CosmicCompConfig {
|
|
|
|
|
pub workspaces: workspace::WorkspaceConfig,
|
2025-01-31 14:13:33 -08:00
|
|
|
pub pinned_workspaces: Vec<workspace::PinnedWorkspace>,
|
2023-12-20 16:52:44 -08:00
|
|
|
pub input_default: input::InputConfig,
|
|
|
|
|
pub input_touchpad: input::InputConfig,
|
2025-08-20 16:49:08 +02:00
|
|
|
pub input_touchpad_override: TouchpadOverride,
|
2023-12-20 16:52:44 -08:00
|
|
|
pub input_devices: HashMap<String, input::InputConfig>,
|
|
|
|
|
pub xkb_config: XkbConfig,
|
2025-02-12 05:35:22 -08:00
|
|
|
pub keyboard_config: KeyboardConfig,
|
2024-02-08 14:25:18 -05:00
|
|
|
/// Autotiling enabled
|
|
|
|
|
pub autotile: bool,
|
|
|
|
|
/// Determines the behavior of the autotile variable
|
|
|
|
|
/// If set to Global, autotile applies to all windows in all workspaces
|
|
|
|
|
/// If set to PerWorkspace, autotile only applies to new windows, and new workspaces
|
|
|
|
|
pub autotile_behavior: TileBehavior,
|
|
|
|
|
/// Active hint enabled
|
|
|
|
|
pub active_hint: bool,
|
2024-09-04 11:13:59 -05:00
|
|
|
/// Enables changing keyboard focus to windows when the cursor passes into them
|
|
|
|
|
pub focus_follows_cursor: bool,
|
|
|
|
|
/// Enables warping the cursor to the focused window when focus changes due to keyboard input
|
|
|
|
|
pub cursor_follows_focus: bool,
|
|
|
|
|
/// The delay in milliseconds before focus follows mouse (if enabled)
|
|
|
|
|
pub focus_follows_cursor_delay: u64,
|
2024-08-23 18:26:08 +02:00
|
|
|
/// Let X11 applications scale themselves
|
2025-04-04 18:49:45 +02:00
|
|
|
pub descale_xwayland: XwaylandDescaling,
|
2025-03-28 17:45:28 +01:00
|
|
|
/// Let X11 applications snoop on certain key-presses to allow for global shortcuts
|
|
|
|
|
pub xwayland_eavesdropping: XwaylandEavesdropping,
|
2025-02-14 21:58:09 +11:00
|
|
|
/// The threshold before windows snap themselves to output edges
|
|
|
|
|
pub edge_snap_threshold: u32,
|
2025-01-24 17:49:13 +01:00
|
|
|
pub accessibility_zoom: ZoomConfig,
|
2025-12-08 18:21:58 +01:00
|
|
|
pub appearance_settings: AppearanceConfig,
|
cursor: Add idle-hide timeout
Adds a cursor_hide_timeout config key (Option<u32> seconds) to
CosmicCompConfig. When set, the cursor is hidden after the configured
period of pointer inactivity and revealed again by any pointer event.
Touch input does not count as activity (no visible cursor to surface).
Implementation:
- Per-seat hidden flag, calloop timer token, and last-armed Instant on
CursorStateInner.
- notify_cursor_activity called from each pointer-related input branch
(motion, button, axis, tablet) resets the flag and reschedules the
timer; rapid successive calls are coalesced behind a 100ms throttle
so high-frequency mice don't churn the calloop timer source.
- On timer fire, the hidden flag is set, draw_cursor short-circuits to
an empty element list, and a render is scheduled. Active pointer
grabs (drags, resizes) suppress the hide.
- Config reload arms or cancels the timer immediately; None as the
configured value collapses the cancel path into the same function.
Closes #2231.
Drafted with Claude (Anthropic); reviewed and tested by the committer.
2026-05-20 23:52:45 +02:00
|
|
|
/// Hide the cursor after this many seconds of pointer inactivity (None disables)
|
|
|
|
|
pub cursor_hide_timeout: Option<u32>,
|
2026-07-20 16:11:13 -06:00
|
|
|
/// Briefly magnify the cursor when the pointer is shaken, to help locate it
|
|
|
|
|
pub cursor_shake_to_find: bool,
|
2026-05-22 17:06:49 +02:00
|
|
|
pub activation_policy: ActivationPolicy,
|
2024-02-08 14:25:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for CosmicCompConfig {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
workspaces: Default::default(),
|
2025-01-31 14:13:33 -08:00
|
|
|
pinned_workspaces: Vec::new(),
|
2024-02-08 14:25:18 -05:00
|
|
|
input_default: Default::default(),
|
2024-07-31 06:04:08 +02:00
|
|
|
// By default, enable tap-to-click and disable-while-typing.
|
|
|
|
|
input_touchpad: input::InputConfig {
|
|
|
|
|
state: input::DeviceState::Enabled,
|
|
|
|
|
click_method: Some(input::ClickMethod::Clickfinger),
|
|
|
|
|
disable_while_typing: Some(true),
|
|
|
|
|
tap_config: Some(input::TapConfig {
|
|
|
|
|
enabled: true,
|
|
|
|
|
button_map: Some(input::TapButtonMap::LeftRightMiddle),
|
|
|
|
|
drag: true,
|
|
|
|
|
drag_lock: false,
|
|
|
|
|
}),
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
2025-08-20 16:49:08 +02:00
|
|
|
input_touchpad_override: Default::default(),
|
2024-02-08 14:25:18 -05:00
|
|
|
input_devices: Default::default(),
|
|
|
|
|
xkb_config: Default::default(),
|
2025-02-12 05:35:22 -08:00
|
|
|
keyboard_config: Default::default(),
|
2024-02-08 14:25:18 -05:00
|
|
|
autotile: Default::default(),
|
|
|
|
|
autotile_behavior: Default::default(),
|
|
|
|
|
active_hint: true,
|
2024-09-04 11:13:59 -05:00
|
|
|
focus_follows_cursor: false,
|
|
|
|
|
cursor_follows_focus: false,
|
|
|
|
|
focus_follows_cursor_delay: 250,
|
2025-04-04 18:49:45 +02:00
|
|
|
descale_xwayland: XwaylandDescaling::Fractional,
|
2025-03-28 17:45:28 +01:00
|
|
|
xwayland_eavesdropping: XwaylandEavesdropping::default(),
|
2025-02-14 21:58:09 +11:00
|
|
|
edge_snap_threshold: 0,
|
2025-01-24 17:49:13 +01:00
|
|
|
accessibility_zoom: ZoomConfig::default(),
|
2025-12-08 18:21:58 +01:00
|
|
|
appearance_settings: AppearanceConfig::default(),
|
cursor: Add idle-hide timeout
Adds a cursor_hide_timeout config key (Option<u32> seconds) to
CosmicCompConfig. When set, the cursor is hidden after the configured
period of pointer inactivity and revealed again by any pointer event.
Touch input does not count as activity (no visible cursor to surface).
Implementation:
- Per-seat hidden flag, calloop timer token, and last-armed Instant on
CursorStateInner.
- notify_cursor_activity called from each pointer-related input branch
(motion, button, axis, tablet) resets the flag and reschedules the
timer; rapid successive calls are coalesced behind a 100ms throttle
so high-frequency mice don't churn the calloop timer source.
- On timer fire, the hidden flag is set, draw_cursor short-circuits to
an empty element list, and a render is scheduled. Active pointer
grabs (drags, resizes) suppress the hide.
- Config reload arms or cancels the timer immediately; None as the
configured value collapses the cancel path into the same function.
Closes #2231.
Drafted with Claude (Anthropic); reviewed and tested by the committer.
2026-05-20 23:52:45 +02:00
|
|
|
cursor_hide_timeout: None,
|
2026-07-20 16:11:13 -06:00
|
|
|
cursor_shake_to_find: true,
|
2026-05-22 17:06:49 +02:00
|
|
|
activation_policy: ActivationPolicy::default(),
|
2024-02-08 14:25:18 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Deserialize, Serialize)]
|
|
|
|
|
pub enum TileBehavior {
|
|
|
|
|
#[default]
|
|
|
|
|
Global,
|
|
|
|
|
PerWorkspace,
|
2023-12-20 16:52:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
2023-08-29 13:49:41 -07:00
|
|
|
pub struct XkbConfig {
|
|
|
|
|
pub rules: String,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub layout: String,
|
|
|
|
|
pub variant: String,
|
|
|
|
|
pub options: Option<String>,
|
2024-05-19 18:19:43 +02:00
|
|
|
#[serde(default = "default_repeat_delay")]
|
|
|
|
|
pub repeat_delay: u32,
|
|
|
|
|
#[serde(default = "default_repeat_rate")]
|
|
|
|
|
pub repeat_rate: u32,
|
2023-08-29 13:49:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for XkbConfig {
|
|
|
|
|
fn default() -> XkbConfig {
|
|
|
|
|
XkbConfig {
|
|
|
|
|
rules: String::new(),
|
|
|
|
|
model: String::new(),
|
|
|
|
|
layout: String::new(),
|
|
|
|
|
variant: String::new(),
|
|
|
|
|
options: None,
|
2024-05-19 18:19:43 +02:00
|
|
|
repeat_delay: default_repeat_delay(),
|
|
|
|
|
repeat_rate: default_repeat_rate(),
|
2023-08-29 13:49:41 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-19 18:19:43 +02:00
|
|
|
|
|
|
|
|
fn default_repeat_rate() -> u32 {
|
|
|
|
|
25
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn default_repeat_delay() -> u32 {
|
|
|
|
|
600
|
|
|
|
|
}
|
2025-01-24 17:49:13 +01:00
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
|
|
|
|
pub struct ZoomConfig {
|
|
|
|
|
pub start_on_login: bool,
|
2025-03-25 14:38:35 +01:00
|
|
|
pub show_overlay: bool,
|
2025-01-24 17:49:13 +01:00
|
|
|
pub increment: u32,
|
|
|
|
|
pub view_moves: ZoomMovement,
|
2025-03-25 14:42:20 +01:00
|
|
|
pub enable_mouse_zoom_shortcuts: bool,
|
2025-01-24 17:49:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for ZoomConfig {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
ZoomConfig {
|
|
|
|
|
start_on_login: false,
|
2025-03-25 14:38:35 +01:00
|
|
|
show_overlay: true,
|
2025-02-14 19:17:36 +01:00
|
|
|
increment: 50,
|
|
|
|
|
view_moves: ZoomMovement::Continuously,
|
2025-03-25 14:42:20 +01:00
|
|
|
enable_mouse_zoom_shortcuts: true,
|
2025-01-24 17:49:13 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
|
|
|
|
pub enum ZoomMovement {
|
|
|
|
|
OnEdge,
|
|
|
|
|
Centered,
|
|
|
|
|
Continuously,
|
|
|
|
|
}
|
2025-03-28 17:45:28 +01:00
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
|
|
|
|
pub struct XwaylandEavesdropping {
|
|
|
|
|
pub keyboard: EavesdroppingKeyboardMode,
|
|
|
|
|
pub pointer: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
|
|
|
|
pub enum EavesdroppingKeyboardMode {
|
2025-04-04 14:29:29 -06:00
|
|
|
#[default]
|
2025-03-28 17:45:28 +01:00
|
|
|
None,
|
|
|
|
|
Modifiers,
|
|
|
|
|
Combinations,
|
|
|
|
|
All,
|
|
|
|
|
}
|
2025-04-04 18:49:45 +02:00
|
|
|
|
2026-05-22 17:06:49 +02:00
|
|
|
#[derive(Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq, Eq)]
|
|
|
|
|
pub enum ActivationPolicy {
|
|
|
|
|
#[default]
|
|
|
|
|
Focus,
|
|
|
|
|
FocusIfActiveWorkspace,
|
|
|
|
|
Urgent,
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-04 18:49:45 +02:00
|
|
|
#[derive(Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq, Eq)]
|
|
|
|
|
#[serde(rename_all = "lowercase")]
|
|
|
|
|
pub enum XwaylandDescaling {
|
|
|
|
|
#[serde(rename = "true")]
|
|
|
|
|
Enabled,
|
|
|
|
|
#[serde(rename = "false")]
|
|
|
|
|
Disabled,
|
|
|
|
|
#[default]
|
|
|
|
|
Fractional,
|
|
|
|
|
}
|