Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
## Checklist
- [ ] My code adheres to the coding and style guidelines of the project.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have made corresponding changes to the documentation.
- [ ] I have made corresponding changes to the documentation.
6 changes: 3 additions & 3 deletions .github/workflows/label-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
script: |
const prBody = context.payload.pull_request.body || '';
const labelsToAdd = [];

if (/\[x\]\s*New feature/i.test(prBody)) {
labelsToAdd.push('new feature');
}
Expand All @@ -34,12 +34,12 @@ jobs:
if (/\[x\]\s*UI\/UX improvement/i.test(prBody)) {
labelsToAdd.push('ui update');
}

if (labelsToAdd.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: labelsToAdd
});
}
}
20 changes: 17 additions & 3 deletions config/appnavigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,39 @@
"Order": "2",
"Description": "Use Chocolatey for package management"
},
"WPFCollapseAllCategories": {
"Content": "Collapse All Categories",
"Category": "__Selection",
"Type": "Button",
"Order": "1",
"Description": "Collapse all application categories"
},
"WPFExpandAllCategories": {
"Content": "Expand All Categories",
"Category": "__Selection",
"Type": "Button",
"Order": "2",
"Description": "Expand all application categories"
},
"WPFClearInstallSelection": {
"Content": "Clear Selection",
"Category": "__Selection",
"Type": "Button",
"Order": "1",
"Order": "3",
"Description": "Clear the selection of applications"
},
"WPFGetInstalled": {
"Content": "Get Installed",
"Category": "__Selection",
"Type": "Button",
"Order": "2",
"Order": "4",
"Description": "Show installed applications"
},
"WPFselectedAppsButton": {
"Content": "Selected Apps: 0",
"Category": "__Selection",
"Type": "Button",
"Order": "3",
"Order": "5",
"Description": "Show the selected applications"
}
}
6 changes: 3 additions & 3 deletions config/themes.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"shared":{
"AppEntryWidth": "130",
"AppEntryWidth": "200",
"AppEntryFontSize": "11",
"AppEntryMargin": "1,1,1,1",
"AppEntryMargin": "1,0,1,0",
"AppEntryBorderThickness": "0",
"CustomDialogFontSize": "12",
"CustomDialogFontSizeHeader": "14",
Expand Down Expand Up @@ -91,7 +91,7 @@
"AppInstallOverlayBackgroundColor":"#2E3135",
"ComboBoxForegroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747",
"LabelboxForegroundColor": "#0567ff",
"LabelboxForegroundColor": "#5bdcff",
"MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#232629",
Expand Down
4 changes: 2 additions & 2 deletions docs/content/dev/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -546,5 +546,5 @@ Outputs `winutil.ps1` in the root directory.

---

**Last Updated**: January 2026
**Maintainers**: Chris Titus Tech and contributors
**Last Updated**: January 2026
**Maintainers**: Chris Titus Tech and contributors
2 changes: 1 addition & 1 deletion docs/content/dev/tweaks/Essential-Tweaks/Hibernation.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"powercfg.exe /hibernate on"
],
```

## Registry Changes
Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

Write-Host \"Uninstalling OneDrive...\"
Start-Process 'C:\\Windows\\System32\\OneDriveSetup.exe' -ArgumentList '/uninstall' -Wait

# Some of OneDrive files use explorer, and OneDrive uses FileCoAuth
Write-Host \"Removing leftover OneDrive Files...\"
Stop-Process -Name FileCoAuth,Explorer
Expand Down
2 changes: 1 addition & 1 deletion docs/content/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,5 +297,5 @@ Can't find your answer? Try these resources:

---

**Last Updated**: January 2026
**Last Updated**: January 2026
**Found this helpful?** Consider starring the project on [GitHub](https://github.com/ChrisTitusTech/winutil)!
4 changes: 2 additions & 2 deletions docs/content/userguide/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Apply optimizations for performance, privacy, and usability. Choose from preset

Quick fixes for common Windows problems:
- Reset network settings
- Fix Windows Update issues
- Fix Windows Update issues
- Repair system files
- Access legacy Windows panels

Expand Down Expand Up @@ -152,7 +152,7 @@ This User Guide covers everything you need to know:

1. **[Getting Started](getting-started/)** - Installation, first run, basic usage
2. **[Application Store](store/)** - Installing software, using presets
3. **[Tweaks](tweaks/)** - System optimizations and customizations
3. **[Tweaks](tweaks/)** - System optimizations and customizations
4. **[Features & Fixes](features/)** - Troubleshooting tools and utilities
5. **[MicroWin](microwin/)** - Creating custom Windows ISOs
6. **[Updates](updates/)** - Managing Windows Update behavior
Expand Down
61 changes: 46 additions & 15 deletions functions/private/Find-AppsByNameOrDescription.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,68 @@ function Find-AppsByNameOrDescription {
# Reset the visibility if the search string is empty or the search is cleared
if ([string]::IsNullOrWhiteSpace($SearchString)) {
$sync.ItemsControl.Items | ForEach-Object {
# Each item is a StackPanel container
$_.Visibility = [Windows.Visibility]::Visible
$_.Children | ForEach-Object {
if ($null -ne $_) {
$_.Visibility = [Windows.Visibility]::Visible

if ($_.Children.Count -ge 2) {
$categoryLabel = $_.Children[0]
$wrapPanel = $_.Children[1]

# Keep category label visible
$categoryLabel.Visibility = [Windows.Visibility]::Visible

# Respect the collapsed state of categories (indicated by + prefix)
if ($categoryLabel.Content -like "+*") {
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
} else {
$wrapPanel.Visibility = [Windows.Visibility]::Visible
}

# Show all apps within the category
$wrapPanel.Children | ForEach-Object {
$_.Visibility = [Windows.Visibility]::Visible
}
}
}
return
}

# Perform search
$sync.ItemsControl.Items | ForEach-Object {
# Ensure ToggleButtons remain visible
if ($_.Tag -like "CategoryToggleButton") {
$_.Visibility = [Windows.Visibility]::Visible
return
}
# Hide all CategoryWrapPanel and ToggleButton
$_.Visibility = [Windows.Visibility]::Collapsed
if ($_.Tag -like "CategoryWrapPanel_*") {
# Search for Apps that match the search string
$_.Children | Foreach-Object {
# Each item is a StackPanel container with Children[0] = label, Children[1] = WrapPanel
if ($_.Children.Count -ge 2) {
$categoryLabel = $_.Children[0]
$wrapPanel = $_.Children[1]
$categoryHasMatch = $false

# Keep category label visible
$categoryLabel.Visibility = [Windows.Visibility]::Visible

# Search through apps in this category
$wrapPanel.Children | ForEach-Object {
$appEntry = $sync.configs.applicationsHashtable.$($_.Tag)
if ($appEntry.Content -like "*$SearchString*" -or $appEntry.Description -like "*$SearchString*") {
# Show the App and the parent CategoryWrapPanel if the string is found
# Show the App and mark that this category has a match
$_.Visibility = [Windows.Visibility]::Visible
$_.parent.Visibility = [Windows.Visibility]::Visible
$categoryHasMatch = $true
}
else {
$_.Visibility = [Windows.Visibility]::Collapsed
}
}

# If category has matches, show the WrapPanel and update the category label to expanded state
if ($categoryHasMatch) {
$wrapPanel.Visibility = [Windows.Visibility]::Visible
$_.Visibility = [Windows.Visibility]::Visible
# Update category label to show expanded state (-)
if ($categoryLabel.Content -like "+*") {
$categoryLabel.Content = $categoryLabel.Content -replace "^\+ ", "- "
}
} else {
# Hide the entire category container if no matches
$_.Visibility = [Windows.Visibility]::Collapsed
}
}
}
}
8 changes: 4 additions & 4 deletions functions/private/Initialize-InstallAppArea.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@
$itemsControl.VerticalAlignment = 'Stretch'
$scrollViewer.Content = $itemsControl

# Enable virtualization for the ItemsControl to improve performance (It's hard to test if this is actually working, so if you know what you're doing, please check this)
# Use WrapPanel to create dynamic columns based on AppEntryWidth and window width
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.WrapPanel])
$factory.SetValue([Windows.Controls.WrapPanel]::OrientationProperty, [Windows.Controls.Orientation]::Horizontal)
$factory.SetValue([Windows.Controls.WrapPanel]::HorizontalAlignmentProperty, [Windows.HorizontalAlignment]::Left)
$itemsPanelTemplate.VisualTree = $factory
$itemsControl.ItemsPanel = $itemsPanelTemplate
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)

# Add the Border containing the App Area to the target Grid
$targetGrid.Children.Add($Border) | Out-Null
Expand Down
84 changes: 61 additions & 23 deletions functions/private/Initialize-InstallCategoryAppList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,6 @@ function Initialize-InstallCategoryAppList {
$TargetElement,
$Apps
)
function Add-Category {
param(
[string]$Category,
[Windows.Controls.ItemsControl]$TargetElement
)

$toggleButton = New-Object Windows.Controls.Label
$toggleButton.Content = "$Category"
$toggleButton.Tag = "CategoryToggleButton"
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
$sync.$Category = $toggleButton

$null = $TargetElement.Items.Add($toggleButton)
}


# Pre-group apps by category
$appsByCategory = @{}
Expand All @@ -42,17 +26,71 @@ function Initialize-InstallCategoryAppList {
$appsByCategory[$category] += $appKey
}
foreach ($category in $($appsByCategory.Keys | Sort-Object)) {
Add-Category -Category $category -TargetElement $TargetElement
# Create a container for category label + apps
$categoryContainer = New-Object Windows.Controls.StackPanel
$categoryContainer.Orientation = "Vertical"
$categoryContainer.Margin = New-Object Windows.Thickness(0, 0, 0, 0)
$categoryContainer.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch

# Bind Width to the ItemsControl's ActualWidth to force full-row layout in WrapPanel
$binding = New-Object Windows.Data.Binding
$binding.Path = New-Object Windows.PropertyPath("ActualWidth")
$binding.RelativeSource = New-Object Windows.Data.RelativeSource([Windows.Data.RelativeSourceMode]::FindAncestor, [Windows.Controls.ItemsControl], 1)
[void][Windows.Data.BindingOperations]::SetBinding($categoryContainer, [Windows.FrameworkElement]::WidthProperty, $binding)

# Add category label to container
$toggleButton = New-Object Windows.Controls.Label
$toggleButton.Content = "- $Category"
$toggleButton.Tag = "CategoryToggleButton"
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "LabelboxForegroundColor")
$toggleButton.Cursor = [System.Windows.Input.Cursors]::Hand
$toggleButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
$sync.$Category = $toggleButton

# Add click handler to toggle category visibility
$toggleButton.Add_MouseLeftButtonUp({
param($sender, $e)

# Find the parent StackPanel (categoryContainer)
$categoryContainer = $sender.Parent
if ($categoryContainer -and $categoryContainer.Children.Count -ge 2) {
# The WrapPanel is the second child
$wrapPanel = $categoryContainer.Children[1]

# Toggle visibility
if ($wrapPanel.Visibility -eq [Windows.Visibility]::Visible) {
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
# Change - to +
$sender.Content = $sender.Content -replace "^- ", "+ "
} else {
$wrapPanel.Visibility = [Windows.Visibility]::Visible
# Change + to -
$sender.Content = $sender.Content -replace "^\+ ", "- "
}
}
})

$null = $categoryContainer.Children.Add($toggleButton)

# Add wrap panel for apps to container
$wrapPanel = New-Object Windows.Controls.WrapPanel
$wrapPanel.Orientation = "Horizontal"
$wrapPanel.HorizontalAlignment = "Stretch"
$wrapPanel.VerticalAlignment = "Center"
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 20)
$wrapPanel.HorizontalAlignment = "Left"
$wrapPanel.VerticalAlignment = "Top"
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 0)
$wrapPanel.Visibility = [Windows.Visibility]::Visible
$wrapPanel.Tag = "CategoryWrapPanel_$category"
$null = $TargetElement.Items.Add($wrapPanel)
$appsByCategory[$category] |Sort-Object | ForEach-Object {
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)

$null = $categoryContainer.Children.Add($wrapPanel)

# Add the entire category container to the target element
$null = $TargetElement.Items.Add($categoryContainer)

# Add apps to the wrap panel
$appsByCategory[$category] | Sort-Object | ForEach-Object {
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)
}
}
}
2 changes: 2 additions & 0 deletions functions/public/Invoke-WPFButton.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ function Invoke-WPFButton {
"WPFInstall" {Invoke-WPFInstall}
"WPFUninstall" {Invoke-WPFUnInstall}
"WPFInstallUpgrade" {Invoke-WPFInstallUpgrade}
"WPFCollapseAllCategories" {Invoke-WPFToggleAllCategories -Action "Collapse"}
"WPFExpandAllCategories" {Invoke-WPFToggleAllCategories -Action "Expand"}
"WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"}
"WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"}
"WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"}
Expand Down
Loading
Loading