Subject: Re: bug#79298: patch: full color in windows terminal

From: Ewan <[email-masked]>
Date: Thu, 04 Sep 2025 06:01:41 +0000

> I meant hiding it at the beginning of an update (in
> w32con_update_begin) and showing it at the end of the update, which we
> already do. Then we can move it at will without it appearing on the
> screen, right?

Correct, and I tried this initially, but while it fixes the "jumping" 
problem, it causes the cursor to flash in-place irregularly, since it 
is hidden during updates, and updates have a variable duration (meaning 
you can't mitigate it with a tailored system cursor blink rate). The 
strategy of hiding it only when updating the echo area was a response to
this issue. It minimizes the "off" time, so the flashing in-place is 
reduced to a slight flicker.

> > Previously, we maintained the "cursor" throughout the update as an internal
> > coordinate variable, without "realizing" the position in the system cursor,
> > through a call to SetConsoleCursorPosition, until the after-update hook.
> > That is no longer possible -- the system cursor position must be realized
> > in real-time. Hiding the system cursor the whole time, and replacing it
> > with a (nominal) "cursor" drawn in with the rest of the glyphs, achieves
> > the same effect that we had before, in light of the new constraint. The
> > (actual, system) cursor jumps around, invisibly, during the write, while
> > the (nominal, visible) cursor stays stable, then makes one discrete move
> > (when its new row is written).
> 
> 
> It sounds like you are describing what I suggested above, so we agree
> on how to handle this when WriteConsole is in use? 

Not quite. By "the whole time", I mean always, whether updating or not.
We effectively replace the internal coordinate variable with the actual
system cursor by making it invisible at all times, and moving it around.

> But what do you mean by "replacing it with a (nominal) "cursor" drawn 
> in with the rest of the glyphs" in this context? 
> ... why "replacing", and what is the "nominal cursor"?

You "replace" the (previously, visible) system cursor with a glyph that
has its regular face_id temporarily replaced by the CURSOR_FACE_ID. The 
"nominal cursor" is then just a temporary assignment of the cursor face
to a whichever glyph will coincide with the (invisible) system cursor at 
the end of the update cycle. You compute this position just before the 
glyph matrix is written to the screen buffer. Visually, it is like the 
solid GUI cursor, as its appearance is determined by the cursor face.

Here's a recent build, in case you want to try for yourself:
https://github.com/ewantown/wemacs-build/releases/tag/v31.35.20250904.0a313d5

And here's a video demo, in case you don't want to run strangers' code:
https://sendvid.com/o4rr6p2b

> I know that Windows 11 has ConHost which supports the control
> sequences.  It's the potential issues with older systems (AFAIR,
> ConHost premiered in XP) that I'm bothered with.  Although I don't
> expect any such issues, it would be nice not to risk them at all, by
> keeping as much of the current code as possible. If someone does
> report such issues, testing a fix for them will be quite tricky, given
> the almost non-existent access to such old systems, and the fact that
> Emacs compiled with MinGW64 cannot even run on them.

I see, fair concern. FWIW I have not /removed/ any of the old code. 
The old path is still intact. At runtime you can ensure that it is used 
by setting w32-use-virtual-terminal-sequences to nil (done automatically
if VT processing is not available), and w32-use-visible-system-cursor to 
non-nil (manual - existing default is nil, unless using a screen-reader).
Not quite as comforting as a static guarantee of backward compatibility,
but I've tried to thread the new code through the old, branching on the
feature flags, so the old path remains functionally untouched.