From f679b3d8036a8fae2ae96c18c857c71c47c74f7c Mon Sep 17 00:00:00 2001 From: jess Date: Fri, 24 Apr 2026 11:49:33 -0700 Subject: [PATCH] linux tranparency --- Cargo.toml | 3 +++ src/bin/layers_shell.rs | 53 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8b33296..000e5b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,3 +73,6 @@ windows = { version = "0.58", features = [ "Win32_Graphics_Dwm", "Win32_UI_WindowsAndMessaging", ] } + +[target.'cfg(target_os = "linux")'.dependencies] +x11-dl = "2" diff --git a/src/bin/layers_shell.rs b/src/bin/layers_shell.rs index 4234728..2445b7b 100644 --- a/src/bin/layers_shell.rs +++ b/src/bin/layers_shell.rs @@ -328,7 +328,58 @@ fn set_window_alpha(window: &Window, alpha: f32) { } } -#[cfg(not(target_os = "windows"))] +#[cfg(target_os = "linux")] +fn set_window_alpha(window: &Window, alpha: f32) { + use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; + use std::ffi::CString; + use x11_dl::xlib; + + let Ok(win_handle) = window.window_handle() else { return; }; + let Ok(disp_handle) = window.display_handle() else { return; }; + + let (display_ptr, xid) = match (win_handle.as_raw(), disp_handle.as_raw()) { + (RawWindowHandle::Xlib(win), RawDisplayHandle::Xlib(disp)) => { + let Some(dp) = disp.display else { return; }; + (dp.as_ptr() as *mut xlib::Display, win.window as xlib::Window) + } + _ => return, + }; + + let xlib = match xlib::Xlib::open() { + Ok(x) => x, + Err(_) => return, + }; + + let atom_name = match CString::new("_NET_WM_WINDOW_OPACITY") { + Ok(s) => s, + Err(_) => return, + }; + let cardinal_name = match CString::new("CARDINAL") { + Ok(s) => s, + Err(_) => return, + }; + + let opacity = (alpha.clamp(0.0, 1.0) * u32::MAX as f32).round() as u32; + + unsafe { + let atom = (xlib.XInternAtom)(display_ptr, atom_name.as_ptr(), xlib::False); + let cardinal = (xlib.XInternAtom)(display_ptr, cardinal_name.as_ptr(), xlib::False); + if atom == 0 || cardinal == 0 { return; } + (xlib.XChangeProperty)( + display_ptr, + xid, + atom, + cardinal, + 32, + xlib::PropModeReplace, + &opacity as *const u32 as *const u8, + 1, + ); + (xlib.XFlush)(display_ptr); + } +} + +#[cfg(not(any(target_os = "windows", target_os = "linux")))] fn set_window_alpha(_window: &Window, _alpha: f32) {} #[cfg(target_os = "windows")]