crossterm icon indicating copy to clipboard operation
crossterm copied to clipboard

Documentation Regarding Raw Mode's Effects Are Incomplete Regarding Windows

Open KSBilodeau opened this issue 4 years ago • 5 comments
trafficstars

Describe the bug \n is said not to work while in raw mode; however, testing with windows reveals that \n does work, but results in flickering. Also, \r\n produces flickering as well for some ungodly reason beyond my comprehension despite no mention of issues regarding this character combination on the docs.

I think its unlikely that this is something fixable through the library, so something in the docs should simply state that for optimal compatibility across all platforms, use of any sort of newline character/s should be avoided, as they have been shown to cause flickering on windows.

To Reproduce Steps to reproduce the behavior:

  1. Create an application with raw mode enabled and a way to output text that has \r\n or just \n appended to it
  2. Attempt to flush the console in one way or another
  3. Flickering will occur with every flush so long as the text with \r\n or \n is still written to stdout

Expected behavior Any text following \r\n should be rendered on the next line, and \n should only render on the next line without moving back to the left side of the screen.

OS MacOS - does not flicker with flushing text to the console containing \r\n and exhibits the expected behavior with both \r\n and \n.

https://user-images.githubusercontent.com/22333708/125906999-06029151-f031-4032-98c3-895606bdd428.mov

Windows - experiences the entire bug

https://user-images.githubusercontent.com/22333708/125906653-ed5e3e20-4d60-4534-a535-5b0706e6e1ce.mp4

Terminal/Console Command Prompt/Powershell/windows terminal

Works on MacOS terminal

KSBilodeau avatar Jul 16 '21 07:07 KSBilodeau

It's known that windows consoles can be slower than Unix terminals. Prevent unnecessarily draw calls. So \n should not work in raw modes, perhaps this can be fixed. http://winapi.freetechsecrets.com/win32/WIN32SetConsoleMode.htm

Over here we have a raw mode mask that is used to set the winapi raw console mode. When I look at winapi specs I see we do not unset 'ENABLE_PROCESSED_OUTPUT':

Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or ReadConsole function are examined for ASCII control sequences and the correct action is performed. Backspace, tab, bell, carriage return, and linefeed characters are processed.

I wonder if enabling this could fix the issue. Since we currently only disable the ENABLE_PROCESSED_INPUT flag it will only apply to input not output.

TimonPost avatar Jul 17 '21 10:07 TimonPost

Hello, my terminal blinks anytime I press a key. I'm too much of a noob to figure out how to fix my code. Currently, I run print!("{esc}[2J{esc}[1;1H", esc = 27 as char) every event.

    enable_raw_mode()?;
    async_std::task::block_on(print_events(selector));
    disable_raw_mode()

any alternatives are welcome.

PS; if u want me to delete my comment ill do so.

NicTanghe avatar Jul 25 '21 18:07 NicTanghe

Just prevent system calls, especially flush operations.

TimonPost avatar Jul 26 '21 16:07 TimonPost

How would I go about doing that ?

NicTanghe avatar Jul 27 '21 10:07 NicTanghe

Look into the 'queue' macro crossterm provides. Basically don't call 'stdout().flush()' every frame or use \n\r, those things cause a flush to the underlying output which is a system call that can make your program slow depending on the interval you call it at. And I am not sure if you do this, but do not enable/disable raw mode each frame. Prevent printline commands if they are not required. You can write your escape codes/text to a writable buffer first, and once in a while flush it (writing it to output).

TimonPost avatar Jul 27 '21 12:07 TimonPost