Ask for the collection's name where the keyboard can reach it

"New collection from selection" created the collection under a placeholder
name and then opened the rename field in the sidebar tree.

On a tablet the sidebar is not on screen. It is instantiated all the same —
app.slint collapses it to zero width and `visible: false` rather than using an
`if`, because an `if` there is a layout loop Slint panics on — so the rename
field was created, its `init` took focus, and Android raised the on-screen
keyboard over a box nobody could see. Nothing else on the screen is focusable,
so the keyboard had nowhere to go: it stayed, the name could not be typed, and
the collection was already written under the name the user did not want.

Asked in a sheet instead, on the same card as the filing and keywording sheets,
before anything is written. That also fixes what was hiding behind it: an
abandoned rename used to leave a "New collection" in the tree, because the
collection existed before the name did.

`Field` gains `take-focus()` so a sheet whose field is the only thing to do in
it can answer the keyboard for the user — a function rather than a property,
because focus is an event and a bound property would re-take it on every
unrelated re-evaluation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 23:17:40 +02:00
co-authored by Claude Opus 5
parent 91fe6cf300
commit d1f3b97245
5 changed files with 188 additions and 30 deletions
+16
View File
@@ -617,6 +617,22 @@ export component Field inherits Rectangle {
/// because the breakage is in Slint's binding model, not the styling.
callback edited(string);
/// Take the keyboard, and select what is already there.
///
/// For a sheet whose field is the only thing to do in it: the field arrives
/// with the sheet, nothing else on the card can sensibly hold focus, and
/// asking the user to tap a box that is the only box is a step with no
/// decision in it. On a tablet it is also what raises the on-screen
/// keyboard, which is the actual point.
///
/// A function rather than a property, because focus is an event and not a
/// state: bound to a property it would fight anything else that took focus
/// afterwards, and re-take it on every unrelated re-evaluation.
public function take-focus() {
input.focus();
input.select-all();
}
height: Theme.touch-target;
border-radius: Theme.radius;
border-width: 1px;