129 lines
6.0 KiB
Markdown
129 lines
6.0 KiB
Markdown
---
|
|
author: Pankaj Bhojwani, pabhojwa@microsoft.com
|
|
created on: 2020-11-20
|
|
last updated: 2021-2-5
|
|
issue id: #8345
|
|
---
|
|
|
|
# Appearance configuration objects for profiles
|
|
|
|
## Abstract
|
|
|
|
This spec outlines how we can support 'configuration objects' in our profiles, which
|
|
will allow us to render differently depending on the state of the control. For example, a
|
|
control can be rendered differently if it's focused as compared to when it's unfocused.
|
|
|
|
## Inspiration
|
|
|
|
Reference: [#3062](https://github.com/microsoft/terminal/issues/3062)
|
|
|
|
Users want there to be a more visible indicator than the one we have currently for which
|
|
pane is focused and which panes are unfocused. This change would grant us that feature.
|
|
|
|
## Solution Design
|
|
|
|
The implementation design for appearance config objects centers around the recent change where inheritance was added to the
|
|
`TerminalSettings` class in the Terminal Settings Model - i.e. different `TerminalSettings` objects can inherit from each other.
|
|
The reason for this change was that we did not want a settings reload to erase any overrides `TermControl` may have made
|
|
to the settings during runtime. By instead passing a child of the `TerminalSettings` object to the control, we can change
|
|
the parent of the child during a settings reload without the overrides being erased (since those overrides live in the child).
|
|
|
|
The idea behind unfocused appearance configurations is similar. We will pass in another `TerminalSettings` object to the control,
|
|
which is simply a child that already has some overrides in it. When the control gains or loses focus, it simply switches between
|
|
the two settings objects appropriately.
|
|
|
|
### Allowed parameters
|
|
|
|
For now, these states are meant to be entirely appearance-based. So, not all parameters which can be
|
|
defined in a `Profile` can be defined in this new object (for example, we do not want parameters which
|
|
would cause a resize in this object.) Here is the list of parameters we will allow:
|
|
|
|
- Anything regarding colors: `colorScheme`, `foreground`, `background`, `cursorColor` etc
|
|
- Anything regarding background image: `path`, `opacity`, `alignment`, `stretchMode`
|
|
- `cursorShape`
|
|
|
|
We may wish to allow further parameters in these objects in the future (like `bellStyle`?). The addition
|
|
of further parameters can be discussed in the future and is out of scope for this spec.
|
|
|
|
### Inheritance
|
|
|
|
The inheritance model can be thought of as an 'all-or-nothing' approach in the sense that the `unfocusedAppearance` object
|
|
is considered as a *single* setting instead of an object with many settings. We have chosen this model because it is cleaner
|
|
and easier to understand than the alternative, where each setting within an `unfocusedAppearance` object has a parent from which
|
|
it obtains its value.
|
|
|
|
Note that when `TerminalApp` initializes a control, it creates a `TerminalSettings` object for that profile and passes the
|
|
control a child of that object (so that the control can store overrides in the child, as described earlier). If an unfocused
|
|
config is defined in the profile (or in globals/profile defaults), then `TerminalApp` will create a *child of that child*,
|
|
put the relevant overrides in it, and pass that into the control as well. Thus, the inheritance of any undefined parameters
|
|
in the unfocused config will be as follows:
|
|
|
|
1. The unfocused config specified in the profile (or in globals/profile defaults)
|
|
2. Overrides made by the terminal control
|
|
3. The parent profile
|
|
|
|
## UI/UX Design
|
|
|
|
Users will be able to add a new setting to their profiles that will look like this:
|
|
|
|
```
|
|
"unfocusedAppearance":
|
|
{
|
|
"colorScheme": "Campbell",
|
|
"cursorColor": "#888",
|
|
"cursorShape": "emptyBox",
|
|
"foreground": "#C0C0C0",
|
|
"background": "#000000"
|
|
}
|
|
```
|
|
|
|
When certain appearance settings are changed via OSC sequences (such as the background color), only the focused/regular
|
|
appearance will change and the unfocused one will remain unchanged. However, since the unfocused settings object inherits
|
|
from the regular one, it will still apply the change (provided it does not define its own value for that setting).
|
|
|
|
## Capabilities
|
|
|
|
### Accessibility
|
|
|
|
Does not affect accessibility.
|
|
|
|
### Security
|
|
|
|
Does not affect security.
|
|
|
|
### Reliability
|
|
|
|
This is another location in the settings where parsing/loading the settings may fail. However, this is the case
|
|
for any new setting we add so I would say that this is a reasonable cost for this feature.
|
|
|
|
### Compatibility
|
|
|
|
Should not affect compatibility.
|
|
|
|
### Performance, Power, and Efficiency
|
|
|
|
Rapidly switching between many panes, causing several successive appearance changes in a short period of time, could
|
|
potentially impact performance. However, regular/reasonable pane switching should not have a noticeable effect.
|
|
|
|
## Potential Issues
|
|
|
|
Inactive tabs will be 'rendered' in the background with the `UnfocusedRenderingParams` object, we need to make
|
|
sure that switching to an inactive tab (and so causing the renderer to update with the 'normal' parameters)
|
|
does not cause the window to flash/show a jarring indicator that the rendering values changed.
|
|
|
|
## Future considerations
|
|
|
|
We will need to decide how this will look in the settings UI.
|
|
|
|
We may wish to add more states in the future (like 'elevated'). When that happens, we will need to deal with how
|
|
these appearance objects can scale/layer over each other. We had a lot of discussion about this and could not find
|
|
a suitable solution to the problem of multiple states being valid at the same time (like unfocused and elevated).
|
|
This, along with the fact that it is uncertain if there even will be more states we would want to add led us to
|
|
the conclusion that we should only support the unfocused state for now, and come back to this issue later. If there
|
|
are no more states other than unfocused and elevated, we could allow combining them (like having an 'unfocused elevated' state).
|
|
If there are more states, we could do the implementation as an extension rather than inherently supporting it.
|
|
|
|
## Resources
|
|
|
|
|