Skip to content

Commit 9034c16

Browse files
committed
Add launcher installer, resources, and packaging tweaks
Introduce a Windows installer/launcher and packaging improvements. Key changes: - Add .cargo/config.toml to statically link MSVC CRT (+crt-static) for Store certification. - Add build.rs and winresource to embed the application icon into binaries. - Revamp src/launcher.rs: owner-drawn launcher UI, embedded Ekush font, improved layout/colors, GitHub button, and logic to install/remove the .scr in %WINDIR%\System32 using elevated ShellExecuteW + cmd (copy/del) and reg.exe to update HKCU so changes aren't MSIX-virtualized. Also use SystemParametersInfoW to notify Windows of changes and poll for async operations. - Add .github/copilot-instructions.md with project overview and developer notes. - Update README.md to document the BanglaSaver launcher, Microsoft Store distribution, installation flow, config paths, and UI/feature details. - Minor packaging and manifest text tweaks and add logs.txt to .gitignore. These changes enable a native launcher/installer workflow (with UAC), embed resources, and prepare the project for Store-friendly builds and packaging.
1 parent e77707c commit 9034c16

12 files changed

Lines changed: 800 additions & 272 deletions

File tree

.cargo/config.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Statically link the MSVC C runtime so the binaries have zero
2+
# runtime dependencies (no vcruntime140.dll). Required for
3+
# Microsoft Store certification (policy 10.2.4.1).
4+
[target.x86_64-pc-windows-msvc]
5+
rustflags = ["-C", "target-feature=+crt-static"]
6+
7+
[target.aarch64-pc-windows-msvc]
8+
rustflags = ["-C", "target-feature=+crt-static"]

.github/copilot-instructions.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copilot Instructions – bsaver
2+
3+
## Project Overview
4+
5+
**bsaver** is a Windows screensaver (`.scr`) displaying a Bangla digital clock with Bengali calendar (বঙ্গাব্দ) support. Written in Rust (2024 edition), it uses raw Win32 APIs via `windows-rs` for window management and `cosmic-text` for Bangla text shaping/rendering. There is no GPU rendering — all drawing is CPU-based to a BGRA pixel buffer blitted via GDI.
6+
7+
## Architecture
8+
9+
Six modules with clear responsibilities — all wired through `main.rs`:
10+
11+
- **`main.rs`** — Entry point. Parses `/s`, `/p <hwnd>`, `/c` args into `ScreensaverMode` and dispatches.
12+
- **`screensaver.rs`** — Win32 window creation, message loop, double-buffered GDI rendering. Owns the global `Renderer` via `OnceLock<Mutex<Renderer>>`. Uses a thread-local `RENDER_BUFFER` to avoid per-frame heap allocations.
13+
- **`renderer.rs`** — Text rendering with `cosmic-text`. Loads only the embedded Ekush font (no system fonts). Provides `render_text()` (BGRA output), `render_text_centered()`, and `render_time_fixed_grid()` (fixed-width digit cells to prevent clock jitter). Caches digit widths and periodically resets `SwashCache` to bound memory.
14+
- **`clock.rs`** — Formats time, date, day, season strings. Handles 12h/24h, Bangla/English numerals and names. Region-aware via `Config`.
15+
- **`bangla_date.rs`** — Gregorian-to-Bengali calendar conversion. Handles Bangladesh (Apr 14 Pohela Boishakh, UTC+6) vs India (Apr 15, UTC+5:30) conventions. Always converts to the region's timezone first, not local system time. Has comprehensive tests.
16+
- **`config.rs`**`Config` struct with serde JSON serialization. Stored at `ProjectDirs::from("dev", "abusayed", "bsaver")`. Uses `let-chain` syntax for loading.
17+
- **`settings.rs`** — Native Win32 settings dialog built with `CreateWindowExW` toggle buttons.
18+
- **`launcher.rs`** — Separate binary (`BanglaSaver`) providing a launcher UI to register/unregister the screensaver via HKCU registry. Uses `thread_local!` + `Cell` for Win32 UI state (Rust 2024 forbids `static mut`). Registry writes use `reg.exe` (not `RegSetValueExW`) to bypass MSIX virtualization.
19+
20+
## Two Binaries
21+
22+
Defined in `Cargo.toml`:
23+
- `bsaver` (`src/main.rs`) — The screensaver itself
24+
- `BanglaSaver` (`src/launcher.rs`) — Launcher/installer UI
25+
26+
Both use `#![windows_subsystem = "windows"]` to hide the console.
27+
28+
## Key Patterns
29+
30+
- **No `static mut`**: Rust 2024 edition. Use `OnceLock`, `LazyLock`, `thread_local!` with `Cell`/`RefCell`, or `Mutex` for shared state.
31+
- **Embedded font**: The Ekush font is included via `include_bytes!("../font/Ekush-Regular.ttf")` — no runtime font loading or system font enumeration.
32+
- **BGRA pixel buffers**: All rendering goes to `Vec<u8>` in BGRA format, then `SetDIBitsToDevice` to GDI. The screen buffer is thread-local and never shrinks.
33+
- **Fixed-width time grid**: `render_time_fixed_grid()` measures the widest digit and centers each character in a fixed cell to prevent layout shifts when digits change.
34+
- **Timezone-first date calculation**: `BanglaDate::from_local_with_region()` converts local time → UTC → region timezone before calculating the Bengali date. This is intentional — see tests in `bangla_date.rs`.
35+
- **Memory discipline**: SwashCache cleanup every 500 renders, no system font loading, reusable buffers. Target: ~12MB private working set at 1080p.
36+
- **MSIX registry bypass**: The launcher uses `std::process::Command` to invoke `reg.exe` for all `HKCU\Control Panel\Desktop` writes/reads/deletes. Direct `RegSetValueExW`/`RegQueryValueExW` calls are virtualized inside an MSIX container, so the Windows screensaver service would never see them. `reg.exe` is a system binary outside the MSIX package, so its writes go to the real registry.
37+
- **Static CRT linking**: `.cargo/config.toml` sets `+crt-static` to eliminate the MSVC CRT (`vcruntime140.dll`) runtime dependency for Store distribution.
38+
39+
## Build & Test
40+
41+
```powershell
42+
cargo build # Dev build
43+
cargo build --release # Optimized release (~2MB)
44+
cargo test --verbose # Run tests (bangla_date has timezone/calendar tests)
45+
cargo clippy -- -D warnings # Lint (CI enforces zero warnings)
46+
cargo fmt --all -- --check # Format check
47+
```
48+
49+
Release profile uses `lto = true`, `codegen-units = 1`, `panic = "abort"`, `strip = true`.
50+
51+
To package as MSIX: `.\packaging\build-msix.ps1` (requires Windows 10 SDK for `MakeAppx.exe`).
52+
53+
## CI
54+
55+
GitHub Actions (`windows-latest` only): test → clippy → fmt → build + MSIX. The build job uploads `bsaver.exe`, `BanglaSaver.exe`, and `.msix` artifacts. Releases trigger on `v*` tags.
56+
57+
## When Modifying
58+
59+
- **Adding display elements**: Add config field in `config.rs` → format in `clock.rs` → render in `screensaver.rs::render_clock_content()` → toggle in `settings.rs`.
60+
- **Calendar logic**: All date math is in `bangla_date.rs`. Month lengths follow the 2019 revised Bangladesh calendar (first 5 months = 31 days). Add tests covering multiple timezones.
61+
- **Win32 APIs**: All `unsafe` blocks must be explicit (Rust 2024). Use `windows-rs` typed wrappers. Clean up GDI resources (`DeleteObject`, `DeleteDC`) after use.
62+
- **Font changes**: Replace `font/Ekush-Regular.ttf` and the `include_bytes!` path. Bangla shaping requires `Shaping::Advanced` in cosmic-text.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
# OS
1414
.DS_Store
1515
Thumbs.db
16+
logs.txt

Cargo.lock

Lines changed: 89 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ categories = ["gui"]
1414
cosmic-text = "0.18.2"
1515

1616
# Time handling
17-
chrono = "0.4"
17+
chrono = "0.4.44"
1818

1919
# Configuration
2020
serde = { version = "1.0", features = ["derive"] }
@@ -27,13 +27,16 @@ windows = { version = "0.62", features = [
2727
"Win32_Foundation",
2828
"Win32_System_LibraryLoader",
2929
"Win32_UI_WindowsAndMessaging",
30+
"Win32_UI_Controls",
3031
"Win32_Graphics_Gdi",
3132
"Win32_System_SystemServices",
32-
"Win32_System_Registry",
3333
"Win32_UI_Shell",
3434
"Win32_UI_Input_KeyboardAndMouse",
3535
] }
3636

37+
[build-dependencies]
38+
winresource = "0.1"
39+
3740
[profile.release]
3841
opt-level = 3
3942
lto = true

0 commit comments

Comments
 (0)