The layout pass needs to see when going over the layout, that these
properties are set. So inline the element that sets these properties if
they are not set in the base.
Fixes#8091
During the second phase, anything that involve @children should already
have been processed, so there shouldn't be anything left to inline.
But the children insertion point may be pointing to the wrong location
if some items were moved around (eg because of the `clip`).
So work it around by not accessing the children array at that indax that
might be out of range.
Fixes#7724
Only the interpreter is implemented so far
MacOs won't work yet because we don't disable the default winit menubar
The viewer don't support removing the MenuBar yet
The first inlining pass should inline any element that has children.
Row is going to be optimized out before the second inlining pass.
In that pass, we shouldn't care if there is no children while inlining
in a `@children`
Fixes#7284
SmolStr has an Arc internally for large strings. This allows
cheap copies of large strings, but we lose that ability
when we convert the SmolStr to a &str and then reconstruct a
SmolStr from that slice.
I was hoping for some larger gains here, considering the impact
of this code change, but it only removes ~50k allocations,
while the impact on the runtime is not noticeable at all.
Still, I believe this is the right thing to do.
Before:
```
allocations: 2338981
Time (mean ± σ): 988.3 ms ± 17.9 ms [User: 690.2 ms, System: 206.4 ms]
Range (min … max): 956.4 ms … 1016.3 ms 10 runs
```
After:
```
allocations: 2287723
Time (mean ± σ): 989.8 ms ± 23.2 ms [User: 699.2 ms, System: 197.6 ms]
Range (min … max): 945.3 ms … 1021.4 ms 10 runs
```
This removes a lot of allocations and speeds up the compiler step
a bit. Sadly, this patch is very invasive as it touches a lot of
files. That said, each individual hunk is pretty trivial.
For a non-trivial real-world example, the impact is significant,
we get rid of ~29% of all allocations and improve the runtime by
about 4.8% (measured until the viewer loop would start).
Before:
```
Benchmark 1: ./target/release/slint-viewer ../slint-perf/app.slint
Time (mean ± σ): 664.2 ms ± 6.7 ms [User: 589.2 ms, System: 74.0 ms]
Range (min … max): 659.0 ms … 682.4 ms 10 runs
allocations: 4886888
temporary allocations: 857508
```
After:
```
Benchmark 1: ./target/release/slint-viewer ../slint-perf/app.slint
Time (mean ± σ): 639.5 ms ± 17.8 ms [User: 556.9 ms, System: 76.2 ms]
Range (min … max): 621.4 ms … 666.5 ms 10 runs
allocations: 3544318
temporary allocations: 495685
```
We need to give unique name to optimized item as well, otherwise the
properties ends up the same.
Also fix the optimized element and timer when inlining
Fixes#5977Fixes#5976
Preparation for multi-components
Note that this had to rename one instance of TextStyle because it
conflicts with the struct of the same name used in the FontSettings
in the style. This wasn't a problem before because it shares some
property in common, and the the order of processing of component has
changed leading to the other one being generated.
(But that is a wider bug in the compiler outside of the scope of this
refactoring)
ammend previous commit to fix building the examples
When inlining things inside a Popup, we must process the popups first.
But in order to inline the popup inside another component, we must
process the popups last.
This makes the code a bit more complicated
This regressed in commit 12d904a71c
which changed the order of the pass to get the lower_popup pass before
the first inlining pass.
If by chance (which is likely if one have children), the component that
inherits from PopupWindow was inlined in that pass, it would be as
if it was not a component, and it would be removed from its parent.
But since it is no longer inlined, we need to support that case and
delay the removal when processing the component that holds that popup.
The problem was that the code from #4322 inlined the init code in the
parent Component as at that point, the per-repeater component don't
exist yet.
Fix it by removing the workaround from #4322, but changing the order of
the passes so that the init code are already proccessed before any
inlining. This required to change the order of a bunch of passes.
Fixes#5146
As a drive-by, also add the missing C++ implementation of set_animated_value
for Brush that was discovered by the test. (Code wouldn't compile)
Updated the version from 1.1 to 1.2
Renamed the header to "Slint Royalty-free Desktop, Mobile, and Web Applications License"
Added definition of "Mobile Application" and grant of right
Moved "Limitations" to 3rd section and "License Conditions - Attributions" to 2nd section
Added flexibility to choose between showing "MadeWithSlint" as a dialog/splash screen or on a public webpage
Moved the para on copyright notices to section under "Limitations"
* Don't require inlining if an animated property is private and local
This avoids inlining Button elements from our widget set.
This is covered by tests/cases/properties/animation_merging.slint
Achieve this by generating a `focus()` function for such components
and call it from the outside.
This replaces the previous focus handling with what should be cleaner:
- Any `forward-focus: some-element;` is basically syntactic sugar for
`public function focus() { some-element.focus(); }`.
- The init code gets simplified to calling focus() on the root, if it's
available.
Since the `focus()` functions are now generated in the imports pass,
they become visible in the style checker. That means the checker
requires consistent focus handling between the styles.
When a component declares an init callback as well as the element that
instantiates it, the init callback of the container would not
get invoked if the container was inlined:
```
component InlinedContainer {
init => { ... } // not invoked
@children // force inlining
}
component UseSite {
InlinedContainer {
init => { ... }
}
}
```
That's because the inlining happens very early, before the init
callbacks are collected into the init code. And during inlining that
would be treated like a property binding and the "binding" at the
element site overrides the one at the component site.
One natural approach would be to move the init code collection to an
earlier place before inlining, but that isn't possible because the
boundaries of the compiler components (Rc<Component>) aren't set
up yet (repeated component extraction phase happens much later).
An alternative would be to re-introduce the init callback code in
ElementRc and place it in there at *::from_node() time.
This patch chooses to solve this at the inlining time: When we're in the
first phase of the inlining (the optional one), do what
with the init binding what collect_init_code would do later: Move it
straight into the init_code of the component we're inlining into.
Fixes#4317
... so that we have one that controls the embedding operation and one
that we can turn into a dynamic tree node where the actual embedding
happens.
Mark the placeholder Element as `is_component_placeholder` and make sure to not
optimize out that object in a later pass.
Adapt Element creation to account for the new
`is_component_placeholder`.