From f9db6f52087e34b855e8d74e62fff20fec07ab7d Mon Sep 17 00:00:00 2001 From: Rene-Kuhm <157995252+Rene-Kuhm@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:41:04 -0300 Subject: [PATCH 1/3] feat: show config keys in tooltips --- docs/src/content/docs/guides/automation.mdx | 2 + .../private/Get-WinUtilConfigToolTip.ps1 | 24 ++++++++++++ .../private/Initialize-InstallAppEntry.ps1 | 2 +- functions/public/Invoke-WPFUIElements.ps1 | 12 +++--- pester/config-tooltips.Tests.ps1 | 38 +++++++++++++++++++ 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 functions/private/Get-WinUtilConfigToolTip.ps1 create mode 100644 pester/config-tooltips.Tests.ps1 diff --git a/docs/src/content/docs/guides/automation.mdx b/docs/src/content/docs/guides/automation.mdx index f44efae938..27d77031dc 100644 --- a/docs/src/content/docs/guides/automation.mdx +++ b/docs/src/content/docs/guides/automation.mdx @@ -29,6 +29,8 @@ To create your own config file: 3. Choose **Export**. 4. Save the exported JSON file. +When editing a configuration manually, hover over an application or tweak in WinUtil to see its configuration key, such as `WPFInstallfirefox` or `WPFTweaksTelemetry`. + Once you have exported a config, launch WinUtil with it using this command: ```powershell & ([ScriptBlock]::Create((irm "https://christitus.com/win"))) -Config "C:\Path\To\Config.json" diff --git a/functions/private/Get-WinUtilConfigToolTip.ps1 b/functions/private/Get-WinUtilConfigToolTip.ps1 new file mode 100644 index 0000000000..acebed6fe2 --- /dev/null +++ b/functions/private/Get-WinUtilConfigToolTip.ps1 @@ -0,0 +1,24 @@ +function Get-WinUtilConfigToolTip { + <# + .SYNOPSIS + Builds a tooltip that includes an entry's configuration key. + .PARAMETER Description + The user-facing description of the configuration entry. + .PARAMETER ConfigKey + The key used to reference the entry in an exported configuration. + #> + param( + [AllowEmptyString()] + [string]$Description, + + [Parameter(Mandatory)] + [string]$ConfigKey + ) + + $configKeyText = "Configuration key: $ConfigKey" + if ([string]::IsNullOrWhiteSpace($Description)) { + return $configKeyText + } + + return "$Description`n`n$configKeyText" +} diff --git a/functions/private/Initialize-InstallAppEntry.ps1 b/functions/private/Initialize-InstallAppEntry.ps1 index 8318f12ba3..a222daba89 100644 --- a/functions/private/Initialize-InstallAppEntry.ps1 +++ b/functions/private/Initialize-InstallAppEntry.ps1 @@ -19,7 +19,7 @@ function Initialize-InstallAppEntry { $border = New-Object Windows.Controls.Border $border.Style = $sync.Form.Resources.AppEntryBorderStyle $border.Tag = $appKey - $border.ToolTip = $app.description + $border.ToolTip = Get-WinUtilConfigToolTip -Description $app.description -ConfigKey $appKey $border.Add_MouseLeftButtonUp({ # Resolve through $sync because the border's child is a layout Grid for FOSS entries $childCheckbox = $sync.$($this.Tag) diff --git a/functions/public/Invoke-WPFUIElements.ps1 b/functions/public/Invoke-WPFUIElements.ps1 index eb50fae0b5..9d884f7732 100644 --- a/functions/public/Invoke-WPFUIElements.ps1 +++ b/functions/public/Invoke-WPFUIElements.ps1 @@ -81,6 +81,7 @@ function Invoke-WPFUIElements { Checked = $entryInfo.Checked ButtonWidth = $entryInfo.ButtonWidth GroupName = $entryInfo.GroupName # Added for RadioButton groupings + ToolTip = Get-WinUtilConfigToolTip -Description $entryInfo.description -ConfigKey $entry } if (-not $organizedData.ContainsKey($entryObject.Panel)) { @@ -190,7 +191,7 @@ function Invoke-WPFUIElements { $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content - $label.ToolTip = $entryInfo.Description + $label.ToolTip = $entryInfo.ToolTip $label.HorizontalAlignment = "Left" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") @@ -224,7 +225,7 @@ function Invoke-WPFUIElements { $toggleButton = New-Object Windows.Controls.Primitives.ToggleButton $toggleButton.Name = $entryInfo.Name $toggleButton.Content = $entryInfo.Content[1] - $toggleButton.ToolTip = $entryInfo.Description + $toggleButton.ToolTip = $entryInfo.ToolTip $toggleButton.HorizontalAlignment = "Left" $toggleButton.Style = $ToggleButtonStyle [System.Windows.Automation.AutomationProperties]::SetName($toggleButton, $entryInfo.Content[0]) @@ -268,7 +269,7 @@ function Invoke-WPFUIElements { $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content $label.HorizontalAlignment = "Left" - $label.ToolTip = $entryInfo.Description + $label.ToolTip = $entryInfo.ToolTip $label.VerticalAlignment = "Center" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $label.UseLayoutRounding = $true @@ -398,6 +399,7 @@ function Invoke-WPFUIElements { $button = New-Object Windows.Controls.Button $button.Name = $entryInfo.Name $button.Content = $entryInfo.Content + $button.ToolTip = $entryInfo.ToolTip $button.HorizontalAlignment = "Left" $button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin") $button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") @@ -448,7 +450,7 @@ function Invoke-WPFUIElements { $radioButton.HorizontalAlignment = "Left" $radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin") $radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") - $radioButton.ToolTip = $entryInfo.Description + $radioButton.ToolTip = $entryInfo.ToolTip $radioButton.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($radioButton, $entryInfo.Content) @@ -490,7 +492,7 @@ function Invoke-WPFUIElements { $checkBox.Name = $entryInfo.Name $checkBox.Content = $entryInfo.Content $checkBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") - $checkBox.ToolTip = $entryInfo.Description + $checkBox.ToolTip = $entryInfo.ToolTip $checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin") $checkBox.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($checkBox, $entryInfo.Content) diff --git a/pester/config-tooltips.Tests.ps1 b/pester/config-tooltips.Tests.ps1 new file mode 100644 index 0000000000..013133d308 --- /dev/null +++ b/pester/config-tooltips.Tests.ps1 @@ -0,0 +1,38 @@ +#=========================================================================== +# Tests - Configuration tooltips +#=========================================================================== + +BeforeAll { + $script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + . (Join-Path $script:repoRoot "functions\private\Get-WinUtilConfigToolTip.ps1") +} + +Describe "Get-WinUtilConfigToolTip" { + It "appends the configuration key to an existing description" { + $toolTip = Get-WinUtilConfigToolTip ` + -Description "Installs Mozilla Firefox." ` + -ConfigKey "WPFInstallfirefox" + + $toolTip | Should -Be "Installs Mozilla Firefox.`n`nConfiguration key: WPFInstallfirefox" + } + + It "shows the configuration key when an entry has no description" { + Get-WinUtilConfigToolTip -Description "" -ConfigKey "WPFOOSUbutton" | + Should -Be "Configuration key: WPFOOSUbutton" + } +} + +Describe "Configuration tooltip rendering" { + It "uses configuration-key tooltips for install entries" { + $entryScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-InstallAppEntry.ps1") -Raw + + $entryScript | Should -Match '\$border\.ToolTip = Get-WinUtilConfigToolTip -Description \$app\.description -ConfigKey \$appKey' + } + + It "uses configuration-key tooltips for generated tweak controls" { + $rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw + + $rendererScript | Should -Match 'ToolTip\s*= Get-WinUtilConfigToolTip -Description \$entryInfo\.description -ConfigKey \$entry' + $rendererScript | Should -Not -Match '\.ToolTip = \$entryInfo\.Description' + } +} From 3aa72d6d9dba399311119328a83399d75b27072e Mon Sep 17 00:00:00 2001 From: Rene-Kuhm <157995252+Rene-Kuhm@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:49:25 -0300 Subject: [PATCH 2/3] fix: limit keys to importable controls --- functions/public/Invoke-WPFUIElements.ps1 | 13 +++++++++---- pester/config-tooltips.Tests.ps1 | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/functions/public/Invoke-WPFUIElements.ps1 b/functions/public/Invoke-WPFUIElements.ps1 index 9d884f7732..39e3cc89de 100644 --- a/functions/public/Invoke-WPFUIElements.ps1 +++ b/functions/public/Invoke-WPFUIElements.ps1 @@ -65,6 +65,12 @@ function Invoke-WPFUIElements { # Iterate through JSON data and organize by panel and category foreach ($entry in $configHashtable.Keys) { $entryInfo = $configHashtable[$entry] + $entryToolTip = $entryInfo.description + $isSelectableEntry = [string]::IsNullOrWhiteSpace([string]$entryInfo.type) -or $entryInfo.type -in @("Toggle", "ToggleButton") + $isImportableKey = $entry -match '^(WPFTweaks|WPFToggle|WPFFeature|WPFAppx)' + if ($isSelectableEntry -and $isImportableKey) { + $entryToolTip = Get-WinUtilConfigToolTip -Description $entryInfo.description -ConfigKey $entry + } # Create an object for the application $entryObject = [PSCustomObject]@{ @@ -81,7 +87,7 @@ function Invoke-WPFUIElements { Checked = $entryInfo.Checked ButtonWidth = $entryInfo.ButtonWidth GroupName = $entryInfo.GroupName # Added for RadioButton groupings - ToolTip = Get-WinUtilConfigToolTip -Description $entryInfo.description -ConfigKey $entry + ToolTip = $entryToolTip } if (-not $organizedData.ContainsKey($entryObject.Panel)) { @@ -269,7 +275,7 @@ function Invoke-WPFUIElements { $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content $label.HorizontalAlignment = "Left" - $label.ToolTip = $entryInfo.ToolTip + $label.ToolTip = $entryInfo.Description $label.VerticalAlignment = "Center" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $label.UseLayoutRounding = $true @@ -399,7 +405,6 @@ function Invoke-WPFUIElements { $button = New-Object Windows.Controls.Button $button.Name = $entryInfo.Name $button.Content = $entryInfo.Content - $button.ToolTip = $entryInfo.ToolTip $button.HorizontalAlignment = "Left" $button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin") $button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") @@ -450,7 +455,7 @@ function Invoke-WPFUIElements { $radioButton.HorizontalAlignment = "Left" $radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin") $radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") - $radioButton.ToolTip = $entryInfo.ToolTip + $radioButton.ToolTip = $entryInfo.Description $radioButton.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($radioButton, $entryInfo.Content) diff --git a/pester/config-tooltips.Tests.ps1 b/pester/config-tooltips.Tests.ps1 index 013133d308..c68e0050dd 100644 --- a/pester/config-tooltips.Tests.ps1 +++ b/pester/config-tooltips.Tests.ps1 @@ -32,7 +32,19 @@ Describe "Configuration tooltip rendering" { It "uses configuration-key tooltips for generated tweak controls" { $rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw - $rendererScript | Should -Match 'ToolTip\s*= Get-WinUtilConfigToolTip -Description \$entryInfo\.description -ConfigKey \$entry' - $rendererScript | Should -Not -Match '\.ToolTip = \$entryInfo\.Description' + $rendererScript | Should -Match '\$isSelectableEntry = .*"Toggle", "ToggleButton"' + $rendererScript | Should -Match '\$isImportableKey = \$entry -match.*WPFTweaks.*WPFToggle.*WPFFeature.*WPFAppx' + $rendererScript | Should -Match '\$entryToolTip = Get-WinUtilConfigToolTip -Description \$entryInfo\.description -ConfigKey \$entry' + $rendererScript | Should -Match '\$label\.ToolTip = \$entryInfo\.ToolTip' + $rendererScript | Should -Match '\$toggleButton\.ToolTip = \$entryInfo\.ToolTip' + $rendererScript | Should -Match '\$checkBox\.ToolTip = \$entryInfo\.ToolTip' + } + + It "keeps non-selectable controls out of configuration-key tooltips" { + $rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw + + $rendererScript | Should -Not -Match '\$button\.ToolTip = \$entryInfo\.ToolTip' + $rendererScript | Should -Match '\$label\.ToolTip = \$entryInfo\.Description' + $rendererScript | Should -Match '\$radioButton\.ToolTip = \$entryInfo\.Description' } } From 8b1c15c3fbfb6dca14cab86851ea335fcbd14100 Mon Sep 17 00:00:00 2001 From: Rene-Kuhm <157995252+Rene-Kuhm@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:54:50 -0300 Subject: [PATCH 3/3] fix: exclude unsupported toggle config keys --- functions/public/Invoke-WPFUIElements.ps1 | 9 ++++----- pester/config-tooltips.Tests.ps1 | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/functions/public/Invoke-WPFUIElements.ps1 b/functions/public/Invoke-WPFUIElements.ps1 index 39e3cc89de..6b7f892c6d 100644 --- a/functions/public/Invoke-WPFUIElements.ps1 +++ b/functions/public/Invoke-WPFUIElements.ps1 @@ -66,9 +66,8 @@ function Invoke-WPFUIElements { foreach ($entry in $configHashtable.Keys) { $entryInfo = $configHashtable[$entry] $entryToolTip = $entryInfo.description - $isSelectableEntry = [string]::IsNullOrWhiteSpace([string]$entryInfo.type) -or $entryInfo.type -in @("Toggle", "ToggleButton") - $isImportableKey = $entry -match '^(WPFTweaks|WPFToggle|WPFFeature|WPFAppx)' - if ($isSelectableEntry -and $isImportableKey) { + $isConfigSelectionEntry = [string]::IsNullOrWhiteSpace([string]$entryInfo.type) -and $entry -match '^(WPFTweaks|WPFFeature|WPFAppx)' + if ($isConfigSelectionEntry) { $entryToolTip = Get-WinUtilConfigToolTip -Description $entryInfo.description -ConfigKey $entry } @@ -197,7 +196,7 @@ function Invoke-WPFUIElements { $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content - $label.ToolTip = $entryInfo.ToolTip + $label.ToolTip = $entryInfo.Description $label.HorizontalAlignment = "Left" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") @@ -231,7 +230,7 @@ function Invoke-WPFUIElements { $toggleButton = New-Object Windows.Controls.Primitives.ToggleButton $toggleButton.Name = $entryInfo.Name $toggleButton.Content = $entryInfo.Content[1] - $toggleButton.ToolTip = $entryInfo.ToolTip + $toggleButton.ToolTip = $entryInfo.Description $toggleButton.HorizontalAlignment = "Left" $toggleButton.Style = $ToggleButtonStyle [System.Windows.Automation.AutomationProperties]::SetName($toggleButton, $entryInfo.Content[0]) diff --git a/pester/config-tooltips.Tests.ps1 b/pester/config-tooltips.Tests.ps1 index c68e0050dd..0c6750082d 100644 --- a/pester/config-tooltips.Tests.ps1 +++ b/pester/config-tooltips.Tests.ps1 @@ -29,22 +29,22 @@ Describe "Configuration tooltip rendering" { $entryScript | Should -Match '\$border\.ToolTip = Get-WinUtilConfigToolTip -Description \$app\.description -ConfigKey \$appKey' } - It "uses configuration-key tooltips for generated tweak controls" { + It "uses configuration-key tooltips for generated config selections" { $rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw - $rendererScript | Should -Match '\$isSelectableEntry = .*"Toggle", "ToggleButton"' - $rendererScript | Should -Match '\$isImportableKey = \$entry -match.*WPFTweaks.*WPFToggle.*WPFFeature.*WPFAppx' + $rendererScript | Should -Match '\$isConfigSelectionEntry = .*\$entryInfo\.type.*WPFTweaks.*WPFFeature.*WPFAppx' $rendererScript | Should -Match '\$entryToolTip = Get-WinUtilConfigToolTip -Description \$entryInfo\.description -ConfigKey \$entry' - $rendererScript | Should -Match '\$label\.ToolTip = \$entryInfo\.ToolTip' - $rendererScript | Should -Match '\$toggleButton\.ToolTip = \$entryInfo\.ToolTip' $rendererScript | Should -Match '\$checkBox\.ToolTip = \$entryInfo\.ToolTip' } It "keeps non-selectable controls out of configuration-key tooltips" { $rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw + $configSelectionLine = ($rendererScript -split "`r?`n") | Where-Object { $_ -like '*$isConfigSelectionEntry*' } + $configSelectionLine | Should -Not -Match 'WPFToggle' $rendererScript | Should -Not -Match '\$button\.ToolTip = \$entryInfo\.ToolTip' $rendererScript | Should -Match '\$label\.ToolTip = \$entryInfo\.Description' + $rendererScript | Should -Match '\$toggleButton\.ToolTip = \$entryInfo\.Description' $rendererScript | Should -Match '\$radioButton\.ToolTip = \$entryInfo\.Description' } }