terminal: [1.15+] Flushing FTCS sequences causes flickering in nushell 0.66+
Windows Terminal version
1.15.2003.0
Windows build number
Microsoft Windows [Version 10.0.22000.795]
Other Software
Nushell v0.66+
Steps to reproduce
Hi, I work on a cross-platform shell called Nushell and we’ve noticed a rendering regression in Windows Terminal Preview v1.15.
Nushell’s prompt now flickers on every keystroke. The following recording illustrates the problem (but it’s a little worse in real life, the recording didn’t capture every flicker):
To reproduce this, run any version of Nushell from v0.66 or later and start typing. Nushell can be downloaded from our GitHub releases or installed with Scoop (scoop install nushell) or winget (winget install nushell). nu.exe is the executable for Nushell.
Details / Investigation
The flickering does not occur in Windows Terminal v1.14.1963.0.
We bisected Nushell’s code and found that the flickering did not occur prior to this PR which added some scroll mark ANSI escape codes for VS Code. WT v1.15 Preview added experimental support for scroll marks; maybe this is a bug in the experimental scroll mark code?
The flickering occurs even with the scroll mark settings (experimental.autoMarkPrompts and experimental.showMarksOnScrollbar) set to false.
If there’s anything else we can do to help with investigation or reproduction, just let me know!
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 95
- Comments: 29 (11 by maintainers)
Commits related to this issue
- Prevent flickering in nushell due to FTCS marks (#14677) Tl;dr: Conpty would flush a frame whenever it encountered a FTCS mark. Combine that with the whole-line redrawing that nushell does, and the ... — committed to microsoft/terminal by zadjii-msft a year ago
- Update conpty to rev 0ee2c74cd432eda153f3f3e77588164cde95044f I want to try out the FTCS flush and any other conpty fixes that may have been made since our last update. refs: https://github.com/micr... — committed to wez/wezterm by wez a year ago
@popcar2 When you disable
shell_integrationyou lose the ability to have automatic OSC 133;A/B/C/D terminal markers (FTCS sequences) and automatic OSC 2 & OSC 7 term/window titles. It may also interfere with OSC 8 clickable links in nushell.ba777dfbf doesn’t seem to flash anymore. I’ll have to make sure I didn’t blow anything else up.
I’m a tad worried about capturing the screenbuffer pointer in that lambda like that.
(huge apologies to folks following this thread, these notes are an unintelligible stream of consciousness)
Refer to #13163
My outline of events in https://github.com/microsoft/terminal/issues/13710#issuecomment-1209754247 might be wrong[1]. Look at the video closer - is that it? The left prompt is always visible, even as command and right prompt are flickering. Hmm.
This diff would seem to suggest that the prompt is written as one long string, “
FTCS A+prompt+FTCS B”, presumably followed by the command, followed by the right prompt. In 1.15, ~only FTCS A would have been implemented~. I don’t think that matters~In 1.15 we return false out of the adapter on the
FTCS Bwhich means “I didn’t understand that, just write that to the pipe NOW”.~ this is also wrong.ConPty always flushes all FTCS’s in 1.15. On “
FTCS A+prompt+FTCS B”, we doas three frames. That it shouldn’t. That probably should all be one frame. Can we just
FlushNoWrite()from the adapter? Would that be insane? We’d have to be careful to write to the buffer, not write the frame to the pipe, write the sequence, but then also leave the engine in a state where the regularly scheduled paint frame tick would still cause the actualPresentto the pipe, but with a quick path for "we had nothing to do but we did have stuff we already did.I’ll keep editing with notes as I go
[1] it might not be, I’ve re-edited this comment like 10 times as writing it
This is what I get out the debug tap. Now, where are the frames…
CR, cursor off, Cursor Forward 17 (?!), mark
This is what actually gets written to conhost
[2 qlooks out of place…Okay playing with this more locally, and staring at it, I do see the prompt section flickering as I’d expect.
So, I guess the trick now is that even if we do not immediately flush the frame, a regular frame might come in in the middle of the string. Hmm.
Bad idea
The console should be locked for that whole write, start to finish.
ApiRoutines::WriteConsoleWImpltakes the lock and holds it till it’s all processed. So that must mean we’re getting aFlushwe’re not expecting, during the handling of the string. After the133;A, before theB. Hmm.A fix was mentioned in another thread and I can confirm it works:
config nushell_integrationand set it tofalseIt should stop flickering now. I don’t know what the downside is for disabling shell integration, everything seems to work totally fine over a month in.
Alas, no. I haven’t noodled on this too much since getting back from leave, and I’m only just getting back into the swing of things after the holidays.
I’ve got this marked up to take a look at ~this month, but I seriously doubt I’ll have a good solution that fast.
IIRC we briefly discussed some ideas, that might work okay in this specific scenario, but wouldn’t work more broadly for the other sequences that are leveraging the same flushing that we do here (looking at you alt buffer sequences). I can’t remember the details though 😕
Thanks! That was super easy to reproduce. I should’ve realized that given that this issue was also about FTCS. I’ve opened #16769 so we don’t ping the ~dozen people on this issue unnecessarily. I’ll try to fix it soon (if possible).
@wez wezterm nightly, downloaded from here exhibits a similar issue as before but slightly different.
if one of you could check this behavior with the current nightly build of wezterm, I’d appreciate it: I updated the bundled conpty pieces to match 0ee2c74cd432eda153f3f3e77588164cde95044f of this repo, so my understanding is that this should be fixed in wezterm now too.
Oh good, I’m glad! This was a tricky fix so I’m really glad it did work after all.
Looks like our friendly neighborhood bot is having a tough time this week and forgot to come around with release notes. This fix shipped in Terminal Preview 1.18 earlier this week.
(I’m supposed to be on vacation RN so apologies for the brevity in my notes)
Hmmmmmmmmm. I wonder if this isn’t playing nicely with the frame flushing. Like, when the prompt gets drawn, what’s happening is a
The trick is that we’re flushing all buffered state to the Terminal when we see a prompt sequence. The problem is that at the time the mark is re-rendered, the prompt line is empty, causing the flickering.
No clever solutions off the top of the dome. I’ll noodle on the drive home.
Edit 2023/01/10: The above set of steps is wrong. Don’t use that as a guide for what’s happening.
any update?
This problem does not occur when nushell runs on alacritty 😉
I mean, FTCS support landed literally 3 months ago - I’m not sure it’s even made its way to any official Windows builds yet 😅
Uh oh, the terminal flickering is back!
I can reproduce it in Terminal Preview 1.20.10303.0 and Nu 0.90.1. I cannot reproduce it in Terminal 1.18.10301.0.
It seems to occur with or without AtlasEngine enabled.
@zadjii-msft Would you like me to open a new issue for this?
Nushell is still flickering when used within Windows Terminal (both MS store stable/preview + latest GitHub release).
FWIW, wezterm bundles and uses openconsole.exe and conpty.dll built from GitHub. I just updated it to the most recent tag this morning and the issue reproduces there too.
https://github.com/wez/wezterm/commit/0d85d05442a2ca38264a2cd3a21f57d565a4464f