Skip to content

Commit 1c965bf

Browse files
authored
Merge pull request #13 from cyrinux/feat/add-exclude
feat: Update config, support exclude
2 parents c052733 + 16eb751 commit 1c965bf

File tree

3 files changed

+71
-21
lines changed

3 files changed

+71
-21
lines changed

Cargo.lock

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "hyprland-autoname-workspaces"
33
authors = ["Cyril Levis", "Maxim Baz"]
4-
version = "0.2.15"
4+
version = "0.3.0"
55
edition = "2021"
66
categories = ["gui"]
77
keywords = ["linux", "desktop-application", "hyprland","waybar","wayland"]
@@ -19,3 +19,4 @@ toml = { version = "0.5.10", features = ["indexmap", "preserve_order"] }
1919
xdg = "2.4.1"
2020
inotify = "0.10.0"
2121
rustc-hash = "1.1.0"
22+
serde = "1.0.152"

src/main.rs

+67-19
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use hyprland::prelude::*;
66
use hyprland::shared::WorkspaceType;
77
use inotify::{Inotify, WatchMask};
88
use rustc_hash::{FxHashMap, FxHashSet};
9+
use serde::Deserialize;
910
use signal_hook::consts::{SIGINT, SIGTERM};
1011
use signal_hook::iterator::Signals;
1112
use std::error::Error;
@@ -24,36 +25,71 @@ struct Args {
2425
}
2526

2627
struct Config {
27-
icons: FxHashMap<String, String>,
28+
config: ConfigFile,
2829
cfg_path: PathBuf,
2930
}
3031

32+
#[derive(Deserialize)]
33+
struct ConfigFile {
34+
icons: FxHashMap<String, String>,
35+
#[serde(default)]
36+
exclude: FxHashMap<String, String>,
37+
}
38+
3139
impl Config {
3240
fn new() -> Result<Config, Box<dyn Error>> {
3341
let mut config_file: File;
3442
let xdg_dirs = xdg::BaseDirectories::with_prefix("hyprland-autoname-workspaces")?;
3543
let cfg_path = xdg_dirs.place_config_file("config.toml")?;
3644
if !cfg_path.exists() {
3745
config_file = File::create(&cfg_path)?;
38-
let default_icons = r#"# Add your icons mapping
46+
let default_config = r#"[icons]
47+
# Add your icons mapping
3948
# use double quote the key and the value
4049
# take class name from 'hyprctl clients'
4150
"DEFAULT" = ""
4251
"kitty" = "term"
4352
"firefox" = "browser"
44-
"#;
45-
write!(&mut config_file, "{default_icons}")?;
53+
54+
# Add your applications that need to be exclude
55+
# You can put what you want as value, "" make the job.
56+
[exclude]
57+
fcitx5 = ""
58+
fcitx = ""
59+
"#;
60+
write!(&mut config_file, "{default_config}")?;
4661
println!("Default config created in {cfg_path:?}");
4762
}
48-
let config = fs::read_to_string(cfg_path.clone())?;
49-
let icons: FxHashMap<String, String> =
50-
toml::from_str(&config).map_err(|e| format!("Unable to parse: {e:?}"))?;
51-
let icons_uppercase = icons
63+
let mut config_string = fs::read_to_string(cfg_path.clone())?;
64+
65+
// config file migration if needed
66+
// can be remove "later" ...
67+
if !config_string.contains("[icons]") {
68+
config_string = "[icons]\n".to_owned() + &config_string;
69+
fs::write(&cfg_path, &config_string)
70+
.map_err(|e| format!("Cannot migrate config file: {e:?}"))?;
71+
println!("Config file migrated from v1 to v2");
72+
}
73+
74+
let config: ConfigFile =
75+
toml::from_str(&config_string).map_err(|e| format!("Unable to parse: {e:?}"))?;
76+
77+
let icons = config
78+
.icons
79+
.iter()
80+
.map(|(k, v)| (k.to_uppercase(), v.clone()))
81+
.collect::<FxHashMap<_, _>>();
82+
83+
let exclude = config
84+
.exclude
5285
.iter()
5386
.map(|(k, v)| (k.to_uppercase(), v.clone()))
5487
.collect::<FxHashMap<_, _>>();
55-
let icons = icons.into_iter().chain(icons_uppercase).collect();
56-
Ok(Config { cfg_path, icons })
88+
89+
Ok(Config {
90+
config: ConfigFile { icons, exclude },
91+
cfg_path,
92+
})
5793
}
5894
}
5995

@@ -118,24 +154,35 @@ impl Renamer {
118154

119155
for client in clients {
120156
let class = client.class;
157+
121158
if class.is_empty() {
122159
continue;
123160
}
161+
162+
if self
163+
.cfg
164+
.lock()?
165+
.config
166+
.exclude
167+
.contains_key(&class.to_uppercase())
168+
{
169+
continue;
170+
}
171+
124172
let workspace_id = client.workspace.id;
125173
let icon = self.class_to_icon(&class);
126-
let fullscreen = client.fullscreen;
127174
let is_dup = !deduper.insert(format!("{workspace_id}-{icon}"));
128175
let should_dedup = self.args.dedup && is_dup;
129176

130-
self.workspaces.lock()?.insert(client.workspace.id);
177+
self.workspaces.lock()?.insert(workspace_id);
131178

132179
let workspace = workspaces
133180
.entry(workspace_id)
134181
.or_insert_with(|| "".to_string());
135182

136-
if fullscreen && should_dedup {
183+
if client.fullscreen && should_dedup {
137184
*workspace = workspace.replace(&icon, &format!("[{icon}]"));
138-
} else if fullscreen && !should_dedup {
185+
} else if client.fullscreen && !should_dedup {
139186
*workspace = format!("{workspace} [{icon}]");
140187
} else if !should_dedup {
141188
*workspace = format!("{workspace} {icon}");
@@ -197,7 +244,7 @@ impl Renamer {
197244
// Clojure to force quick release of lock
198245
{
199246
match Config::new() {
200-
Ok(config) => self.cfg.lock()?.icons = config.icons,
247+
Ok(config) => self.cfg.lock()?.config = config.config,
201248
Err(err) => println!("Unable to reload config: {err:?}"),
202249
}
203250
}
@@ -210,11 +257,12 @@ impl Renamer {
210257

211258
fn class_to_icon(&self, class: &str) -> String {
212259
let default_value = String::from("no default icon");
213-
let cfg = self.cfg.lock().expect("Unable to obtain lock for config");
214-
cfg.icons
260+
let cfg = &self.cfg.lock().expect("Unable to obtain lock for config");
261+
cfg.config
262+
.icons
215263
.get(class)
216-
.or_else(|| cfg.icons.get(class.to_uppercase().as_str()))
217-
.unwrap_or_else(|| cfg.icons.get("DEFAULT").unwrap_or(&default_value))
264+
.or_else(|| cfg.config.icons.get(class.to_uppercase().as_str()))
265+
.unwrap_or_else(|| cfg.config.icons.get("DEFAULT").unwrap_or(&default_value))
218266
.into()
219267
}
220268

0 commit comments

Comments
 (0)