oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git

Fixed box::leak issue.

Commit
f188c7767dfd3ae1c3079f5073cbe01ff6c865c6
Parent
ed311f0
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-10-15 07:19:25

Diff

diff --git a/src/bar/blocks/mod.rs b/src/bar/blocks/mod.rs
index ac73099..0c97c22 100644
--- a/src/bar/blocks/mod.rs
+++ b/src/bar/blocks/mod.rs
@@ -19,7 +19,7 @@ pub trait Block {
 
 #[derive(Clone)]
 pub struct BlockConfig {
-    pub format: &'static str,
+    pub format: String,
     pub command: BlockCommand,
     pub interval_secs: u64,
     pub color: u32,
@@ -28,28 +28,28 @@ pub struct BlockConfig {
 
 #[derive(Clone)]
 pub enum BlockCommand {
-    Shell(&'static str),
-    DateTime(&'static str),
+    Shell(String),
+    DateTime(String),
     Battery {
-        format_charging: &'static str,
-        format_discharging: &'static str,
-        format_full: &'static str,
+        format_charging: String,
+        format_discharging: String,
+        format_full: String,
     },
     Ram,
-    Static(&'static str),
+    Static(String),
 }
 
 impl BlockConfig {
     pub fn to_block(&self) -> Box<dyn Block> {
-        match self.command {
+        match &self.command {
             BlockCommand::Shell(cmd) => Box::new(ShellBlock::new(
-                self.format,
+                &self.format,
                 cmd,
                 self.interval_secs,
                 self.color,
             )),
             BlockCommand::DateTime(fmt) => Box::new(DateTime::new(
-                self.format,
+                &self.format,
                 fmt,
                 self.interval_secs,
                 self.color,
@@ -65,7 +65,7 @@ impl BlockConfig {
                 self.interval_secs,
                 self.color,
             )),
-            BlockCommand::Ram => Box::new(Ram::new(self.format, self.interval_secs, self.color)),
+            BlockCommand::Ram => Box::new(Ram::new(&self.format, self.interval_secs, self.color)),
             BlockCommand::Static(text) => Box::new(StaticBlock::new(
                 &format!("{}{}", self.format, text),
                 self.color,
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 4b4f766..612fd7e 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -98,19 +98,15 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
             .map(|s| parse_modkey(s))
             .collect::<Result<Vec<_>, _>>()?;
 
-        let modifiers_static: &'static [KeyButMask] = Box::leak(modifiers.into_boxed_slice());
-
         let key = string_to_keycode(&kb_data.key)?;
         let action = parse_key_action(&kb_data.action)?;
         let arg = arg_data_to_arg(kb_data.arg)?;
 
-        keybindings.push(Key::new(modifiers_static, key, action, arg));
+        keybindings.push(Key::new(modifiers, key, action, arg));
     }
 
     let mut status_blocks = Vec::new();
     for block_data in data.status_blocks {
-        let format_static: &'static str = Box::leak(block_data.format.into_boxed_str());
-
         let command = match block_data.command.as_str() {
             "DateTime" => {
                 let fmt = block_data
@@ -119,8 +115,7 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
                         command: "DateTime".to_string(),
                         field: "command_arg".to_string(),
                     })?;
-                let fmt_static: &'static str = Box::leak(fmt.into_boxed_str());
-                BlockCommand::DateTime(fmt_static)
+                BlockCommand::DateTime(fmt)
             }
             "Shell" => {
                 let cmd = block_data
@@ -129,14 +124,12 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
                         command: "Shell".to_string(),
                         field: "command_arg".to_string(),
                     })?;
-                let cmd_static: &'static str = Box::leak(cmd.into_boxed_str());
-                BlockCommand::Shell(cmd_static)
+                BlockCommand::Shell(cmd)
             }
             "Ram" => BlockCommand::Ram,
             "Static" => {
                 let text = block_data.command_arg.unwrap_or_default();
-                let text_static: &'static str = Box::leak(text.into_boxed_str());
-                BlockCommand::Static(text_static)
+                BlockCommand::Static(text)
             }
             "Battery" => {
                 let formats =
@@ -147,16 +140,16 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
                             field: "battery_formats".to_string(),
                         })?;
                 BlockCommand::Battery {
-                    format_charging: Box::leak(formats.charging.into_boxed_str()),
-                    format_discharging: Box::leak(formats.discharging.into_boxed_str()),
-                    format_full: Box::leak(formats.full.into_boxed_str()),
+                    format_charging: formats.charging,
+                    format_discharging: formats.discharging,
+                    format_full: formats.full,
                 }
             }
             _ => return Err(ConfigError::UnknownBlockCommand(block_data.command)),
         };
 
         status_blocks.push(BlockConfig {
-            format: format_static,
+            format: block_data.format,
             command,
             interval_secs: block_data.interval_secs,
             color: block_data.color,
@@ -312,21 +305,11 @@ fn parse_key_action(s: &str) -> Result<crate::keyboard::KeyAction, ConfigError>
     }
 }
 
-fn arg_data_to_arg(data: ArgData) -> Result<crate::keyboard::Arg, ConfigError> {
+fn arg_data_to_arg(data: ArgData) -> Result<Arg, ConfigError> {
     match data {
         ArgData::None => Ok(Arg::None),
-        ArgData::String(s) => {
-            let static_str: &'static str = Box::leak(s.into_boxed_str());
-            Ok(Arg::Str(static_str))
-        }
+        ArgData::String(s) => Ok(Arg::Str(s)),
         ArgData::Int(n) => Ok(Arg::Int(n)),
-        ArgData::Array(arr) => {
-            let static_strs: Vec<&'static str> = arr
-                .into_iter()
-                .map(|s| Box::leak(s.into_boxed_str()) as &'static str)
-                .collect();
-            let static_slice: &'static [&'static str] = Box::leak(static_strs.into_boxed_slice());
-            Ok(Arg::Array(static_slice))
-        }
+        ArgData::Array(arr) => Ok(Arg::Array(arr)),
     }
 }
diff --git a/src/keyboard/handlers.rs b/src/keyboard/handlers.rs
index d0ebe67..34c9cd3 100644
--- a/src/keyboard/handlers.rs
+++ b/src/keyboard/handlers.rs
@@ -26,8 +26,8 @@ pub enum KeyAction {
 pub enum Arg {
     None,
     Int(i32),
-    Str(&'static str),
-    Array(&'static [&'static str]),
+    Str(String),
+    Array(Vec<String>),
 }
 
 impl Arg {
@@ -38,19 +38,14 @@ impl Arg {
 
 #[derive(Clone)]
 pub struct Key {
-    pub(crate) modifiers: &'static [KeyButMask],
+    pub(crate) modifiers: Vec<KeyButMask>,
     pub(crate) key: Keycode,
     pub(crate) func: KeyAction,
     pub(crate) arg: Arg,
 }
 
 impl Key {
-    pub const fn new(
-        modifiers: &'static [KeyButMask],
-        key: Keycode,
-        func: KeyAction,
-        arg: Arg,
-    ) -> Self {
+    pub fn new(modifiers: Vec<KeyButMask>, key: Keycode, func: KeyAction, arg: Arg) -> Self {
         Self {
             modifiers,
             key,
@@ -72,7 +67,7 @@ pub fn setup_keybinds(
     keybindings: &[Key],
 ) -> Result<(), X11Error> {
     for keybinding in keybindings {
-        let modifier_mask = modifiers_to_mask(keybinding.modifiers);
+        let modifier_mask = modifiers_to_mask(&keybinding.modifiers);
 
         connection.grab_key(
             false,
@@ -88,7 +83,7 @@ pub fn setup_keybinds(
 
 pub fn handle_key_press(event: KeyPressEvent, keybindings: &[Key]) -> (KeyAction, Arg) {
     for keybinding in keybindings {
-        let modifier_mask = modifiers_to_mask(keybinding.modifiers);
+        let modifier_mask = modifiers_to_mask(&keybinding.modifiers);
 
         if event.detail == keybinding.key && event.state == modifier_mask.into() {
             return (keybinding.func, keybinding.arg.clone());
@@ -102,7 +97,7 @@ pub fn handle_spawn_action(action: KeyAction, arg: &Arg) -> io::Result<()> {
     use io::ErrorKind;
     if let KeyAction::Spawn = action {
         match arg {
-            Arg::Str(command) => match Command::new(command).spawn() {
+            Arg::Str(command) => match Command::new(command.as_str()).spawn() {
                 Err(err) if err.kind() == ErrorKind::NotFound => {
                     eprintln!(
                         "KeyAction::Spawn failed: could not spawn \"{}\", command not found",
@@ -117,7 +112,8 @@ pub fn handle_spawn_action(action: KeyAction, arg: &Arg) -> io::Result<()> {
                     return Ok(());
                 };
 
-                match Command::new(cmd).args(args).spawn() {
+                let args_str: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
+                match Command::new(cmd.as_str()).args(&args_str).spawn() {
                     Err(err) if err.kind() == ErrorKind::NotFound => {
                         eprintln!(
                             "KeyAction::Spawn failed: could not spawn \"{}\", command not found",
diff --git a/src/lib.rs b/src/lib.rs
index 77a87fe..5038201 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -82,97 +82,97 @@ impl Default for Config {
                 .collect(),
             keybindings: vec![
                 Key::new(
-                    &[MODKEY],
+                    vec![MODKEY],
                     keycodes::RETURN,
                     KeyAction::Spawn,
-                    Arg::Str(TERMINAL),
+                    Arg::Str(TERMINAL.to_string()),
                 ),
                 Key::new(
-                    &[MODKEY],
+                    vec![MODKEY],
                     keycodes::D,
                     KeyAction::Spawn,
-                    Arg::Array(&["sh", "-c", "dmenu_run -l 10"]),
+                    Arg::Array(vec!["sh".to_string(), "-c".to_string(), "dmenu_run -l 10".to_string()]),
                 ),
-                Key::new(&[MODKEY], keycodes::Q, KeyAction::KillClient, Arg::None),
+                Key::new(vec![MODKEY], keycodes::Q, KeyAction::KillClient, Arg::None),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::F,
                     KeyAction::ToggleFullScreen,
                     Arg::None,
                 ),
-                Key::new(&[MODKEY], keycodes::A, KeyAction::ToggleGaps, Arg::None),
-                Key::new(&[MODKEY, SHIFT], keycodes::Q, KeyAction::Quit, Arg::None),
-                Key::new(&[MODKEY, SHIFT], keycodes::R, KeyAction::Restart, Arg::None),
-                Key::new(&[MODKEY], keycodes::F, KeyAction::ToggleFloating, Arg::None),
-                Key::new(&[MODKEY], keycodes::J, KeyAction::FocusStack, Arg::Int(-1)),
-                Key::new(&[MODKEY], keycodes::K, KeyAction::FocusStack, Arg::Int(1)),
-                Key::new(&[MODKEY], keycodes::KEY_1, KeyAction::ViewTag, Arg::Int(0)),
-                Key::new(&[MODKEY], keycodes::KEY_2, KeyAction::ViewTag, Arg::Int(1)),
-                Key::new(&[MODKEY], keycodes::KEY_3, KeyAction::ViewTag, Arg::Int(2)),
-                Key::new(&[MODKEY], keycodes::KEY_4, KeyAction::ViewTag, Arg::Int(3)),
-                Key::new(&[MODKEY], keycodes::KEY_5, KeyAction::ViewTag, Arg::Int(4)),
-                Key::new(&[MODKEY], keycodes::KEY_6, KeyAction::ViewTag, Arg::Int(5)),
-                Key::new(&[MODKEY], keycodes::KEY_7, KeyAction::ViewTag, Arg::Int(6)),
-                Key::new(&[MODKEY], keycodes::KEY_8, KeyAction::ViewTag, Arg::Int(7)),
-                Key::new(&[MODKEY], keycodes::KEY_9, KeyAction::ViewTag, Arg::Int(8)),
+                Key::new(vec![MODKEY], keycodes::A, KeyAction::ToggleGaps, Arg::None),
+                Key::new(vec![MODKEY, SHIFT], keycodes::Q, KeyAction::Quit, Arg::None),
+                Key::new(vec![MODKEY, SHIFT], keycodes::R, KeyAction::Restart, Arg::None),
+                Key::new(vec![MODKEY], keycodes::F, KeyAction::ToggleFloating, Arg::None),
+                Key::new(vec![MODKEY], keycodes::J, KeyAction::FocusStack, Arg::Int(-1)),
+                Key::new(vec![MODKEY], keycodes::K, KeyAction::FocusStack, Arg::Int(1)),
+                Key::new(vec![MODKEY], keycodes::KEY_1, KeyAction::ViewTag, Arg::Int(0)),
+                Key::new(vec![MODKEY], keycodes::KEY_2, KeyAction::ViewTag, Arg::Int(1)),
+                Key::new(vec![MODKEY], keycodes::KEY_3, KeyAction::ViewTag, Arg::Int(2)),
+                Key::new(vec![MODKEY], keycodes::KEY_4, KeyAction::ViewTag, Arg::Int(3)),
+                Key::new(vec![MODKEY], keycodes::KEY_5, KeyAction::ViewTag, Arg::Int(4)),
+                Key::new(vec![MODKEY], keycodes::KEY_6, KeyAction::ViewTag, Arg::Int(5)),
+                Key::new(vec![MODKEY], keycodes::KEY_7, KeyAction::ViewTag, Arg::Int(6)),
+                Key::new(vec![MODKEY], keycodes::KEY_8, KeyAction::ViewTag, Arg::Int(7)),
+                Key::new(vec![MODKEY], keycodes::KEY_9, KeyAction::ViewTag, Arg::Int(8)),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_1,
                     KeyAction::MoveToTag,
                     Arg::Int(0),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_2,
                     KeyAction::MoveToTag,
                     Arg::Int(1),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_3,
                     KeyAction::MoveToTag,
                     Arg::Int(2),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_4,
                     KeyAction::MoveToTag,
                     Arg::Int(3),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_5,
                     KeyAction::MoveToTag,
                     Arg::Int(4),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_6,
                     KeyAction::MoveToTag,
                     Arg::Int(5),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_7,
                     KeyAction::MoveToTag,
                     Arg::Int(6),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_8,
                     KeyAction::MoveToTag,
                     Arg::Int(7),
                 ),
                 Key::new(
-                    &[MODKEY, SHIFT],
+                    vec![MODKEY, SHIFT],
                     keycodes::KEY_9,
                     KeyAction::MoveToTag,
                     Arg::Int(8),
                 ),
             ],
             status_blocks: vec![crate::bar::BlockConfig {
-                format: "{}",
-                command: crate::bar::BlockCommand::DateTime("%a, %b %d - %-I:%M %P"),
+                format: "{}".to_string(),
+                command: crate::bar::BlockCommand::DateTime("%a, %b %d - %-I:%M %P".to_string()),
                 interval_secs: 1,
                 color: 0x0db9d7,
                 underline: true,