Ribbon: holding a press no longer scrolls the document (#1019) (#1041)

* test(engine): drop a needless drop() that clippy 1.97 rejects (drop_non_drop)

* Ribbon: a held press no longer scrolls the document (#1019)

- Double-click release paths in the canvas returned before ending the text drag
- The stale drag made any later press drive the edge auto-scroll
- A drag now ends once the button is up, wherever it was released
- Test: header double-click, then a held press on the ribbon

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
gossardla
2026-10-14 16:03:52 -04:00
committed by GitHub
co-authored by Brandon Thomas
parent e29fbdb0bf
commit 85fcbabcb1
3 changed files with 64 additions and 2 deletions
+3 -1
View File
@@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (title rename and account settings; previously trivial: progress log: Down and Up no longer skip a table, #1007; previously trivial: progress log: privacy options on save, #1062; previously trivial: progress log: equation pictures in theme colours on Windows, #1002; previously trivial: symbol fonts, #776; previously trivial: the save prompt answers from the keyboard, #861; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (progress log: a press on the ribbon no longer scrolls the document, #1019; previously trivial: title rename and account settings; previously trivial: progress log: Down and Up no longer skip a table, #1007; previously trivial: progress log: privacy options on save, #1062; previously trivial: progress log: equation pictures in theme colours on Windows, #1002; previously trivial: symbol fonts, #776; previously trivial: the save prompt answers from the keyboard, #861; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
> **Printing update:** 2026-10-12 · direct desktop printing through craft-print; details below.
@@ -137,6 +137,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
| Date | What landed |
|---|---|
| 2026-10-12 | Page background pictures and textures (Design › Page Color › Fill Effects) are drawn (tiled or stretched) and kept on save instead of being dropped from the package (#999); PDF export paints them too |
| 2026-10-12 | Holding a click on the ribbon or toolbar no longer scrolls the document up (#1019): a double-click in the header or footer area left a text drag running, so the next press anywhere drove the edge auto-scroll; a drag now ends with the button, wherever it's released |
| 2026-10-12 | Document title opens Rename Document; the account badge opens Options › General for user name and initials. `file.rename {name}` preserves file extensions and refuses an existing destination; unsaved names become the suggested save name without changing the Title property. |
| 2026-10-13 | Rounded rectangles (#1476): a `roundRect` keeps the corner radius its file gives it (`adj`), on screen, in PDF and when saved; all were drawn with a 16% corner |
| 2026-10-13 | PAGEREF in headers and footers (#1477): "Page X of Y" with Y a page reference to a bookmark at each letter's end shows each letter's own total instead of the result stored in the file |
@@ -332,6 +333,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
| Date | Change | Summary |
|---|---|---|
| 2026-10-12 | trivial | Progress log: a press on the ribbon no longer scrolls the document (#1019) |
| 2026-10-12 | trivial | Document title opens Rename Document; the account badge opens Options › General for user name and initials. |
| 2026-10-13 | trivial | Progress log: rounded rectangle corners (#1476) |
| 2026-10-13 | trivial | Progress log: PAGEREF in headers and footers (#1477) |
+7 -1
View File
@@ -874,7 +874,13 @@ pub fn show(app: &mut WordApp, ui: &mut Ui) {
};
// Dragging a selection near the viewport's edge scrolls on (#688): from a crawl at the margin
// to full speed at the edge, through the same offset the wheel writes.
let (down, pointer, dt) = ui.input(|i| (i.pointer.primary_down(), i.pointer.latest_pos(), i.stable_dt));
let (down, released, pointer, dt) = ui.input(|i| (i.pointer.primary_down(), i.pointer.primary_released(), i.pointer.latest_pos(), i.stable_dt));
// A release `mouse` returned before seeing (double-click paths, off the canvas) ends the drag here (#1019).
if app.canvas.dragging && !down && !released {
app.canvas.dragging = false;
app.canvas.column_drag = None;
app.canvas.unit_drag = None;
}
let auto_delta = if !app.session.view.read_mode
&& app.canvas.drag_selecting()
&& down
+54
View File
@@ -3153,6 +3153,60 @@ mod tests {
assert!(!a.session.sel.is_collapsed(), "the drag left a selection");
}
/// #1019: a double-click in the header area returned before the release ended the drag, so
/// a later press held on the ribbon edge-scrolled the document up.
#[test]
fn a_press_on_the_ribbon_after_a_header_double_click_does_not_scroll() {
let ctx = egui::Context::default();
let mut a = app();
a.run("insert.editHeader", json!({})).unwrap();
a.run("text.insert", json!({"text": "Header"})).unwrap();
a.run("insert.closeHeader", json!({})).unwrap();
a.run("text.insert", json!({"text": "lorem ipsum dolor sit amet consectetur ".repeat(1200)})).unwrap();
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1280.0, 600.0));
let mut t = 0.0;
let mut frame = |a: &mut WordApp, events: Vec<egui::Event>| {
t += 1.0 / 60.0;
let input = egui::RawInput { events, time: Some(t), screen_rect: Some(screen), ..Default::default() };
ctx.run_ui(input, |ui| {
a.logic(ui.ctx());
a.ui(ui);
})
.drop_without_applying_deltas();
};
let btn = |pos, pressed| egui::Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
for _ in 0..30 {
frame(&mut a, Vec::new());
}
a.run("caret.docStart", json!({})).unwrap();
for _ in 0..30 {
frame(&mut a, Vec::new());
}
let (Some(vp), Some(page)) = (a.canvas.viewport, a.canvas.page_rects.first().copied()) else { panic!("the canvas laid out") };
let header = egui::pos2(page.left() + 150.0, page.top() + 70.0);
assert!(vp.contains(header));
frame(&mut a, vec![egui::Event::PointerMoved(header)]);
for _ in 0..2 {
frame(&mut a, vec![btn(header, true)]);
frame(&mut a, vec![btn(header, false)]);
}
frame(&mut a, Vec::new());
assert!(!a.canvas.drag_selecting(), "the double-click's release ended the drag");
a.run("insert.closeHeader", json!({})).unwrap();
a.run("caret.docEnd", json!({})).unwrap();
for _ in 0..30 {
frame(&mut a, Vec::new());
}
let ribbon = egui::pos2(vp.center().x, vp.min.y - 40.0);
let before = a.canvas.scroll_offset;
frame(&mut a, vec![egui::Event::PointerMoved(ribbon), btn(ribbon, true)]);
for _ in 0..30 {
frame(&mut a, vec![egui::Event::PointerMoved(ribbon)]);
}
assert_eq!(a.canvas.scroll_offset, before, "holding a press on the ribbon leaves the document where it is");
frame(&mut a, vec![btn(ribbon, false)]);
}
/// The control channel's `ui.wheel` scrolls the canvas like a mouse wheel over it.
#[test]
fn control_wheel_scrolls_the_canvas() {