@@ -46,6 +46,8 @@ pub struct Config { |
| 46 | pub screen_timeout_seconds: u32, | 46 | pub screen_timeout_seconds: u32, |
| 47 | // Compositor selection: "picom" (default), "garchomp", or "none" | 47 | // Compositor selection: "picom" (default), "garchomp", or "none" |
| 48 | pub compositor: String, | 48 | pub compositor: String, |
| | 49 | + // Picom backend: "glx" (GPU) or "xrender" (CPU, safer on NVIDIA) |
| | 50 | + pub picom_backend: String, |
| 49 | // Compositor visual settings (picom) | 51 | // Compositor visual settings (picom) |
| 50 | // These are stored for reference and potential dynamic picom config generation | 52 | // These are stored for reference and potential dynamic picom config generation |
| 51 | pub corner_radius: u32, | 53 | pub corner_radius: u32, |
@@ -82,6 +84,18 @@ impl Config { |
| 82 | /// Generate picom.conf content from current config settings. | 84 | /// Generate picom.conf content from current config settings. |
| 83 | pub fn generate_picom_config(&self) -> String { | 85 | pub fn generate_picom_config(&self) -> String { |
| 84 | let blur_section = if self.blur_enabled { | 86 | let blur_section = if self.blur_enabled { |
| | 87 | + // dual_kawase requires GLX backend; fall back to kernel blur on xrender |
| | 88 | + let (blur_method, blur_strength) = if self.picom_backend == "xrender" |
| | 89 | + && self.blur_method == "dual_kawase" |
| | 90 | + { |
| | 91 | + tracing::info!( |
| | 92 | + "Switching blur from dual_kawase to kernel (xrender backend doesn't support dual_kawase)" |
| | 93 | + ); |
| | 94 | + ("kernel".to_string(), self.blur_strength) |
| | 95 | + } else { |
| | 96 | + (self.blur_method.clone(), self.blur_strength) |
| | 97 | + }; |
| | 98 | + |
| 85 | format!( | 99 | format!( |
| 86 | r#"# Blur | 100 | r#"# Blur |
| 87 | blur-method = "{}"; | 101 | blur-method = "{}"; |
@@ -98,7 +112,7 @@ blur-background-exclude = [ |
| 98 | "window_type = 'popup_menu'", | 112 | "window_type = 'popup_menu'", |
| 99 | "_NET_WM_BYPASS_COMPOSITOR = 1" | 113 | "_NET_WM_BYPASS_COMPOSITOR = 1" |
| 100 | ];"#, | 114 | ];"#, |
| 101 | - self.blur_method, self.blur_strength | 115 | + blur_method, blur_strength |
| 102 | ) | 116 | ) |
| 103 | } else { | 117 | } else { |
| 104 | "# Blur disabled".to_string() | 118 | "# Blur disabled".to_string() |
@@ -259,7 +273,7 @@ animations = ({{ |
| 259 | # Edit ~/.config/gar/init.lua instead and reload with Mod+Shift+R | 273 | # Edit ~/.config/gar/init.lua instead and reload with Mod+Shift+R |
| 260 | | 274 | |
| 261 | # Backend Configuration | 275 | # Backend Configuration |
| 262 | -backend = "glx"; | 276 | +backend = "{}"; |
| 263 | vsync = true; | 277 | vsync = true; |
| 264 | use-ewmh-active-win = true; | 278 | use-ewmh-active-win = true; |
| 265 | | 279 | |
@@ -317,6 +331,7 @@ wintypes: |
| 317 | }}; | 331 | }}; |
| 318 | }}; | 332 | }}; |
| 319 | "#, | 333 | "#, |
| | 334 | + self.picom_backend, |
| 320 | self.corner_radius, | 335 | self.corner_radius, |
| 321 | blur_section, | 336 | blur_section, |
| 322 | shadow_section, | 337 | shadow_section, |
@@ -545,6 +560,8 @@ impl Default for Config { |
| 545 | screen_timeout_seconds: 600, | 560 | screen_timeout_seconds: 600, |
| 546 | // Compositor selection: "picom" (default), "garchomp", or "none" | 561 | // Compositor selection: "picom" (default), "garchomp", or "none" |
| 547 | compositor: "picom".to_string(), | 562 | compositor: "picom".to_string(), |
| | 563 | + // Picom backend: "glx" (GPU) or "xrender" (CPU, safer on NVIDIA) |
| | 564 | + picom_backend: "glx".to_string(), |
| 548 | // Compositor settings (picom) - matching picom.conf defaults | 565 | // Compositor settings (picom) - matching picom.conf defaults |
| 549 | corner_radius: 12, | 566 | corner_radius: 12, |
| 550 | blur_enabled: true, | 567 | blur_enabled: true, |