diff --git a/crates/ui-egui/src/mini_toolbar.rs b/crates/ui-egui/src/mini_toolbar.rs index 0af9e39e1..7e4d15657 100644 --- a/crates/ui-egui/src/mini_toolbar.rs +++ b/crates/ui-egui/src/mini_toolbar.rs @@ -232,7 +232,16 @@ pub fn show_in_context_menu(app: &mut WordApp, ui: &mut egui::Ui) { fn content(app: &mut WordApp, ui: &mut egui::Ui, t: &Tokens) { let st: Value = app.session.run("format.state", &json!({})).unwrap_or_default(); let flag = |k: &str| st.get(k).and_then(Value::as_bool).unwrap_or(false); - let align = app.session.doc.para_at(&app.session.sel.focus).map(|p| app.session.doc.styles.resolve_para(&p.props).align).unwrap_or_default(); + // As on the ribbon, the buttons show alignment as seen on the page (#3579). + let align = app + .session + .doc + .para_at(&app.session.sel.focus) + .map(|p| { + let r = app.session.doc.styles.resolve_para(&p.props); + r.align.visual(r.bidi) + }) + .unwrap_or_default(); let row = |ui: &mut egui::Ui, app: &mut WordApp, add: &dyn Fn(&mut egui::Ui, &mut WordApp)| { ui.allocate_ui_with_layout(Vec2::new(ui.available_width(), ROW_H), Layout::left_to_right(Align::Center), |ui| { ui.set_min_height(ROW_H); @@ -924,4 +933,60 @@ mod tests { assert!(h.state().canvas.want_focus, "the swatch pick returns focus to the document"); assert!(format_state(&mut h).get("highlight").is_some_and(|v| !v.is_null()), "the first swatch applied a highlight"); } + + /// #3579: in a right-to-left paragraph the bar lit Align Left for a paragraph that sits on + /// the right. Like the ribbon, it marks the alignment as seen on the page, the one its buttons + /// set. Only the bar is drawn, so the ribbon's own alignment buttons can't answer for it. + #[test] + fn alignment_buttons_mark_the_alignment_seen_on_the_page_in_a_right_to_left_paragraph() { + use egui_kittest::kittest::Queryable; + // A left-to-right paragraph first: a bar that always swapped the two would pass the RTL cases alone. + for (rtl, cmd, lit, unlit) in [ + (false, None, "Align Left", "Align Right"), + (true, None, "Align Right", "Align Left"), + (true, Some("para.alignLeft"), "Align Left", "Align Right"), + ] { + let mut a = WordApp::new(wordcraft_engine::Session::new(wordcraft_doc::Document::from_text("سلام دنیا")), Default::default()); + a.run("select.all", json!({})).unwrap(); + if rtl { + a.run("para.rtl", json!({})).unwrap(); + } + if let Some(cmd) = cmd { + a.run(cmd, json!({})).unwrap(); + } + // The bar writes in the interface fonts, which take effect the frame after they are set. + let mut fonts = false; + let mut h = egui_kittest::Harness::builder().with_size(Vec2::new(500.0, 200.0)).build_ui_state( + move |ui, app: &mut WordApp| { + if !fonts { + crate::theme::install_fonts(ui.ctx()); + fonts = true; + return; + } + egui::Area::new(egui::Id::new("mini_align_probe")).fixed_pos(pos2(10.0, 10.0)).show(ui.ctx(), |ui| { + let t = Tokens::get(ui.ctx()); + content(app, ui, &t); + }); + }, + a, + ); + steps(&mut h); + let checked = Tokens::get(&h.ctx).checked; + let marked: Vec = h + .output() + .shapes + .iter() + .filter_map(|s| match &s.shape { + egui::Shape::Rect(r) if r.fill == checked => Some(r.rect), + _ => None, + }) + .collect(); + let is_marked = |label: &str| { + let r = h.get_by_label(label).rect(); + marked.iter().any(|m| m.contains(r.center())) + }; + assert!(is_marked(lit), "rtl={rtl} {cmd:?}: {lit} is marked"); + assert!(!is_marked(unlit), "rtl={rtl} {cmd:?}: {unlit} is not marked"); + } + } } diff --git a/docs/ui-parity.md b/docs/ui-parity.md index c974a537d..2e9bb6130 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity with Microsoft Word -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-24 · **Change:** trivial (Review › Accept and Reject menus: Accept/Reject and Move to Next, Accept/Reject All Changes and Stop Tracking; previously trivial: Reading Mode: the parity catalog counts Read Mode's View menu, Layout missing; previously trivial: comment times in the user's time zone, in the pane and the balloons, #2322, #2337; previously trivial: Read Mode's Page color: None, Sepia, Inverse; previously trivial: Insert › Table's grid previews the hovered table on the page, #3931; previously trivial: mail merge: First Record, Last Record and a record number box in Preview Results; Finish & Merge asks which records to merge or print, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: read only and comments-only protection grey out edits; previously trivial: the Font dialog previews "NaN" or "inf" in the Size box at 12 pt, #3663; previously trivial: File › Options disables the User name field while Restrict Editing is active; previously trivial: while editing a header or footer, a click in the other one edits it there without scrolling; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: Insert Table of Figures dialog: any caption label, #3013; previously trivial: Home › Underline drop-down shows its lines, #2738; previously trivial: the text context menu includes the formatting mini toolbar, #2959; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: the scrollbar page tip stays on one line as the page number grows, #3341; previously trivial: File › Home and New: templates and recent documents are buttons named for screen readers, #3176; previously trivial: forms protection greys out the Developer tab's control buttons and Properties; previously trivial: AltGr doesn't open KeyTips, #2388; previously trivial: closing the header or footer puts the caret back where it was in the body, #3331; previously trivial: Format Page Numbers dialog: number format and Continue from previous section / Start at, #1113; previously trivial: inline pictures drag to a dashed insertion cursor and stay inline, #2233, #2234; previously trivial: Save Changes prompt: a text file saved over itself closes, #2376; previously trivial: the equation being edited is framed as in Word: an outline as tall as its line, a grip, an options strip that opens its menu, and its current argument shaded; previously trivial: the table handles show while the caret is in the table, #2428; previously trivial: legacy menu keys, #1697; previously trivial: Shape Fill › Gradient and the Format Shape pane, #1500; previously trivial: Focus fills the screen, and Full Screen View shows the pages alone, #1678; previously trivial: the text pointer over the page is drawn black or white on Windows, #1746; previously trivial: a click in the header/footer band from the body no longer scrolls to the body text, #2103; previously trivial: File › Recover follows the app theme, #3243; previously trivial: long navigation headings wrap onto further lines within the pane, #3015; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: dragging the vertical scrollbar names the page at the top of the window, #2551; previously trivial: Add Font imports every selected font file, #1789); previously trivial (File › Close keeps the window, #1712; previously trivial: the Spike: Ctrl+F3 and Ctrl+Shift+F3; previously trivial: Ctrl+wheel zoom no longer scrolls the document, #1743; previously trivial: a mouse drag on a table leaves the view where it is, #1738; previously trivial: numbered headings, #1793; previously trivial: Navigation Find exposes Results, #2096; previously trivial: the tab strip never draws tabs over Comments / Editing / Share, #2026; previously trivial: Columns on selected text, #2024; previously trivial: Different First Page headers reachable from page 1, #2826; previously trivial: a copied equation also goes in the clipboard's MathML formats, #1297; previously trivial: Read Mode keeps the keyboard, shows whole columns and keeps text clear of the page-turn bar, #1772); previously trivial: font list entries of tall-ascent fonts sit in their row, not cut off, #2570); previously trivial: Split Cells and Convert Text to Table dialogs follow Word's merged-cell limits and Initial column width, #2592; previously trivial: a new source's Tag is made like Word's, three letters of the author and two digits of the year with a number added when taken, and an edit keeps the Tag, #2094; previously trivial: Web Layout text fills the window width, #1876; previously trivial: Language dialog keeps inherited proofing language and no-proof choices (#2717)); previously trivial: comment balloons readable in the dark theme, #2045; previously trivial: Recently Used Fonts section at the top of the font list, #2068; previously trivial: web preferences kept between visits, #2132; previously trivial: dialog close control: a Windows-style box at the title bar's right end, the whole box clickable, red on hover, #1885); previously trivial (Modify Table Style formats every table style part, #714); previously trivial: a click on the ribbon chrome hands the keyboard to the page in the same frame, #1093 follow-up; previously trivial: Page Setup vertical alignment, #1320; previously trivial: the app opens on the Home tab every launch, as in Word; previously trivial: no document behind the Start screen, #1129; previously trivial: equation pictures share a few textures, #1002; previously trivial: selection bar in the left margin, #856; 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 major: first version; ribbon, dialogs, shortcuts and on-canvas interaction measured from `crates/ui-egui` and the command registry) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-25 · **Change:** trivial (the mini toolbar marks a right-to-left paragraph's alignment as seen on the page, like the ribbon, #3579; previously trivial: Review › Accept and Reject menus: Accept/Reject and Move to Next, Accept/Reject All Changes and Stop Tracking; previously trivial: Reading Mode: the parity catalog counts Read Mode's View menu, Layout missing; previously trivial: comment times in the user's time zone, in the pane and the balloons, #2322, #2337; previously trivial: Read Mode's Page color: None, Sepia, Inverse; previously trivial: Insert › Table's grid previews the hovered table on the page, #3931; previously trivial: mail merge: First Record, Last Record and a record number box in Preview Results; Finish & Merge asks which records to merge or print, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: read only and comments-only protection grey out edits; previously trivial: the Font dialog previews "NaN" or "inf" in the Size box at 12 pt, #3663; previously trivial: File › Options disables the User name field while Restrict Editing is active; previously trivial: while editing a header or footer, a click in the other one edits it there without scrolling; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: Insert Table of Figures dialog: any caption label, #3013; previously trivial: Home › Underline drop-down shows its lines, #2738; previously trivial: the text context menu includes the formatting mini toolbar, #2959; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: the scrollbar page tip stays on one line as the page number grows, #3341; previously trivial: File › Home and New: templates and recent documents are buttons named for screen readers, #3176; previously trivial: forms protection greys out the Developer tab's control buttons and Properties; previously trivial: AltGr doesn't open KeyTips, #2388; previously trivial: closing the header or footer puts the caret back where it was in the body, #3331; previously trivial: Format Page Numbers dialog: number format and Continue from previous section / Start at, #1113; previously trivial: inline pictures drag to a dashed insertion cursor and stay inline, #2233, #2234; previously trivial: Save Changes prompt: a text file saved over itself closes, #2376; previously trivial: the equation being edited is framed as in Word: an outline as tall as its line, a grip, an options strip that opens its menu, and its current argument shaded; previously trivial: the table handles show while the caret is in the table, #2428; previously trivial: legacy menu keys, #1697; previously trivial: Shape Fill › Gradient and the Format Shape pane, #1500; previously trivial: Focus fills the screen, and Full Screen View shows the pages alone, #1678; previously trivial: the text pointer over the page is drawn black or white on Windows, #1746; previously trivial: a click in the header/footer band from the body no longer scrolls to the body text, #2103; previously trivial: File › Recover follows the app theme, #3243; previously trivial: long navigation headings wrap onto further lines within the pane, #3015; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: dragging the vertical scrollbar names the page at the top of the window, #2551; previously trivial: Add Font imports every selected font file, #1789); previously trivial (File › Close keeps the window, #1712; previously trivial: the Spike: Ctrl+F3 and Ctrl+Shift+F3; previously trivial: Ctrl+wheel zoom no longer scrolls the document, #1743; previously trivial: a mouse drag on a table leaves the view where it is, #1738; previously trivial: numbered headings, #1793; previously trivial: Navigation Find exposes Results, #2096; previously trivial: the tab strip never draws tabs over Comments / Editing / Share, #2026; previously trivial: Columns on selected text, #2024; previously trivial: Different First Page headers reachable from page 1, #2826; previously trivial: a copied equation also goes in the clipboard's MathML formats, #1297; previously trivial: Read Mode keeps the keyboard, shows whole columns and keeps text clear of the page-turn bar, #1772); previously trivial: font list entries of tall-ascent fonts sit in their row, not cut off, #2570); previously trivial: Split Cells and Convert Text to Table dialogs follow Word's merged-cell limits and Initial column width, #2592; previously trivial: a new source's Tag is made like Word's, three letters of the author and two digits of the year with a number added when taken, and an edit keeps the Tag, #2094; previously trivial: Web Layout text fills the window width, #1876; previously trivial: Language dialog keeps inherited proofing language and no-proof choices (#2717)); previously trivial: comment balloons readable in the dark theme, #2045; previously trivial: Recently Used Fonts section at the top of the font list, #2068; previously trivial: web preferences kept between visits, #2132; previously trivial: dialog close control: a Windows-style box at the title bar's right end, the whole box clickable, red on hover, #1885); previously trivial (Modify Table Style formats every table style part, #714); previously trivial: a click on the ribbon chrome hands the keyboard to the page in the same frame, #1093 follow-up; previously trivial: Page Setup vertical alignment, #1320; previously trivial: the app opens on the Home tab every launch, as in Word; previously trivial: no document behind the Start screen, #1129; previously trivial: equation pictures share a few textures, #1002; previously trivial: selection bar in the left margin, #856; 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 major: first version; ribbon, dialogs, shortcuts and on-canvas interaction measured from `crates/ui-egui` and the command registry) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 Recovery discovery no longer interrupts an explicitly created or opened document. Older copies remain in File › Recover, whose buttons use the interface palette. See [local recovery](recovery.md). @@ -83,6 +83,7 @@ Footnote and endnote editing keeps body and note text at normal opacity, on ligh | 2026-10-23 | trivial | Insert › Table: hovering the grid shows the table on the page, at the caret, as Word's Live Preview does; it follows the pointer and is laid out on a copy, so the document and Undo change only when a square is clicked (#3931) | | 2026-10-23 | trivial | Comment times: the Comments pane and the balloons show each comment's and reply's time in the user's time zone, under its author, as Word does. The file keeps UTC (`w16cex:dateUtc` when Word wrote one), a time without a zone shows as written, and the web app asks the browser for the zone (#2322, #2337) | | 2026-10-22 | trivial | Mail merge: First Record, Last Record, a record number box, and record choices for Edit Individual Documents and Print Documents (#3028) | +| 2026-10-23 | trivial | Mini toolbar: in a right-to-left paragraph the alignment buttons mark the alignment as seen on the page, as the ribbon does, so a start-aligned paragraph lights Align Right instead of Align Left; the buttons already set the alignment as seen on the page (#3579) | | 2026-10-22 | trivial | While editing a header, a single click in the footer (or the reverse, or another page's own header) edits that one with the caret where clicked; the click was placed in the header being edited, and the view scrolled back to it, so a double-click on the footer rarely landed | | 2026-10-18 | trivial | Explicit New/Open is not interrupted by startup recovery discovery; older copies stay available and Recover follows the interface theme. | | 2026-10-19 | trivial | Insert Table of Figures opens a Table of Figures dialog: caption label (Figure, Table, Equation, the user's own and those the document's captions use), Include label and number, page numbers, right margin and tab leader, with a preview; the ribbon button, KeyTip and command search reach it (#3013) |