Sign in Sign up
kretrod/lodestone Public
Branches
master
34 lines (29 loc) · 1.3 KB Raw
//! "Hide from screen capture".
//!
//! The menu is drawn into the game's own back buffer, so to a recorder its
//! pixels *are* the game's pixels — there is no way to exclude just the menu
//! from a capture of that window. What Windows does offer is
//! `SetWindowDisplayAffinity`, which takes the whole window out of capture:
//! recorders, screen shares and PrintScreen get black where it used to be.
//!
//! So this is honest about what it is: an all-or-nothing switch on the game
//! window, not a way to record clean footage with the menu open.

use std::sync::atomic::{AtomicIsize, Ordering};

use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::UI::WindowsAndMessaging::{
    SetWindowDisplayAffinity, WDA_EXCLUDEFROMCAPTURE, WDA_NONE,
};

static HWND_CELL: AtomicIsize = AtomicIsize::new(0);

pub fn set_window(hwnd: HWND) {
    HWND_CELL.store(hwnd as isize, Ordering::SeqCst);
}

/// Returns false when Windows refused — the API needs Windows 10 2004 or newer.
pub fn apply(hide: bool) -> bool {
    let hwnd = HWND_CELL.load(Ordering::SeqCst);
    if hwnd == 0 {
        return false;
    }
    let affinity = if hide { WDA_EXCLUDEFROMCAPTURE } else { WDA_NONE };
    // SAFETY: hwnd is the game's window, stored once at startup.
    unsafe { SetWindowDisplayAffinity(hwnd as HWND, affinity) != 0 }
}