Rust's std::process::Command escapes inner double quotes as \" when
wrapping the args(["/c", &cmd]) array. cmd.exe does not understand the
\" escape, so the swap-and-restart command got mangled: `start ""
"PATH"` arrived as `start \"\" \"PATH\"`, which the cmd parser
collapsed into `start \ PATH` — producing the "Windows cannot find
'\'" dialog and aborting the update.
Switching to raw_arg lets us hand cmd.exe the literal command line it
expects. The two quote characters cmd needs to keep are the outer pair
wrapping the whole /c argument; cmd's "more than two quotes, special
chars present" branch then preserves the inner path quotes intact.
Bumps version to 0.1.2 since this is the first updater fix that ships
through the updater itself for any future v0.1.2+ user.
Bubble shape changes from circle to rounded rectangle showing two stacked
horizontal bars — top: session (5h), bottom: weekly (7d) — each followed
by a right-aligned "X% · Yh Zm" string (percent + countdown).
Bubble surface:
- BubbleConfig/BubbleState carry session+weekly percents and texts (mirrors
PanelData); update_percentage renamed to update_data
- Aspect ratio fixed at 3:1; size_logical is interpreted as width with
height derived. Clamp is 120..360 (was 32..128 square)
- Hit-testing uses a rounded-rect predicate (point_in_rounded_rect) shared
with the alpha mask so paint and click area can't drift
- New rgb_to_dib helper for direct DIB writes — BI_RGB 32bpp stores B,G,R,X
in memory which is the opposite of COLORREF. The previous code wrote
COLORREF-packed u32 straight into DIB pixels; invisible while every color
was gray, but the new orange/red bar fills would have rendered blue
- bar_h capped at h/4 (range 6..18) so the text font derived from it stays
small enough that "100% · 23h" fits in right_text_w (= 6×bar_h, min 56);
the first iteration had a 19-px font in a 60-px column and ellipsized
away the countdown
- Initial session_text/weekly_text seeded with "…" so the bubble has
visible feedback during the first poll instead of two empty grey tracks
Compile + cleanup needed to make the port build at all:
- Color::from_hex added back as an infallible wrapper around parse_hex
(15 call sites in bubble.rs/panel.rs assumed the old infallible API)
- Color::to_colorref → into_colorref at 5 call sites
- GetModuleFileNameW added to the LibraryLoader import in bubble.rs
- usage::Error gains Creds(#[from] creds::Error) so `?` works in the
Anthropic and ChatGPT providers
- FlattenBoxed::flatten renamed to flatten_box — the std Option::flatten
was shadowing it and yielding Option<Box<T>> instead of Option<T>
- PanelState marked unsafe Send (HWND has *mut c_void; state is only
touched from the UI thread, Mutex is for OnceLock satisfaction)
- Crate-level #![allow(dead_code)] for in-progress port API surface
(creds, usage, update, os::dpi); unused pub-use re-exports removed
App wiring:
- propagate_to_ui now feeds both windows + their formatted texts into
update_data (was a single percent)