diff --git a/src-tauri/src/thumbbar.rs b/src-tauri/src/thumbbar.rs index 6a93811..a5573c0 100644 --- a/src-tauri/src/thumbbar.rs +++ b/src-tauri/src/thumbbar.rs @@ -252,12 +252,20 @@ mod imp { SIZING_LATCH.store(true, Ordering::Relaxed); } else if msg == WM_ENTERSIZEMOVE { IN_MODAL.store(true, Ordering::Relaxed); - // DWM suspends the ACRYLIC accent for the whole modal loop but - // keeps compositing the plain BLURBEHIND one, so the window swaps + // DWM suspends the ACRYLIC accent inside a live RESIZE loop but + // keeps compositing the plain BLURBEHIND one, so a resize swaps // down to Blur for the gesture instead of going see-through. - // Every modal loop gets this — move drags included, since a - // suspended acrylic punches through on those exactly the same. - if GLASS_ON.load(Ordering::Relaxed) { + // A MOVE loop is different: DWM composites the acrylic straight + // through one — measured 2026-08-31 on this machine, stationary + // and at mouse-speed motion over a striped backdrop — while the + // Blur fallback ignores the gradient tint and skips the acrylic + // dimming, landing ~15% brighter over a bright backdrop. That + // brightness step for the whole of every titlebar drag is what + // "the window gets light when I drag it" was. So only a latched + // RESIZE parks the accent at Blur; a move keeps the acrylic. If + // the latch ever misses a real resize, the WM_SIZING arm below + // swaps the accent one mouse-move later. + if GLASS_ON.load(Ordering::Relaxed) && SIZING_LATCH.load(Ordering::Relaxed) { let _ = apply_accent(hwnd.0, Accent::Blur); } // Arm on the LOOP, not on WM_SIZING. Press a border and hold still @@ -279,6 +287,12 @@ mod imp { // cannot arm on a move. It arms one mouse-move later than the // latch does, which is why the latch is still the primary. if !IN_SIZE_DRAG.swap(true, Ordering::Relaxed) { + // The latch missed, so ENTERSIZEMOVE kept the acrylic; a + // WM_SIZING is proof this loop is a resize after all, so the + // accent parks at Blur here instead. + if GLASS_ON.load(Ordering::Relaxed) { + let _ = apply_accent(hwnd.0, Accent::Blur); + } unsafe { let _ = PostMessageW(Some(hwnd), WM_RESIZE_DRAG, WPARAM(1), LPARAM(0)); } diff --git a/src/lib/glass.js b/src/lib/glass.js index fa99c32..b8a712d 100644 --- a/src/lib/glass.js +++ b/src/lib/glass.js @@ -43,11 +43,15 @@ export function applyGlass(on) { * * HOW GLASS SURVIVES A GESTURE (2026-08-28, three layers, Rust-first): * - * 1. Modal move/size loops (border drags, titlebar drags): the subclass in - * src-tauri/src/thumbbar.rs swaps the accent from ACRYLIC down to plain - * BLURBEHIND for the length of the loop and back on release. DWM - * suspends the acrylic inside the loop but keeps compositing the plain - * blur, so the window stays glassy instead of see-through or black. + * 1. Modal move/size loops: the subclass in src-tauri/src/thumbbar.rs parks + * the accent at plain BLURBEHIND for the length of a RESIZE loop and puts + * ACRYLIC back on release — DWM suspends the acrylic inside a live resize + * but keeps compositing the plain blur, so the window stays glassy + * instead of see-through or black. A titlebar MOVE loop keeps the + * acrylic: DWM composites it clean through one (measured 2026-08-31, + * stationary and at mouse speed), and the plain blur it would swap to is + * ~15% brighter over a bright backdrop — that step, held for the whole of + * every drag, was Kyle's "the window gets light when I drag it". * * 2. Discrete jumps (maximize, restore, snap, DPI): the DWM zoom animation * scales a SNAPSHOT of the window, not the window — the accent visual