elw00d / consoleframework

Cross-platform toolkit for easy development of TUI applications.
http://elw00d.github.io/consoleframework
MIT License
550 stars 63 forks source link

Framework doesn't work in GitBash terminal emulator #61

Open webmaster442 opened 4 years ago

webmaster442 commented 4 years ago

Programs using the consoleframework can't run in terminal emulators, like GitBash command prompt. An Exception is thrown (invalid handle) at the start of the program.

Reproduction steps

  1. Have a small program, like:
using ConsoleFramework;
using ConsoleFramework.Controls;

namespace CrashTest
{
    class Program
    {
        static void Main(string[] args)
        {

            WindowsHost windowsHost = new WindowsHost();
            Window window = new Window();
            window.Content = new TextBlock
            {
                Text = "This will crash in Terminal Emulator"
            };
            windowsHost.Show(window);
            ConsoleApplication.Instance.Run(windowsHost);

        }
    }
}
  1. Compile it and try to execute it GitBash terminal ./CrashTest.exe

Result:

Unhandled exception. System.IO.IOException: Invalid handle.
   at System.ConsolePal.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
   at System.Console.get_WindowLeft()
   at ConsoleFramework.ConsoleApplication.runWindows(Control control)
   at ConsoleFramework.ConsoleApplication.Run(Control control)
   at CrashTest.Program.Main(String[] args) in Program.cs:line 18

Expected:

UI, like in Windows Command prompt (cmd.exe)

elw00d commented 4 years ago

I think GuiBash is not the best choice to run TUI apps compiled for Windows )

GuiBash is designed to run cross-compiled unix programs and does not guarantee that all win32 api will be available inside it. But console-framework app compiled for Windows tries to use Win32 console api, not unix api (cross-compiled libc, ncurses).

I think on Windows there is better option to run console-based TUI apps on standard cmd terminal.

ForNeVeR commented 4 years ago

For example, Far Manager doesn't work in the "Git Bash" (mintty terminal emulator, actually) directly, either.

There's a special wrapper program that converts observable WinAPI console behavior to ANSI terminal commands, which is called winpty. It is available in the Git Bash environment, and Windows programs with TUI based on WinAPI (e.g. Far Manager or programs written using ConsoleFramework) are runnable via winpty, I've just checked both.

Just run winpty followed by your program arguments, and it will work: image

It would be cool to have ConsoleFramework run in "pure ANSI" mode on top of any ANSI-compatible terminal, because, since Windows 10, the native conhost is ANSI-compatible, too. I'm not sure if it's a viable approach to suggest that improvement though. It looks like we still need some stuff from environment, like terminal size and such, which couldn't be easily retrieved using the "pure ANSI" approach, and would probably require some additional measures to link against mintty environment.

ForNeVeR commented 4 years ago

Mouse doesn't seem to work well under winpty, though: when I click the top of the window (point 1 on the picture below), it registers click on the top of the ConsoleFramework canvas (point 2):

image

Probably this is something which could be improved, because Far Manager works perfectly with this setup: it eats the whole buffer (maybe because it prints text to the whole buffer, while the canvas of my test ConsoleFramework program was mostly empty), and mouse clicks are registered properly.

I believe we could introduce a compatibility hack for mintty: print a character to the very end of our buffer to force terminal scrolling and reduce the amount of mouse-related bugs. It could be introduced manually by program authors though, and I don't know a reliable way to detect mintty terminal environment: it reports TERM=xterm.

ForNeVeR commented 4 years ago

And, for the record, I've found some crazy Haskell code that detects whether the program is running in mintty by messing with stderr handle. Not sure if we want the mintty workaround that much though :)