Files
Sprimo/issues/issue1.md
2026-02-12 22:58:33 +08:00

10 KiB

Title

Windows overlay renders as large opaque window; background not transparent; sprite shows magenta matte; window is not pet-sized.

Severity

P0

Environment

  • OS: Windows
  • App: sprimo-app frontend runtime
  • Reported on: 2026-02-12
  • Evidence screenshot: issues/screenshots/issue1.png

Summary

Current runtime output violates overlay requirements:

  • opaque dark background is visible behind the pet
  • sprite keeps magenta matte background
  • window footprint is larger than expected pet footprint

Reproduction Steps

  1. Launch the frontend executable on Windows.
  2. Observe the initial overlay window at startup.

Expected Result

  • Window appears borderless and transparent.
  • Only pet pixels are visible.
  • Sprite background uses alpha (no magenta matte).
  • Window size is constrained to sprite bounds plus small margin.

Actual Result

  • Window background appears opaque dark gray.
  • Sprite contains magenta matte rectangle.
  • Window appears larger than a pet-sized overlay.

Root Cause Analysis

Current findings from repository inspection:

  • The default sprite is RGB (Format24bppRgb) and depends on runtime chroma-key conversion.
  • Window and clear-color transparency settings were configured, but layered-window attributes were not explicitly applied during window-handle attachment.
  • SetTransform.x/y was applied to both window coordinates and sprite world translation, causing visible offset within the client area and making the window appear larger than pet bounds.
  • Chroma-key conversion used exact color matching only, which is fragile for near-magenta pixels.

Fix Plan

  1. Reproduce with runtime logs enabled and capture an explicit before screenshot.
  2. Validate chroma-key conversion path against loaded texture content.
  3. Validate Windows composition and layered style behavior with attached HWND.
  4. Apply targeted renderer/platform fixes.
  5. Capture after screenshot and rerun verification checklist.

Implementation Notes

Implemented code changes:

  1. crates/sprimo-app/src/main.rs
  • Sprite now spawns centered at (0, 0, 0); persisted x/y remains window placement only.
  • SetTransform.x/y no longer mutates sprite world translation.
  • Chroma-key conversion now:
    • uses tolerance matching around #FF00FF,
    • preserves non-key alpha values,
    • forces chroma-key when an alpha-bearing image is fully opaque but key-colored in large areas.
  • Added regression tests for tolerant keying, alpha preservation, and force-key detection.
  1. crates/sprimo-platform/src/lib.rs
  • Windows adapter now applies layered style + SetLayeredWindowAttributes when window handle is attached.
  • Click-through toggles now reuse the layered-style application path to keep transparency setup stable.
  1. Additional Windows window configuration hardening (crates/sprimo-app/src/main.rs)
  • Primary window now explicitly sets composite_alpha_mode = PreMultiplied.
  • Primary window now starts with a small explicit resolution (544x544) to avoid large default client area before runtime pack sizing applies.
  1. Follow-up rollback + keying adjustment after new screenshot review
  • Removed explicit composite_alpha_mode override to return control to Bevy/WGPU default.
  • Removed forced layered alpha attributes from Windows adapter to avoid opaque black composition.
  • Increased chroma-key tolerance to better remove magenta fringe around sprite edges.
  1. Windows compositor fallback for persistent opaque background
  • Added Windows color-key transparency fallback:
    • sets WS_EX_LAYERED on attached HWND
    • applies SetLayeredWindowAttributes(..., LWA_COLORKEY) with key color #01FE03
  • Switched Windows clear color to the same key color so non-sprite background can be cut out by the OS compositor even when swapchain alpha blending is not honored.
  1. Windows mode switch to avoid swapchain-alpha path conflicts
  • On Windows, primary window now disables Bevy transparent swapchain mode (transparent = false) and relies on layered color-key composition only.
  • Non-Windows behavior remains unchanged (transparent = true + alpha clear).
  1. DWM composition strategy after transparent color-key regression
  • Removed Windows color-key compositor strategy (it hid sprite on tested path).
  • Added DWM composition setup on HWND attach:
    • DwmIsCompositionEnabled
    • DwmExtendFrameIntoClientArea with full glass margins
    • DwmEnableBlurBehindWindow
  • Restored Windows render path to alpha clear + transparent = true.
  1. Renderer alpha mode correction pass
  • Removed DWM composition overrides to avoid conflicting transparency mechanisms.
  • Forced Bevy window CompositeAlphaMode::PostMultiplied on Windows to align with transparent swapchain blending expectations.
  • Kept native alpha clear color render path.
  1. Hardware-safe Windows fallback after runtime panic
  • Runtime log showed wgpu surface supports alpha modes [Opaque] only on this machine.
  • Switched Windows path to opaque swapchain (transparent = false) plus Win32 layered color-key transparency (WS_EX_LAYERED + LWA_COLORKEY).
  • Aligned Windows clear color to the same key color (#FF00FF) and removed crash-causing post-multiplied alpha request.
  1. Color-key visibility fix for opaque presentation path
  • In Windows colorkey mode, keyed pixels are now emitted with alpha 255 (not 0) so key RGB survives the presentation path and can be matched by LWA_COLORKEY.
  • Updated chroma-key unit tests for platform-specific keyed-alpha expectations.

Verification

Commands Run

  • cargo check --workspace
  • cargo test --workspace
  • just qa-validate

Screenshots

  • Before:
    • issues/screenshots/issue1.png (legacy baseline)
  • After:
    • pending (capture required before Verification Passed/Closed)

Command Output Summary

  • cargo check --workspace: pass
  • cargo test --workspace: pass
  • just qa-validate: pass
  • cargo check -p sprimo-app -p sprimo-platform: pass
  • cargo test -p sprimo-app: pass
  • dist runtime binary refreshed from latest debug build: done
  • Follow-up rebuild + dist binary refresh after screenshot-guided rollback: done
  • Windows color-key fallback build + dist binary refresh: done
  • Windows transparent-mode switch build + dist binary refresh: done
  • DWM composition fallback build + dist binary refresh: done
  • Post-multiplied alpha mode build + dist binary refresh: done
  • Opaque+colorkey fallback build + dist binary refresh: done
  • Keyed-alpha colorkey build + dist binary refresh: done

Result

  • Current Status: Fix Implemented
  • Notes: code fix implemented and validated by tests; runtime after screenshot still pending.

Status History

  • 2026-02-12 20:15 - reporter - Reported - initial bug report with screenshot.
  • 2026-02-12 20:35 - codex - Triaged - validated screenshot symptoms and repository context.
  • 2026-02-12 20:50 - codex - Reported - lifecycle file normalized; fix not yet applied.
  • 2026-02-12 21:20 - codex - In Progress - implemented window/transparency/chroma-key fixes.
  • 2026-02-12 21:30 - codex - Fix Implemented - workspace checks/tests and QA validator passed.
  • 2026-02-12 22:10 - codex - In Progress - added explicit Windows composite alpha mode and startup resolution.
  • 2026-02-12 22:15 - codex - Fix Implemented - app/platform targeted checks passed and dist binary refreshed.
  • 2026-02-12 22:35 - codex - In Progress - analyzed new after screenshot showing black opaque background and magenta fringe.
  • 2026-02-12 22:45 - codex - Fix Implemented - rolled back layered alpha/composite override and tightened chroma-key edge removal.
  • 2026-02-12 22:55 - codex - In Progress - analyzed latest screenshot still showing opaque black background.
  • 2026-02-12 23:05 - codex - Fix Implemented - added Windows color-key compositor fallback and aligned clear color.
  • 2026-02-12 23:15 - codex - In Progress - analyzed latest screenshot showing color-key path still ineffective with swapchain transparency.
  • 2026-02-12 23:22 - codex - Fix Implemented - switched Windows to non-transparent swapchain mode and kept layered color-key compositor path.
  • 2026-02-12 23:30 - codex - In Progress - analyzed screenshot where window became effectively empty/over-transparent.
  • 2026-02-12 23:42 - codex - Fix Implemented - removed color-key strategy and switched to DWM composition setup.
  • 2026-02-12 23:55 - codex - In Progress - analyzed screenshot where black background persisted under DWM strategy.
  • 2026-02-13 00:05 - codex - Fix Implemented - removed DWM overrides and forced post-multiplied alpha mode on Windows.
  • 2026-02-13 00:35 - codex - In Progress - reproduced startup panic from runtime log (alpha modes: [Opaque]).
  • 2026-02-13 00:45 - codex - Fix Implemented - replaced transparent swapchain path with Windows opaque+colorkey fallback; startup panic no longer reproduced.
  • 2026-02-13 00:55 - codex - In Progress - analyzed persistent black background under opaque+colorkey path.
  • 2026-02-13 01:05 - codex - Fix Implemented - changed keyed-pixel alpha to 255 in Windows colorkey mode and updated tests.

Closure

  • Current Status: Fix Implemented
  • Close Date:
  • Owner:
  • Linked PR/commit:

Original Report (2026-02-12, normalized from legacy encoding)

Bug Report / Debugging Issue (Windows)

Title: Windows overlay renders as large opaque window; background not transparent; sprite shows magenta matte; window not pet-sized.

Severity: P0 (core functionality broken; not an overlay pet)

Component: Frontend (Bevy renderer / windowing / transparency pipeline)

Summary: The app shows a large opaque dark-gray window with a character sprite on top. The sprite includes a magenta rectangular matte. This violates transparent borderless overlay requirements.

Evidence from screenshot (issues/screenshots/issue1.png):

  1. Opaque background fills most of the window.
  2. Window appears much larger than pet-only bounds.
  3. Magenta matte appears behind the sprite.

Expected:

  • Borderless transparent overlay.
  • Pet-only visible pixels.
  • No magenta matte.

Actual:

  • Opaque dark window.
  • Magenta sprite background.
  • Regular app-window behavior.

Likely causes in original report:

  1. Missing OS-level transparent/layered window behavior.
  2. Non-transparent clear color or camera clear.
  3. Sprite asset alpha issue (RGB or wrong export).
  4. Missing chroma-key discard path.
  5. Missing pet-sized window sizing logic.