Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failing To Render On Windows Terminal #703

Open
sangeethnandakumar opened this issue Jan 26, 2022 · 6 comments
Open

Failing To Render On Windows Terminal #703

sangeethnandakumar opened this issue Jan 26, 2022 · 6 comments
Labels
bug Something isn't working ⭐ top bug Top bug.

Comments

@sangeethnandakumar
Copy link

sangeethnandakumar commented Jan 26, 2022

Ways To Reproduce:

  1. Setup Windows Terminal (https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701#activetab=pivot:overviewtab) with Visual Studio.
  2. Create a simple progress view

using Spectre.Console;

AnsiConsole.Progress()
    .Start(ctx =>
    {
        // Define tasks
        var task1 = ctx.AddTask("[green]Reticulating splines[/]");
        var task2 = ctx.AddTask("[green]Folding space[/]");

        while (!ctx.IsFinished)
        {
            task1.Increment(1.5);
            task2.Increment(0.5);
            Thread.Sleep(100);
        }
    });

Console.ReadKey();
  1. Run the program. This will print and updates an active progress bar
    image

  2. Now adjust the width of Windows Terminal while progress bar is running. The render fails and messes up the console.
    image

  3. There is no going back after this. Once console got messy, Even if we resize the console back to normal or maximized stage, The screen won't update to normal way


Please upvote 👍 this issue if you are interested in it.

@sangeethnandakumar sangeethnandakumar added the bug Something isn't working label Jan 26, 2022
@mgood7123
Copy link

mgood7123 commented Apr 23, 2022

this works fine in Windows Console

do note, that trying to update text WHILE it is resizing is often UB in all terminals

after the console has been resized, the Row and Width info are unreliable and you cannot update test unless you restore to original or greater window size

for example if you know you need to move up 5 rows to get to the start, and to resize to 2 width, then moving up 5 rows will not get you to start, corrupting your output

same for columns and width

also occurs when resizing smaller than what is being updated in terms of height

such is very difficult to fix and standardize

@sangeethnandakumar
Copy link
Author

sangeethnandakumar commented Nov 7, 2022

That is true. When terminals are resizing it's challenging to keep up with size.
But can we do something like this, Just an idea only not sure if it comes with challenges

  1. Listen to Window Resize events from running terminal
  2. When a resize event is triggered, Immediately store the current state of renderer
  3. Hault until window resize done
  4. Repaint the renderer state with updated window size

Anyways, Big thanks for this awesome library.

@FrankRay78
Copy link
Contributor

Is there a cross-platform / cross-terminal way to hook into window resize events?

@sangeethnandakumar
Copy link
Author

How about this goes with cross-platform & cross-terminal?

Demo

image

Code

 static void Main(string[] args)
 {
     // Store the initial terminal size
     int initialWidth = Console.WindowWidth;
     int initialHeight = Console.WindowHeight;

     // Register for the terminal resize event
     Console.CancelKeyPress += (sender, eventArgs) =>
     {
         // Check if the event was a terminal resize (e.g., Ctrl+C)
         if (eventArgs.SpecialKey == ConsoleSpecialKey.ControlC)
         {
             // Handle the terminal resize event here
             Console.WriteLine("Terminal resized");
         }
     };

     // Continuously monitor and print the terminal size
     while (true)
     {
         // Check the current terminal size
         int currentWidth = Console.WindowWidth;
         int currentHeight = Console.WindowHeight;

         // Print the current size
         Console.WriteLine($"Terminal Size: {currentWidth} columns x {currentHeight} rows");

         // Sleep briefly before checking again
         Thread.Sleep(1000); // Adjust the sleep interval as needed
     }
 }

@sangeethnandakumar
Copy link
Author

Other approaches include:

  • In Linux, we can use the SIGWINCH signal to detect terminal resize events.
  • In MacOS also, we can use the SIGWINCH signal to detect terminal resize events.
  • In Windows, we can use the CONSOLE_FONT_INFOEX structure and related functions.

Mono Posix Approach

Otherwise for Unix-Like systems (like Linux or MacOS). We can also rely on this Mono Posix NuGet -

Mono.Posix is a library that provides access to Unix-specific APIs from C# or .NET applications. It allows you to interact with Unix-like operating systems (such as Linux and macOS) and access functionality not typically available in cross-platform .NET code.

Repo:
https://github.com/mono/mono.posix

Couldn't check all the aspects of the below code fully. Only did a basic test on a VM running Ubuntu:

using System;
using Mono.Unix;
using Mono.Unix.Native;

class Program
{
    static void Main(string[] args)
    {
        // Register for the terminal resize signal
        UnixSignal[] signals = new UnixSignal[] {
            new UnixSignal(Signum.SIGWINCH)
        };

        Console.WriteLine("Listening for terminal resize events. Press Ctrl+C to exit.");

        while (true)
        {
            // Wait for a signal (including terminal resize)
            int index = UnixSignal.WaitAny(signals);

            // Check if the signal is due to a terminal resize
            if (signals[index].Signum == Signum.SIGWINCH)
            {
                Console.WriteLine("Terminal resized");
            }
        }
    }
}

@FrankRay78
Copy link
Contributor

It's an area I'm quite interested in, and thanks for the code contribution above @sangeethnandakumar. However, for me, at this time, it's unlikely I'll do anything more than simply watch this issue from the sidelines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ⭐ top bug Top bug.
Projects
Status: Todo 🕑
Development

No branches or pull requests

3 participants