diff --git a/.github/actions/spelling/dictionary/apis.txt b/.github/actions/spelling/dictionary/apis.txt index 505e69e11..b1bbc3456 100644 --- a/.github/actions/spelling/dictionary/apis.txt +++ b/.github/actions/spelling/dictionary/apis.txt @@ -22,6 +22,7 @@ Hashtable HIGHCONTRASTON HIGHCONTRASTW href +IAppearance IAsync IBind IBox diff --git a/.github/actions/spelling/dictionary/names.txt b/.github/actions/spelling/dictionary/names.txt index f1f8af36f..35ee2b4b8 100644 --- a/.github/actions/spelling/dictionary/names.txt +++ b/.github/actions/spelling/dictionary/names.txt @@ -50,6 +50,7 @@ oising oldnewthing opengl osgwiki +pabhojwa paulcam pauldotknopf PGP diff --git a/doc/specs/#3062 - Appearance configuration object for profiles.md b/doc/specs/#3062 - Appearance configuration object for profiles.md new file mode 100644 index 000000000..b15d7a5ee --- /dev/null +++ b/doc/specs/#3062 - Appearance configuration object for profiles.md @@ -0,0 +1,128 @@ +--- +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 + +