1use crate::Modifier;
2use serde::{Deserialize, Serialize};
3use smart_default::SmartDefault;
4use std::path::Path;
5
6#[derive(SmartDefault, Debug, Clone, PartialEq, Deserialize, Serialize)]
7#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
8#[serde(deny_unknown_fields)]
9pub struct Config {
10 #[default(crate::CURRENT_CONFIG_VERSION)]
11 pub version: u16,
12 #[default(None)]
13 pub windows: Option<Windows>,
14}
15
16#[derive(SmartDefault, Debug, Clone, PartialEq, Deserialize, Serialize)]
17#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
18#[serde(deny_unknown_fields)]
19pub struct Windows {
20 #[default = 8.5]
21 pub scale: f64,
22 #[default = 5]
23 pub items_per_row: u8,
24 #[default(None)]
25 pub overview: Option<Overview>,
26 #[default(None)]
27 pub switch: Option<Switch>,
28 #[default(None)]
29 pub switch_2: Option<Switch>,
30}
31
32#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
33#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
34#[serde(deny_unknown_fields)]
35pub struct Overview {
36 pub launcher: Launcher,
37 #[default = "Super_L"]
38 pub key: Box<str>,
39 #[default(Modifier::Super)]
40 pub modifier: Modifier,
41 #[default(Vec::new())]
42 pub filter_by: Vec<FilterBy>,
43 #[default = false]
44 pub hide_filtered: bool,
45 #[default = ""]
46 pub exclude_special_workspaces: Box<str>,
47}
48
49#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
50#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
51#[serde(deny_unknown_fields)]
52pub struct Launcher {
53 #[default(None)]
54 pub default_terminal: Option<Box<str>>,
55 #[default(Modifier::Ctrl)]
56 pub launch_modifier: Modifier,
57 #[default = 650]
58 pub width: u32,
59 #[default = 5]
60 pub max_items: u8,
61 #[default = true]
62 pub show_when_empty: bool,
63 #[default(Plugins{
64 applications: Some(ApplicationsPluginConfig::default()),
65 terminal: Some(EmptyConfig::default()),
66 shell: None,
67 websearch: Some(WebSearchConfig::default()),
68 calc: Some(EmptyConfig::default()),
69 path: Some(EmptyConfig::default()),
70 actions: Some(ActionsPluginConfig::default()),
71 })]
72 pub plugins: Plugins,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
78#[serde(deny_unknown_fields)]
79pub struct Plugins {
80 pub applications: Option<ApplicationsPluginConfig>,
81 pub terminal: Option<EmptyConfig>,
82 pub shell: Option<EmptyConfig>,
83 pub websearch: Option<WebSearchConfig>,
84 pub calc: Option<EmptyConfig>,
85 pub path: Option<EmptyConfig>,
86 pub actions: Option<ActionsPluginConfig>,
87}
88
89#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
90#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
91#[serde(deny_unknown_fields)]
92pub struct EmptyConfig {}
93
94#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
95#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
96#[serde(deny_unknown_fields)]
97pub struct ActionsPluginConfig {
98 #[default(vec![
99 ActionsPluginAction::LockScreen,
100 ActionsPluginAction::Hibernate,
101 ActionsPluginAction::Logout,
102 ActionsPluginAction::Reboot,
103 ActionsPluginAction::Shutdown,
104 ActionsPluginAction::Suspend,
105 ActionsPluginAction::Custom(ActionsPluginActionCustom {
106 names: vec!["Kill".into(), "Stop".into()],
107 details: "Kill or stop a process by name".into(),
108 command: "pkill \"{}\" && notify-send hyprshell \"stopped {}\"".into(),
109 icon: Box::from(Path::new("remove")),
110 }),
111 ActionsPluginAction::Custom(ActionsPluginActionCustom {
112 names: vec!["Reload Hyprshell".into()],
113 details: "Reload Hyprshell".into(),
114 command: "sleep 1; hyprshell socat '\"Restart\"'".into(),
115 icon: Box::from(Path::new("system-restart")),
116 }),
117 ])]
118 pub actions: Vec<ActionsPluginAction>,
119}
120
121#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
122#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
123#[serde(deny_unknown_fields)]
124pub struct ApplicationsPluginConfig {
125 #[default = 8]
126 pub run_cache_weeks: u8,
127 #[default = true]
128 pub show_execs: bool,
129 #[default = true]
130 pub show_actions_submenu: bool,
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
134#[serde(rename_all = "snake_case")]
135pub enum ActionsPluginAction {
136 LockScreen,
137 Hibernate,
138 Logout,
139 Reboot,
140 Shutdown,
141 Suspend,
142 Custom(ActionsPluginActionCustom),
143}
144
145#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
146#[serde(deny_unknown_fields)]
147pub struct ActionsPluginActionCustom {
148 pub names: Vec<Box<str>>,
149 pub details: Box<str>,
150 pub command: Box<str>,
151 pub icon: Box<Path>,
152}
153
154#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
155#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
156#[serde(deny_unknown_fields)]
157pub struct WebSearchConfig {
158 #[default(vec![SearchEngine {
159 url: "https://www.google.com/search?q={}".into(),
160 name: "Google".into(),
161 key: 'g',
162 }, SearchEngine {
163 url: "https://en.wikipedia.org/wiki/Special:Search?search={}".into(),
164 name: "Wikipedia".into(),
165 key: 'w',
166 }])]
167 pub engines: Vec<SearchEngine>,
168}
169
170#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
171#[serde(deny_unknown_fields)]
172pub struct SearchEngine {
173 pub url: Box<str>,
174 pub name: Box<str>,
175 pub key: char,
176}
177
178#[derive(SmartDefault, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
179#[cfg_attr(not(feature = "ci_no_default_config_values"), serde(default))]
180#[serde(deny_unknown_fields)]
181pub struct Switch {
182 #[default(Modifier::Alt)]
183 pub modifier: Modifier,
184 #[default = "Tab"]
185 pub key: Box<str>,
186 #[default(vec![FilterBy::CurrentMonitor])]
187 pub filter_by: Vec<FilterBy>,
188 #[default = false]
189 pub switch_workspaces: bool,
190 #[default = ""]
191 pub exclude_special_workspaces: Box<str>,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
195#[serde(rename_all = "snake_case")]
196pub enum FilterBy {
197 SameClass,
198 CurrentWorkspace,
199 CurrentMonitor,
200}