This PR adds support for the _blink_ graphic rendition attribute. When a character is output with this attribute set, it "blinks" at a regular interval, by cycling its color between the normal rendition and a dimmer shade of that color. The majority of the blinking mechanism is encapsulated in a new `BlinkingState` class, which is shared between the Terminal and Conhost implementations. This class keeps track of the position in the blinking cycle, which determines whether characters are rendered as normal or faint. In Windows Terminal, the state is stored in the `Terminal` class, and in Conhost it's stored in the `CONSOLE_INFORMATION` class. In both cases, the `IsBlinkingFaint` method is used to determine the current blinking rendition, and that is passed on as a parameter to the `TextAttribute::CalculateRgbColors` method when these classes are looking up attribute colors. Prior to calculating the colors, the current attribute is also passed to the `RecordBlinkingUsage` method, which keeps track of whether there are actually any blink attributes in use. This is used to determine whether the screen needs to be refreshed when the blinking cycle toggles between the normal and faint renditions. The refresh itself is handled by the `ToggleBlinkingRendition` method, which is triggered by a timer. In Conhost this is just piggybacking on the existing cursor blink timer, but in Windows Terminal it needs to have its own separate timer, since the cursor timer is reset whenever a key is pressed, which is not something we want for attribute blinking. Although the `ToggleBlinkingRendition` is called at the same rate as the cursor blinking, we actually only want the cells to blink at half that frequency. We thus have a counter that cycles through four phases, and blinking is rendered as faint for two of those four. Then every two cycles - when the state changes - a redraw is triggered, but only if there are actually blinking attributes in use (as previously recorded). As mentioned earlier, the blinking frequency is based on the cursor blink rate, so that means it'll automatically be disabled if a user has set their cursor blink rate to none. It can also be disabled by turning off the _Show animations in Windows_ option. In Conhost these settings take effect immediately, but in Windows Terminal they only apply when a new tab is opened. This PR also adds partial support for the `SGR 6` _rapid blink_ attribute. This is not used by DEC terminals, but was defined in the ECMA/ANSI standards. It's not widely supported, but many terminals just it implement it as an alias for the regular `SGR 5` blink attribute, so that's what I've done here too. ## Validation Steps Performed I've checked the _Graphic rendition test pattern_ in Vttest, and compared our representation of the blink attribute to that of an actual DEC VT220 terminal as seen on [YouTube]. With the right color scheme it's a reasonably close match. [YouTube]: https://www.youtube.com/watch?v=03Pz5AmxbE4&t=1m55s Closes #7388
249 lines
7.9 KiB
C++
249 lines
7.9 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- settings.hpp
|
|
|
|
Abstract:
|
|
- This module is used for all configurable settings in the console
|
|
|
|
Author(s):
|
|
- Michael Niksa (MiNiksa) 23-Jul-2014
|
|
- Paul Campbell (PaulCam) 23-Jul-2014
|
|
|
|
Revision History:
|
|
- From components of consrv.h
|
|
- This is a reduced/de-duplicated version of settings that were stored in the registry, link files, and in the console information state.
|
|
--*/
|
|
#pragma once
|
|
|
|
#include "../buffer/out/TextAttribute.hpp"
|
|
|
|
// To prevent invisible windows, set a lower threshold on window alpha channel.
|
|
constexpr unsigned short MIN_WINDOW_OPACITY = 0x4D; // 0x4D is approximately 30% visible/opaque (70% transparent). Valid range is 0x00-0xff.
|
|
|
|
#include "ConsoleArguments.hpp"
|
|
#include "../inc/conattrs.hpp"
|
|
|
|
class Settings
|
|
{
|
|
public:
|
|
Settings();
|
|
|
|
void ApplyDesktopSpecificDefaults();
|
|
|
|
void ApplyStartupInfo(const Settings* const pStartupSettings);
|
|
void ApplyCommandlineArguments(const ConsoleArguments& consoleArgs);
|
|
void InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo);
|
|
void Validate();
|
|
|
|
CONSOLE_STATE_INFO CreateConsoleStateInfo() const;
|
|
|
|
DWORD GetVirtTermLevel() const;
|
|
void SetVirtTermLevel(const DWORD dwVirtTermLevel);
|
|
|
|
bool IsAltF4CloseAllowed() const;
|
|
void SetAltF4CloseAllowed(const bool fAllowAltF4Close);
|
|
|
|
bool IsReturnOnNewlineAutomatic() const;
|
|
void SetAutomaticReturnOnNewline(const bool fAutoReturnOnNewline);
|
|
|
|
bool IsGridRenderingAllowedWorldwide() const;
|
|
void SetGridRenderingAllowedWorldwide(const bool fGridRenderingAllowed);
|
|
|
|
bool IsScreenReversed() const;
|
|
void SetScreenReversed(const bool fScreenReversed);
|
|
|
|
bool GetFilterOnPaste() const;
|
|
void SetFilterOnPaste(const bool fFilterOnPaste);
|
|
|
|
const std::wstring_view GetLaunchFaceName() const;
|
|
void SetLaunchFaceName(const std::wstring_view launchFaceName);
|
|
|
|
UINT GetCodePage() const;
|
|
void SetCodePage(const UINT uCodePage);
|
|
|
|
UINT GetScrollScale() const;
|
|
void SetScrollScale(const UINT uScrollScale);
|
|
|
|
bool GetTrimLeadingZeros() const;
|
|
void SetTrimLeadingZeros(const bool fTrimLeadingZeros);
|
|
|
|
bool GetEnableColorSelection() const;
|
|
void SetEnableColorSelection(const bool fEnableColorSelection);
|
|
|
|
bool GetLineSelection() const;
|
|
void SetLineSelection(const bool bLineSelection);
|
|
|
|
bool GetWrapText() const;
|
|
void SetWrapText(const bool bWrapText);
|
|
|
|
bool GetCtrlKeyShortcutsDisabled() const;
|
|
void SetCtrlKeyShortcutsDisabled(const bool fCtrlKeyShortcutsDisabled);
|
|
|
|
BYTE GetWindowAlpha() const;
|
|
void SetWindowAlpha(const BYTE bWindowAlpha);
|
|
|
|
DWORD GetHotKey() const;
|
|
void SetHotKey(const DWORD dwHotKey);
|
|
|
|
bool IsStartupTitleIsLinkNameSet() const;
|
|
|
|
DWORD GetStartupFlags() const;
|
|
void SetStartupFlags(const DWORD dwStartupFlags);
|
|
void UnsetStartupFlag(const DWORD dwFlagToUnset);
|
|
|
|
WORD GetFillAttribute() const;
|
|
void SetFillAttribute(const WORD wFillAttribute);
|
|
|
|
WORD GetPopupFillAttribute() const;
|
|
void SetPopupFillAttribute(const WORD wPopupFillAttribute);
|
|
|
|
WORD GetShowWindow() const;
|
|
void SetShowWindow(const WORD wShowWindow);
|
|
|
|
WORD GetReserved() const;
|
|
void SetReserved(const WORD wReserved);
|
|
|
|
COORD GetScreenBufferSize() const;
|
|
void SetScreenBufferSize(const COORD dwScreenBufferSize);
|
|
|
|
COORD GetWindowSize() const;
|
|
void SetWindowSize(const COORD dwWindowSize);
|
|
|
|
bool IsWindowSizePixelsValid() const;
|
|
COORD GetWindowSizePixels() const;
|
|
void SetWindowSizePixels(const COORD dwWindowSizePixels);
|
|
|
|
COORD GetWindowOrigin() const;
|
|
void SetWindowOrigin(const COORD dwWindowOrigin);
|
|
|
|
DWORD GetFont() const;
|
|
void SetFont(const DWORD dwFont);
|
|
|
|
COORD GetFontSize() const;
|
|
void SetFontSize(const COORD dwFontSize);
|
|
|
|
UINT GetFontFamily() const;
|
|
void SetFontFamily(const UINT uFontFamily);
|
|
|
|
UINT GetFontWeight() const;
|
|
void SetFontWeight(const UINT uFontWeight);
|
|
|
|
const WCHAR* const GetFaceName() const;
|
|
bool IsFaceNameSet() const;
|
|
void SetFaceName(const std::wstring_view faceName);
|
|
|
|
UINT GetCursorSize() const;
|
|
void SetCursorSize(const UINT uCursorSize);
|
|
|
|
bool GetFullScreen() const;
|
|
void SetFullScreen(const bool fFullScreen);
|
|
|
|
bool GetQuickEdit() const;
|
|
void SetQuickEdit(const bool fQuickEdit);
|
|
|
|
bool GetInsertMode() const;
|
|
void SetInsertMode(const bool fInsertMode);
|
|
|
|
bool GetAutoPosition() const;
|
|
void SetAutoPosition(const bool fAutoPosition);
|
|
|
|
UINT GetHistoryBufferSize() const;
|
|
void SetHistoryBufferSize(const UINT uHistoryBufferSize);
|
|
|
|
UINT GetNumberOfHistoryBuffers() const;
|
|
void SetNumberOfHistoryBuffers(const UINT uNumberOfHistoryBuffers);
|
|
|
|
bool GetHistoryNoDup() const;
|
|
void SetHistoryNoDup(const bool fHistoryNoDup);
|
|
|
|
gsl::span<const COLORREF> Get16ColorTable() const;
|
|
gsl::span<const COLORREF> Get256ColorTable() const;
|
|
void SetColorTableEntry(const size_t index, const COLORREF ColorValue);
|
|
COLORREF GetColorTableEntry(const size_t index) const;
|
|
|
|
COLORREF GetCursorColor() const noexcept;
|
|
CursorType GetCursorType() const noexcept;
|
|
|
|
void SetCursorColor(const COLORREF CursorColor) noexcept;
|
|
void SetCursorType(const CursorType cursorType) noexcept;
|
|
|
|
bool GetInterceptCopyPaste() const noexcept;
|
|
void SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept;
|
|
|
|
COLORREF GetDefaultForegroundColor() const noexcept;
|
|
void SetDefaultForegroundColor(const COLORREF defaultForeground) noexcept;
|
|
|
|
COLORREF GetDefaultBackgroundColor() const noexcept;
|
|
void SetDefaultBackgroundColor(const COLORREF defaultBackground) noexcept;
|
|
|
|
bool IsTerminalScrolling() const noexcept;
|
|
void SetTerminalScrolling(const bool terminalScrollingEnabled) noexcept;
|
|
|
|
bool GetUseDx() const noexcept;
|
|
bool GetCopyColor() const noexcept;
|
|
|
|
private:
|
|
DWORD _dwHotKey;
|
|
DWORD _dwStartupFlags;
|
|
WORD _wFillAttribute;
|
|
WORD _wPopupFillAttribute;
|
|
WORD _wShowWindow; // used when window is created
|
|
WORD _wReserved;
|
|
// START - This section filled via memcpy from shortcut properties. Do not rearrange/change.
|
|
COORD _dwScreenBufferSize;
|
|
COORD _dwWindowSize; // this is in characters.
|
|
COORD _dwWindowOrigin; // used when window is created
|
|
DWORD _nFont;
|
|
COORD _dwFontSize;
|
|
UINT _uFontFamily;
|
|
UINT _uFontWeight;
|
|
WCHAR _FaceName[LF_FACESIZE];
|
|
UINT _uCursorSize;
|
|
BOOL _bFullScreen; // deprecated
|
|
BOOL _bQuickEdit;
|
|
BOOL _bInsertMode; // used by command line editing
|
|
BOOL _bAutoPosition;
|
|
UINT _uHistoryBufferSize;
|
|
UINT _uNumberOfHistoryBuffers;
|
|
BOOL _bHistoryNoDup;
|
|
// END - memcpy
|
|
UINT _uCodePage;
|
|
UINT _uScrollScale;
|
|
bool _fTrimLeadingZeros;
|
|
bool _fEnableColorSelection;
|
|
bool _bLineSelection;
|
|
bool _bWrapText; // whether to use text wrapping when resizing the window
|
|
bool _fCtrlKeyShortcutsDisabled; // disables Ctrl+<something> key intercepts
|
|
BYTE _bWindowAlpha; // describes the opacity of the window
|
|
|
|
bool _fFilterOnPaste; // should we filter text when the user pastes? (e.g. remove <tab>)
|
|
std::wstring _LaunchFaceName;
|
|
bool _fAllowAltF4Close;
|
|
DWORD _dwVirtTermLevel;
|
|
bool _fAutoReturnOnNewline;
|
|
bool _fRenderGridWorldwide;
|
|
bool _fScreenReversed;
|
|
bool _fUseDx;
|
|
bool _fCopyColor;
|
|
|
|
std::array<COLORREF, XTERM_COLOR_TABLE_SIZE> _colorTable;
|
|
|
|
// this is used for the special STARTF_USESIZE mode.
|
|
bool _fUseWindowSizePixels;
|
|
COORD _dwWindowSizePixels;
|
|
|
|
// Technically a COLORREF, but using INVALID_COLOR as "Invert Colors"
|
|
unsigned int _CursorColor;
|
|
CursorType _CursorType;
|
|
|
|
bool _fInterceptCopyPaste;
|
|
|
|
COLORREF _DefaultForeground;
|
|
COLORREF _DefaultBackground;
|
|
bool _TerminalScrolling;
|
|
friend class RegistrySerialization;
|
|
};
|