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

When the terminal has exited, ctrl+D to close pane, Enter to restart terminal #14060

Merged
14 commits merged into from
Dec 8, 2022

Conversation

sotteson1
Copy link
Contributor

@sotteson1 sotteson1 commented Sep 22, 2022

When a terminal process exits (successful or not) and the profile isn't
set to automatically close the pane, a new message is displayed:

You can now close this terminal with ^D or Enter to restart.

Ctrl+D then is able to close the pane and Enter restarts it.

I originally tried to do this at the ConptyConnection layer by changing
the connection state from Failed to Closed, but then that didn't work
for the case where the process exited successfully but the profile isn't
set to exit automatically. So, I added an event to
ControlCore/TermControl that Pane watches. ControlCore watches to see if
the input is Ctrl+D (0x4) and if the connection is closed or failed, and
then raises the event so that Pane can close itself. As it turned out, I
think this is the better place to have the logic to watch for the Ctrl+D
key. Doing it at the ConptyConnection layer meant I had to parse out the
key from the escaped text passed to ConptyConnection::WriteInput.

Validation Steps Performed

Tried adding lots of panes and then killing the processes outside of
Terminal. Each showed the new message and I could close them with Ctrl+D
or restart them with Enter. Also set a profile to never close
automatically to make sure Ctrl+D would work when a process exits
successfully.

Closes #12849
Closes #11570
Closes #4379

@ghost ghost added Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal. labels Sep 22, 2022
@sotteson1 sotteson1 changed the title Ctrl+d to close a pane when the terminal has exited When the terminal has exited, ctrl+D to close pane, Enter to restart terminal Sep 23, 2022
Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the one thing. This is awesome, thanks!

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Sep 26, 2022
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! I've got a couple thoughts before I dig into the code (whereupon I'm preemptively blocking to have the discussion/avoid it merging while we noodle!)

  • I'm a little worried about making connections restartable. In our original connection state flow model, connections never regressed and only marched forward to one of the terminal states (finished, failed). There's a few knock-on effects as a result of this change: output threads need to be restartable, and listeners to the state change notification need to be audited to make sure they, too, can handle regressive state flow.
    • I wonder, does TerminalControl or TerminalApp have enough information to reconstruct the connection anew?
  • Should we emit a RIS (hard reset) to the terminal before restarting? Apps like vim and MC leaving the terminal in an inconsistent state when they die is a big cause of user confusion, and this feature might offer similar behavior across application sessions/conpty sessions.

@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Sep 27, 2022
@sotteson1
Copy link
Contributor Author

sotteson1 commented Sep 27, 2022

  • I'm a little worried about making connections restartable. In our original connection state flow model, connections never regressed and only marched forward to one of the terminal states (finished, failed). There's a few knock-on effects as a result of this change: output threads need to be restartable, and listeners to the state change notification need to be audited to make sure they, too, can handle regressive state flow.

I totally get the concern about the connection going back to the beginning from closed/failed. I wasn't sure I could get it to work without changing a lot of stuff, but I think I found a minimal way to do it. Also, I make sure I've closed the output thread and the pipes before I restart. Maybe there's more to it than that. I've only been looking at this code for a week now, so I'm definitely no expert!

As for cursor inheritance, the big thing I had to figure out was to always preserve the changing size (rows, cols), even when closed/failed, and then use them when restarting. Before I figured that out, it was always using the initial size which wasn't always guaranteed to be what the pane was currently using, and weird things happened in the output.

Also, I considered clearing/resetting the buffer at restart instead of inheriting the current cursor. That might be safer, although I saw that people were asking to reuse the buffer when restarting, so that's what I was trying to do.

carlos-zamora added a commit that referenced this pull request Oct 8, 2022
carlos-zamora added a commit that referenced this pull request Oct 11, 2022
@vadimkantorov
Copy link

One minor comment: Ctrl+D may be a clearer message and match keybinding info in tab tooltips, at least makes sense to add it in brackets ^D (i.e. Ctrl+D)

@zadjii-msft
Copy link
Member

Initial thought just playing with this: hot DAMN re-using the same terminal feels crisp. I kinda imagined the restart being a whole "discard the existing TermControl and recreate a new one in its place", but this is neat.

I agree that we might want to avoid "restartable connections", and instead make fresh connections. That can totally be an us problem IMO, as a pre-ship codehealth fix (I don't really want to ask you to do that).

carlos-zamora added a commit that referenced this pull request Oct 25, 2022
@sotteson1
Copy link
Contributor Author

Initial thought just playing with this: hot DAMN re-using the same terminal feels crisp. I kinda imagined the restart being a whole "discard the existing TermControl and recreate a new one in its place", but this is neat.

Yeah, when I got it working, I thought it was pretty slick. I have terminals running PowerShell where it would be nice to say "exit" and then be able to hit Enter to get a fresh terminal with the same command line parameters that started it. Much better than exiting the tab and hunting down the one I want to start a clean one.

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is really straightforward. Yea, lets do this. I'll file the follow up to this, I wouldn't want to bother a non-team member with that kind of code shuffling

return true;
}

if (ch == Enter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: file a blocking codehealth task, to turn this into an event for the control to request from the app a new connection.

void _resetConnectionState()
{
{
std::lock_guard<std::mutex> stateLock{ _stateMutex };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: removing this delta should be part of the codehealth follow-up

@sotteson1
Copy link
Contributor Author

One minor comment: Ctrl+D may be a clearer message and match keybinding info in tab tooltips, at least makes sense to add it in brackets ^D (i.e. Ctrl+D)

I went ahead and just changed it to Ctrl+D in the text.

@sotteson1
Copy link
Contributor Author

If you can, please fix merge conflicts too :). Thanks for being so patient with us.

Done!

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@DHowett
Copy link
Member

DHowett commented Dec 8, 2022

Moved from PR body

image

@sotteson1 thanks so much for this, and for your patience!

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm cool with this, but I did have a minor rewording suggestion and a question.

Thanks again!

And thank you Mike for taking on the follow up work 😄

@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label Dec 8, 2022
@ghost
Copy link

ghost commented Dec 8, 2022

Hello @zadjii-msft!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost
Copy link

ghost commented Jan 24, 2023

🎉Windows Terminal Preview v1.17.1023 has been released which incorporates this pull request.:tada:

Handy links:

DHowett pushed a commit that referenced this pull request Apr 28, 2023
A different take on #14548.

> We didn't love that a connection could transition back in the state
diagram, from Closed -> Start. That felt wrong. To remedy this, we're
going to allow the ControlCore to...

ASK the app to restart its connection. This is a much more sensible
approach, than leaving the ConnectionInfo in the core and having the
core do the restart itself. That's mental.

Cleanup from #14060

Closes #14327

Obsoletes #14548
DHowett pushed a commit that referenced this pull request Apr 28, 2023
Adds an action for immediately restarting the connection. I suspect
most folks that wanted #3726 will be happy just with the
<kbd>enter</kbd> solution from #14060, but this will work without having
to `exit` the client. Just, relaunch whatever the commandline is. Easy
peasy.

Closes #3726.

Obsoletes #14549
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal. zBugBash-Consider
Projects
None yet
6 participants