From 6cafffc883b30d7cf50d6538fab67e81740ba810 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sat, 23 May 2026 21:06:26 +0700 Subject: [PATCH] fix(bubble): show 7d percent at default size and 125% DPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v0.3.0 introduced a tail 7d% reading but the layout-collapse guard fired at every common bubble configuration — at the default 200-logical size on both 100% and 125% DPI, after reserving the CJK worst-case countdown column ("999시간") and the "100%" text rect, the tail had less than 20 logical of bar room left. The guard collapsed the % rect to zero width and the paint code's `if rect.right > rect.left` skip ran on every frame, so the feature was effectively dead on arrival for the majority of users. The 20-logical bar minimum was the pre-feature bar floor, used to guarantee a readable bar at very small bubble sizes. It does not need to apply when the % is shown — the % is the actual data and the bar becomes secondary visual context. Split into two thresholds: - `bar_min_with_pct = 8 logical` decides whether the % can fit. With 8 logical of bar room the bar still renders as a short pill. - `bar_min = 20 logical` only applies on the fallback (140-logical minimum bubble) path where the % has been dropped — preserving the pre-feature readable-bar behavior at the smallest size. The bar's render floor now follows the active path (`bar_render_min`) so a thin bar in the pct-active case does not overlap the countdown. --- src/bubble.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/bubble.rs b/src/bubble.rs index 509e484..e4964ea 100644 --- a/src/bubble.rs +++ b/src/bubble.rs @@ -1031,23 +1031,29 @@ fn compute_bubble_layout(size_logical: i32, dpi: u32, mem_dc: HDC) -> BubbleLayo let tail_countdown_right = tail_right; let tail_countdown_left = tail_countdown_right - countdown_w; - // Try to seat a 7d% text between the "7d" label and the bar. If that would - // squeeze the bar below the 20-logical minimum, collapse the % rect (zero - // width) and fall back to the original label→bar→countdown layout. This - // keeps the 140-logical bubble legible without dropping the bar. + // Try to seat a 7d% text between the "7d" label and the bar. The % + // number is the actual data, so it takes precedence over keeping the + // bar at its pre-feature minimum: when the % shows, the bar may + // compress to `bar_min_with_pct` (still visible as a pill). Only when + // even that small bar wouldn't fit do we collapse the % rect entirely + // and restore the pre-feature `bar_min` to keep the bar readable. + // Without this two-tier threshold, the worst-case CJK countdown column + // ("999시간") leaves <20 logical of bar room at the default 200-logical + // size on both 100% and 125% DPI, and the % silently disappears. let bar_min = scale_to_dpi(20, dpi); - let (tail_pct_left, tail_pct_right, tail_bar_left) = { + let bar_min_with_pct = scale_to_dpi(8, dpi); + let (tail_pct_left, tail_pct_right, tail_bar_left, bar_render_min) = { let pct_left = tail_label_right + pad; let pct_right = pct_left + pct_reserve_w; let bar_left = pct_right + pad; - if (tail_countdown_left - pad) - bar_left >= bar_min { - (pct_left, pct_right, bar_left) + if (tail_countdown_left - pad) - bar_left >= bar_min_with_pct { + (pct_left, pct_right, bar_left, bar_min_with_pct) } else { let bar_left = tail_label_right + pad; - (bar_left, bar_left, bar_left) + (bar_left, bar_left, bar_left, bar_min) } }; - let tail_bar_right = (tail_countdown_left - pad).max(tail_bar_left + bar_min); + let tail_bar_right = (tail_countdown_left - pad).max(tail_bar_left + bar_render_min); let tail_bar_h = scale_to_dpi(5, dpi); let tail_bar_top = (height_px - tail_bar_h) / 2;