neofetch/
wm.rs

1#[cfg(windows)]
2pub async fn get_wm() -> crate::error::Result<String> {
3    tokio::task::spawn_blocking(|| -> crate::error::Result<String> {
4        use windows::Win32::{
5            Foundation::CloseHandle,
6            System::Diagnostics::ToolHelp::{
7                CreateToolhelp32Snapshot, PROCESSENTRY32W, Process32FirstW, Process32NextW,
8                TH32CS_SNAPPROCESS,
9            },
10        };
11
12        unsafe {
13            let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0).map_err(|e| {
14                crate::error::NeofetchError::system_call(format!(
15                    "Failed to create process snapshot: {}",
16                    e
17                ))
18            })?;
19
20            if snapshot.is_invalid() {
21                return Err(crate::error::NeofetchError::system_call(
22                    "Invalid process snapshot",
23                ));
24            }
25
26            let mut pe32 = PROCESSENTRY32W {
27                dwSize: std::mem::size_of::<PROCESSENTRY32W>() as u32,
28                ..Default::default()
29            };
30
31            if Process32FirstW(snapshot, &mut pe32).is_ok() {
32                loop {
33                    let name = String::from_utf16_lossy(
34                        &pe32.szExeFile[..pe32.szExeFile.iter().position(|&c| c == 0).unwrap_or(0)],
35                    );
36
37                    if name.starts_with("explorer.exe") {
38                        let _ = CloseHandle(snapshot);
39                        return Ok("Explorer".into());
40                    }
41
42                    if Process32NextW(snapshot, &mut pe32).is_err() {
43                        break;
44                    }
45                }
46            }
47            let _ = CloseHandle(snapshot);
48        }
49
50        Err(crate::error::NeofetchError::data_unavailable(
51            "Window manager not found",
52        ))
53    })
54    .await?
55}
56
57#[cfg(not(windows))]
58pub async fn get_wm() -> crate::error::Result<String> {
59    Err(crate::error::NeofetchError::UnsupportedPlatform)
60}
61
62#[cfg(windows)]
63pub async fn get_wm_theme() -> crate::error::Result<String> {
64    tokio::task::spawn_blocking(|| -> crate::error::Result<String> {
65        use crate::share::get_file_name;
66
67        use winreg::RegKey;
68        use winreg::enums::*;
69
70        let hkey_current_user = RegKey::predef(HKEY_CURRENT_USER);
71
72        let themes_key = hkey_current_user
73            .open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Themes")
74            .map_err(|e| {
75                crate::error::NeofetchError::system_call(format!(
76                    "Failed to open registry key: {}",
77                    e
78                ))
79            })?;
80
81        let current_theme: String = themes_key.get_value("CurrentTheme").map_err(|e| {
82            crate::error::NeofetchError::system_call(format!(
83                "Failed to read CurrentTheme value: {}",
84                e
85            ))
86        })?;
87
88        let theme_name = get_file_name(&current_theme).ok_or_else(|| {
89            crate::error::NeofetchError::parse_error("theme_path", "Failed to extract theme name")
90        })?;
91
92        Ok(theme_name)
93    })
94    .await?
95}
96
97#[cfg(not(windows))]
98pub async fn get_wm_theme() -> crate::error::Result<String> {
99    Err(crate::error::NeofetchError::UnsupportedPlatform)
100}