Commit Graph

70 Commits

Author SHA1 Message Date
Olivier FAURE 9ffc650983
Remove `Box<dyn Widget>` from a few places (#837)
Having `Box<dyn Widget>` implement the `Widget` trait is a crutch that
makes a bunch of things more complicated.

It leads to double-boxing in cases when the `dyn Widget` is itself a
`Box<dyn Widget>` (especially since the arena's current implementation
boxes all widgets by default), makes it harder to reason about
downcasting, and ends up producing a lot of code to handle the edge
cases.

On the xilem side, `Box<dyn Widget>` is slightly redundant with
`DynWidget`.

This PR still leaves a lot of boxing. On the long term, we'd like for
the arena to pack arbitrary widgets efficiently using some kind of
archetype scheme, but in the meantime, boxing will have to do.

Changes in this PR:
- New `FromDynWidget` trait that maybe-downcasts widgets to a
maybe-sized `Widget` type.
- Most places that accept `Widget` now accept `Widget + ?Sized`.
- Remove `impl Widget for Box<dyn Widget>`.
- Replace all instances of `WidgetPod<Box<dyn Widget>>` with
`WidgetPod<dyn Widget>`.
- Replace all instances of `xilem::Pod<Box<dyn Widget>>` with
`xilem::Pod<dyn Widget>`.
- Rename WidgetPod to WidgetBox in xilem_core example to avoid
ambiguity.
2025-01-20 12:52:08 +00:00
Olivier FAURE eb63bf6b09
Improve handling of window focus (#830)
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
2025-01-16 14:39:45 +00:00
Olivier FAURE e7ed917ca8
Implement very basic widget inspector (#820) 2025-01-15 17:10:20 +00:00
Daniel McNab 2e92e89ba1
Document the IME cursor area workaround (#826) 2025-01-15 11:31:12 +00:00
Olivier FAURE 4cf365334f
Document RenderRoot fields (#824)
Remove duplicate CursorIcon field.
2025-01-14 17:51:02 +00:00
Olivier FAURE d49b06a8e2
Make pointer events affect focus (#822)
Clear the focus when user clicks outside of the focused widget
Add `most_recently_clicked_widget` value, so that clicking influences
which widget will be focused by future Tab events.
2025-01-14 17:10:26 +00:00
Olivier FAURE 51a355615f
Document most items in Masonry (#815)
Move `#[allow(missing_docs)]` to two modules. Missing docs now warn
everywhere else by default.

Remove `#[expect(rustdoc::broken_intra_doc_links)]` and fix all broken
links.
2025-01-13 17:36:31 +00:00
Olivier FAURE 522dfd4433
Add links to documentation in pass code (#811) 2025-01-13 10:49:29 +00:00
Olivier FAURE 5ed3178789
Remove last references to debug logger (#814)
Code has been unused for a long time.
Widgets weren't even logging to it.
2025-01-13 10:48:37 +00:00
Olivier FAURE be9fc8730b
Rename `WidgetArena::widget_states` to `WidgetArena::states` (#816) 2025-01-13 10:48:23 +00:00
Olivier FAURE c1e0c83b0b
Have AppDriver take a reference to RenderRoot for more flexibility (#808) 2025-01-10 14:16:37 +00:00
Bruce Mitchener ee4411467c
Fix and un-allow `clippy::use_self` lints (#799) 2024-12-19 13:45:57 +00:00
Tom Churchman 806946bb2a
Improve IME area reporting and set IME area in `TextArea` (#785)
This adds the required context methods for (re)setting the IME area.
These are added to the mutable context types, which I believe is the
right place.

`TextArea` now uses `PlainEditor::ime_cursor_area` to report its IME
area.

Note Masonry currently reports new IME cursor areas only when the widget
itself moves or the focus changes to a new widget, but Parley's
`PlainEditor` determines the IME cursor area based on the selection and
preedit state of the editor, meaning the area can change based on events
as well. Other widgets may choose to have different behavior still.

(It appears Masonry currently doesn't account for the IME area
potentially changing based on relayout, which may be a bug.)

This replaces the old IME area reporting with a check at the end of the
rewrite pass to see if IME is active, and if it is, whether the IME area
has moved. If it has, the new area is reported to the platform.

---------

Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
2024-12-11 16:21:18 +00:00
Kirpal Grewal a1d47a06bb
Tree arena (#752)
I've had a try at implementing the unsafe `tree_arena` in a separate lib
(but in the same workspace for now) - haven't thought of a good way to
make non root access not O(depth), without slowing down insertion or
using more memory, though have improved accessing nodes from the root to
O(1) from O(depth) and accessing direct children to O(1) from
O(children)
2024-12-05 10:18:52 +00:00
Daniel McNab 10dc9d171c
Update to Vello 0.3.0, Parley main, AccessKit 0.17 (#616)
The biggest remaining issue in this PR is that IME support is not
present.

However, I think landing this is *better* than not landing it, because:
1) If we don't land it, it's going to languish again
2) Getting IME support back can be parallelised (cc @tomcur)
3) Getting Vello 0.3.0 and Parley 0.2.0 unlocks real advantages,
including full emoji support (#420).

To be clear, my first follow-up priority will be connecting the IME back
up. I do not however think this should block on Parley 0.3.0.

Discussion in
https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Updating.20Parley.20dependency
2024-11-18 17:25:02 +00:00
Marco Melorio 6db696d268
Add basic window control (#670)
This is the first merge-able part of #606.

It allows to implement custom CSDs via window management signals and a
new `WindowHandle` widget which is useful to implement a custom
titlebar.
2024-11-11 09:36:20 +00:00
Olivier FAURE 8342c7ec12
Streamline giving ids to TreeArena methods (#709) 2024-10-21 14:24:18 +00:00
Daniel McNab 03245d0080
Refactor tracing handling for events (#688)
Inspired by #687, I thought some more tidying up of the log file was in
order.

The main differences are:
1) Higher-scale spans exist for key operations
2) Something is always logged for each event, but less for high-density
eventskey
3) Less is logged for high-density events
4) Key repeats are no longer treated as high density
5) We no longer do extra work if the hover and focus paths haven't
changed (which also means less logging)

This PR *does not* depend on #687
2024-10-21 13:11:24 +00:00
Daniel McNab 38415d65ca
Don't use full tracing spans in full-tree passes by default (#687)
This can be toggled using the `MASONRY_TRACE_PASSES` environment
variable.

This is as-discussed in [#xilem > Scrolling is insanely
laggy](https://xi.zulipchat.com/#narrow/channel/354396-xilem/topic/Scrolling.20is.20insanely.20laggy).
There are a few overlapping issues, but this *significantly* improves
performance in debug mode.

The main pass which was problematic was the compose pass, however this
also had a significant impact on the time taken by the
accessibility/paint passes.

This only applies to the passes which traverse the entire tree, so not
the targeted passes. I also chose to exclude update_disabled and
update_stashed, as those will not necessarily happen to all widgets.

This also significantly reduces the size of the created log files - see
[#masonry > Heavy amounts of logs with large
app](https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Heavy.20amounts.20of.20logs.20with.20large.20app).
In most cases, if you're using the log file, you will be in development,
which means that you can hopefully recreate the issue with the logging
for the passes you need enabled.
2024-10-21 09:51:34 +00:00
Olivier FAURE f403337219
Implement fixpoint loop in run_rewrite_passes (#696)
This implements the last feature from the Pass Specification RFC 🎉
2024-10-20 17:12:18 +00:00
Olivier FAURE d5f28ba2de
Refactor away some redundant methods in RenderRoot (#694) 2024-10-20 16:01:56 +00:00
Olivier FAURE 3d8c7950e4
Reorder imports across project (#690)
Split off from #637.
2024-10-20 14:54:13 +00:00
Olivier FAURE ef5d9afec3
Rename `RenderRoot::state` to `global_state` (#691) 2024-10-20 14:46:46 +00:00
Olivier FAURE cdda9b542d
Only send ImeMoved signal for focused text input (#684) 2024-10-17 12:06:28 +00:00
Olivier FAURE 3ba0df6064
Reorder update passes (#674)
Reorder update passes so their code is in the same order as they're run.
Split out anim pass to a separate file (since it's not run with the
other passes).
This is strictly cut-and-paste, no code has been changed.
2024-10-16 16:44:30 +00:00
Olivier FAURE 17f5f24ff3
Remove debug_validate method (#676)
I'm pretty sure this method never caught a single bug.

I think the idea of a "safety net" that checks invariants are upheld by
passes (without trusting pass code) has merit, but it should be based on
a survey of previous bugs in pass code.
2024-10-16 15:21:14 +00:00
Olivier FAURE 1258a258cd
Rename pass functions from root_xxx to run_xxx_pass (#675)
This means all the pass functions now have the same naming convention,
which makes the code more grep-able.
2024-10-16 13:53:39 +00:00
Olivier FAURE a26bf11119
Add target field to EventCtx (#657)
Remove target field from AccessEvent
2024-10-13 01:21:52 +00:00
Olivier FAURE 76c808b454
Refactor rewrite passes (#639)
Create run_rewrite_passes function.
Remove redundant uses of synthetic WidgetState.
Small bugfixes.
Move RenderRoot::root_layout code into the layout pass. Rename
update_new_widgets pass to update_widget_tree.
2024-10-12 14:37:49 +00:00
Olivier FAURE 9899a700c7
Add needs_rewrite_passes and content_changed methods (#658)
These methods will be used with #639 to implement a fixpoint loop for
rewrite passes.

This also lets us remove `mark_changed`, since we can use
`content_changed` for the same purpose.
2024-10-12 13:33:55 +00:00
Olivier FAURE da92ba6cf0
Add TestHarness::animate_ms method (#661) 2024-10-09 14:01:28 +00:00
Olivier FAURE e9efc8cb18
Add RenderRoot::request_render_all method (#659)
Add a method which brute-force resets the paint and accessibility flags
for all widgets.
This is useful for rescale, and for testing purposes where you want a
quick and dirty way to repaint everything.
2024-10-09 09:59:44 +00:00
Olivier FAURE 1d3df8c493
Remove or split up some cruft comments (#662) 2024-10-09 09:33:57 +00:00
Olivier FAURE 801affd01e
Send synthetic PointerLeave event when pointer capture is lost (#647) 2024-10-09 09:31:48 +00:00
Tom Churchman 653874e103
masonry: reimplement `Widget::get_child_at_pos` (#565)
The `Widget::get_child_at_pos` has a default linear search
implementation, upholding some conditions (e.g., picking the last child
in "z-order" in case of overlap). Widgets can override this with a
custom implementation (e.g., a widget with many children that maintains
a quadtree to search through). Custom implementations should uphold the
same conditions, we can add some debug assertions to check this in a
later PR.

This introduces a `QueryCtx`, allowing widget methods access to the
global state, widget state, and widget subtree. `QueryCtx` is similar to
the other (mutable) context types, but can be shared.

This also changes `WidgetRef` to consist of a `Widget` and a `QueryCtx`,
similar to `WidgetMut` consisting of a `Widget` and `MutateCtx`. This
required changing where `WidgetRef` can be constructed.

This resolves code comment
ac95f2524a/masonry/src/widget/widget_ref.rs (L192-L199)
2024-09-26 14:37:05 +00:00
Olivier FAURE fa4eff5648
Add emit_signal method (#611)
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
2024-09-24 17:34:43 +00:00
Olivier FAURE ecc94684d5
Clean up IME handling code (#599)
Should fix the way repaints were requested every paint on some
platforms.

This PR unfortunately comes with a lack of tests. TestHarness currently
doesn't have good support for testing signals, but even if it did, this
is an inherently visual feature that we don't really have a way to test
visually.

I don't know how to trigger IME on my machine. (I'm using PopOS, a
Debian variant.) If someone wants to either test this or help me get to
speed, I'd appreciate it.
2024-09-23 17:14:45 +00:00
Matt Campbell 37af4b985f
Run the focus pass in post-processing for all events (#604)
Requesting and resigning focus can happen when handling pointer and
accessibility events, not just keyboard events.

---------

Co-authored-by: Olivier FAURE <couteaubleu@gmail.com>
2024-09-23 10:56:40 +00:00
Olivier FAURE 07dab9b73c
Implement stashed state (#601)
Add update_stashed pass
Add is_still_interactive method
2024-09-23 08:49:28 +00:00
Olivier FAURE 2642a9e146
Replace RouteWidgetAdded event with new register_children method (#602)
Make lifecycle method optional.
Remove InternalLifecycle.
2024-09-23 08:25:32 +00:00
Daniel McNab 0d56c592f5
Add the `lens` component (#587)
See
https://xi.zulipchat.com/#narrow/stream/354396-xilem/topic/Lens.20View

Usage:
```rust
fn app_logic(state: &mut FlightPlanner) -> impl WidgetView<FlightPlanner> {
    lens(date_picker, state, |state| &mut state.date)
}

struct FlightPlanner {
    date: Date,
    available_flights: Vec<Flight>,
}
```

Also extends the docs features in Xilem Core, and increases the
complexity threshold

---------

Co-authored-by: Kaur Kuut <strom@nevermore.ee>
Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
2024-09-18 08:10:50 +00:00
Olivier FAURE 7679e7c75e
Fix tab focus when no widget is currently focused (#593) 2024-09-17 08:52:59 +00:00
Olivier FAURE 09d9ad555d
Make `Textbox` focusable and trigger redraw in response to `request_layout` (#537)
Fixes #301.
2024-09-16 15:31:37 +00:00
Olivier FAURE 01cca4610c
Add temporary passes and remove most of lifecycle method (#589)
Add update_focus_chain pass.
Add update_new_widgets pass.
Remove RenderRoot::root_lifecycle.
Move call_widget_method_with_checks out of Widgetpod.

These new passes aren't intended to stay long-term, but are meant to
make future refactors easier and more concise.
The other goal is to remove almost all the remaining code in the
lifecycle method.
2024-09-16 12:30:41 +00:00
Olivier FAURE 4746766d89
Implement update_focus pass (#538)
Make Textbox Widget tab-focusable.

This is part of the Pass Specification RFC:
https://github.com/linebender/rfcs/pull/7
2024-09-12 11:29:21 +00:00
Olivier FAURE 2fa8a055bd
Implement update_anim pass (#539)
This is part of the Pass Specification RFC:
https://github.com/linebender/rfcs/pull/7

---------

Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
2024-09-12 11:06:33 +00:00
Olivier FAURE dcea01a4a9
Migrate layout pass (#529) 2024-09-09 12:35:36 +00:00
Olivier FAURE 2ae73268a8
Implement update_scrolls pass (#550)
This is part of the Pass Specification RFC:
https://github.com/linebender/rfcs/pull/7

Note: This PRs comes with a lot of new TODO items. Addressing most of
these items is difficult without major refactors, because Portal code
deals with accessing values across multiple widgets, which is still hard
to do elegantly.
2024-09-09 11:28:32 +00:00
Olivier FAURE 4cddfc5157
Implement update_disabled pass (#540) 2024-08-25 13:23:38 +00:00
Olivier FAURE ff7635e4c2
Implement paint and accessibility passes (#522)
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
2024-08-23 08:47:02 +00:00