-
Notifications
You must be signed in to change notification settings - Fork 696
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
Make non-fullscreen apps possible #272
Comments
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 :-) |
Thx for the reply. I had worried we'd need Win32 APIs and couldn't rely on VT sequences. Oh well. XD |
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 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. |
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. 😎 Thanks for looking into it. |
FWIW, I really want this to be an option for |
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 |
@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. |
I think the changes I did in the |
The recent changes I did in the |
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. |
// I've changed the title of this Issue to make it a feature request. |
My PR #1331, with |
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 |
I'll add my vote to this feature request. My primary use case would be a PowerShell session running in Windows Terminal. |
After thinking about this for a few years, I think that the solution is simple. We do need a "View" that is "OriginalView", and this can be used as the background view, upon which you would run everything else. The OriginalView would be initialized on Windows using the Console API to retrieve the contents of the screen, and on Unix/Xterms/network connections you can use the escape sequences to read the screen contents (DECRQCRA sequence). It might not be fast, so I recommend that this is an opt-in feature. The reason that it might not be fast is because DECRQCRA is used to checksum the screen, it is not really an API to read the contents, so you need to scan the columns/rows one at a time to capture the contents. |
I'd like to understand more about this approach. Why store the screen history? Is the goal to have the 'background' view render that content? We should identify use cases to better understand the requirements and complexity:
These seem to be in order of increasing difficulty. I think the screen history bit is required for the second use case, and the third sounds quite challenging, if not impossible. Are there other libraries that have this kind of feature we can investigate for ideas? UPDATE: Are there any security considerations to reading old terminal buffer? It could have sensitive stuff in it. |
Some terminals disable that escape sequence for security reasons. But if you are running code, there is very little you can do to stop the app from doing whatever they want, like they could just an external screenshot app for example. |
Relevant. Mintty is leading the charge in many ways. See status line. https://github.com/mintty/mintty/blob/master/wiki/CtrlSeqs.md |
Specifically here: https://github.com/mintty/mintty/blob/master/wiki/CtrlSeqs.md#status-line--area It should be trivial to add support for this. Add a I believe this would automatically constrain the TUI app to the bottom |
A view that displays the contents of the buffer is a good idea. However, this content does not differentiate between newlines whether it is a word wrap or whether it is actually a line break, because it does not store '\n' or '\r\n'. Therefore, when resizing the console, the formatting will be corrupted and it will never be possible to reformat correctly. |
Theoretically, it should be possible for a terminal to retain the source data in the back buffer so that it can resize the back buffer properly. I recall reading some terminal has actually but I don't remember which one. Regardless, I'm now convinced that we can make great progress on addressing this customer need I simply taking advantage of statusline. While it doesn't give the full flexibility of a "non-fullscreen " app it does meet the Spirit of it. |
Very very rarely, as even things like |
I believe less/man rely on switching screens, not on reading the contents of the screen. That is why it is preserved. |
Correct. I thought that's what you were referring to. The alternate screen buffer switching is how pretty much every app that preserved the terminal state works. Standard part of the C stdlib. |
It is not, because the feature request here is to draw something that appears to leave the original buffer untouched. When you switch to the other screen, you do not have any of the old contents, so we would not get the desired effect. To get the desired effect, we need to somehow get the contents of the screen, so we can render at will and draw at will there. You could draw on top of the existing UI, but in a destructive way (so dragging, or showing/hiding) would permanently destroy the contents. |
I tried something that get the contents but I'm struggling with non-bmp glyphs, color and resizing issues. But I'll try find any some workarounds to overcome them. |
Oh oh oh. Meaning overlay of the current environment, not switching and restoring. 🤦♂️ Ok, I'm on the same page now. |
Yeah grabbing the screen contents without already being the owner of the TTY is a no-no for clearly obvious reasons. We'd need to basically host a terminal, effectively becoming a whole shell to do it cleanly I think. Feels out of scope, especially for v2. That said, if a user wants that kind of behavior, they can host their own terminal in their terminal.gui app. |
While there is such a tool (XtermSharp - a full terminal emulator, and one that had support for an earlier version of Terminal.Gui) that does not let us "read" the existing content - it would only work if we started a new session there. That said, the feature could be added to Windows without any of the downsides. |
None of you commented on my statusline idea above. Did you see it? |
I did not quite understand how that would work. That merely sets aside a region to not be changed (in rows), but my reading of the intent is to be able to layer an arbitrary set of views, and move those, while preserving the illusion of the background. |
Perhaps we can tackle these possibilities seperately? An isolated screen region that is fixed and runs a Terminal.Gui app is probably the easier of the two and still of value in many of these 'non fullscreen' use cases? |
I think my comment resurrected this thread so I feel obligated to chime in. First off, I am not a developer. I have been using this to build things in a PowerShell session. You can think of me as a power user. The technical details you've been throwing around are way above my pay grade. What I would love to have, is the ability to create a smaller TUI that doesn't take over the entire console. I'd like to be able to create a small entry form that is displayed over the contents of the current screen. Like a popup. In a perfect world, it would be nice to specify a position in the terminal for the TUI. I wouldn't expect the user to have to reposition the TUI which sounds complicated to have to redraw the underlying terminal. Where this gets (more) complicated is that I would need to support this in Windows, Linux and MacOS which means I have no idea what terminal might be running PowerShell. To give you an idea, I can create this: But it takes over the entire console. If the consensus is that this is not practical, I'm OK. I figure it never hurts to ask the question. |
This is precisely why I suggested StatusLine. It does not allow arbitrary popups but DOES address the intent of the OP. |
An option that allow arbitrary popups where moving it will always showing the original contents is a better solution. As @migueldeicaza said using a |
I think it is worth trying both because as you say, its a tough task to 'deal with any arbitrary content that might be in console on load' in a cross platform way and also handling environmental factors such as SSH, PuTTy etc. Running in fixed isolated area should be way easier and more robust. It can even have the same API interface so application end user can switch between the two depending on runtime environment? e.g. with UserSettings |
On Unix systems it's possible to switch between apps by pressing |
I have a feeling this issue might be out of scope for a project like this. the whole point of terminal.gui is to make TUIs no? especially if theres already a well working solution for non TUI console apps Spectre.Console it feels like trying to do both in one app makes less sense and also makes it insanely difficult to develop from that point on. Please call me out if im missing something tho |
I guess it depends on your definition of TUI. My opinion is TUI means Terminal User Interface, which literally means "any user interface that runs in a terminal." |
Clipping screen out area should be relatively easy after #3837 The I/O layer just needs to 'lie' to the rest of the world about the size of the terminal. Obviously the terminal isn't usable while Terminal.Gui is running in this case but it's still a nice first step. |
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.
Toplevel
with a frame of 100x1 and using that withApplication.Run
Init()
call was goofing me up, so I tried subclassingToplevel
and setting those values myself, then using that subclass withApplication.Run<T>
to use theFunc<Toplevel>
overload ofApplication.Init
Window
orToplevel
instances that set the bounds smaller than the terminal extentsI 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 😁)
Thanks!
The text was updated successfully, but these errors were encountered: