Find: "Find what:" has the keyboard when the dialog opens (#951)

Ctrl+F and typing searches without clicking the field first, and the field
keeps the keyboard after Enter finds a match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Zetenypapp
2026-10-18 18:00:41 +02:00
co-authored by Claude Opus 5.5
parent 868016ee2f
commit 172952f6e0
4 changed files with 58 additions and 1 deletions
+1
View File
@@ -131,6 +131,7 @@ app's JSON control channel (`deckcraft --control PORT`).
| Date | What landed |
|---|---|
| 2026-10-18 | Find (Ctrl+F): "Find what:" has the keyboard as soon as the dialog opens, and keeps it after Enter finds a match, so the search can be typed and changed without clicking the field (#951) |
| 2026-10-17 | Opening a file caps absurd effect sizes (glow, soft edges, shadows, reflections, on shapes, text and table text) at what Format Shape allows: a glow of 10^18 pt in a .pptx made rendering ask for 34 GB and abort |
| 2026-10-17 | Opening a .deckcraft file whose shapes repeat an id gives the repeats fresh ids (groups, layouts and masters too), so the deck validates and edits by id find one shape |
| 2026-10-17 | Edit Points: turning a shape into a freeform is one undo step, so Undo brings the original shape back (it used to stay a freeform) |
+12 -1
View File
@@ -3196,7 +3196,18 @@ fn tabs_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool {
/// Home › Find / Replace: step through matches (slide text, table cells, notes) or replace them.
fn find_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool {
let replace_mode = d.get("replace", "0") == "1";
field(ui, d, "Find what:", "text", "");
// "Find what:" has the keyboard when the dialog opens, so Ctrl+F and typing finds (#951).
let mut what = d.get("text", "");
ui.horizontal(|ui| {
ui.add_sized(vec2(120.0, 20.0), egui::Label::new("Find what:"));
let r = ui.add(egui::TextEdit::singleline(&mut what).desired_width(180.0));
// Enter finds the next match and leaves the keyboard here, so the search can be changed.
if !d.fields.contains_key("focused") || (r.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter))) {
r.request_focus();
d.fields.insert("focused".into(), "1".into());
}
});
d.fields.insert("text".into(), what);
if replace_mode {
field(ui, d, "Replace with:", "with", "");
}
+43
View File
@@ -0,0 +1,43 @@
//! Home › Find (Ctrl+F): "Find what:" has the keyboard as soon as the dialog opens (#951).
use deckcraft_engine::Session;
use egui_kittest::Harness;
use serde_json::json;
use crate::{Services, SlideApp};
#[test]
fn ctrl_f_puts_the_caret_in_find_what() {
let mut s = Session::with_new();
s.execute("slide.new", &json!({"layout": "blank"})).unwrap();
s.execute("insert.textBox", &json!({"rect": [40, 40, 400, 80], "text": "Hello there"})).unwrap();
s.execute("text.exit", &json!({})).unwrap();
s.doc_mut().unwrap().selection.shapes.clear();
let app = SlideApp::new(s, Services::default());
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).with_step_dt(1.0 / 60.0).build_ui_state(
|ui, app: &mut SlideApp| {
app.logic(ui.ctx());
app.ui(ui);
},
app,
);
h.run_steps(3);
h.key_press_modifiers(egui::Modifiers::COMMAND, egui::Key::F);
h.run_steps(3);
assert_eq!(h.state().dialog.as_ref().map(|d| d.id.as_str()), Some("find"));
// Typing right away goes into the field, without clicking it first.
h.event(egui::Event::Text("there".into()));
h.run_steps(3);
let typed = h.state().dialog.as_ref().and_then(|d| d.fields.get("text").cloned());
assert_eq!(typed.as_deref(), Some("there"));
// Enter finds it.
h.key_press(egui::Key::Enter);
h.run_steps(3);
let status = h.state().dialog.as_ref().and_then(|d| d.fields.get("status").cloned());
assert!(status.as_deref().is_some_and(|m| m.starts_with("Match 1 of 1")), "Enter didn't find the text: {status:?}");
// The keyboard stays in the field afterwards: more typing adds to it.
h.event(egui::Event::Text("!".into()));
h.run_steps(3);
let typed = h.state().dialog.as_ref().and_then(|d| d.fields.get("text").cloned());
assert_eq!(typed.as_deref(), Some("there!"));
}
+2
View File
@@ -2052,6 +2052,8 @@ mod compare_tests;
#[cfg(test)]
mod eyedropper_tests;
#[cfg(test)]
mod find_dialog_tests;
#[cfg(test)]
mod huge_deck_tests;
#[cfg(test)]
mod ime_tests;