| Age | Commit message (Collapse) | Author |
|
|
|
|
|
A whole bunch of inline annotations, some of these were tracked down
with Instruments.app, others are guesses / just seemed right because
they were trivial wrapper functions.
Regardless, these changes are ultimately supported by improved vtebench
results on my machine (Apple M3 Max).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
It's possible for the hyperlink or string capacity to be exceeded in a
single row, in which case it doesn't matter if we move the row to a new
page, it will still be a problem. This was causing actual crashes under
some circumstances.
|
|
|
|
Even though the viewport pin isn't used unless the `viewport` is `pin`,
it's still possible to access undefined data through `clone`. Valgrind
found this:
```
==107091== Conditional jump or move depends on uninitialised value(s)
==107091== at 0x392B96A: terminal.PageList.clone (PageList.zig:540)
==107091== by 0x392C9A0: terminal.Screen.clonePool (Screen.zig:348)
==107091== by 0x392DF7A: terminal.Screen.clone (Screen.zig:330)
==107091== by 0x394E6D4: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1129)
==107091== by 0x3919BF8: renderer.Thread.renderCallback (Thread.zig:607)
==107091== by 0x3919A6F: renderer.Thread.wakeupCallback (Thread.zig:524)
==107091== by 0x394FA6E: callback (async.zig:679)
==107091== by 0x394FA6E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_436371__struct_440666.callback (async.zig:181)
==107091== by 0x38F781E: backend.io_uring.Completion.invoke (io_uring.zig:804)
==107091== by 0x38FA448: backend.io_uring.Loop.tick___anon_431479 (io_uring.zig:193)
==107091== by 0x38FA53D: backend.io_uring.Loop.run (io_uring.zig:84)
==107091== by 0x38FEFE3: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==107091== by 0x38FF2E2: renderer.Thread.threadMain_ (Thread.zig:263)
==107091== by 0x38DDF80: renderer.Thread.threadMain (Thread.zig:202)
==107091== by 0x38B5C0A: Thread.callFn__anon_421402 (Thread.zig:488)
==107091== by 0x3888604: Thread.PosixThreadImpl.spawn__anon_418943.Instance.entryFn (Thread.zig:757)
==107091== by 0x6C6E7EA: start_thread (pthread_create.c:448)
==107091== by 0x6CF1FB3: clone (clone.S:100)
==107091==
```
|
|
This tests for the bug fixed in the last commit.
|
|
Before, if the row count increase past the active area then we added new
rows to make sure that we had enough for the active area, but we didn't
make sure that the viewport pin wasn't below the active area pin, which
meant that later on if someone tried to get the bottom right pin for the
viewport it would overshoot and we'd use null. This resulted in either a
memory corruption bug in ReleaseFast if you scaled down the font while
scrolled up slightly, or in Debug mode it was just a crash.
|
|
Fixes #7536
When we're reflowing a row and we need to insert a spacer head, we must
move to the next row to insert it. Previously, we were setting a spacer
head and then copying data into that spacer head, which could lead to
corrupt data and an eventual crash.
In debug builds this triggers assertion failures but in release builds
this would lead to silent corruption and a crash later on.
The unit test shows the issue clearly but effectively you need a
multi-codepoint grapheme such as `👨👨👦👦` to wrap across a row by changing
the columns.
|
|
This logic is cleaner and produces better behavior when selecting by
dragging the mouse outside the bounds of the surface, previously when
doing this on the left side of the surface selections would include the
first cell of the next row, this is no longer the case.
This introduces methods on PageList.Pin which move a pin left or right
while wrapping to the prev/next row, or clamping to the ends of the row.
These need unit tests.
|
|
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.
These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.
I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.
I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
|
|
|
|
Otherwise pages may have the wrong width if they were resized down with
a fast path that just chanes the size without adjusting capacity at all.
|
|
|
|
|
|
Fixes #2958
The y was alround bounded but we allowed any x value and assumed the
caller would handle it. This is not the case so we now check the x and
return null if it's out of bounds (same as y, which was already doing
this).
|
|
In multiple tests we create 1 or more pages by growing them 1 row at a
time, which results in an integrity check of the page for each row grown
which is just... horrible. By simply pausing integrity checks while
growing these pages (since growing them is not the point of the test) we
MASSIVELY speed up all of these tests.
Also reduced grapheme bytes during testing and made the Terminal "glitch
text" test actually assert what it intends to achieve, rather than just
blindly assuming 100 copies of the text will be the right amount -- this
lets us stop a lot earlier, making it take practically no time.
|
|
|
|
|
|
Fixes #2877
As the comment in the diff states, we rely on `mmap` to zero our memory.
When we reset we are reusing previously allocated memory so we won't hit
an `mmap`. We need to zero the memory ourselves.
This is pretty slow if there is a lot of memory but in every case except
allocation failures, we expect there to be only a few pages allocated.
|
|
|
|
|
|
|
|
This is more correct: a pagelist is a linked list of nodes, not pages.
The nodes themselves contain pages but we were previously calling the
nodes "pages" which was confusing, especially as I plan some future
changes to the way pages are stored.
|
|
We're already using `>=`, we don't need to also use `- 1`
|
|
|
|
See comments in the test, also this:
> The scenario is if you adjustCapacity a page beyond a std_size then our
> precondition no longer holds. PageList.adjustCapacity makes no guarantee
> that the resulting capacity fits within a standard page size. It is in fact
> documented this way and that it is slow since we have to mmap out of our
> memory pool.
|
|
Running alacritty/vtebench on some machines causes Ghostty to fail on
`assert(first != last)` when trying to grow scrollback. We now make sure
we have enough pages before trying to reuse pages.
|
|
fix(terminal/PageList): update self.cols at start of resizeCols
|
|
It's possible for `self.grow` to be called within the body of the
function, and `self.grow` uses `self.cols` to create a new page if
there's no more room in the current one.
|
|
|
|
|
|
Also avoids leaving content in out-of-bounds rows, since it doesn't copy
the content to them in the first place. Over all, just a lot cleaner.
|
|
If we call `moveLastRowToNewPage` at any point because we failed to copy
some managed memory, it tries to copy managed memory that hasn't been
cloned yet when moving our progress to a new page.
Avoid this by setting our content tag, hyperlink flag, and style id to
indicate no managed memory is present on the cell.
|
|
Before, cells that were explicitly set to match the default bg color
were treated as if they did NOT have the default and extending would
occur. We now check the exact RGB of each cell.
|
|
I noticed that the HashMap iterator showed up prominently in Instruments when quickly
resizing Ghostty.
I think this is related to the [tombstone issue](https://github.com/ziglang/zig/issues/17851),
where the `next()` function has to skip unused meta-nodes.
In that same issue, Andrew is suggesting that the non-array hashmap might get deleted from the
standard library.
After switching to `AutoArrayHashMapUnmanaged`, iteration barely shows up anymore.
Deletion from the pin list should also be fast as swapRemove is used (order does not need to be preserved).
Question is if insertion performance is negatively affected, though I'm not seeing anything obvious.
Still, checking this PR for any perf regressions might be a good idea.
If this pans out, there are more places where this switch might be beneficial.
|
|
|
|
|
|
There are scenarios where this configuration looks bad. This commit
introduces some heuristics to prevent it. Here are the heuristics:
* Extension is always enabled on alt screen.
* Extension is disabled if a row contains any default bg color. The
thinking is that in this scenario, using the default bg color looks
just fine.
* Extension is disabled if a row is marked as a prompt (using semantic
prompt sequences). The thinking here is that prompts often contain
perfect fit glyphs such as Powerline glyphs and those look bad when
extended.
This introduces some CPU cost to the extension feature but it should be
minimal and respects dirty tracking. This is unfortunate but the feature
makes many terminal scenarios look much better and the performance cost
is minimal so I believe it is worth it.
Further heuristics are likely warranted but this should be a good
starting set.
|
|
|
|
|
|
|
|
|