Merge PR #139 from alexanderalber: Text: typing goes on after Tab in a text box (#78)

# Conflicts:
#	crates/ui-egui/src/lib.rs
This commit is contained in:
Brandon Thomas
2026-10-14 15:08:45 -04:00
3 changed files with 47 additions and 6 deletions
+44
View File
@@ -1098,6 +1098,12 @@ impl SlideApp {
}
}
egui::Event::Key { key, pressed: true, modifiers, .. } => {
if key == egui::Key::Tab {
// The slide has the keyboard, so Tab is ours (indent, tab character, next
// shape). Left to egui it would also focus the first ribbon widget, and
// every key after it would go there instead of the slide (#78).
ctx.memory_mut(|m| m.move_focus(egui::FocusDirection::None));
}
let mods = Mods { shift: modifiers.shift, alt: modifiers.alt, cmd: modifiers.command || modifiers.ctrl };
if !self.session.tool.drawing_freeform() && menus::ui_shortcut(self, key, mods) {
continue;
@@ -1647,6 +1653,44 @@ mod tests {
assert_eq!(pictures(harness.state()), 1);
}
/// #78: after Tab in a text box, typing and deleting no longer reached the text.
#[test]
fn typing_goes_on_after_tab_in_a_text_box() {
let mut harness = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|ui, app: &mut SlideApp| {
app.logic(ui.ctx());
app.ui(ui);
},
SlideApp::new(Session::with_new(), Services::default()),
);
harness.run_steps(2);
let title = harness.state().session.active().unwrap().doc.slides[0].shapes[0].id.0;
harness.state_mut().session.execute("text.edit", &json!({"id": title})).unwrap();
harness.event(egui::Event::Text("ab".into()));
harness.run_steps(2);
harness.key_press(egui::Key::Tab);
harness.run_steps(2);
harness.event(egui::Event::Text("c".into()));
harness.run_steps(2);
assert_eq!(title_text(harness.state()), "ab\tc");
harness.key_press(egui::Key::Backspace);
harness.run_steps(2);
assert_eq!(title_text(harness.state()), "ab\t");
assert!(harness.state().session.active().unwrap().selection.text.is_some(), "still editing");
// Tab at the start of a paragraph indents it, and typing goes on there too (#93).
harness.key_press(egui::Key::Enter);
harness.run_steps(2);
harness.key_press(egui::Key::Tab);
harness.run_steps(2);
harness.event(egui::Event::Text("d".into()));
harness.run_steps(2);
assert_eq!(title_text(harness.state()), "ab\t\nd");
let level = |h: &egui_kittest::Harness<SlideApp>| {
h.state().session.active().unwrap().doc.slides[0].shapes[0].text.as_ref().unwrap().paragraphs[1].level
};
assert_eq!(level(&harness), 1);
}
#[test]
fn home_needs_an_open_presentation() {
let mut app = SlideApp::new(Session::new(), Services::default());
+1 -5
View File
@@ -213,11 +213,6 @@ Detail in [file-format-parity.md](file-format-parity.md).
- **Impact:** copy-paste of screenshots is a core workflow.
- **Estimate:** 2–4 h. **Beta blocker.**
### Tab inside a text box ends text entry (#78)
- **Evidence:** #78.
- **Impact:** tab stops and indented lists can't be typed.
- **Estimate:** 1–2 h.
### Charts: data grid, elements and the newer chart types
- **Evidence:** checklist rows "Edit chart data" (P0, partial), "Chart elements" (partial), "Other
chart types" (partial); `chartex` parts (waterfall, funnel, treemap, sunburst, histogram, Pareto,
@@ -471,5 +466,6 @@ Detail in [localization-parity.md](localization-parity.md).
| 2026-10-12 | minor | IME composition in slide text and notes, and CJK interface text with real glyphs (#101): the IME gap is now Korean on the web and table-cell underlines |
| 2026-10-12 | minor | EMF/WMF text, pattern and hatch brushes drawn; legacy OLE and ActiveX previews shown; the SVG gap keeps only EMF clip regions |
| 2026-10-12 | minor | Text warps render (all 40 presets, adjusts round-trip); the warp gap is now the gallery, command and handles |
| 2026-10-11 | minor | Removed "Tab inside a text box ends text entry" (#78, fixed) |
| 2026-10-10 | minor | Noted that no gap blocks alpha (core-workflow gate passes) |
| 2026-10-10 | major | Created: every gap from the 2026-10-10 re-measure and the 16 open GitHub issues, ranked, with beta blockers marked |
+2 -1
View File
@@ -122,7 +122,7 @@ menu colours taken from the theme tokens (menu `chrome`, page `card`).
| Connector glue and rerouting | yes | yes |
| Edit points on freeforms | yes | partial: Edit Shape ▸ Edit Points turns any shape into a freeform; drag vertices and their Bézier handles, Ctrl/Cmd-click to add or delete, right-click for Smooth/Straight/Corner Point and Delete Point; no Straight/Curved Segment or Open/Close Path yet |
| Crop handles, crop to shape, aspect ratio | yes | partial |
| Text caret, selection, double/triple click, drag-select | yes | yes; Tab in text boxes ends editing (#78) |
| Text caret, selection, double/triple click, drag-select | yes | yes |
| Exact size/position, lock aspect | yes | yes — Size and Position dialog (height, width, rotation, scale %, lock aspect, position from the top-left), one undo step; ribbon spinners still resize one side at a time |
| Rulers with indent markers and tab stops | yes | rulers yes; tab stops partial |
| Context menus on shapes, slides, text, thumbnails | yes | yes, shorter; a right click selects the shape under the pointer first |
@@ -224,4 +224,5 @@ on the slide as shapes. No pixel comparison against PowerPoint screenshots has b
| 2026-10-12 | minor | Off-slide objects drawn and editable around the slide in Normal view (#270) |
| 2026-10-12 | minor | Selection Pane matched to PowerPoint (#133): drag and drop, arrows, groups, eye, Lock |
| 2026-10-12 | minor | Text editing keys: Ctrl+arrows, Ctrl+Backspace/Delete, Ctrl+Up/Down, Home/End on wrapped lines, Shift+F3, font size keys, as observed in PowerPoint for Windows (#268) |
| 2026-10-11 | minor | Tab in text boxes keeps editing (#78) |
| 2026-10-10 | major | Created: shell, panes and dialogs, direct manipulation, shortcuts and visual fidelity against PowerPoint 16.113 |