Text: typing goes on after Tab in a text box (#78)

The engine handled Tab (a tab character, or a list level at the start of
a paragraph), but egui also treated it as focus navigation: with no
widget focused it focused the first ribbon widget, and since the slide
only takes keys while nothing is focused, every key after Tab was lost.
When the slide has the keyboard, the keyboard handler now cancels that
focus move.

This also covers the "can't type after indenting" part of #93.

generated with Claude Code
This commit is contained in:
Alexander Alber
2026-10-11 09:26:42 +02:00
parent a98df49b21
commit 3bb284cfdd
3 changed files with 47 additions and 6 deletions
+44
View File
@@ -664,6 +664,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;
@@ -932,6 +938,44 @@ mod tests {
assert_eq!(harness.state().session.documents().len(), 2);
}
/// #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
@@ -138,11 +138,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, box &
@@ -247,5 +242,6 @@ Detail in [localization-parity.md](localization-parity.md).
| Date | Change | Summary |
|---|---|---|
| 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
@@ -48,7 +48,7 @@ AGENTS.md §2). Dimension score: **~60% ready** (estimated), **30–50 h** to pa
| Connector glue and rerouting | yes | yes |
| Edit points on freeforms | yes | **no** |
| 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 |
| Rulers with indent markers and tab stops | yes | rulers yes; tab stops partial |
| Context menus on shapes, slides, text, thumbnails | yes | yes, shorter |
@@ -87,4 +87,5 @@ imitate Microsoft's. No pixel comparison against PowerPoint screenshots has been
| Date | Change | Summary |
|---|---|---|
| 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 |