Switch default overlay to frosted glass egui, fix open/close latency, add instant toggle

This commit is contained in:
katR 2026-09-05 16:24:24 +05:30
parent f8c9212420
commit eceb67dbaf
5 changed files with 122 additions and 14 deletions

View file

@ -36,6 +36,21 @@ fn ensure_wayland_env() {
env::set_var("DBUS_SESSION_BUS_ADDRESS", format!("unix:path={}", bus_path));
}
}
if env::var("HYPRLAND_INSTANCE_SIGNATURE").is_err() {
let hypr_dir = std::path::Path::new(&runtime_dir).join("hypr");
if let Ok(entries) = std::fs::read_dir(&hypr_dir) {
for entry in entries.flatten() {
if entry.path().is_dir() {
let sig = entry.file_name().to_string_lossy().to_string();
if !sig.is_empty() {
env::set_var("HYPRLAND_INSTANCE_SIGNATURE", &sig);
println!("Auto-detected Hyprland instance signature: {}", sig);
break;
}
}
}
}
}
if env::var("XDG_CURRENT_DESKTOP").is_err() {
env::set_var("XDG_CURRENT_DESKTOP", "Hyprland");
}

View file

@ -29,6 +29,20 @@ fn ensure_wayland_env() {
env::set_var("DBUS_SESSION_BUS_ADDRESS", format!("unix:path={}", bus_path));
}
}
if env::var("HYPRLAND_INSTANCE_SIGNATURE").is_err() {
let hypr_dir = std::path::Path::new(&runtime_dir).join("hypr");
if let Ok(entries) = std::fs::read_dir(&hypr_dir) {
for entry in entries.flatten() {
if entry.path().is_dir() {
let sig = entry.file_name().to_string_lossy().to_string();
if !sig.is_empty() {
env::set_var("HYPRLAND_INSTANCE_SIGNATURE", &sig);
break;
}
}
}
}
}
if env::var("XDG_CURRENT_DESKTOP").is_err() && env::var("WAYLAND_DISPLAY").is_ok() {
env::set_var("XDG_CURRENT_DESKTOP", "Hyprland");
}
@ -114,6 +128,53 @@ fn get_ui_cmd() -> std::process::Command {
cmd
}
fn check_and_toggle_overlay() -> bool {
let pid_path = scythe::ipc::get_overlay_pid_path();
if pid_path.exists() {
if let Ok(content) = std::fs::read_to_string(&pid_path) {
if let Ok(pid) = content.trim().parse::<i32>() {
#[cfg(unix)]
{
let exists = unsafe { libc::kill(pid, 0) == 0 };
if exists && pid != std::process::id() as i32 {
let proc_cmd = format!("/proc/{}/cmdline", pid);
let is_scythe = std::fs::read_to_string(&proc_cmd)
.map(|cmd| cmd.contains("scythe") || cmd.contains("vrec"))
.unwrap_or(false);
if is_scythe {
// Overlay already open: toggle it closed instantly!
unsafe { libc::kill(pid, libc::SIGTERM) };
let _ = std::fs::remove_file(&pid_path);
return true;
}
}
}
}
}
let _ = std::fs::remove_file(&pid_path);
}
let my_pid = std::process::id().to_string();
let _ = std::fs::write(&pid_path, my_pid);
false
}
fn ensure_daemon_running_async() {
#[cfg(unix)]
{
use std::os::unix::net::UnixStream;
if UnixStream::connect(scythe::ipc::get_socket_path()).is_ok()
|| UnixStream::connect(scythe::ipc::get_legacy_socket_path()).is_ok() {
return;
}
}
let _ = get_daemon_cmd()
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn();
}
fn ensure_daemon_running() {
if query_status().is_err() {
let _ = get_daemon_cmd()
@ -122,7 +183,7 @@ fn ensure_daemon_running() {
.stderr(std::process::Stdio::null())
.spawn();
for _ in 0..15 {
std::thread::sleep(std::time::Duration::from_millis(100));
std::thread::sleep(std::time::Duration::from_millis(80));
if query_status().is_ok() {
break;
}
@ -219,17 +280,29 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
return send_with_notification(Command::SaveReplay, "Replay saved");
}
"--menu" => {
ensure_daemon_running();
ensure_daemon_running_async();
ensure_hotkeys_running();
#[cfg(not(target_os = "linux"))]
if check_and_toggle_overlay() {
return Ok(());
}
scythe::overlay_egui::run_egui_overlay();
#[cfg(target_os = "linux")]
scythe::overlay::show_menu_overlay();
return Ok(());
}
"--egui" => {
ensure_daemon_running_async();
ensure_hotkeys_running();
if check_and_toggle_overlay() {
return Ok(());
}
scythe::overlay_egui::run_egui_overlay();
return Ok(());
}
"--gtk" => {
ensure_daemon_running();
ensure_hotkeys_running();
#[cfg(target_os = "linux")]
scythe::overlay::show_menu_overlay();
#[cfg(not(target_os = "linux"))]
scythe::overlay_egui::run_egui_overlay();
return Ok(());
}
@ -278,6 +351,7 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("Usage:");
println!(" scythe-ui Open the interactive overlay UI menu (default)");
println!(" scythe-ui --menu Open the interactive overlay UI menu");
println!(" scythe-ui --gtk Open legacy GTK layer-shell overlay (Linux)");
println!(" scythe-ui --hotkeys Run global hotkey manager in background");
println!(" scythe-ui --status Query current daemon status");
println!(" scythe-ui --save Save instant replay and show notification");
@ -292,12 +366,12 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
_ => {}
}
} else {
ensure_daemon_running();
ensure_daemon_running_async();
ensure_hotkeys_running();
#[cfg(not(target_os = "linux"))]
if check_and_toggle_overlay() {
return Ok(());
}
scythe::overlay_egui::run_egui_overlay();
#[cfg(target_os = "linux")]
scythe::overlay::show_menu_overlay();
return Ok(());
}

View file

@ -178,3 +178,20 @@ pub fn query_status() -> Result<DaemonStatus, Box<dyn std::error::Error + Send +
Err(last_err.unwrap_or_else(|| "Failed to query status from scythe-daemon".into()))
}
pub fn get_overlay_pid_path() -> std::path::PathBuf {
#[cfg(unix)]
{
let runtime_dir = std::env::var("XDG_RUNTIME_DIR")
.unwrap_or_else(|_| format!("/run/user/{}", unsafe { libc::getuid() }));
std::path::PathBuf::from(runtime_dir).join("scythe-overlay.pid")
}
#[cfg(not(unix))]
{
std::env::temp_dir().join("scythe-overlay.pid")
}
}
pub fn clean_overlay_pid() {
let _ = std::fs::remove_file(get_overlay_pid_path());
}

View file

@ -1007,14 +1007,14 @@ pub fn show_menu_overlay() {
}
/* Frosted Settings Panel */
.settings-panel {
background-color: rgba(15, 22, 32, 0.90);
background-color: #0f1620;
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: 18px;
padding: 20px 26px;
box-shadow: 0px 24px 64px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.settings-section-card {
background-color: rgba(24, 32, 46, 0.55);
background-color: #18202e;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 14px 18px;
@ -1140,7 +1140,7 @@ pub fn show_menu_overlay() {
window.connect_key_press_event(move |_, key| {
if key.keyval() == gdk::keys::constants::Escape {
w_esc.close();
gtk::glib::Propagation::Stop
std::process::exit(0);
} else {
gtk::glib::Propagation::Proceed
}

View file

@ -1495,10 +1495,10 @@ impl eframe::App for ScytheOverlayApp {
self.replay_dropdown_open = false;
self.record_dropdown_open = false;
self.update_window_size(ctx);
} else if self.current_view != ShadowPlayView::MainHud {
self.switch_view(ShadowPlayView::MainHud, ctx);
} else {
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
crate::ipc::clean_overlay_pid();
std::process::exit(0);
}
}
@ -1538,4 +1538,6 @@ pub fn run_egui_overlay() {
options,
Box::new(|_cc| Ok(Box::new(ScytheOverlayApp::new()))),
);
crate::ipc::clean_overlay_pid();
}