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.
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.
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.
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>
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)
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
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.
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
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.
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.
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.
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.
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.
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.
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)
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.
Requesting and resigning focus can happen when handling pointer and
accessibility events, not just keyboard events.
---------
Co-authored-by: Olivier FAURE <couteaubleu@gmail.com>
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.
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>
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.