Skip to content

fix: scrollbar thumb drift on click/drag #78

Description

@cc-claws

问题描述

消息区滚动条(右侧单列)点击滑块(thumb)后,thumb 会跳离鼠标位置,导致「点滑块抓不住 / 拖动乱跳」。

已确认事实

漂移 bug 存在:测试 thumb_click_drift_runtime_proof(event/mod.rs)用 ratatui 0.30 真实渲染证明:

  • 6 种内容长度 × 5 种位置 = 30 个采样点
  • 点击 thumb 中点后,thumb 必然跳离鼠标位置(assert total_drifted > 0)

当前鼠标映射公式(event/mod.rs:315):

fn message_scrollbar_offset_for_row(metrics: MessageScrollbarMetrics, row: u16) -> usize {
    let bar_inner_height = metrics.bar_area.height.saturating_sub(2);
    let rel_y = row.saturating_sub(metrics.bar_area.y.saturating_add(1)).min(bar_inner_height);
    ((metrics.max_offset as u128 * rel_y as u128) / bar_inner_height as u128) as usize
}

offset = max_offset * rel_y / track

未确认(需进一步调查)

ratatui 的 thumb 定位公式:ratatui Scrollbar::part_lengths() 的源码未能直接查看(cargo registry 本地不可用,网上文档被截断)。归档文档记录的公式为:

thumb_start = position * track / (content_length - 1 + viewport)

此公式未经源码验证,可能不准确。

可能的修复方向

  1. 写诊断测试 dump ratatui 真实 thumb 位置,反推精确公式
  2. 实现与 ratatui 一致的逆映射(thumb 行 → offset)
  3. 区分点击 thumb vs track(thumb 上记录 drag_y_offset 防跳动)

涉及文件

  • peri-tui/src/event/mod.rs — 鼠标事件处理 + offset 计算
  • peri-tui/src/ui/main_ui/message_area.rs — 滚动条渲染
  • peri-widgets/src/scrollable.rsunified_vertical_scrollbar() 构造器

复现条件

  • 内容较长时必现
  • 点击或拖拽滚动条滑块可见跳动

环境

  • ratatui 0.30.0
  • Windows / macOS 均可复现

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions