R6.13 round 3 fix: each wheel notch turns; drop the unused part()

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-15 20:43:11 -04:00
1 parent 407ce00ab9
commit a2bbbead12
5 files changed
+29 -11

No files matched your search

+1 -1
View File
@@ -305,4 +305,4 @@ cargo run -p ely-doc 启动一个应用(ElyDoc 先 cargo build -p ely
- 2026-10-15(用户报:ElyMark 源码模式“测”后的插入点画在“测”的中间):组件库 `CodeEditor` 原按“列 × m 的宽”放插入点、选区、按下处与输入法框,中日韩字与表情约宽两格。组件库 9fb607b 起按 gpui 排好的这一行定位(`editor::measure`,含着色带来的字重),块状与下划线插入点取所在字的宽;标尺与缩进参考线仍按列(R6.8)。上下移动仍按字数记目标列。cd61653:按下处取最近的字首或行末(gpui 的 `closest_index_for_x` 越过末字字首即给行末);上次绘制得出的括号与配对位置只属当时的文字(`Buffer` 每次改动换一个戳),输入法改字后、下次绘制前的测量不用它们(原先把新字切进不同字体段,DirectWrite 崩溃)。
- 2026-10-15(用户报:ElyMark 三、四级标题不显眼):组件库 5954132 起标题字号随正文按 Typora 的倍数(一至六级 2.25、1.75、1.5、1.25、1、1),一律加粗,六级为次要色,行高为字号的 1.3 倍(原为固定的 24、20、16、14 像素,正文 13,三、四级只是中等字重)(R6.9)。90bd37b:粗体与标题同一字重(原粗体为半粗,标题里的粗体反而更细,正文粗体随之由半粗改为粗,同 Typora);标题行高按自身字号取 1.3 倍。Windows 真窗口核对(`.work/r69`):可视模式各级标题分明、“你好↵测试”两行,源码模式“测”后的插入点落在两字之间。
- 2026-10-15(用户报:macOS 打开一个文档,程序坞里有两个同样的图标):LOK worker 在应用包的 `Contents/MacOS` 里启动 AppKit,系统按包的 Info.plist 把它也登记为常规应用(`lsappinfo` 里应用与 worker 都是 Foreground),程序坞多一个图标;内核自己从不设激活策略。worker 在内核启动 AppKit 之前(`Lok::hook` 打开内核之后、调钩子之前)把本进程主包信息里的 `LSUIElement` 设为真,AppKit 登记时即为辅助应用(无程序坞图标、无菜单栏,仍可建屏外窗口);钩子之后核对激活策略是辅助,不是即报错、不启动(`ffi/accessory.rs`);包外的 worker(`cargo run`、单测)无包可登记,策略为禁止,此时改设辅助(R6.12 第 2 轮)。原先在登记之后才改策略,审查实测 15 次启动有 11 次先登记为 Foreground 约 30 毫秒(R6.12 第 1 轮)。`tests/scripts/dock-macos.sh` 连续启动三个应用与包外的开发构建,从 worker 启动起采样其类型到首块图块,见 Foreground 即失败(R6.12)。
- 2026-10-15(用户报:ElyShow 编辑区滚轮与上下键不换页,三端):内核在未选中对象时把上下键当作滚动窗口(`fupoor.cxx`),Ely 的画布整页适合、无处可滚,滚轮同样。`LokView::turn_parts`(ElyShow 首次适合时调用)之后:整页可见时滚轮换页(`view/turn.rs`):滚轮的行按本平台每格的行数(`ely_lok::notch`:macOS 1,Windows 取系统设置,X11 与 Wayland 为 3)折成格;X11 的滚轮与触控板同为行、分不出,所以行与像素一律按手势计:一次手势换一页(满一格或 50 像素),惯性不算;有起止的手势(macOS 触控板)只到结束才算完,没有起止的停 200 毫秒即为下一次(逐格有停顿地滚,每格一页)。未选中对象、未编辑文字时上下键换页。换页一律经有序输入队列交 worker(`TURN`):worker 按之前各输入回报后的状态判定,有选区、选中对象或插入点即把方向键照常交内核,否则当场切页(到首末页即停,同缩略图条的 `setPart`),视图在落地时换上 worker 所示的页,其后排队的键与点按都落在新页上(Tab 后紧接的 Down 移动所选对象;Down、Tab、Down 是换页后在新页上选中并移动);ElyShow 后台读回的当前页只在视图已无待落地输入时采用(R6.13)。
- 2026-10-15(用户报:ElyShow 编辑区滚轮与上下键不换页,三端):内核在未选中对象时把上下键当作滚动窗口(`fupoor.cxx`),Ely 的画布整页适合、无处可滚,滚轮同样。`LokView::turn_parts`(ElyShow 首次适合时调用)之后:整页可见时滚轮换页(`view/turn.rs`):滚轮的行按本平台每格的行数(`ely_lok::notch`:macOS 1,Windows 取系统设置,X11 与 Wayland 为 3)折成格,整格的行每格一页(快速连滚与一次多格都照格数);一串行里出现不足一格的(X11、Windows 的触控板)即为平滑滚动,此后到停顿前不再换页,像素(macOS、Wayland 的触控板)同按手势:一次手势换一页(满一格或 50 像素),惯性不算;有起止的手势(macOS)只到结束才算完,没有起止的停 200 毫秒即为下一次。X11 的滚轮与触控板同为行、gpui 不分,以整格开头的触控板滑动在出现小数之前会按格换页(已知限制)。未选中对象、未编辑文字时上下键换页。换页一律经有序输入队列交 worker(`TURN`):worker 按之前各输入回报后的状态判定,有选区、选中对象或插入点即把方向键照常交内核,否则当场切页(到首末页即停,同缩略图条的 `setPart`),视图在落地时换上 worker 所示的页,其后排队的键与点按都落在新页上(Tab 后紧接的 Down 移动所选对象;Down、Tab、Down 是换页后在新页上选中并移动);ElyShow 后台读回的当前页只在视图已无待落地输入时采用(R6.13)。
+5
View File
@@ -46,6 +46,11 @@ fn the_wheel_and_up_down_turn_slides() {
let mut shown = VisualTestContext::from_window(window.into(), &cx);
shown.run_until_parked();
assert_eq!(current(&mut shown, &deck), 0);
wheel(&mut shown, -2.0);
assert_eq!(current(&mut shown, &deck), 2, "two notches in one event turn two");
wheel(&mut shown, 1.0);
wheel(&mut shown, 1.0);
assert_eq!(current(&mut shown, &deck), 0, "rapid notches each turn");
wheel(&mut shown, -1.0);
assert_eq!(current(&mut shown, &deck), 1, "the wheel turns down");
shown.update(|window, app| {
+17 -9
View File
@@ -42,6 +42,8 @@ pub(super) struct Turning {
spent: bool,
/// The platform began a gesture it has not ended.
held: bool,
/// Fractional lines in this run: a touchpad, not a wheel.
smooth: bool,
last: Option<Instant>,
}
@@ -58,7 +60,16 @@ impl Turning {
};
// Phases bound a gesture; without them, a pause does.
if phase == Some(TouchPhase::Started) || paused && !self.held {
(self.travel, self.spent) = (0.0, false);
(self.travel, self.spent, self.smooth) = (0.0, false, false);
}
let whole = travel.round();
if phase.is_none() && (whole == 0.0 || (travel - whole).abs() >= 1e-3) {
self.smooth = true;
}
// Whole wheel notches each turn, until fractions show a touchpad.
if phase.is_none() && !self.smooth {
(self.travel, self.spent, self.held) = (0.0, true, false);
return -(whole as i32);
}
self.held = match phase {
Some(TouchPhase::Started) => true,
@@ -85,11 +96,6 @@ impl LokView {
self.turning.get_or_insert_default();
}
/// The part shown.
pub fn part(&self) -> usize {
self.part
}
/// Queues Up, Down; the worker turns if nothing is picked.
pub(super) fn turn_key(&mut self, keystroke: &Keystroke) -> bool {
if self.turning.is_none() || keystroke.modifiers != Modifiers::none() {
@@ -148,7 +154,9 @@ mod tests {
assert_eq!(wheel(-3.0, now), 1, "Windows and Linux scroll three lines a notch");
assert_eq!(wheel(-3.0, now + PAUSE), 1);
assert_eq!(wheel(3.0, now + PAUSE * 2), -1);
assert_eq!(wheel(-6.0, now + PAUSE * 3), 1, "two notches at once turn once");
assert_eq!(wheel(-6.0, now + PAUSE * 3), 2, "two notches in one event");
assert_eq!(wheel(-3.0, now + PAUSE * 3), 1, "rapid notches each turn");
assert_eq!(wheel(-3.0, now + PAUSE * 3), 1);
assert_eq!(wheel(-1.0, now + PAUSE * 4), 0, "a third of a notch");
let mut mac = Turning::default();
assert_eq!(mac.wheel(lines(-1.0), TouchPhase::Moved, now, 1.0), 1, "macOS scrolls a line a notch");
@@ -157,8 +165,8 @@ mod tests {
#[test]
fn a_stream_of_lines_turns_once() {
let (mut turning, now) = (Turning::default(), std::time::Instant::now());
// X11 smooth scrolling: whole steps, then fractions, no pause.
let stream = [-3.0, -3.0, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4];
// A whole step, then fractions: no more turns once smooth.
let stream = [-3.0, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -3.0];
let turned: i32 = stream.iter().map(|&y| turning.wheel(lines(y), TouchPhase::Moved, now, NOTCH)).sum();
assert_eq!(turned, 1, "one swipe turns once");
let mut turning = Turning::default();
+1 -1
View File
@@ -271,5 +271,5 @@
- [x] R6.11 Windows 升级后旧文件仍在(R6.10 本机重装查出):安装程序只覆盖不删除,旧版 ElyMark 的 `git` 与 CEF 文件留在安装目录;安装程序记下所装的文件,升级与卸载只移去这些;文件被占用即什么也不改,失败时放回旧版。第 3 轮后(最后一轮,修完不再审查):备份按清单次序编号,近 260 字的路径照样升级与卸载;卸载先查清单本身,删不掉即放回全部
- [x] R6.10 重发 0.1.5(用户定:仍为 0.1.5):删去 v0.1.5 的全部文件,标签移到修复的提交,三端全部包重建并上传,本机重装(标签在 53630ce;推标签即起发布流程,其 Windows 与 Linux 任务建出并上传,与本机同时起的 Windows 构建撞上,本机那份未上传;macOS 任务未上传,dmg 由 Mac mini 本机建、公证、钉票;44 个文件,同名的源码包只留 Linux 的一份,见 P3-16;下载回的 ElyMark 安装程序与清单的散列与构建相同;本机六个应用 0.1.5 经新安装程序升级,ElyMark 目录无 `git`,冒烟启动均正常退出、日志无警告)
- [x] R6.12 macOS 打开一个文档,程序坞里 ElyDoc、ElyTable、ElyShow 各出现两个图标(用户 2026-10-15 报):LOK worker 在应用包内启动 AppKit,系统按包的 Info.plist 把它也登记为常规应用(`lsappinfo` 两个 Foreground);worker 在内核启动 AppKit 前把本进程主包信息的 `LSUIElement` 设为真,登记即为辅助应用,钩子后核对策略(第 1 轮:原先登记后才改,15 次有 11 次先为 Foreground);`tests/scripts/dock-macos.sh` 在 Mac mini 上 30 次启动全为 UIElement,旧 worker 即失败;第 2 轮:包外的 worker(`cargo run`、单测)策略为禁止,原核对即退出,改设辅助,测试另启包外的开发构建(40 次全过);第 3 轮通过
- [ ] R6.13 ElyShow 编辑区的滚轮与上下键不换页(用户报,三端;放映时正常):内核在未选中对象时把上下键当作滚动窗口,Ely 的画布整页适合、无处可滚;整页可见时滚轮换页(每格一页,触控板一次手势一页),未选中对象、未编辑文字时上下键换页,同缩略图条的路径,到首末页即停;第 1 轮:Windows 一格三行原换三页,X11 触控板的小数行一次滑动换多页,按住手指停顿后再滑又换一页,Tab 后紧接的 Down 按旧状态换页;改为按平台每格行数计格、小数行与像素按手势计、有起止的手势只到结束才算完、上下键由 worker 按输入次序判定;第 2 轮:换页在 worker 回复后才排进队列,排在其后的键先作用于旧页,以整格开头的 X11 平滑滚动仍按格多次换页;改为换页(键与滚轮)都由 worker 在输入次序中当场切页,行与像素一律按手势计(无起止的停 200 毫秒为界)
- [x] R6.13 ElyShow 编辑区的滚轮与上下键不换页(用户报,三端;放映时正常):内核在未选中对象时把上下键当作滚动窗口,Ely 的画布整页适合、无处可滚;整页可见时滚轮换页(每格一页,触控板一次手势一页),未选中对象、未编辑文字时上下键换页,同缩略图条的路径,到首末页即停;第 1 轮:Windows 一格三行原换三页,X11 触控板的小数行一次滑动换多页,按住手指停顿后再滑又换一页,Tab 后紧接的 Down 按旧状态换页;改为按平台每格行数计格、小数行与像素按手势计、有起止的手势只到结束才算完、上下键由 worker 按输入次序判定;第 2 轮:换页在 worker 回复后才排进队列,排在其后的键先作用于旧页,以整格开头的 X11 平滑滚动仍按格多次换页;改为换页(键与滚轮)都由 worker 在输入次序中当场切页;第 3 轮:一律按手势计使快速连滚与一次多格只换一页,`LokView::part` 已无调用者;改为整格的行每格一页、出现小数即按手势,删去 `part`(第 3 轮为最后一轮,修后不再审查)
- [ ] R6.14 重发 0.1.5(用户定:仍为 0.1.5,全部重建并重传):删去 v0.1.5 的全部文件,标签移到 R6.12、R6.13 的提交,三端全部包重建并上传,本机重装
+5
View File
@@ -0,0 +1,5 @@
FAIL
- crates/ely-lok/src/view/turn.rs:69 — Treating every line delta as one gesture breaks R6.13's one-page-per-wheel-notch requirement. In the rebuilt-worker integration probes, three physical notches delivered without a 200 ms pause advance from slide 1 to slide 2 instead of slide 4; one event containing two notches reaches slide 2 instead of slide 3 (`.work/R6.13-r3/probe-tests.log`). The new unit test even expects two notches to turn once. Preserve the adapter's discrete-wheel versus smooth-scroll distinction, count every discrete notch, and retain the one-turn limit for touchpad gestures; cover both rapid notches and multi-notch events.
- crates/ely-lok/src/view/turn.rs:89 — `LokView::part()` is now dead code: this round deletes its sole caller, `Deck::turn`, and no production or checked-in test caller remains under `apps/` or `crates/` (`.work/R6.13-r3/part-callers.log`). The worker-driven navigation path no longer uses this accessor, violating agents.md rule 6. Remove the unused accessor.