jupyter-xeus / cpp-terminal

C++ library for writing multiplatform terminal applications
https://jupyter-xeus.github.io/cpp-terminal/
Other
513 stars 54 forks source link

Bug: Text Wrap Incompatibility #268

Open TobiasWallner opened 1 year ago

TobiasWallner commented 1 year ago

I noticed that if in the terminal properties (windows cmd and powershell) if I turn off 'properties>layout>wrap text output on resize' and I resize the window in a way where I make it smaller and make the border touch a printed character, the terminal would crash.

For example when starting the 'menue' from the example programs, the program would crash when resizing with disabled text wrapping once the window got smaller than the printed menue itself. However, it would not crash when text wrapping was turned on.

Interestingly other programs from the example folder like 'colors' would not crash. But they would if I add the following line:

Term::terminal.setOptions(Term::Option::ClearScreen, Term::Option::NoSignalKeys, Term::Option::NoCursor, Term::Option::Raw);

and then recompile, start the colors program, turned of line wrapping in the console and then made the console window smaller until it touched one of the printed color bars and it would crash too.

So something in setOptions() makes the Windows terminals crash, but I have not figured out what exactly, since it is very difficult to debug a problem where your whole terminal dissapears and your debug tools cannot give you a stack trace.

Is this a cpp-terminal or a Windows bug?

In case you are wondering why I wanted to disable line wrapping .... so that resizeing the window does not make all the text lines go wild.

TobiasWallner commented 1 year ago

Ok so I think it has something to do with the Term::Option::Raw option

flagarde commented 1 year ago

We can investigate on this but maybe it's a windows bug. Some options are incompatible and windows help pages are very cryptic to me. Their "logic" is counterintuitive to me 😂

But it's very nice you do some test and report this problem. Maybe people with more knowledge will know how to solve this or tell us if it's a windows feature.

flagarde commented 1 year ago

@TobiasWallner By the way, what is the wrap text output on resize doing ?

TobiasWallner commented 1 year ago

by default wrap text output on resize is turned on, and it enables line wrapping when resizeing the window. So you can imageine that when you make the window width by one symbol larger there is now an empty symbol at the end of every line. One way of filling that is by using the first character of the following line and thus shifting all lines by one symbol to the left times their line count (This is the default when wrap text output on resize is turned on).

And that happens by the console, before my program has time to print a new screen so when resizeing I get those wild and crazy screens where everything is all over the place.

Another way is by filling it with a space which would happen when you deactivate that feature. Which works great if you make the window larger. Then the screen does not go wild and everything stays where it is. However, when makeing the window smaller there is a tendency of crashing the console.

flagarde commented 1 year ago

@TobiasWallner Very strange indeed :( Cousl you provide some code for me to try on my desktop ?

TobiasWallner commented 1 year ago
// c++ std
#include <chrono>
#include <thread>

// cpp-terminal
#include <cpp-terminal/terminal.hpp>
#include <cpp-terminal/event.hpp>
#include <cpp-terminal/key.hpp>
#include <cpp-terminal/cursor.hpp>
#include <cpp-terminal/input.hpp>

#define move_not_newline

int main(){
    using namespace std::chrono_literals;

    // set options for the console
    Term::terminal.setOptions(
        Term::Option::ClearScreen,  // start from a cear screen
        Term::Option::NoSignalKeys, // deactivate key combinations that generate a signal or interrupt
        Term::Option::NoCursor,     // deactivate the cursor, we will display it ourselfs
        Term::Option::Raw           // get the raw and unprozessed io data from the console buffers
    );

    while(true){
        Term::terminal 
            #ifdef move_not_newline
            << Term::cursor_move(1, 1) 
            #else
            << '\n'
            #endif
            << "When the console property 'Wrap Text output on resize' is turned off"
            #ifdef move_not_newline
            << Term::cursor_move(2, 1) 
            #else
            << '\n'
            #endif
            << "The application crashes if the window gets too small. Beware the prozess will not properly end."
            #ifdef move_not_newline
            << Term::cursor_move(3, 1) 
            #else
            << '\n'
            #endif
            << "Press any key to end";

        auto event = Term::read_event();
        if(event.type() == Term::Event::Type::Key){
            break;
        }
    }

}