hyprshell_core_lib/config/
structs.rs

1use serde::{Deserialize, Serialize};
2use smart_default::SmartDefault;
3use std::fmt::Display;
4
5#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
6#[serde(default, deny_unknown_fields)]
7pub struct Config {
8    #[default = true]
9    pub layerrules: bool,
10    #[default(None)]
11    pub launcher: Option<Launcher>,
12    #[default(Some(Windows::default()))]
13    pub windows: Option<Windows>,
14}
15
16#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
17#[serde(default, deny_unknown_fields)]
18pub struct Launcher {
19    #[default(None)]
20    pub default_terminal: Option<Box<str>>,
21    #[default = 650]
22    pub width: u32,
23    #[default = 5]
24    pub max_items: u8,
25    #[default = 250]
26    pub animate_launch_ms: u64,
27    #[default(Plugins::default())]
28    pub plugins: Plugins,
29}
30
31#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
32#[serde(default, deny_unknown_fields)]
33pub struct Plugins {
34    #[default(Some(Default::default()))]
35    pub applications: Option<ApplicationsPluginConfig>,
36    #[default(Some(Default::default()))]
37    pub terminal: Option<EmptyConfig>,
38    #[default(None)]
39    pub shell: Option<EmptyConfig>,
40    #[default(Some(Default::default()))]
41    pub websearch: Option<WebSearchConfig>,
42    #[default(Some(Default::default()))]
43    pub calc: Option<EmptyConfig>,
44}
45
46#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
47#[serde(default, deny_unknown_fields)]
48pub struct EmptyConfig {}
49
50#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
51#[serde(default, deny_unknown_fields)]
52pub struct ApplicationsPluginConfig {
53    #[default = 4]
54    pub run_cache_weeks: u8,
55    #[default = true]
56    pub show_execs: bool,
57}
58
59#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
60#[serde(default, deny_unknown_fields)]
61pub struct WebSearchConfig {
62    #[default(vec![SearchEngine {
63        url: "https://www.google.com/search?q={}".into(),
64        name: "Google".into(),
65        key: 'g',
66    }])]
67    pub engines: Vec<SearchEngine>,
68}
69
70#[derive(Debug, Clone, Deserialize, Serialize)]
71#[serde(deny_unknown_fields)]
72pub struct SearchEngine {
73    pub url: String,
74    pub name: String,
75    pub key: char,
76}
77
78#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
79#[serde(default, deny_unknown_fields)]
80pub struct Windows {
81    #[default = 8.5]
82    pub scale: f64,
83    #[default = 5]
84    pub workspaces_per_row: u8,
85    #[default = true]
86    pub strip_html_from_workspace_title: bool,
87    pub overview: Option<Overview>,
88    pub switch: Option<Switch>,
89}
90
91#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
92#[serde(default, deny_unknown_fields)]
93pub struct Overview {
94    pub open: OpenOverview,
95    pub navigate: Navigate,
96    pub other: OtherOverview,
97}
98
99#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
100#[serde(default, deny_unknown_fields)]
101pub struct OtherOverview {
102    #[default(Vec::new())]
103    pub filter_by: Vec<FilterBy>,
104    #[default = false]
105    pub hide_filtered: bool,
106}
107
108#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
109#[serde(default, deny_unknown_fields)]
110pub struct OpenOverview {
111    #[default = "super"]
112    pub key: KeyMaybeMod,
113    #[default(Mod::Super)]
114    pub modifier: Mod,
115}
116
117#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
118#[serde(default, deny_unknown_fields)]
119pub struct Navigate {
120    #[default = "tab"]
121    pub forward: String,
122    #[default(Reverse::Mod(Mod::Shift))]
123    pub reverse: Reverse,
124}
125
126#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
127#[serde(default, deny_unknown_fields)]
128pub struct Switch {
129    pub open: OpenSwitch,
130    pub navigate: Navigate,
131    pub other: OtherSwitch,
132}
133
134#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
135#[serde(default, deny_unknown_fields)]
136pub struct OpenSwitch {
137    #[default(Mod::Super)]
138    pub modifier: Mod,
139}
140
141#[derive(SmartDefault, Debug, Clone, Deserialize, Serialize)]
142#[serde(default, deny_unknown_fields)]
143pub struct OtherSwitch {
144    #[default(Vec::new())]
145    pub filter_by: Vec<FilterBy>,
146    #[default = true]
147    pub hide_filtered: bool,
148}
149
150#[derive(Debug, Clone, Copy, Deserialize, Serialize, Eq, PartialEq)]
151#[serde(rename_all = "snake_case")]
152pub enum FilterBy {
153    SameClass,
154    CurrentWorkspace,
155    CurrentMonitor,
156}
157
158#[derive(Debug, Clone, Deserialize, Serialize)]
159#[serde(rename_all = "snake_case")]
160pub enum Reverse {
161    Key(String),
162    Mod(Mod),
163}
164#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
165#[serde(rename_all = "snake_case")]
166pub enum Mod {
167    Alt,
168    Ctrl,
169    Super,
170    Shift,
171}
172
173impl Display for Mod {
174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175        match self {
176            Mod::Alt => write!(f, "alt"),
177            Mod::Ctrl => write!(f, "ctrl"),
178            Mod::Super => write!(f, "super"),
179            Mod::Shift => write!(f, "shift"),
180        }
181    }
182}
183
184#[derive(Debug, Clone, Deserialize, Serialize)]
185pub struct KeyMaybeMod(String);
186impl From<&str> for KeyMaybeMod {
187    fn from(s: &str) -> Self {
188        Self(s.to_string())
189    }
190}
191
192// https://wiki.hyprland.org/Configuring/Variables/#variable-types
193// SHIFT CAPS CTRL/CONTROL ALT MOD2 MOD3 SUPER/WIN/LOGO/MOD4 MOD5
194impl KeyMaybeMod {
195    pub fn to_key(&self) -> String {
196        match &*self.0.to_ascii_lowercase() {
197            "alt" => "alt_l".to_string(),
198            "ctrl" => "ctrl_l".to_string(),
199            "super" => "super_l".to_string(),
200            "shift" => "shift_l".to_string(),
201            a => a.to_string(),
202        }
203    }
204}
205
206impl Mod {
207    pub fn mod_to_keys(&self) -> [&'static str; 2] {
208        match self {
209            Mod::Alt => ["alt_l", "alt_r"],
210            Mod::Ctrl => ["control_l", "control_r"], // WHY is this not ctrl_l and ctrl_r?
211            Mod::Super => ["super_l", "super_r"],
212            Mod::Shift => ["shift_l", "shift_r"],
213        }
214    }
215}