Terminal.Gui icon indicating copy to clipboard operation
Terminal.Gui copied to clipboard

Make non-fullscreen apps possible

Open alexwnovak opened this issue 5 years ago • 38 comments

What I'm Looking For

I'm interested in drawing controls over the current terminal, instead of switching away to a completely different screen.

What I've Tried

I've tried just about everything I can think of, but I always end up with a terminal full of blue. I'm on Windows 10, .NET 4.7.1.

  • Creating a new Toplevel with a frame of 100x1 and using that with Application.Run
  • I thought maybe the Init() call was goofing me up, so I tried subclassing Toplevel and setting those values myself, then using that subclass with Application.Run<T> to use the Func<Toplevel> overload of Application.Init
  • A variety of Window or Toplevel instances that set the bounds smaller than the terminal extents

I didn't see anything in the docs or any Google results or any Stack Overflow tags. Am I just missing it? Or is this not supported? (If not, I can fill out an enhancement issue :grin:)

Thanks!

alexwnovak avatar Oct 12 '19 23:10 alexwnovak

I had not considered that scenario, so some work will be required.

This would only work on Windows where it is possible to control part of the screen without touching the rest, on terminals, we do not really know what the screen contains when we draw, nor can we "save" the contents that we draw on.

So possible, but you will have to figure it out :-)

migueldeicaza avatar Mar 25 '20 15:03 migueldeicaza

Thx for the reply. I had worried we'd need Win32 APIs and couldn't rely on VT sequences. Oh well. XD

alexwnovak avatar Apr 15 '20 02:04 alexwnovak

Update: I have discovered that it is possible to read the contents of the terminal on some terminals. What terminal are you interested in?

If this were to work, we could create a "screenshot" view that would be initialized with data before the application starts to run. Perhaps an Application.Init (screenshot: true), and then we could surface an Application.StartupView that contains the original view that happens to be the top-level where you add elements. So it is technically going to repaint, but it will look like the original text.

This should work with some xterm-derivatives, not sure if this will work with other terminals like the ones used in VSCode, the Windows terminal and the Linux console.

migueldeicaza avatar Apr 15 '20 20:04 migueldeicaza

On Windows, I used to run ConEmu exclusively until Windows Terminal came out. On Mac I run zsh under iTerm2. I'm not much of a Linux user.

This is a neat idea, and I'd love it if it were a cross-plat solution that everyone could get in on, but I'm not holding my breath. :sunglasses: Thanks for looking into it.

alexwnovak avatar Apr 16 '20 01:04 alexwnovak

FWIW, I really want this to be an option for out-consolegridview. See the use case of using OCGV for displaying history. In that use-case it would be ideal if OCGV didn't take over the whole screen.

https://github.com/PowerShell/GraphicalTools/issues/96

tig avatar Jun 04 '20 04:06 tig

Related to OCGV but would probably need to be implemented downstream, is if it took up half the view, and which half depended on where the current cursor position was. As long as gui.cs allowed a setting to choose "top half" or "lower half" then its probably possible.

JustinGrote avatar Jan 22 '21 17:01 JustinGrote

Related to OCGV but would probably need to be implemented downstream, is if it took up half the view, and which half depended on where the current cursor position was. As long as gui.cs allowed a setting to choose "top half" or "lower half" then its probably possible.

Neat idea. So ocgv -PopupRight would cause only the right part of the screen, starting at the prompt cursor location to be occluded by ocgv? ocgv -PopupBelow would cause only space below the prompt cursor to be occluded? Etc.?

tig avatar Jan 22 '21 18:01 tig

@tig I would expect it to be more intelligent than that. ocgv would either only take over the top half or bottom half of the screen depending on if your prompt was at the top of the screen (e.g. new window) vs bottom (youv'e been doing stuff a while). Basically the goal would be to not overlay over your existing command so you can maintain visual context of what you're working on.

JustinGrote avatar Jan 22 '21 18:01 JustinGrote

This is a neat idea, and I'd love it if it were a cross-plat solution that everyone could get in on, but I'm not holding my breath. 😎

I think the changes I did in the NetDriver, starting using virtual sequences may be the best solution for cross-platform, but it need to be worked better yet.

BDisp avatar Jan 22 '21 18:01 BDisp

Neat idea. So ocgv -PopupRight would cause only the right part of the screen, starting at the prompt cursor location to be occluded by ocgv? ocgv -PopupBelow would cause only space below the prompt cursor to be occluded? Etc.?

The recent changes I did in the ListView and TextView already manipulate the scrolling top/bottom and left/right. The ScrollBarView I had included is only for position indicator and notify fthe host for changes positions, but the scrolling redraw is up to host.

BDisp avatar Jan 22 '21 18:01 BDisp

What we could do is ensure that the Toplevel only takes over a part of the screen, and that it does not go beyond it - at least this should be possible on Windows. To complete the story, we could retrieve the contents of the screen and store them while we run and restore them on exit.

This gave me the idea: instead of making the code work with a subset of the screen, we could have a "PreviousScreenshotView" that is a view that gets loaded with the original contents - this would allow for example to have views that can change size, windows popup and other things, without having to worry about not touching something in particular.

On shut down, this view could repaint the original contents.

This on Windows should be pretty easy.

For Unix, I never thought this could be possible, but then I remembered that in xterm and newer terminals there is a way of retrieving the contents of the terminal. This is what various test-suites use to validate that terminals use.

While this would be limited to xterm-like terminals, I think Windows + xterm should cover pretty much anything out there. The only Unix challenge would be to precisely map the previous screen attributes to ncurses attributes, but that is a minor problem.

migueldeicaza avatar Jan 24 '21 04:01 migueldeicaza

// I've changed the title of this Issue to make it a feature request.

tig avatar May 31 '21 22:05 tig

My PR #1331, with Mdi Container could be a solution for this. Setting Toplevel.IsMdiContainer as true we can create many Windows and Toplevels and navigate throught them.

BDisp avatar Jul 13 '21 18:07 BDisp

I would love using a terminal roughly like that ...

$ cat log.log
A
B
C
D
E
$ dotnet run app-with-gui.cs
==================================================================
| What is your favourite color: _Purple__________                |
| What is your favourite pet:   _Dog_____________                |
| [Save] [Cancel]                                                |
==================================================================
$ wc Program.cs
234134

I tried Specte.Console as an alternative but that library is not supporting multi-widget re-rendering and is more focused on outputting information. I want to use one of the two libraries to built a console UI for a work item library.

tthiery avatar May 26 '22 21:05 tthiery