scripts/capture-screenshots.ps1
|
# capture-screenshots.ps1 -- capture a screenshot of each bundled theme # applied to the current Windows Terminal tab. Outputs PNGs to # docs/screenshots/<name>.png, one per theme. # # USAGE: # 1. Open a Windows Terminal tab (this script must run INSIDE WT). # Resize the window to a reasonable thumbnail-friendly size, # e.g. ~900x600 pixels, before starting. # 2. From this repo: # pwsh -File .\scripts\capture-screenshots.ps1 # 3. Do not touch the keyboard / window focus while it runs (~3-4 # seconds per theme). # 4. When done, the original theme is restored automatically. # 5. Review docs/screenshots/, then commit. # # NOTE: requires the tstyles installation at %LOCALAPPDATA%\TerminalStyles\. # If you've been editing themes locally without installing, run # .\install.ps1 (or 'iwr | iex' the one-liner) first. #Requires -Version 5.1 $ErrorActionPreference = 'Stop' # --- Win32 PrintWindow with PW_RENDERFULLCONTENT (works for WT) --- Add-Type @" using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public class WTScreenCapture { [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32.dll")] public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint nFlags); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; } public static void CaptureForegroundTo(string outputPath) { IntPtr hWnd = GetForegroundWindow(); if (hWnd == IntPtr.Zero) throw new InvalidOperationException("No foreground window."); RECT r; GetWindowRect(hWnd, out r); int w = r.Right - r.Left; int h = r.Bottom - r.Top; if (w <= 0 || h <= 0) throw new InvalidOperationException("Foreground window has zero size."); using (var bmp = new Bitmap(w, h)) { using (var g = Graphics.FromImage(bmp)) { IntPtr hdc = g.GetHdc(); // 2 = PW_RENDERFULLCONTENT, required for DirectX-rendered // windows like Windows Terminal. PrintWindow(hWnd, hdc, 2); g.ReleaseHdc(hdc); } bmp.Save(outputPath, ImageFormat.Png); } } } "@ -ReferencedAssemblies System.Drawing # --- Sanity checks --- if (-not $env:WT_SESSION) { throw "This script must be run from inside a Windows Terminal tab. The PrintWindow capture only works on the focused WT window." } if (-not (Get-Command tstyles -ErrorAction SilentlyContinue)) { throw "The 'tstyles' command is not available in this session. Run install.ps1 first, or '. `$PROFILE'." } $installDir = Join-Path $env:LOCALAPPDATA 'TerminalStyles' $installStylesDir = Join-Path $installDir 'styles' if (-not (Test-Path -LiteralPath $installStylesDir)) { throw "TerminalStyles install not found at $installDir. Run install.ps1 first." } $repoRoot = Split-Path -Parent $PSScriptRoot $outDir = Join-Path $repoRoot 'docs\screenshots' if (-not (Test-Path -LiteralPath $outDir)) { New-Item -ItemType Directory -Path $outDir -Force | Out-Null } # --- Enumerate themes from the INSTALL directory (matches what tstyles sees) --- $themes = Get-ChildItem -LiteralPath $installStylesDir -Directory | Where-Object { Test-Path (Join-Path $_.FullName 'scheme.json') } | Sort-Object Name if (-not $themes) { throw "No themes found at $installStylesDir." } # --- Save current theme so we can restore it at the end --- $originalTheme = (tstyles current 2>$null) -join '' $originalTheme = "$originalTheme".Trim() if (-not $originalTheme -or $originalTheme -match 'no bundled style') { $originalTheme = $null } Write-Host "" Write-Host "Capturing $($themes.Count) theme screenshots into:" -ForegroundColor Cyan Write-Host " $outDir" -ForegroundColor Gray Write-Host "" Write-Host "Don't touch the keyboard or change window focus while this runs." -ForegroundColor Yellow Write-Host "Starting in 3 seconds..." -ForegroundColor Yellow Start-Sleep -Seconds 3 $captured = @() foreach ($theme in $themes) { # Apply silently (Apply-StyleDirect's "Style applied: X" status line # would clutter the screenshot if we let it print into the same tab). tstyles $theme.Name *>&1 | Out-Null # Wipe the tab and re-render just the banner + prompt fresh, so the # screenshot is the cleanest possible representation of the theme. Clear-Host $stylePs1 = Join-Path $installDir 'current-style.ps1' if (Test-Path -LiteralPath $stylePs1) { . $stylePs1 } # Give WT a beat to re-render colors, font, cursor, bg before snapping. Start-Sleep -Milliseconds 700 $outFile = Join-Path $outDir "$($theme.Name).png" try { [WTScreenCapture]::CaptureForegroundTo($outFile) $size = (Get-Item -LiteralPath $outFile).Length $captured += [pscustomobject]@{ Name = $theme.Name; Path = $outFile; Bytes = $size } } catch { Write-Host " ! Failed to capture $($theme.Name): $_" -ForegroundColor Red } } # --- Restore the original theme --- if ($originalTheme) { tstyles $originalTheme *>&1 | Out-Null } Clear-Host Write-Host "" Write-Host "Captured $($captured.Count) screenshot(s):" -ForegroundColor Green foreach ($c in $captured) { Write-Host (" - {0,-16} {1,8:N0} bytes -> {2}" -f $c.Name, $c.Bytes, $c.Path) } Write-Host "" Write-Host "Next steps:" -ForegroundColor Cyan Write-Host " 1. Open docs/screenshots/ and review each PNG." -ForegroundColor Gray Write-Host " 2. If any look wrong, re-run this script (it overwrites)." -ForegroundColor Gray Write-Host " 3. Commit: git add docs/screenshots/ ; git commit -m 'Refresh theme screenshots'" -ForegroundColor Gray Write-Host "" |