diff --git a/crates/pf-clipboard/Cargo.toml b/crates/pf-clipboard/Cargo.toml index e9331753..831b41d8 100644 --- a/crates/pf-clipboard/Cargo.toml +++ b/crates/pf-clipboard/Cargo.toml @@ -42,6 +42,10 @@ wayland-protocols = { version = "0.32", features = ["client", "staging"] } # delayed rendering (`WM_RENDERFORMAT`) for text / CF_HTML / RTF / PNG. windows = { version = "0.62", features = [ "Win32_Foundation", + # WNDCLASSW/RegisterClassW reference HBRUSH/HICON/HCURSOR, so windows-rs only generates + # them with the Gdi feature on. The host build got it via workspace feature-unification; + # a standalone `cargo check -p pf-clipboard` didn't (E0432) — declare it honestly. + "Win32_Graphics_Gdi", "Win32_System_DataExchange", "Win32_System_LibraryLoader", "Win32_System_Memory", diff --git a/crates/pf-clipboard/src/host/windows.rs b/crates/pf-clipboard/src/host/windows.rs index e24b28ac..2af936a2 100644 --- a/crates/pf-clipboard/src/host/windows.rs +++ b/crates/pf-clipboard/src/host/windows.rs @@ -245,8 +245,8 @@ impl WinClip { .format_for_wire(wire) .context("unsupported wire MIME")?; // Image fetch with no native "PNG" on the clipboard (most apps): read CF_DIB and convert. - // SAFETY: IsClipboardFormatAvailable has no preconditions and needs no open clipboard. let mut via_dib = false; + // SAFETY: IsClipboardFormatAvailable has no preconditions and needs no open clipboard. if wire == WIRE_PNG && unsafe { IsClipboardFormatAvailable(fmt) }.is_err() { fmt = CF_DIB.0 as u32; via_dib = true; diff --git a/crates/pf-frame/src/dxgi.rs b/crates/pf-frame/src/dxgi.rs index f2b48733..2ebb96da 100644 --- a/crates/pf-frame/src/dxgi.rs +++ b/crates/pf-frame/src/dxgi.rs @@ -346,9 +346,16 @@ fn auto_priority_gate(device: &ID3D11Device) { // The adapter identity this device runs on. let luid = match device .cast::() - .and_then(|d| unsafe { d.GetAdapter() }) - .and_then(|a| unsafe { a.GetDesc() }) - { + .and_then(|d| { + // SAFETY: `d` is a live IDXGIDevice from the cast; GetAdapter returns an owned + // COM wrapper that drops with its windows-rs handle. + unsafe { d.GetAdapter() } + }) + .and_then(|a| { + // SAFETY: `a` is the live adapter from GetAdapter; GetDesc fills a plain + // out-struct by value. + unsafe { a.GetDesc() } + }) { Ok(desc) => desc.AdapterLuid, Err(e) => { tracing::warn!(error = %e, "REALTIME auto-gate: no adapter LUID — staying HIGH"); @@ -418,16 +425,17 @@ fn spawn_vram_gate(luid: LUID) { let mut realtime = false; // we start at the HIGH floor let mut clean_ticks = 0u32; loop { + let mut mi = DXGI_QUERY_VIDEO_MEMORY_INFO::default(); // SAFETY: `adapter` is a live IDXGIAdapter3 owned by this thread; the query // fills the local out-struct `mi`. - let mut mi = DXGI_QUERY_VIDEO_MEMORY_INFO::default(); let info = unsafe { adapter.QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &mut mi) }; if info.is_ok() { let (usage, budget) = (mi.CurrentUsage, mi.Budget); - if budget > 0 { - let pct = usage * 100 / budget; + // checked_div = the budget>0 guard (a fresh/lost adapter reports 0). + // usage is bytes; *100 cannot overflow u64 at any real VRAM size. + if let Some(pct) = (usage * 100).checked_div(budget) { if realtime && pct > VRAM_DOWNGRADE_PCT { // SAFETY: pseudo-handle + by-name gdi32 call (setter's contract). let st = unsafe {