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