hyprshell_exec_lib/
plugin.rs1use anyhow::Context;
2use config_lib::Modifier;
3use hyprland::ctl::plugin;
4use hyprland_plugin::PluginConfig;
5use std::path::Path;
6use tracing::{debug, debug_span, trace};
7
8pub fn load_plugin(
9 switch: Option<Modifier>,
10 overview: Option<(Modifier, Box<str>)>,
11) -> anyhow::Result<()> {
12 let _span = debug_span!("load_plugin").entered();
13 let config = PluginConfig {
14 xkb_key_switch_mod: switch.map(|s| Box::from(mod_to_xkb_key(s))),
15 xkb_key_overview_mod: overview
16 .as_ref()
17 .map(|(r#mod, _)| Box::from(r#mod.to_string())),
18 xkb_key_overview_key: overview.map(|(_, key)| key),
19 };
20
21 if check_new_plugin_needed(&config) {
22 unload().context("unable to unload old plugin")?;
23 hyprland_plugin::generate(&config).context("unable to generate plugin")?;
24 trace!(
25 "generated plugin at {:?}",
26 hyprland_plugin::PLUGIN_OUTPUT_PATH
27 );
28 plugin::load(Path::new(hyprland_plugin::PLUGIN_OUTPUT_PATH))
29 .context("unable to load plugin")?;
30 trace!("loaded plugin");
31 } else {
32 debug!("plugin already loaded, skipping");
33 }
34
35 Ok(())
36}
37
38pub fn check_new_plugin_needed(config: &PluginConfig) -> bool {
39 let plugins = plugin::list().unwrap_or_default();
40 trace!("plugins: {plugins:?}");
41 for plugin in plugins {
42 if plugin.name == hyprland_plugin::PLUGIN_NAME {
43 let Some(desc) = plugin.description.split(" - ").last() else {
44 continue;
45 };
46 if desc == config.to_string() {
47 return false;
49 }
50 }
51 }
52 true
53}
54
55pub fn unload() -> anyhow::Result<()> {
56 let plugins = plugin::list().unwrap_or_default();
57 for plugin in plugins {
58 if plugin.name == hyprland_plugin::PLUGIN_NAME {
59 debug!("plugin loaded, unloading it");
60 plugin::unload(Path::new(hyprland_plugin::PLUGIN_OUTPUT_PATH)).with_context(|| {
61 format!(
62 "unable to unload old plugin at: {}",
63 hyprland_plugin::PLUGIN_OUTPUT_PATH
64 )
65 })?;
66 debug!("plugin unloaded");
67 }
68 }
69 Ok(())
70}
71
72#[allow(clippy::must_use_candidate)]
73pub const fn mod_to_xkb_key(r#mod: Modifier) -> &'static str {
74 match r#mod {
75 Modifier::Alt => "XKB_KEY_Alt",
76 Modifier::Ctrl => "XKB_KEY_Control",
77 Modifier::Super => "XKB_KEY_Super",
78 }
79}