mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-12 02:51:16 +10:00
Make MPO tweak a three-state control (#4897)
* refactor: make MPO tweak a three-state control * docs: explain MPO tweak states * docs: address code review comments * refactor: make Multiplane Overlay config-driven
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
function Get-WinUtilRegistryComboState {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Finds the configured combo-box state matching the current registry values.
|
||||
|
||||
.PARAMETER Registry
|
||||
Registry settings containing a value mapping for each supported state.
|
||||
|
||||
.OUTPUTS
|
||||
The name of the matching state.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
$Registry
|
||||
)
|
||||
|
||||
foreach ($state in $Registry[0].Values.PSObject.Properties) {
|
||||
$stateMatches = $true
|
||||
foreach ($setting in @($Registry)) {
|
||||
$currentValue = Get-WinUtilRegistryComboValue -Setting $setting
|
||||
$actualValue = if ($currentValue.Exists -and $null -ne $currentValue.Value) { $currentValue.Value } else { $setting.DefaultValue }
|
||||
$configuredValue = $setting.Values.PSObject.Properties[$state.Name].Value
|
||||
# Removal represents the effective Windows default when matching the current state.
|
||||
$expectedValue = if ($configuredValue -eq "<RemoveEntry>") { $setting.DefaultValue } else { $configuredValue }
|
||||
if ([string]$actualValue -ne [string]$expectedValue) {
|
||||
$stateMatches = $false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($stateMatches) {
|
||||
return $state.Name
|
||||
}
|
||||
}
|
||||
|
||||
throw "Registry values do not match a supported state."
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
function Get-WinUtilRegistryComboValue {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Reads one registry value for a registry-backed combo-box state.
|
||||
|
||||
.PARAMETER Setting
|
||||
The registry setting from the combo-box configuration.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
$Setting
|
||||
)
|
||||
|
||||
try {
|
||||
$item = Get-ItemProperty -Path $Setting.Path -Name $Setting.Name -ErrorAction Stop
|
||||
$property = $item.PSObject.Properties[$Setting.Name]
|
||||
return [pscustomobject]@{ Exists = $null -ne $property; Value = $property.Value }
|
||||
} catch [System.Management.Automation.PSArgumentException] {
|
||||
# The registry provider uses PSArgumentException when a named value is absent.
|
||||
return [pscustomobject]@{ Exists = $false; Value = $null }
|
||||
} catch [System.Management.Automation.ItemNotFoundException] {
|
||||
return [pscustomobject]@{ Exists = $false; Value = $null }
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ Function Invoke-WinUtilCurrentSystem {
|
||||
$serviceKeys = $entry.service
|
||||
$entryType = $entry.Type
|
||||
|
||||
if ($registryKeys -or $serviceKeys) {
|
||||
if (($registryKeys -or $serviceKeys) -and $entryType -ne "Combobox") {
|
||||
$Values = @()
|
||||
|
||||
if ($entryType -eq "Toggle") {
|
||||
|
||||
@@ -62,7 +62,7 @@ function Invoke-WinUtilTweaks {
|
||||
}
|
||||
}
|
||||
if ($sync.configs.tweaks.$CheckBox.registry) {
|
||||
$sync.configs.tweaks.$CheckBox.registry | ForEach-Object {
|
||||
$sync.configs.tweaks.$CheckBox.registry | Where-Object { -not $psitem.Values } | ForEach-Object {
|
||||
Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
function Set-WinUtilRegistryComboState {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Applies and verifies a config-defined registry combo-box state.
|
||||
|
||||
.PARAMETER Registry
|
||||
Registry settings containing a value mapping for each supported state.
|
||||
|
||||
.PARAMETER State
|
||||
The state name to apply.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
$Registry,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$State
|
||||
)
|
||||
|
||||
if ($Registry[0].Values.PSObject.Properties.Name -notcontains $State) {
|
||||
throw "Unknown registry state '$State'."
|
||||
}
|
||||
|
||||
# Preserve exact prior values so a partial update can be rolled back.
|
||||
$previousValues = foreach ($setting in @($Registry)) {
|
||||
$currentValue = Get-WinUtilRegistryComboValue -Setting $setting
|
||||
[pscustomobject]@{ Setting = $setting; Exists = $currentValue.Exists; Value = $currentValue.Value }
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($setting in @($Registry)) {
|
||||
$configuredValue = $setting.Values.PSObject.Properties[$State].Value
|
||||
$previousValue = $previousValues | Where-Object Setting -EQ $setting
|
||||
if ($configuredValue -ne "<RemoveEntry>" -or $previousValue.Exists) {
|
||||
Set-WinUtilRegistry -Name $setting.Name -Path $setting.Path -Type $setting.Type -Value $configuredValue
|
||||
}
|
||||
}
|
||||
|
||||
# Set-WinUtilRegistry reports write errors without throwing, so verify each result explicitly.
|
||||
foreach ($setting in @($Registry)) {
|
||||
$configuredValue = $setting.Values.PSObject.Properties[$State].Value
|
||||
$currentValue = Get-WinUtilRegistryComboValue -Setting $setting
|
||||
$writeMatches = if ($configuredValue -eq "<RemoveEntry>") {
|
||||
-not $currentValue.Exists
|
||||
} else {
|
||||
$currentValue.Exists -and [string]$currentValue.Value -eq [string]$configuredValue
|
||||
}
|
||||
if (-not $writeMatches) {
|
||||
throw "The registry values did not match the requested state."
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
$applyError = $_.Exception.Message
|
||||
if ([string]::IsNullOrWhiteSpace($applyError)) {
|
||||
$applyError = "The registry values did not match the requested state."
|
||||
}
|
||||
$rollbackFailed = $false
|
||||
foreach ($previousValue in $previousValues) {
|
||||
try {
|
||||
$currentValue = Get-WinUtilRegistryComboValue -Setting $previousValue.Setting
|
||||
if ($previousValue.Exists -or $currentValue.Exists) {
|
||||
$rollbackValue = if ($previousValue.Exists) { $previousValue.Value } else { "<RemoveEntry>" }
|
||||
Set-WinUtilRegistry -Name $previousValue.Setting.Name -Path $previousValue.Setting.Path -Type $previousValue.Setting.Type -Value $rollbackValue
|
||||
}
|
||||
$restoredValue = Get-WinUtilRegistryComboValue -Setting $previousValue.Setting
|
||||
if ($restoredValue.Exists -ne $previousValue.Exists -or ($restoredValue.Exists -and [string]$restoredValue.Value -ne [string]$previousValue.Value)) {
|
||||
$rollbackFailed = $true
|
||||
}
|
||||
} catch {
|
||||
$rollbackFailed = $true
|
||||
}
|
||||
}
|
||||
if ($rollbackFailed) {
|
||||
throw "Unable to apply registry state '$State': $applyError. The previous registry state could not be restored."
|
||||
}
|
||||
throw "Unable to apply registry state '$State': $applyError"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user