A text field keeps the cursor where an edit left it unless it asks to be pinned to the end, which only the time picker does, and a hook for a window that loses the keyboard
A field built with `select_on_focus( true )` kept its cursor at the end of the value after every insertion and deletion. That was meant for the time picker, whose `on_change` normalises what was typed, "2" becoming "02", so that a cursor placed at the end of the typed text would land in the middle of the normalised one. But the flag was also the only way to have a field select its whole value on focus, so every field that wanted that got the pinning too, and in an address bar it is a defect: tapping inside the address to correct a word, the cursor was placed where the finger was, and the first character typed sent it to the end, so the rest of the edit went to the wrong place. The two behaviours are now separate. `select_on_focus` only selects the value when the field takes the focus. The new `TextEdit::pin_cursor_to_end( bool )`, `false` by default, keeps the cursor at the end of the displayed value through the `usize::MAX` sentinel, as before, for fields whose `on_change` rewrites the value. It reaches the runtime in a new `pin_cursor_to_end` field of `WidgetHandlers::TextEdit`, set where the snapshot is built in `Element` and copied in its `Clone`, and the four places in `insert_delete.rs` that anchored the cursor, for an insertion, a delete forward, the deletion of a selection and the move after a replacement, read it instead of `select_on_focus`. The time picker's value fields ask for it, so they behave as they did. A field that uses `select_on_focus` only to select on focus now edits with an ordinary cursor. The one other user known is a dialog in `crate`, which gets the ordinary behaviour; if its `on_change` normalises the text it has to ask for `pin_cursor_to_end( true )` as the time picker does. Documentation of the previous commit and of what building crate showed. `docs/widgets.md` says that a `pressable` loses the tap and the right click to an interactive widget inside it even when that widget has no handler, as a `list_item` without `on_press`, so its content should be built from pieces that take no input; and that the hint of `Button::tooltip` is an xdg-popup beside the button in a window, placed by the compositor and taking no grab, and an overlay spanning the output on a layer surface. `docs/theming.md` gains "Application icons": a desktop entry can point at an installed theme icon, the Figma glass effects resvg does not reproduce, a `backdrop-filter` in a `<foreignObject>` ignored and `plus-lighter` rewritten to `screen` by `decode_svg_bytes`, and the advice to flatten them; the table row of `decode_svg_bytes` mentions the rewrite and that its pixels come back premultiplied. `docs/cookbook.md` says that requesting the focus for the text field that already has it puts the cursor at the end of its value without a second `on_focus`, which is how an application moves the cursor after replacing the value, and that Tab and the vertical arrows reach `App::on_key_with_modifiers` before the field, while Escape reaches it after ltk has closed any transient UI and taken the focus off the field. Losing the keyboard. An application that repeats keys on its own timer, as prompt does for its terminal, never heard that the window lost the keyboard, so a key held while the focus went elsewhere kept repeating until the next key, since its release went to the other window. The new `App::on_keyboard_leave()`, a no-op by default, is called from the keyboard's `leave`, right after ltk stops its own repeat, for the application to stop its repeat and forget the modifiers it kept. Documentation of the previous commit's hooks and widgets. `docs/architecture.md` lists `on_mouse_button` with `MouseButtonEvent` and `MouseButton`, `on_modifiers` and `on_keyboard_leave` among the input hooks. `docs/widgets.md` describes `ListItem::ink( label, secondary )`, which draws a row's label, subtitle, trailing text and hover and press tints in colours of its own for a surface the theme does not know about, and says that `icon_button` keeps a bitmap's proportions, fitting one that is not square into its size and centring it rather than stretching it. Not done. There is no test for the new flag, as `select_on_focus` has one in `text_edit/tests.rs` for its builder and its propagation to the handler, and the documentation of the widget does not mention it.
This commit is contained in:
@@ -82,6 +82,7 @@ icon_button( rgba_bytes, w, h ).on_press( Msg::OpenSearch )
|
||||
count; pass `Length::widget( n )` instead to follow the widget-scaling
|
||||
mode, which is what stock icons (the [`list_item`](#list_item) disclosure
|
||||
arrow) already do — use it when the two sit side by side and should match.
|
||||
The bitmap keeps its proportions: one that is not square is scaled to fit that size and centred in it, never stretched.
|
||||
|
||||
Give it a `width( … )` or `height( … )` and it becomes a framed key: it
|
||||
claims that size, paints the background and border of its `variant` like
|
||||
@@ -132,6 +133,8 @@ pressable(
|
||||
# }
|
||||
```
|
||||
|
||||
A tap and a long press go to the deepest interactive widget under them, and a widget is interactive even without a handler: a `list_item` with no `on_press` inside a `pressable` takes the tap and the right click and does nothing with them, so the pressable never fires. Build the content from pieces that take no input (`container`, `row`, `column`, `text`, `img_widget`); keep an inner `button` only when it should win over the pressable, as a row's own trailing action does.
|
||||
|
||||
**See also**: [`button`](#button) when a plain text button is enough,
|
||||
[`list_item`](#list_item) for the standard "label + subtitle + trailing"
|
||||
pattern.
|
||||
@@ -198,6 +201,7 @@ When both are set the text sits to the left of the icon.
|
||||
`pad_h( px )` overrides the horizontal inset between the row edge and
|
||||
its content (theme default 16 px) — lower it when the enclosing view's
|
||||
own padding already provides the margin.
|
||||
`ink( label, secondary )` draws the label in `label`, the subtitle and trailing text in `secondary`, and tints hover and press with `label`, instead of the theme's colours, for a row laid on a surface the theme does not know about, such as a menu drawn in an app's own colours.
|
||||
|
||||
`height( len )` overrides the theme row height (56 design px, 68 with a subtitle) and `font_size( len )` the primary-label size (16 design px; subtitle and trailing keep their theme sizes), both `impl Into<Length>`. Use them together where a dense list — a context menu, a compact picker — should trade the touch-target generosity of a settings list for row density; the resolved height is floored at the label's rendered height so the text never clips however aggressive the override.
|
||||
|
||||
@@ -797,6 +801,8 @@ The overlay anchors below the widget built with the matching
|
||||
`.id( WidgetId )`. See [`docs/cookbook.md`](./cookbook.md) for the full
|
||||
overlay wiring.
|
||||
|
||||
The hint `Button::tooltip` shows by itself is placed by the runtime. When the main surface is an xdg-shell window it is an xdg-popup child of the window, anchored to the button's rect: the compositor puts it above the button, 6 logical pixels away, flips it below or slides it sideways when it does not fit, and it takes no grab and no input, so the pointer stays with the button. A window does not know where it sits on screen, so this is the only way the hint lands beside the button. On a layer-shell surface (a shell, a panel) the hint is an overlay spanning the output, placed above the button or below it near the top edge.
|
||||
|
||||
**See also**: [`toast`](#toast) for transient self-dismissing
|
||||
notifications.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user