author | created on | last updated | issue id |
---|---|---|---|
Dustin Howett @DHowett-MSFT |
2019-07-19 |
2019-11-05 |
#2563 |
This specification describes an improvement to the closeOnExit
profile feature and the ITerminalConnection
interface that will offer greater flexibility and allow us to provide saner defaults in the face of unreliable software.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Other terminal emulators like ConEmu have a similar feature.
- The
TerminalConnection
interface will be augmented with an enumerator and a set of events regarding connection state transitions.- enum
TerminalConnection::ConnectionState
- This enum attempts to encompass all potential connection states, even those which do not make sense for a local terminal.
- The wide variety of values will be useful to indicate state changes in a user interface.
NotConnected
: All new connections will start out in this stateConnecting
: The connection has been initiated, but has not yet completed connecting.Connected
: The connection is active.Closing
: The connection is being closed (usually by request).Closed
: The connection has been closed, either by request or from the remote end terminating successfully.Failed
: The connection was unexpectedly terminated.
- event
StateChanged(ITerminalConnection, IInspectable)
- (the
IInspectable
argument is recommended and required for a typed event handler, but it will bear no payload.)
- (the
- event
TerminalDisconnected
will be removed, as it is replaced byStateChanged
- NOTE: A conforming implementation MUST treat states as a directed acyclic graph. States MUST NOT be transitioned in reverse.
- enum
- A helper class may be provided for managing state transitions.
- As the decision as to whether to close a terminal control hosting a connection that has transitioned into a terminal state will be made by the application, the unexpressive
Close
event will be removed and replaced with aConnectionStateChanged
event. event ConnectionStateChanged(TerminalControl, IInspectable)
event will project its connection'sStateChanged
event.- TerminalControl's new
ConnectionState
will project its connection'sState
.- (this is indicated for an eventual data binding; see Future Considerations.)
- The existing
closeOnExit
profile key will be replaced with an enumerated string key supporting the following values (behaviors):always
- a tab or pane hosting this profile will always be closed when the launched connection reaches a terminal state.graceful
- a tab or pane hosting this profile will be closed if and only if the launched connection reaches theClosed
terminal state.never
- a tab or pane hosting this profile will not automatically close.- See the Compatibility section for information on the legacy settings transition.
- The new default value for
closeOnExit
will begraceful
.
Pane
will remain responsible for making the final determination as to whether it is closed based on the settings of the profile it is hosting.
- The existing
ITerminalConnection
implementations will be augmented to print out interesting and useful status information when they transition into aClosed
orFailed
state.- Example (ConPTY connection)
- The pseudoconsole cannot be opened, or the process fails to launch.
[failed to spawn 'thing': 0x80070002]
, transition toFailed
. - The process exited unexpectedly.
[process exited with code 300]
, transition toFailed
. - The process exited normally.
[process exited with code 0]
, transition toClosed
.
- The pseudoconsole cannot be opened, or the process fails to launch.
- Example (ConPTY connection)
- The final message will always be printed regardless of user configuration.
- If the user's settings specify
closeOnExit: never/false
, the terminal hosting the connection will never be automatically closed. The message will remain on-screen. - If the user's settings specify
closeOnExit: graceful/true
, the terminal hosting the connection will automatically be closed if the connection's state isClosed
. A connection in theFailed
state will not be closed, and the message will remain on-screen. - If the user's settings specify
closeOnExit: always
, the terminal hosting the connection will be closed. The message will not be seen.
This will give users of all technologies a way to know when their shell has failed to launch or has exited with an unexpected status code.
There will be no impact to security.
Windows Terminal will no longer immediately terminate on startup if the user's shell doesn't exist.
There is an existing closeOnExit
boolean key that a user may have configured in profiles.json. The boolean values should map as follows:
true
->graceful
false
->never
This will make for a clean transition to Windows Terminal's sane new defaults.
There will be no impact to Performance, Power or Efficiency.
- Eventually, we may want to implement a feature like "only close on graceful exit if the shell was running for more than X seconds". This puts us in a better position to do that, as we can detect graceful and clumsy exits more readily.
- (potential suggestion:
{ "closeOnExit": "10s" }
- (potential suggestion:
- The enumerator values for transitioning connection states will be useful for connections that require internet access.
- Since the connection states are exposed through
TerminalControl
, they should be able to be data-bound to other Xaml elements. This can be used to provide discrete UI states for terminal controls, panes or tabs hosting terminal controls.- Example: a tab hosting a terminal control whose connection has been broken MAY display a red border.
- Example: an inactive tab that reaches the
Connected
state MAY flash to indicate that it is ready.