Add support for the "blink" graphic rendition attribute #10280

Closed
opened 2026-01-31 02:17:08 +00:00 by claunia · 10 comments
Owner

Originally created by @j4james on GitHub (Aug 25, 2020).

Description of the new feature/enhancement

We already parse and store the SGR 5 blink attribute, but we don't actually "render" it. This is the only remaining DEC attribute that we don't yet support, and it's widely implemented by other terminal emulators. It's probably not essential, but it can occasionally be useful, and is fun for creating simple "animations".

Proposed technical implementation details (optional)

I've been experimenting with this on the conhost side of things, and I found it could quite easily be implemented by hooking into the existing timer routine in the CursorBlinker class, triggering a redraw of the render target every cycle or two. But since we don't want that overhead if nothing is actually blinking, I have a flag that is enabled whenever a blink attribute is encountered in the renderer, and only trigger the redraw if that flag has been set. The flag is cleared before every redraw, so once the viewport is free of any blinking attributes, the redraws will stop.

As for how the blinking is actually rendered, there are two main approaches, demonstrated in the images below. On the left is what I call the "PC style", where the text actually disappears. On the right is the "DEC style" (the way I believe most DEC terminals worked), where the text is just dimmed. Looking at the two screen shots you can see the pros and cons of each approach. In the "Christmas Card", the blinking lights on the tree clearly look better when they just dim, instead of disappearing. The BBS advert, on the other hand, is completely dependent on the PC style to produce the changing text effect.

blinktest

Having grown up with BBSes, I'm kind of partial to the PC style, but looking at things practically, I do think the DEC style is better. If you actually wanted to use blink to draw attention to some text, it's way better if you can still actually read that text. That's not so easy if it's constantly turning invisible, unless you also have a high blink rate, but that can be really annoying. For general text, a slow, subtle blink effect does seem more appropriate.

That said, I don't know of any other terminal emulators that actually implement the DEC style, so if we think it's important being compatible with other terminals emulators (rather than the actual terminals), then that's a factor to consider as well.

Ideally we'd one day have different compatibility modes, so we could actually support both options, but for now I do think we need to pick one to start with. I can't make up my mind which I prefer, so I'm happy to go with whatever the general consensus is here.

Originally created by @j4james on GitHub (Aug 25, 2020). # Description of the new feature/enhancement We already parse and store the `SGR 5` blink attribute, but we don't actually "render" it. This is the only remaining DEC attribute that we don't yet support, and it's widely implemented by other terminal emulators. It's probably not essential, but it can occasionally be useful, and is fun for creating simple "animations". # Proposed technical implementation details (optional) I've been experimenting with this on the conhost side of things, and I found it could quite easily be implemented by hooking into the existing timer routine in the `CursorBlinker` class, triggering a redraw of the render target every cycle or two. But since we don't want that overhead if nothing is actually blinking, I have a flag that is enabled whenever a blink attribute is encountered in the renderer, and only trigger the redraw if that flag has been set. The flag is cleared before every redraw, so once the viewport is free of any blinking attributes, the redraws will stop. As for how the blinking is actually rendered, there are two main approaches, demonstrated in the images below. On the left is what I call the "PC style", where the text actually disappears. On the right is the "DEC style" (the way I believe most DEC terminals worked), where the text is just dimmed. Looking at the two screen shots you can see the pros and cons of each approach. In the "Christmas Card", the blinking lights on the tree clearly look better when they just dim, instead of disappearing. The BBS advert, on the other hand, is completely dependent on the PC style to produce the changing text effect. ![blinktest](https://user-images.githubusercontent.com/4181424/91108543-2766de00-e670-11ea-9d5e-35d6391a4a79.gif) Having grown up with BBSes, I'm kind of partial to the PC style, but looking at things practically, I do think the DEC style is better. If you actually wanted to use blink to draw attention to some text, it's way better if you can still actually read that text. That's not so easy if it's constantly turning invisible, unless you also have a high blink rate, but that can be really annoying. For general text, a slow, subtle blink effect does seem more appropriate. That said, I don't know of any other terminal emulators that actually implement the DEC style, so if we think it's important being compatible with other terminals emulators (rather than the actual terminals), then that's a factor to consider as well. Ideally we'd one day have different compatibility modes, so we could actually support both options, but for now I do think we need to pick one to start with. I can't make up my mind which I prefer, so I'm happy to go with whatever the general consensus is here.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Aug 25, 2020):

This should perhaps check SystemParametersInfo SPI_GETCLIENTAREAANIMATION, whose description specifically mentions blinking. The blinking frequency in the sample GIF is only one change per second, though.

@KalleOlaviNiemitalo commented on GitHub (Aug 25, 2020): This should perhaps check [SystemParametersInfo SPI_GETCLIENTAREAANIMATION](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-systemparametersinfow#spi_getclientareaanimation), whose description specifically mentions blinking. The blinking frequency in the sample GIF is only one change per second, though.
Author
Owner

@j4james commented on GitHub (Aug 25, 2020):

The current implementation is using the existing timer from the CursorBlinker class, and that's linked to the system cursor blink rate (see GetCaretBlinkTime). That seemed to me like a reasonable proxy for a user's blink rate preference. I wouldn't be opposed to adding a SPI_GETCLIENTAREAANIMATION check on top of that though if there's any concern that this might still be problematic for some users.

I should also mention that my current implementation only blinks at half the cursor rate (which is more or less what a DEC terminal would do), so in the time it takes the cursor to blink on and off, the blinking attribute would only have rendered half a cycle (i.e. it would either be on the whole time, or off the whole time). I think that works nicely for the DEC style of blinking, but may be too slow for a PC style blink.

@j4james commented on GitHub (Aug 25, 2020): The current implementation is using the existing timer from the `CursorBlinker` class, and that's linked to the system cursor blink rate (see [GetCaretBlinkTime](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcaretblinktime)). That seemed to me like a reasonable proxy for a user's blink rate preference. I wouldn't be opposed to adding a `SPI_GETCLIENTAREAANIMATION` check on top of that though if there's any concern that this might still be problematic for some users. I should also mention that my current implementation only blinks at half the cursor rate (which is more or less what a DEC terminal would do), so in the time it takes the cursor to blink on and off, the blinking attribute would only have rendered half a cycle (i.e. it would either be on the whole time, or off the whole time). I think that works nicely for the DEC style of blinking, but may be too slow for a PC style blink.
Author
Owner

@WSLUser commented on GitHub (Aug 27, 2020):

For accessibility purposes, we will need to inherit the OS cursor blink rate configured in "Keyboard Properties" as blinking too fast can cause visual impairment but most users will not want it going too slow either. We can define the blink rate ourselves but I think OS inheritance will be better.

@WSLUser commented on GitHub (Aug 27, 2020): For accessibility purposes, we will need to inherit the OS cursor blink rate configured in "Keyboard Properties" as blinking too fast can cause visual impairment but most users will not want it going too slow either. We can define the blink rate ourselves but I think OS inheritance will be better.
Author
Owner

@j4james commented on GitHub (Aug 27, 2020):

For accessibility purposes, we will need to inherit the OS cursor blink rate configured in "Keyboard Properties"

I just said the current implementation is using the system cursor blink rate (GetCaretBlinkTime). Is that not the same thing?

@j4james commented on GitHub (Aug 27, 2020): > For accessibility purposes, we will need to inherit the OS cursor blink rate configured in "Keyboard Properties" I just said the current implementation is using the system cursor blink rate (`GetCaretBlinkTime`). Is that not the same thing?
Author
Owner

@WSLUser commented on GitHub (Aug 27, 2020):

I honestly have no clue. But I don't believe conhost is responsible for the keyboard settings and properties so I just wanted to put that out there. Since only the Terminal team have access to Windows source code, they can tell if it calls the same code. I do think we should document how to access the setting when this feature is implemented.

@WSLUser commented on GitHub (Aug 27, 2020): I honestly have no clue. But I don't believe conhost is responsible for the keyboard settings and properties so I just wanted to put that out there. Since only the Terminal team have access to Windows source code, they can tell if it calls the same code. I do think we should document how to access the setting when this feature is implemented.
Author
Owner

@zadjii-msft commented on GitHub (Aug 27, 2020):

Without even looking at OS code, this doc would seem to attest that @j4james's assertion is correct.

@zadjii-msft commented on GitHub (Aug 27, 2020): Without even looking at OS code, [this doc](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/dnacc/flashing-user-interface-and-the-getcaretblinktime-function) would seem to attest that @j4james's assertion is correct.
Author
Owner

@jdebp commented on GitHub (Aug 29, 2020):

Personally I like the DEC style, even though most of the home computers and personal computers that I've used have (in text mode) used the IBM MDA style of just AND-gating the foreground pixels, and even though there's the argument that Windows Terminal should stick with its PC heritage here. Note however that the EGA in 16-colour graphics mode blinked pixels by switching between two sets of 8 palette entries, and could implement DEC-style blinking, so the PC heritage is not quite as one-sided as one might think.

Also note the existence of DECBBSM, which is DEC private mode 116. If off, only the foreground pixels change intensity. If on, both foreground and background pixels change intensity.

The far more important configuration option that you'll have to set up is the ability to turn blinking off. Observe that the ability to disable the blink graphic rendition for text is a selectable option in terminal emulators such as (among others) PowerTerm WBT, Reflection ZFE, Foxit KoalaTerm, Terminal.app in MacOS (Apple doco), iTerm2, Konsole, tilix, and PuTTY.

@jdebp commented on GitHub (Aug 29, 2020): Personally I like the DEC style, even though most of the home computers and personal computers that I've used have (in text mode) used the IBM MDA style of just AND-gating the foreground pixels, and even though there's the argument that Windows Terminal should stick with its PC heritage here. Note however that the EGA in _16-colour graphics_ mode blinked pixels by switching between two sets of 8 palette entries, and could implement DEC-style blinking, so the PC heritage is not quite as one-sided as one might think. Also note the existence of DECBBSM, which is DEC private mode 116. If off, only the foreground pixels change intensity. If on, both foreground and background pixels change intensity. The far more important configuration option that you'll have to set up is _the ability to turn blinking off_. Observe that the ability to disable the blink graphic rendition for text is a selectable option in terminal emulators such as (among others) PowerTerm WBT, [Reflection ZFE](https://www.attachmate.com/documentation/rzfe-2-2-3/pdfdoc/rzfe-user/rzfe-user.pdf#page=48), [Foxit KoalaTerm](http://cdn02.foxitsoftware.com/pub/foxit/manual/enu/SecureKoalaTerm_Manual.pdf), [Terminal.app in MacOS](https://alvinalexander.com/blog/post/mac-os-x/disable-blinking-text-in-mac-os-x-terminal-application/) ([Apple doco](https://support.apple.com/en-gb/guide/terminal/trmltxt/mac)), [iTerm2](https://www.iterm2.com/documentation-preferences-profiles-text.html), [Konsole](https://api.kde.org/4.14-api/applications-apidocs/konsole/html/classKonsole_1_1Profile.html#a57848e15fe69d3f27565851fe7cda429a53384164c55e77e2006aa74ab57123cf), [tilix](https://news.ycombinator.com/item?id=14982406), and [PuTTY](https://documentation.help/PuTTY/config-blink.html).
Author
Owner

@j4james commented on GitHub (Aug 29, 2020):

Personally I like the DEC style,

Thanks for the feedback. I'm leaning that way too at the moment.

Also note the existence of DECBBSM, which is DEC private mode 116. If off, only the foreground pixels change intensity. If on, both foreground and background pixels change intensity.

Yeah thanks, I am aware of that, but I'm not looking to do anything that fancy yet. I'm just trying to get us to the level of a basic VT100 terminal for now.

The far more important configuration option that you'll have to set up is the ability to turn blinking off.

In the current implementation you can at least turn it off via the cursor blink settings, and if it's easy I might also add in the animation option that KalleOlaviNiemitalo was suggesting. If anyone still has complaints after that, we can always add more options, but I suspect the reality is that most people will never encounter a blinking attribute unless they're actively looking for one. Do you have any examples of software using blinking that some people might find annoying?

@j4james commented on GitHub (Aug 29, 2020): > Personally I like the DEC style, Thanks for the feedback. I'm leaning that way too at the moment. > Also note the existence of DECBBSM, which is DEC private mode 116. If off, only the foreground pixels change intensity. If on, both foreground and background pixels change intensity. Yeah thanks, I am aware of that, but I'm not looking to do anything that fancy yet. I'm just trying to get us to the level of a basic VT100 terminal for now. > The far more important configuration option that you'll have to set up is _the ability to turn blinking off_. In the current implementation you can at least turn it off via the cursor blink settings, and if it's easy I might also add in the animation option that KalleOlaviNiemitalo was suggesting. If anyone still has complaints after that, we can always add more options, but I suspect the reality is that most people will never encounter a blinking attribute unless they're actively looking for one. Do you have any examples of software using blinking that some people might find annoying?
Author
Owner

@Qix- commented on GitHub (Sep 10, 2020):

Would SGR 6 (fast blink) be supported here too? Perhaps at a perfect 2x rate? Both are turned off by SGR 25 if I understand correctly. I'm not sure the origin of SGR 6, but it's something that has always been listed in the various references I've seen.

EDIT: I see https://github.com/microsoft/terminal/pull/7490/files#diff-f30650c558f3ea3f151ac2c2bea3d9ebR135 already detects it but it's not being handled. This would be a really neat feature to have, given the emergence of "ansi dashboards" nowadays. It'd also set the windows terminal ahead of many (most) other emulators, too.

@Qix- commented on GitHub (Sep 10, 2020): Would `SGR 6` (fast blink) be supported here too? Perhaps at a perfect 2x rate? Both are turned off by `SGR 25` if I understand correctly. I'm not sure the origin of `SGR 6`, but it's something that has always been listed in the various references I've seen. EDIT: I see https://github.com/microsoft/terminal/pull/7490/files#diff-f30650c558f3ea3f151ac2c2bea3d9ebR135 already detects it but it's not being handled. This would be a really neat feature to have, given the emergence of "ansi dashboards" nowadays. It'd also set the windows terminal ahead of many (most) other emulators, too.
Author
Owner

@ghost commented on GitHub (Sep 22, 2020):

:tada:This issue was addressed in #7490, which has now been successfully released as Windows Terminal Preview v1.4.2652.0.🎉

Handy links:

@ghost commented on GitHub (Sep 22, 2020): :tada:This issue was addressed in #7490, which has now been successfully released as `Windows Terminal Preview v1.4.2652.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.4.2652.0) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#10280