[GH-ISSUE #913] Flickering screen in Windows powershell and cmd 🦆 #666

Closed
opened 2026-03-04 01:06:53 +03:00 by kerem · 6 comments
Owner

Originally created by @FJuedesOrcl on GitHub (Nov 6, 2023).
Original GitHub issue: https://github.com/rivo/tview/issues/913

Hi Friends,

i am writing some utilities for directory-servers, for example a browser. My development environment is a Linux box, but i have to cross-compile everything also for Windows. Never used it on Windows myself, but my colleagues are reporting that on Windows the screen is flickering. It looks like as if the entire screen is cleared and redrawn. It is a nuisance when the screen has a black background by default, but when using a white background it is beyond annoying.
When using the OoenSUSE bash window of the wsl everything looks fine - of course that's a Linux shell, now Windows…

Do i miss something or is that just the way how screen updates are performed in Windows?

I am neither an expert in Go nor with the TView package, so any help is welcome.

Thank you very much in advance for your help.

Originally created by @FJuedesOrcl on GitHub (Nov 6, 2023). Original GitHub issue: https://github.com/rivo/tview/issues/913 Hi Friends, i am writing some utilities for directory-servers, for example a browser. My development environment is a Linux box, but i have to cross-compile everything also for Windows. Never used it on Windows myself, but my colleagues are reporting that on Windows the screen is flickering. It looks like as if the entire screen is cleared and redrawn. It is a nuisance when the screen has a black background by default, but when using a white background it is beyond annoying. When using the OoenSUSE bash window of the wsl everything looks fine - of course that's a Linux shell, now Windows… Do i miss something or is that just the way how screen updates are performed in Windows? I am neither an expert in Go nor with the TView package, so any help is welcome. Thank you very much in advance for your help.
kerem closed this issue 2026-03-04 01:06:53 +03:00
Author
Owner

@FJuedesOrcl commented on GitHub (Nov 6, 2023):

Okay, i figured something out:
There are two go-routines, that will update a TextView primitive in an endless loop. I had coded:
Application.QueueUpdate**Draw**(func(){StatusLine.SetText(Buffer)})
To update the content of the TextView element. I have changed this to
Application.QueueUpdate(func(){StatusLine.SetText(Buffer)})
Now the flickering is gone, but the content of those TextView elements is only updated when i press a key on the keyboard.
How can i redraw just the content of a TextView element?
Yes there is a TextView.Draw() function, but what do i use as the Screen parameter?

<!-- gh-comment-id:1796214929 --> @FJuedesOrcl commented on GitHub (Nov 6, 2023): Okay, i figured something out: There are two go-routines, that will update a TextView primitive in an endless loop. I had coded: `Application.QueueUpdate**Draw**(func(){StatusLine.SetText(Buffer)})` To update the content of the TextView element. I have changed this to `Application.QueueUpdate(func(){StatusLine.SetText(Buffer)})`\ Now the flickering is gone, but the content of those TextView elements is only updated when i press a key on the keyboard. How can i redraw just the content of a TextView element? Yes there is a TextView.Draw() function, but what do i use as the Screen parameter?
Author
Owner

@rivo commented on GitHub (Nov 7, 2023):

Regarding flickering on Windows, I'm trying to get some answers here: https://github.com/gdamore/tcell/issues/647. I hope to be able to remove the flickering. As a temporary workaround, you can remove this line:

github.com/rivo/tview@1b91b8131c/application.go (L604)

Regarding writing to the TextView, you could try to buffer your writes and flush them to TextView at fixed intervals (or similar). It's a bit more complicated but it might be a good idea anyway to reduce the number of draw events.

Don't call TextView.Draw() directly. This is never needed. This function should actually be private (but it's not, due to backwards compatibility).

<!-- gh-comment-id:1798499594 --> @rivo commented on GitHub (Nov 7, 2023): Regarding flickering on Windows, I'm trying to get some answers here: https://github.com/gdamore/tcell/issues/647. I hope to be able to remove the flickering. As a temporary workaround, you can remove this line: https://github.com/rivo/tview/blob/1b91b8131c43011d923fe59855b4de3571dac997/application.go#L604 Regarding writing to the `TextView`, you could try to buffer your writes and flush them to `TextView` at fixed intervals (or similar). It's a bit more complicated but it might be a good idea anyway to reduce the number of draw events. Don't call `TextView.Draw()` directly. This is never needed. This function should actually be private (but it's not, due to backwards compatibility).
Author
Owner

@FJuedesOrcl commented on GitHub (Nov 7, 2023):

@rivo
Hi Rivo,

Thank you very much for your answer!
I will try to comment out the screen.Clear() in the tcell package and test how that effects the screen-output on windows and (more important) *ux. It will just take some time to change the package-code and then run the build-script.

i have not understood (yet) how the tcell package internally works, but aeons ago i had a somewhat similar issue on a Unix system with a cshell script that was periodically refreshing the display on a slow 9600 baud terminal.
My solution at that time was not to clear the screen, but instead move the cursor home, then refresh the screen line by line, character by character from the left to wherever the line ended and then send the delete to EOL escape code.
There were still some visible artifacts, but only in single lines and much less disturbing for the human eye.

I am not using any call to *Draw method, except in the function to update the status-line:

//--------------------------------------------------------------------------------
// Update the status-line every 500 milli-seconds in an endless loop
//--------------------------------------------------------------------------------
func UpdateStatusLine() {
  for {
    time.Sleep(500 * time.Millisecond)
    KeyName := LastKey.Name()
    KeyName = strings.ReplaceAll(KeyName,"Rune[","'")
    KeyName = strings.ReplaceAll(KeyName,"]","'")
    Content := fmt.Sprintf("[#F0F000]Display-Frequency: [#F0F0F0]%-4dms " + 
                           "[#F0F000]| Display-Update: [#F0F0F0]%-5t " +
                           "[#F0F000]| Compact-Mode: [#F0F0F0]%-5t " +
                           "[#F0F000]| LastKey: [#F0F0F0]%-14s " + 
                           "[#F0F000]| Page: [#F0F0F0]%-9s " +
                           "[#F0F000]| [#B01010]Press F1 for help.",
                           DataPanelDelay,DisplayUpdate,CompactDisplay,KeyName,CurrentPage)
    MonApp.QueueUpdateDraw(func() { StatusLine.SetText(Content) })
  } // END for
} // END UpdateStatusPanel

which is executed every 500ms. No call to *Draw() anywhere else in my code:

godev@ffappsdev [OUDbrowse]: grep -i draw *.go
StatusLine.go:    MonApp.QueueUpdateDraw(func() { StatusLine.SetText(Content) })
godev@ffappsdev [OUDbrowse]:

It must be something windows specific, so far i have tested Linux on I86, X64, Arm32, Arm64, Sparc and AIX and no flicker, it happens just in Windows cmd and power-shell, inside windows and in full-screen.

<!-- gh-comment-id:1799290834 --> @FJuedesOrcl commented on GitHub (Nov 7, 2023): @rivo Hi Rivo, Thank you very much for your answer! I will try to comment out the `screen.Clear()` in the tcell package and test how that effects the screen-output on windows and (more important) *ux. It will just take some time to change the package-code and then run the build-script. i have not understood (yet) how the tcell package internally works, but aeons ago i had a somewhat similar issue on a Unix system with a cshell script that was periodically refreshing the display on a slow 9600 baud terminal. My solution at that time was not to clear the screen, but instead move the cursor home, then refresh the screen line by line, character by character from the left to wherever the line ended and then send the delete to EOL escape code. There were still some visible artifacts, but only in single lines and much less disturbing for the human eye. I am not using any call to *Draw method, except in the function to update the status-line: ``` //-------------------------------------------------------------------------------- // Update the status-line every 500 milli-seconds in an endless loop //-------------------------------------------------------------------------------- func UpdateStatusLine() { for { time.Sleep(500 * time.Millisecond) KeyName := LastKey.Name() KeyName = strings.ReplaceAll(KeyName,"Rune[","'") KeyName = strings.ReplaceAll(KeyName,"]","'") Content := fmt.Sprintf("[#F0F000]Display-Frequency: [#F0F0F0]%-4dms " + "[#F0F000]| Display-Update: [#F0F0F0]%-5t " + "[#F0F000]| Compact-Mode: [#F0F0F0]%-5t " + "[#F0F000]| LastKey: [#F0F0F0]%-14s " + "[#F0F000]| Page: [#F0F0F0]%-9s " + "[#F0F000]| [#B01010]Press F1 for help.", DataPanelDelay,DisplayUpdate,CompactDisplay,KeyName,CurrentPage) MonApp.QueueUpdateDraw(func() { StatusLine.SetText(Content) }) } // END for } // END UpdateStatusPanel ``` which is executed every 500ms. No call to *Draw() anywhere else in my code: ``` godev@ffappsdev [OUDbrowse]: grep -i draw *.go StatusLine.go: MonApp.QueueUpdateDraw(func() { StatusLine.SetText(Content) }) godev@ffappsdev [OUDbrowse]: ``` It must be something windows specific, so far i have tested Linux on I86, X64, Arm32, Arm64, Sparc and AIX and no flicker, it happens just in Windows cmd and power-shell, inside windows and in full-screen.
Author
Owner

@FJuedesOrcl commented on GitHub (Nov 7, 2023):

OK, update with the screen.Clear() in the tcell package commented out:

  • So far it works on all *ix platforms that i have been able to test.
  • It works find on the Windows CMD window
  • I generates some minor artifacts in the frames when running in a powershell window.

No more flicker on windows, but i still feel a bit uneasy when not clearing the screen before a full redraw…
I will observe and give feedback...

<!-- gh-comment-id:1799366548 --> @FJuedesOrcl commented on GitHub (Nov 7, 2023): OK, update with the `screen.Clear()` in the tcell package commented out: - So far it works on all *ix platforms that i have been able to test. - It works find on the Windows CMD window - I generates some minor artifacts in the frames when running in a powershell window. - No more flicker on windows, but i still feel a bit uneasy when not clearing the screen before a full redraw… I will observe and give feedback...
Author
Owner

@FJuedesOrcl commented on GitHub (Nov 17, 2023):

@rivo
Update on this issue:

Changes to the code of application.go

- line 604: commented out "//[fjuedes 2023-11-17] screen.Clear()
- line 609: changed to "screen.Sync() //[fjuedes 2023-11-17] screen.Show()"
- line 623: changed to: "screen.Sync() //[fjuedes 2023-11-17] screen.Show()"

This will prevent screen-flickering in the windows terminals, cmd, MobaXTerm and MS-Terminal (cmd and powershell).
Few artifacts are visible if the window is resized, especially when the width is changed.

On *nix terminals no visible artifacts, tested with MobaXTerm, PuTTY, MS-Terminal and on Linux-consoles.

To be sure that the changes above will only affect Windows, the runtime package could be used to apply the changes only on windows.

<!-- gh-comment-id:1816982620 --> @FJuedesOrcl commented on GitHub (Nov 17, 2023): @rivo **Update on this issue:** Changes to the code of application.go ``` - line 604: commented out "//[fjuedes 2023-11-17] screen.Clear() - line 609: changed to "screen.Sync() //[fjuedes 2023-11-17] screen.Show()" - line 623: changed to: "screen.Sync() //[fjuedes 2023-11-17] screen.Show()" ``` This will prevent screen-flickering in the windows terminals, cmd, MobaXTerm and MS-Terminal (cmd and powershell). Few artifacts are visible if the window is resized, especially when the width is changed. On *nix terminals no visible artifacts, tested with MobaXTerm, PuTTY, MS-Terminal and on Linux-consoles. To be sure that the changes above will only affect Windows, the _runtime_ package could be used to apply the changes only on windows.
Author
Owner

@rivo commented on GitHub (Dec 6, 2023):

This issue was resolved in tcell and I upgraded tview to the latest version. So the flickering should be gone with the latest commit.

<!-- gh-comment-id:1842801784 --> @rivo commented on GitHub (Dec 6, 2023): This issue was resolved in `tcell` and I upgraded `tview` to the latest version. So the flickering should be gone with the latest commit.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#666
No description provided.