Simplify style selection, now that we are "always up": All we need to do
is change the style when the configuration changes. That is a part
of the initial state request we send when the preview starts up, so we set
the style properly and then we do not need to do anything anymore till
somebody configures a new style.
Start the live preview in a separate process. This simplifies
a couple of things:
* Starting the UI
* UI state handling
* Threading setup
* "Quitting" the preview on Mac
... and many more :-)
This is a hacky approach, but does help a lot with the tedious fixes.
See https://rust-lang.github.io/rust-clippy/master/index.html#/unnecessary_map_or
```
__CARGO_FIX_YOLO=1 cargo clippy --fix --all-targets --workspace --exclude gstreamer-player --exclude i-slint-backend-linuxkms --exclude uefi-demo --exclude ffmpeg -- -A clippy::all -W clippy::unnecessary_map_or
cargo fmt --all
```
When the LS gets new configuration, it will now
start to re-parse all files, sending `SetContents`
messages as it discovers files in new locations (e.g.
due to library path changes).
The live-preview will ignore those: Nothing it knows
depends on those paths.
Finally the LS will send a `SetConfiguration` request,
which will unconditionally trigger a re-rendering
in the live-preview. At this point all files
are known and the request should succeed.
Otherwise we get a lot of error in vscode such as:
```
Error: selectionRange must be contained in fullRange
at Gd.validate (file:///snap/code/178/usr/share/code/resources/app/out/vs/workbench/api/node/extensionHostProcess.js:109:33728)
at new Gd (file:///snap/code/178/usr/share/code/resources/app/out/vs/workbench/api/node/extensionHostProcess.js:109:33936)
at Ke (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:35:72279)
at Ke (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:35:72456)
at o (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:35:46654)
at Object.$P [as map] (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:35:46740)
at Object.Se [as asDocumentSymbols] (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:35:72246)
at c (/home/olivier/.vscode/extensions/slint.slint-nightly-2025.1.109/out/extension.js:39:56055)
at async uI.provideDocumentSymbols (file:///snap/code/178/usr/share/code/resources/app/out/vs/workbench/api/node/extensionHostProcess.js:138:126457)
[Error - 11:41:30 AM] Request textDocument/documentSymbol failed.
```
We shouldn't need to trim the whitespace from the node range.
Because the selected range might be the end of the range and it might
end up being trimmed.
In normal cases, whitespace are not part of the Node anyway
(As seen in the crash reporter)
Eg:
```
thread 'LanguageServer' panicked at tools/lsp/language/completion.rs:731:17:
byte index 4 is not a char boundary; it is inside '🍒' (bytes 2..6) of `./🍒🍓🍇"`
```
This can happen because offset might not be on a char boundary because
of the utf-16 / utf-8 mismatch.
The change in https://github.com/slint-ui/slint/pull/6747
invalidated the cache, but it was only reloaded when one of the dependent was reloaded.
We need to reload the cache for all open file so that LSP feature continue to work on
open document even if they get no changes
Version 3.17 of the spec added a `position_encoding` field in the
ServerCapabilities, so use that.
Note that the spec says that UTF-16 is mendatory, and vscode only
support utf-16, meaning we currently have a bug when having non-ascii in
the source (#5669)
This makes copying such types much cheaper and will allow us to
intern common struct types in the future too. This further
drops the sample cost for langtype.rs from ~6.6% down to 4.0%.
We are now also able to share/intern common struct types.
Before:
```
Time (mean ± σ): 1.073 s ± 0.021 s [User: 0.759 s, System: 0.215 s]
Range (min … max): 1.034 s … 1.105 s 10 runs
allocations: 3074261
```
After:
```
Time (mean ± σ): 1.034 s ± 0.026 s [User: 0.733 s, System: 0.201 s]
Range (min … max): 1.000 s … 1.078 s 10 runs
allocations: 2917476
```
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
```
... and ignore them on file change notifications: The
Editor manages the file content, so we do not need to
care for the on-disk content for these files.
Get a notification of any file change/deleteion. This feels like
overdoing it a bit, but we need to reload when resources change
and those can be anything.
Elements are specified by theit path and start offset. So
request a highlight for that position, not for some random
position somewhere inside the Element to highlight.
That way looking up whether the element is actually
a layout or not does work -- and there is no fallback to
the "it's not a layout" case.
I got carried away, I replaced `u32` with `TextSize` in one place
because that's what I got and I did not want to convert... and
then I fixed the fallout.
No functional change is intended in any of this.
FIXUP
The Properties are no longer sent out straight to the editor, so
we do not need to convert our internal `TextRange` and `TextSize`
to `lsp_types::Range` and `lsp_types::Position`.
We are noweadys turning that straight back into offsets -- which is
just another name for `TextSize` (or pairs of offsets).
These commands are not needed anymore since we integrated
the property editor into the live preview.
Move the properties code out of `common` and into `preview`
for good measure.
Compile test the result of an element move in the `can_move` function
to catch all cases where the move would be problematic.
Shuffle some test code around to allow for testing this new
functionality.