// Furtherance - Track your time without being tracked // Copyright (C) 2024 Ricky Kresslein // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . use std::env; use std::time::Duration; #[cfg(target_os = "linux")] use { std::path::Path, std::sync::Arc }; pub fn get_mac_windows_x11_idle_seconds() -> u64 { 0 // unimplemented } pub fn get_idle_time() -> Result> { match env::consts::OS { "windows" => Ok(get_mac_windows_x11_idle_seconds()), "macos" => Ok(get_mac_windows_x11_idle_seconds()), #[cfg(target_os = "linux")] "linux" => { if is_wayland() { if is_gnome() { get_gnome_idle_sync() } else { get_wayland_idle_sync() } } else if is_x11() { Ok(get_mac_windows_x11_idle_seconds()) } else { Ok(0) } } _ => Ok(0), } } #[cfg(target_os = "linux")] fn is_wayland() -> bool { if let Ok(_) = env::var("XDG_SESSION_TYPE").map(|v| v == "wayland") { return true; } else if let Ok(display) = env::var("WAYLAND_DISPLAY") { if display.chars().next() == Some('/') { return Path::new(&display).exists(); } if let Ok(runtime_dir) = env::var("XDG_RUNTIME_DIR") { return Path::new( &format!("{}/{}", runtime_dir, display) ).exists(); } } false } #[cfg(target_os = "linux")] fn is_x11() -> bool { x11rb::connect(None).is_ok() } #[cfg(target_os = "linux")] fn get_wayland_idle_sync() -> Result> { use crate::helpers::wayland_idle; wayland_idle::initialize_wayland().unwrap(); Ok(wayland_idle::get_idle_time()) } #[cfg(target_os = "linux")] fn get_gnome_idle_sync() -> Result> { use dbus::blocking::stdintf::org_freedesktop_dbus::Properties; let c = dbus::blocking::Connection::new_session()?; let p = c.with_proxy( "org.gnome.Mutter.IdleMonitor", "/org/gnome/Mutter/IdleMonitor/Core", Duration::from_millis(5000), ); let (idle_time,): (u64,) = p.method_call("org.gnome.Mutter.IdleMonitor", "GetIdletime", ())?; Ok(idle_time / 1000) } #[cfg(target_os = "linux")] pub fn is_kde() -> bool { if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") { return desktop.to_uppercase().contains("KDE"); } false } #[cfg(target_os = "linux")] fn is_gnome() -> bool { if let Ok(xdg_current_desktop) = env::var("XDG_CURRENT_DESKTOP") { if xdg_current_desktop.to_lowercase().contains("gnome") { return true; } } if let Ok(gdm_session) = env::var("GDMSESSION") { if gdm_session.to_lowercase().contains("gnome") { return true; } } false }