oxwm

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

Autostart.

Commit
a3649bfbcaefea5f714f96f557c3694dda73fbe4
Parent
1f86f96
Author
tonybanters <tonybanters@gmail.com>
Date
2025-11-07 23:50:00

Diff

diff --git a/justfile b/justfile
index 1f35402..4c8528d 100644
--- a/justfile
+++ b/justfile
@@ -2,13 +2,13 @@ build:
     cargo build --release
 
 install: build
-    cp target/release/oxwm ~/.local/bin/oxwm
-    chmod +x ~/.local/bin/oxwm
-    @echo "✓ oxwm installed to ~/.local/bin/oxwm"
+    cp target/release/oxwm /usr/bin/oxwm
+    chmod +x /usr/bin/oxwm
+    @echo "✓ oxwm installed to /usr/bin/oxwm"
     @echo "  Run 'oxwm --init' to create your config"
 
 uninstall:
-    rm -f ~/.local/bin/oxwm
+    rm -f /usr/bin/oxwm
     @echo "✓ oxwm uninstalled"
     @echo "  Your config at ~/.config/oxwm/config.ron is preserved"
 
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 8232b86..d7c4f2c 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -256,6 +256,9 @@ struct ConfigData {
     scheme_normal: ColorSchemeData,
     scheme_occupied: ColorSchemeData,
     scheme_selected: ColorSchemeData,
+
+    #[serde(default)]
+    autostart: Vec<String>,
 }
 
 #[derive(Debug, Deserialize)]
@@ -458,6 +461,7 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
             background: data.scheme_selected.background,
             underline: data.scheme_selected.underline,
         },
+        autostart: data.autostart,
     })
 }
 
diff --git a/src/errors.rs b/src/errors.rs
index 3481d37..a48010e 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -1,9 +1,12 @@
+use std::io;
+
 #[derive(Debug)]
 pub enum WmError {
     X11(X11Error),
-    Io(std::io::Error),
+    Io(io::Error),
     Anyhow(anyhow::Error),
     Config(ConfigError),
+    Autostart(String, io::Error),
 }
 
 #[derive(Debug)]
@@ -38,6 +41,7 @@ impl std::fmt::Display for WmError {
             Self::Io(error) => write!(f, "{}", error),
             Self::Anyhow(error) => write!(f, "{}", error),
             Self::Config(error) => write!(f, "{}", error),
+            Self::Autostart(command, error) => write!(f, "Failed to spawn autostart command '{}': {}", command, error),
         }
     }
 }
@@ -101,8 +105,8 @@ impl<T: Into<X11Error>> From<T> for WmError {
     }
 }
 
-impl From<std::io::Error> for WmError {
-    fn from(value: std::io::Error) -> Self {
+impl From<io::Error> for WmError {
+    fn from(value: io::Error) -> Self {
         Self::Io(value)
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 8f55ebf..6b5ef02 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -55,6 +55,9 @@ pub struct Config {
     pub scheme_normal: ColorScheme,
     pub scheme_occupied: ColorScheme,
     pub scheme_selected: ColorScheme,
+
+    // Autostart commands
+    pub autostart: Vec<String>,
 }
 
 #[derive(Clone, Copy)]
@@ -298,6 +301,7 @@ impl Default for Config {
                 background: 0x1a1b26,
                 underline: 0xad8ee6,
             },
+            autostart: vec![],
         }
     }
 }
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 760908b..741d547 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -7,6 +7,7 @@ use crate::layout::tiling::TilingLayout;
 use crate::layout::{Layout, LayoutBox, LayoutType, layout_from_str, next_layout};
 use crate::monitor::{Monitor, detect_monitors};
 use std::collections::HashSet;
+use std::process::Command;
 use x11rb::cursor::Handle as CursorHandle;
 
 use x11rb::connection::Connection;
@@ -180,6 +181,7 @@ impl WindowManager {
 
         window_manager.scan_existing_windows()?;
         window_manager.update_bar()?;
+        window_manager.run_autostart_commands()?;
 
         Ok(window_manager)
     }
@@ -1886,4 +1888,16 @@ impl WindowManager {
         }
         Ok(())
     }
+
+    fn run_autostart_commands(&self) -> Result<(), WmError> {
+        for command in &self.config.autostart {
+            Command::new("sh")
+                .arg("-c")
+                .arg(command)
+                .spawn()
+                .map_err(|e| WmError::Autostart(command.clone(), e))?;
+            eprintln!("[autostart] Spawned: {}", command);
+        }
+        Ok(())
+    }
 }
diff --git a/templates/config.ron b/templates/config.ron
index d836e33..3af89fc 100644
--- a/templates/config.ron
+++ b/templates/config.ron
@@ -113,5 +113,15 @@
     scheme_normal: (foreground: $color_fg, background: $color_bg, underline: 0x444444),
     scheme_occupied: (foreground: $color_cyan, background: $color_bg, underline: $color_cyan),
     scheme_selected: (foreground: $color_cyan, background: $color_bg, underline: $color_purple),
+
+    // Autostart commands - these are executed when the window manager starts
+    // Commands are run in a shell, so you can use shell syntax (pipes, &&, etc.)
+    // Example: ["picom", "nitrogen --restore", "~/.config/polybar/launch.sh"]
+    autostart: [
+        // Uncomment and add your autostart commands here:
+        // "picom -b",
+        // "nitrogen --restore &",
+        // "dunst &",
+    ],
 )