gardesk/gar / b44d141

Browse files

add compositor selection and focus_follows_mouse

- Add compositor config option: picom, garchomp, or none
- Add focus_follows_mouse setting (default: true)
- Add start_compositor() and stop_compositor() methods
- Generate picom config only when using picom
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
b44d1414dcf1627ddd01793f526df91a031c76be
Parents
bb18f1e
Tree
00020d9

3 changed files

StatusFile+-
M gar/src/config/lua.rs 18 0
M gar/src/config/mod.rs 70 1
M gar/src/core/mod.rs 2 4
gar/src/config/lua.rsmodified
@@ -383,11 +383,29 @@ impl LuaConfig {
383
                         state.config.mouse_follows_focus = v;
383
                         state.config.mouse_follows_focus = v;
384
                     }
384
                     }
385
                 }
385
                 }
386
+                "focus_follows_mouse" => {
387
+                    if let Value::Boolean(v) = value {
388
+                        state.config.focus_follows_mouse = v;
389
+                    }
390
+                }
386
                 "bar_height" => {
391
                 "bar_height" => {
387
                     if let Value::Integer(v) = value {
392
                     if let Value::Integer(v) = value {
388
                         state.config.bar_height = v as u32;
393
                         state.config.bar_height = v as u32;
389
                     }
394
                     }
390
                 }
395
                 }
396
+                // Compositor selection: "picom", "garchomp", or "none"
397
+                "compositor" => {
398
+                    if let Value::String(s) = value {
399
+                        if let Ok(str_val) = s.to_str() {
400
+                            let comp = str_val.to_lowercase();
401
+                            if comp == "picom" || comp == "garchomp" || comp == "none" {
402
+                                state.config.compositor = comp;
403
+                            } else {
404
+                                tracing::warn!("Unknown compositor '{}', using 'picom'", str_val);
405
+                            }
406
+                        }
407
+                    }
408
+                }
391
                 // Compositor visual settings (picom)
409
                 // Compositor visual settings (picom)
392
                 "corner_radius" => {
410
                 "corner_radius" => {
393
                     if let Value::Integer(v) = value {
411
                     if let Value::Integer(v) = value {
gar/src/config/mod.rsmodified
@@ -31,6 +31,7 @@ pub struct Config {
31
     // Behavior settings
31
     // Behavior settings
32
     pub follow_window_on_move: bool,
32
     pub follow_window_on_move: bool,
33
     pub mouse_follows_focus: bool,
33
     pub mouse_follows_focus: bool,
34
+    pub focus_follows_mouse: bool,
34
     // Manual bar/panel reserved space (overrides struts)
35
     // Manual bar/panel reserved space (overrides struts)
35
     pub bar_height: u32,
36
     pub bar_height: u32,
36
     // garbar integration: spawn garbar automatically if gar.bar is configured
37
     // garbar integration: spawn garbar automatically if gar.bar is configured
@@ -43,6 +44,8 @@ pub struct Config {
43
     // Screen timeout/DPMS settings
44
     // Screen timeout/DPMS settings
44
     pub screen_timeout_enabled: bool,
45
     pub screen_timeout_enabled: bool,
45
     pub screen_timeout_seconds: u32,
46
     pub screen_timeout_seconds: u32,
47
+    // Compositor selection: "picom" (default), "garchomp", or "none"
48
+    pub compositor: String,
46
     // Compositor visual settings (picom)
49
     // Compositor visual settings (picom)
47
     // These are stored for reference and potential dynamic picom config generation
50
     // These are stored for reference and potential dynamic picom config generation
48
     pub corner_radius: u32,
51
     pub corner_radius: u32,
@@ -326,8 +329,15 @@ wintypes:
326
         )
329
         )
327
     }
330
     }
328
 
331
 
329
-    /// Write picom config to ~/.config/gar/picom.conf and signal picom to reload.
332
+    /// Write picom config to ~/.config/gar/picom.conf and optionally restart picom.
333
+    /// Only writes/restarts if compositor is set to "picom".
330
     pub fn write_picom_config(&self) -> std::io::Result<()> {
334
     pub fn write_picom_config(&self) -> std::io::Result<()> {
335
+        // Only generate picom config if using picom
336
+        if self.compositor != "picom" {
337
+            tracing::debug!("Skipping picom config (compositor={})", self.compositor);
338
+            return Ok(());
339
+        }
340
+
331
         let config_dir = dirs::config_dir()
341
         let config_dir = dirs::config_dir()
332
             .ok_or_else(|| std::io::Error::new(
342
             .ok_or_else(|| std::io::Error::new(
333
                 std::io::ErrorKind::NotFound,
343
                 std::io::ErrorKind::NotFound,
@@ -350,6 +360,61 @@ wintypes:
350
         Ok(())
360
         Ok(())
351
     }
361
     }
352
 
362
 
363
+    /// Start the configured compositor.
364
+    /// Called on gar startup to launch the appropriate compositor.
365
+    pub fn start_compositor(&self) {
366
+        use std::process::Command;
367
+
368
+        match self.compositor.as_str() {
369
+            "picom" => {
370
+                // Generate picom config first
371
+                if let Err(e) = self.write_picom_config() {
372
+                    tracing::warn!("Failed to write picom config: {}", e);
373
+                }
374
+                // picom will be started by write_picom_config -> reload_picom
375
+            }
376
+            "garchomp" => {
377
+                // Kill any existing compositor first
378
+                let _ = Command::new("pkill").arg("picom").status();
379
+                let _ = Command::new("pkill").arg("garchomp").status();
380
+
381
+                std::thread::sleep(std::time::Duration::from_millis(100));
382
+
383
+                // Start garchomp
384
+                match Command::new("garchomp").spawn() {
385
+                    Ok(_) => {
386
+                        tracing::info!("Started garchomp compositor");
387
+                    }
388
+                    Err(e) => {
389
+                        tracing::error!("Failed to start garchomp: {}", e);
390
+                        // Fall back to picom
391
+                        tracing::info!("Falling back to picom");
392
+                        Self::reload_picom();
393
+                    }
394
+                }
395
+            }
396
+            "none" => {
397
+                tracing::info!("Compositor disabled (compositor=none)");
398
+                // Kill any running compositor
399
+                let _ = Command::new("pkill").arg("picom").status();
400
+                let _ = Command::new("pkill").arg("garchomp").status();
401
+            }
402
+            _ => {
403
+                tracing::warn!("Unknown compositor '{}', defaulting to picom", self.compositor);
404
+                if let Err(e) = self.write_picom_config() {
405
+                    tracing::warn!("Failed to write picom config: {}", e);
406
+                }
407
+            }
408
+        }
409
+    }
410
+
411
+    /// Stop any running compositor.
412
+    pub fn stop_compositor() {
413
+        use std::process::Command;
414
+        let _ = Command::new("pkill").arg("picom").status();
415
+        let _ = Command::new("pkill").arg("garchomp").status();
416
+    }
417
+
353
     /// Apply screen timeout/DPMS settings using xset
418
     /// Apply screen timeout/DPMS settings using xset
354
     pub fn apply_screen_timeout(&self) {
419
     pub fn apply_screen_timeout(&self) {
355
         use std::process::Command;
420
         use std::process::Command;
@@ -474,6 +539,8 @@ impl Default for Config {
474
             follow_window_on_move: false,
539
             follow_window_on_move: false,
475
             // Behavior: warp mouse pointer to center of focused window
540
             // Behavior: warp mouse pointer to center of focused window
476
             mouse_follows_focus: false,
541
             mouse_follows_focus: false,
542
+            // Behavior: focus window when mouse enters it
543
+            focus_follows_mouse: true,
477
             // Manual bar height (0 = use struts from dock windows)
544
             // Manual bar height (0 = use struts from dock windows)
478
             bar_height: 0,
545
             bar_height: 0,
479
             // garbar not enabled by default (enabled when gar.bar table is set)
546
             // garbar not enabled by default (enabled when gar.bar table is set)
@@ -485,6 +552,8 @@ impl Default for Config {
485
             // Screen timeout: enabled by default with 10 minute timeout
552
             // Screen timeout: enabled by default with 10 minute timeout
486
             screen_timeout_enabled: true,
553
             screen_timeout_enabled: true,
487
             screen_timeout_seconds: 600,
554
             screen_timeout_seconds: 600,
555
+            // Compositor selection: "picom" (default), "garchomp", or "none"
556
+            compositor: "picom".to_string(),
488
             // Compositor settings (picom) - matching picom.conf defaults
557
             // Compositor settings (picom) - matching picom.conf defaults
489
             corner_radius: 12,
558
             corner_radius: 12,
490
             blur_enabled: true,
559
             blur_enabled: true,
gar/src/core/mod.rsmodified
@@ -75,10 +75,8 @@ impl WindowManager {
75
         // Get config values from Lua state
75
         // Get config values from Lua state
76
         let config = lua_state.lock().unwrap().config.clone();
76
         let config = lua_state.lock().unwrap().config.clone();
77
 
77
 
78
-        // Generate picom config from settings
78
+        // Start the configured compositor (picom, garchomp, or none)
79
-        if let Err(e) = config.write_picom_config() {
79
+        config.start_compositor();
80
-            tracing::warn!("Failed to generate picom config: {}", e);
81
-        }
82
 
80
 
83
         // Apply screen timeout/DPMS settings
81
         // Apply screen timeout/DPMS settings
84
         config.apply_screen_timeout();
82
         config.apply_screen_timeout();