I've cleaned up the code we use for scaling and positioning glyphs for
raster, under both CoreText and FreeType. Before we had some
imprecision, and under CoreText we were sometimes stretching glyphs in
unseemly ways. These changes make it so that our constraints can
position and size glyphs *exactly* and we don't have any chopped-off
row/column issues for CoreText. With this, PowerLine Extra symbols now
always align *perfectly* with the cell height:
||Before|After|
|-:|-|-|
|**CoreText**|<img width="105" height="245" alt="image"
src="https://github.com/user-attachments/assets/d3c1b1cb-a798-4e18-a0e0-59551893369c"
/>|<img width="106" height="246" alt="image"
src="https://github.com/user-attachments/assets/dac10c49-9ec1-4f4f-8825-a5e8c2fd3402"
/>|
|**FreeType**|<img width="105" height="245" alt="image"
src="https://github.com/user-attachments/assets/160e1e35-4a3c-42d0-9042-215301e636a1"
/>|<img width="106" height="245" alt="image"
src="https://github.com/user-attachments/assets/89bf1538-7271-4baf-88c0-51ebc4d360df"
/>|
The other changes are mainly just cleanup stuff, though one of the
changes makes it so that we do once again properly apply constraints to
symbols from the dingbats block (it was a regression, noted in #7955,
that we stopped doing that).
### Future work
This has been a problem since we introduced the custom constraints, but
I noticed it while preparing the before/after images: the left-edge PLE
symbols (meant to connect to a full block on the right) expand out to
the *right*, so if they're followed immediately by another character
than they actually get squished and don't match the right-edge symbols:
<img width="75" height="114" alt="image"
src="https://github.com/user-attachments/assets/1420b9a5-9950-4210-9934-8ef7cd7a1e19"
/>
I have a WIP change to move constraint logic to the shapers, and at that
point we can maybe do something to allow the constraint to grow in to
whitespace on the left side instead of on the right side.
The upstream GIR for g_weak_ref_get is incorrect - it does not allow the
returned value to be NULL. This PR pulls in a new version of our GObject
bindings with that patched and improves the safety of dealing with the
command palette weak reference held by the window.
See ianprime0509/zig-gobject#117
This continues #8202 by fixing two of the known issues: `goto_split` key
binds work and closing a split moves focus to the proper place.
A big improvement in this PR is that for the first time ever in our GTK
backend, the up/down/left/right `goto_split` bindings **use spatial
navigation.** "Spatial navigation" means that the direction to move
focus is done based on the nearest split _visually_ from the current
split, rather than via a tree traversal. We did this on macOS a couple
months ago, with a lot more details there: #7523
Similar to macOS, the spatial navigation is currently based on top-left
corner. Now that our split tree is implemented in Zig though it should
be a lot easier for us to work in the current cursor position as the
reference point.
~~🚧 TODO: Going to add some unit tests for the spatial navigation before
merge.~~
This adds on to our existing foundations from #8165 and adds the ability
to create and close splits. We're still missing split navigation,
resizing via keybindings, etc. And there are a number of known issues
(listed below). But this is a strict improvement from where we're at and
includes a number of important bug fixes to our split tree.
The only nasty thing in this PR is that I learned that GTK _did not
like_ rebuilding our split widget tree on every data model change. I
don't know enough about how all the re-parenting plus size allocation
interactions work together. As a compromise, this PR adds a listener,
waits for our surface tree to "settle" by having all surfaces have no
parents, then schedules a single rebuild after that. This works well,
but results in some noticeable flashing for a frame or so. I think we
can improve this later, it works completely well enough.
Importantly, all of this is Valgrind clean. I long suspected our splits
on legacy are NOT free of leaks, but never proved it, so this makes me
happy.
## Demo
https://github.com/user-attachments/assets/e231d89f-581e-486b-ade0-1d7e6795262e
## Known Issues
I may fix this in this PR, I may follow up.
- [ ] Focus doesn't go to the right place after closing a split
- [x] Divider with a transparent background is transparent
- [x] Close split doesn't show any close confirmation dialog
- Missing features:
* [ ] Equalize splits
* [ ] Resize splits keybind (manual mouse action works fine)
* [ ] Go to split keybind
Freetype encodes some font names internally in formats other than UTF-8.
This only affects debug logs but it was annoying me so I fixed it. There
may be other encodings that might need to be dealt with but I took care
of the one that I ran across.
We now also have absolute perfect control over the raster position under
FreeType as well. This means that, for example, powerline extended chars
are appropriately clamped to the cell edges at all sizes.
This should be purely an improvement over what we had before, and now it
also matches what we do for CoreText.
Freetype encodes some font names internally in formats other than UTF-8.
This only affects debug logs but it was annoying me so I fixed it. There
may be other encodings that might need to be dealt with but I took care
of the one that I ran across.
The monochrome hinter is very aggressive but makes text actually look
tolerable when rendered in monochrome. If for some god forsaken reason
we get complaints about this, that someone wanted improperly hinted mono
glyphs, we can introduce additonal configuration; but for now, this is
just a straight improvement.
The old method was nice, but had an issue that's intractible without
significant reworking in how we do shaping: combining glyphs need to
position relative to the glyph they're combining with, but if we re-
center that glyph, it will be off by some amount.
Apologies to Apple, the previous comments in this section of the code
were not correct-- `shouldSubpixelQuantizeFonts` does pretty much what
the minimal documentation for it says it does, it simply quantizes the
position of the glyph and nothing more. Various bugs when testing while
writing the old code that led me to include those comments made me not
realize that the positioning is actually a lot simpler than it seems.
With this version of the positioning there are never any cut-off rows or
columns of pixels on the edges of anything and everything scales as it
should... I hope. I checked pretty thoroughly this time and I'm like 99%
sure this is correct in all cases.