New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix logic for reflowing cursor when growing columns, after shrinking columns #7873
base: master
Are you sure you want to change the base?
Fix logic for reflowing cursor when growing columns, after shrinking columns #7873
Conversation
What makes you think it should? Have you tested other terminal emulators that support terminal reflow? Also could you provide a video of your issue or more detailed reproduction steps please? |
Thanks for the response!
I noticed this as I was debugging a related issue for Warp, where we have similar text reflowing logic (and I was comparing to other terminals). In Warp, it does result in a visible issue, since there's multiple grids and cursors exist in "finished" grids, where the cursor reflow problem manifests itself more clearly and results in incorrect comparisons. I believe the set-up I used in the unit test to repro this bug should be possible in a non-interactive shell (ie with a shell script) perhaps, rather than an interactive shell (I can use ANSI escape codes to manipulate the cursor positions directly). I'll try to see if I can get a repro with these methods - one of the challenges here is needing the saturating subtraction to hit the boundary at (0, 0) too. If I can force a situation where I avoid the shell re-printing characters + do a terminal shrink and grow, I think it should be able to manifest in an incorrect cursor position. |
The easiest way to test this stuff is to just |
Ah haha, I recently landed at the same conclusion before seeing this message (I did a Got a repro!
Note that (1) above leads me to believe my fix is a partial fix and not a completely correct fix - I'd appreciate help in grokking this The command to repro:
|
The reason why the default terminal works and iTerm/Alacritty don't is because it doesn't push the text into history. There's no way to recover the cursor if the text you're tracking is moving off the screen, since the cursor can't follow there. I'm not sure if it's viable to not push the line into the history. Generally this is desired for at least some lines and one would have to test general reflow behavior with the macOS terminal to determine if their solution is even viable or not. However the reflow logic is based on cursor position iirc, so maybe there's some special logic that can be done to prevent moving the cursor's line into history. I do not see a significant improvement from your patch itself, though I haven't tested it on my system. I would expect fixing this bug to be pretty complicated, just because there's so many edgecases and possibilities to introduce regressions. I don't think the current behavior causes any significant issues or correctness problems, so personally I'd avoid spending the time to try and "fix" this, but feel free to look into it if you're willing to potentially waste a bunch of your time. |
Gotcha, makes sense re having history vs not having history! Agreed that we do want to push lines into history - I think my point is moreso around ensuring that lines can come out of history when the terminal is (re)-grown in dimensions. Re my change - I think it does result in a better experience, in that the text is still visible (as opposed to entirely disappearing - in Loom above). Though, the cursor position is not exactly correct, in that particular example. Ack re complexity - I'm planning to fix this on the Warp side, hence was looking to help resolve this here as a side-quest. Will perhaps update the PR if I find a more comprehensive fix here (planning on more unit tests - checked the mid-command cursor behavior and that seems to be be fixed too!). I do think the current fix I have here doesn't regress functionality and improves the experience since it basically ensures that cursor subtraction calculations can be done into history (instead of saturating at the boundary), ONLY if those lines from history are coming out of history (which should be the intended product experience). Specifically, if a |
That is not possible in this scenario, otherwise you'll be losing content.
I mean the text is still there, it's just in the history.
I believe this assumption is incorrect and could lead to rendering glitches. |
Thanks for the response! Curious on some of the points you mentioned (for better understanding this):
|
The thing is that you need to take every grid state as a snapshot without considering what came before. If you flow it into history and right back it might make sense, but if you take the grid with the line just in the history and look at it like a snapshot, it's not necessarily obvious where it came from. All of this is based on a ton of heuristics, mostly wrapline flags and stuff like that, so you can take a guess. But my general assumption is that this might lead to accidentally rotating stuff down that shouldn't be, in which case it will be nuked by the shell's erase in line and be lost forever (which should obviously be avoided). It's very complex to reason about this and this code is the first thing I think of when thinking about horrible Alacritty code, just because it's such a mess and so heuristic heavy. But generally speaking there's just a load of edgecases which is why being careful probably makes sense. If I wanted to implement this, I would not try to rotate things back out of history after moving it into history, since there's too big a risk that will mess stuff up since you're guaranteed to lose cursor tracking. Instead I'd do what Kitty does and break the line towards the bottom of the terminal, so you can reflow it back to the top without losing cursor tracking. However I have no clue how easy that is and since this doesn't really cause any issues due to shell resets, I'd rather not look into it. |
Ah, I see. Thanks for explaining! Haha yeah, this is some very tough code to grok, hence my curiosity/struggle in fixing this "properly", since we have very similar concepts on the Warp-side. Hmm, yeah I think I follow that logic. Got it re your proposed fix - yeah, I think we can perhaps hold off on fixing this on the Alacritty side, though I'll poke around at this on my side. |
Converted to draft for now. Feel free to close if you have no interest in working on this. |
shrink_columns()
and thengrow_columns()
theGrid
's cursor is not being reflowed back to its original position.let mut target = self.cursor.point.sub(self, Boundary::Cursor, num_wrapped);
only being able to subtract until it saturates at theBoundary
. Specifically, in this case, the cursor was hitting the boundary of(0, 0)
and was not getting reflowed correctly.row
is being entirely reflowed (nothing leftover i.e.is_clear
). Then, we can appropriately subtractnum_wrapped
, which gets us to the righttarget
, that we can apply withline_delta
.Grid
with 3 rows and 8 columns, which 5 characters on the first line. We position theCursor
at(0, 5)
.Cursor
will be at(0, 2)
(the first line has the first 3 cells and rest are reflowed onto the second line).Cursor
to be reflowed back to(0, 5)
.(0, 0)
due to the saturation with subtraction at theBoundary
and 1 row staying in scrollback history.cargo test
. Verified new test passes.cargo run
.