spec: propose an evolution of closeOnExit (#2039)
This commit is contained in:
parent
6dec0b66d2
commit
b3ecb7392f
|
@ -0,0 +1,107 @@
|
|||
---
|
||||
author: Dustin Howett @DHowett-MSFT
|
||||
created on: 2019-07-19
|
||||
last updated: 2019-11-05
|
||||
issue id: "#2563"
|
||||
---
|
||||
|
||||
# Improvements to CloseOnExit
|
||||
|
||||
## Abstract
|
||||
|
||||
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.
|
||||
|
||||
### Conventions and Terminology
|
||||
|
||||
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](https://tools.ietf.org/html/rfc2119).
|
||||
|
||||
## Inspiration
|
||||
|
||||
Other terminal emulators like ConEmu have a similar feature.
|
||||
|
||||
## Solution Design
|
||||
|
||||
### `ITerminalConnection` Changes
|
||||
|
||||
* 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 state
|
||||
* `Connecting`: The connection has been initated, 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.)
|
||||
* event `TerminalDisconnected` will be removed, as it is replaced by `StateChanged`
|
||||
* **NOTE**: A conforming implementation MUST treat states as a directed acyclic graph. States MUST NOT be transitioned in reverse.
|
||||
* A helper class may be provided for managing state transitions.
|
||||
|
||||
### `TerminalControl` Changes
|
||||
|
||||
* 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 a `ConnectionStateChanged` event.
|
||||
* `event ConnectionStateChanged(TerminalControl, IInspectable)` event will project its connection's `StateChanged` event.
|
||||
* TerminalControl's new `ConnectionState` will project its connection's `State`.
|
||||
* (this is indicated for an eventual data binding; see Future Considerations.)
|
||||
|
||||
### Application and Settings
|
||||
|
||||
1. The existing `closeOnExit` profile key will be replaced with an enumerated string key supporting the following values (behaviours):
|
||||
* `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 the `Closed` 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 be `graceful`.**
|
||||
2. `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.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
* The existing `ITerminalConnection` implementations will be augmented to print out interesting and useful status information when they transition into a `Closed` or `Failed` state.
|
||||
* Example (ConPTY connection)
|
||||
* The pseudoconsole cannot be opened, or the process fails to launch.<br>`[failed to spawn 'thing': 0x80070002]`, transition to `Failed`.
|
||||
* The process exited unexpectedly.<br>`[process exited with code 300]`, transition to `Failed`.
|
||||
* The process exited normally.<br>`[process exited with code 0]`, transition to `Closed`.
|
||||
* _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 is `Closed`. A connection in the `Failed` 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.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
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.
|
||||
|
||||
### Security
|
||||
|
||||
There will be no impact to security.
|
||||
|
||||
### Reliability
|
||||
|
||||
Windows Terminal will no longer immediately terminate on startup if the user's shell doesn't exist.
|
||||
|
||||
### Compatibility
|
||||
|
||||
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.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
## Potential Issues
|
||||
|
||||
There will be no impact to Performance, Power or Efficiency.
|
||||
|
||||
## Future considerations
|
||||
|
||||
* 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" }`
|
||||
* 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.
|
Loading…
Reference in a new issue