Public/Install-TerminalColorsTitleBar.ps1
|
# System title bar: the second way to get a pure colour, without touching the pane # background and without adding a file. # # By default Windows Terminal draws its tabs INSIDE the title bar, so the window # has no real system title bar and its colour depends on the theme - therefore on # the background colour. Disabling showTabsInTitlebar gives the window a genuine # system title bar back, which DWM can colour directly (DWMWA_CAPTION_COLOR), # exactly like the border: pure colour, immediately, without going through the # background colour. # # The trade-off: the tab strip moves below the title bar, and it stays subject to # the theme. The tab itself therefore only carries the project colour when the # opaque backdrop is installed (Install-TerminalColorsBackdrop). # # The actual colouring is done at runtime by [Enable-TerminalColors -CaptionColor]. function Get-TcShowTabsInTitlebar { <# .SYNOPSIS Value of showTabsInTitlebar in a parsed settings.json. $null when the key is absent (Windows Terminal then treats it as true). #> param($Settings) return (Get-TcJsonProperty -InputObject $Settings -Name 'showTabsInTitlebar') } function Install-TerminalColorsTitleBar { <# .SYNOPSIS Brings back a real system title bar, which DWM can colour in pure colour. .DESCRIPTION Writes [showTabsInTitlebar: false] into settings.json. The Windows Terminal window then regains a system title bar, which TerminalColors colours in the pure project colour through DWM - like the border, and without touching the pane background. Two things to know: - Windows Terminal must be restarted completely (all of its windows closed): this setting is not re-read at runtime. - the actual colouring requires [Enable-TerminalColors -CaptionColor]. Without that switch the title bar keeps the system colour. The tab strip, for its part, moves below the title bar and stays subject to the theme: for the tab itself to carry the project colour, install the opaque backdrop as well (Install-TerminalColorsBackdrop). .PARAMETER SettingsPath Path of the settings.json to modify. Detected automatically by default. .PARAMETER NoBackup Does not write a backup copy. .EXAMPLE Install-TerminalColorsTitleBar Enable-TerminalColors -CaptionColor .EXAMPLE Install-TerminalColorsTitleBar -WhatIf #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType([pscustomobject])] param( [string] $SettingsPath, [switch] $NoBackup ) $SettingsPath = Resolve-TcWtSettingsPath -Path $SettingsPath $text = [System.IO.File]::ReadAllText($SettingsPath) $settings = ConvertFrom-TcJsonText -Text $text if ($null -eq $settings) { throw "TerminalColors: [$SettingsPath] is not valid JSON. Fix it before changing the title bar." } $previous = Get-TcShowTabsInTitlebar -Settings $settings if ($previous -eq $false) { Write-Verbose 'TerminalColors: showTabsInTitlebar is already false.' return [pscustomobject]@{ SettingsPath = $SettingsPath Changed = $false Changes = @() Backup = $null RestartNeeded = $false } } $masked = Get-TcMaskedJson -Text $text $root = Find-TcJsonRootIndex -Masked $masked $applied = Set-TcJsonMember -Text $text -AnchorIndex $root -Name 'showTabsInTitlebar' -Literal 'false' -Indent ' ' $newText = $applied.Text $parsed = ConvertFrom-TcJsonText -Text $newText if ($null -eq $parsed) { throw 'TerminalColors: the change would have produced invalid JSON. Nothing was written.' } if ((Get-TcShowTabsInTitlebar -Settings $parsed) -ne $false) { throw 'TerminalColors: verification failed (showTabsInTitlebar not disabled). Nothing was written.' } $backupPath = $null if ($PSCmdlet.ShouldProcess($SettingsPath, 'Disable showTabsInTitlebar')) { # Record the absence of the key as a value in its own right, so that # uninstalling removes the key instead of writing [true]. if ($null -eq $previous) { Set-TcInstallState -Name 'PreviousShowTabsInTitlebar' -Value 'absent' } else { Set-TcInstallState -Name 'PreviousShowTabsInTitlebar' -Value ([bool]$previous) } $backupPath = Save-TcWtSettings -Path $SettingsPath -Text $newText -NoBackup:$NoBackup } return [pscustomobject]@{ SettingsPath = $SettingsPath Changed = $true Changes = @("showTabsInTitlebar $($applied.Action)") Backup = $backupPath RestartNeeded = $true } } function Uninstall-TerminalColorsTitleBar { <# .SYNOPSIS Puts the tabs back into the title bar (Windows Terminal's default behaviour). .DESCRIPTION Restores the value of showTabsInTitlebar as it was before Install-TerminalColorsTitleBar, removing the key if it was absent. Windows Terminal must be restarted completely. .PARAMETER SettingsPath Path of the settings.json to modify. Detected automatically by default. .PARAMETER NoBackup Does not write a backup copy. .EXAMPLE Uninstall-TerminalColorsTitleBar #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType([pscustomobject])] param( [string] $SettingsPath, [switch] $NoBackup ) $SettingsPath = Resolve-TcWtSettingsPath -Path $SettingsPath $text = [System.IO.File]::ReadAllText($SettingsPath) $settings = ConvertFrom-TcJsonText -Text $text if ($null -eq $settings) { throw "TerminalColors: [$SettingsPath] is not valid JSON." } if ((Get-TcShowTabsInTitlebar -Settings $settings) -ne $false) { Write-Warning 'TerminalColors: showTabsInTitlebar is not disabled; nothing to do.' return } $masked = Get-TcMaskedJson -Text $text $root = Find-TcJsonRootIndex -Masked $masked $restore = Get-TcInstallState -Name 'PreviousShowTabsInTitlebar' if ($null -eq $restore -or [string]$restore -eq 'absent') { $applied = Remove-TcJsonMember -Text $text -AnchorIndex $root -Name 'showTabsInTitlebar' $change = 'showTabsInTitlebar removed' } else { $literal = 'false' if ([bool]$restore) { $literal = 'true' } $applied = Set-TcJsonMember -Text $text -AnchorIndex $root -Name 'showTabsInTitlebar' -Literal $literal -Indent ' ' $change = "showTabsInTitlebar restored ($literal)" } $newText = $applied.Text if ($null -eq (ConvertFrom-TcJsonText -Text $newText)) { throw 'TerminalColors: the change would have produced invalid JSON. Nothing was written.' } $backupPath = $null if ($PSCmdlet.ShouldProcess($SettingsPath, 'Put the tabs back into the title bar')) { $backupPath = Save-TcWtSettings -Path $SettingsPath -Text $newText -NoBackup:$NoBackup Remove-TcInstallState -Name 'PreviousShowTabsInTitlebar' } return [pscustomobject]@{ SettingsPath = $SettingsPath Changed = $true Changes = @($change) Backup = $backupPath RestartNeeded = $true } } function Test-TerminalColorsTitleBar { <# .SYNOPSIS Indicates whether Windows Terminal shows a real system title bar (and can therefore be coloured in pure colour by DWM). .PARAMETER SettingsPath Path of the settings.json to inspect. Detected automatically by default. .EXAMPLE Test-TerminalColorsTitleBar #> [CmdletBinding()] [OutputType([bool])] param([string] $SettingsPath) if (-not $SettingsPath) { $SettingsPath = Get-TcWtSettingsPath } if (-not $SettingsPath -or -not [System.IO.File]::Exists($SettingsPath)) { return $false } $settings = ConvertFrom-TcJsonFile -Path $SettingsPath if ($null -eq $settings) { return $false } return ((Get-TcShowTabsInTitlebar -Settings $settings) -eq $false) } |