mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-04-03 22:16:30 +00:00
Compare commits
17 Commits
master
...
undo-tweak
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c79c05f286 | ||
|
|
105198e396 | ||
|
|
f8f85ca861 | ||
|
|
bd16457552 | ||
|
|
ad225cdf9d | ||
|
|
2eddbe5638 | ||
|
|
b5c576519b | ||
|
|
b1cf364c7d | ||
|
|
bc8fc1a284 | ||
|
|
e9bccccc09 | ||
|
|
b0125ddcd2 | ||
|
|
c15a18c376 | ||
|
|
85bdf765e5 | ||
|
|
bcfed9daff | ||
|
|
91a9beed0c | ||
|
|
cfc868ba91 | ||
|
|
a54c3c6918 |
File diff suppressed because it is too large
Load Diff
@@ -160,7 +160,6 @@ Below is an overview of the key features and functionality offered by Win11Deblo
|
||||
- Add all common folders (Desktop, Downloads, etc.) back to 'This PC' in File Explorer.
|
||||
- Hide the 3D objects, music or OneDrive folder from the File Explorer navigation pane.
|
||||
- Hide the 'Include in library', 'Give access to' and 'Share' options from the context menu.
|
||||
- Change drive letter position or visibility in File Explorer.
|
||||
|
||||
#### Multi-tasking
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000002
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000004
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000000
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000001
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[hkey_users\default\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000002
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[hkey_users\default\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000004
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[hkey_users\default\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000000
|
||||
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[hkey_users\default\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000001
|
||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
|
||||
"ShowDriveLettersFirst"=dword:00000000
|
||||
@@ -9,55 +9,6 @@
|
||||
Background="Transparent"
|
||||
Foreground="{DynamicResource FgColor}">
|
||||
<Window.Resources>
|
||||
<!-- CheckBox Style -->
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Padding" Value="4,2"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<Border Background="{TemplateBinding Background}" BorderThickness="0" CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="CheckBoxBorder" Grid.Column="0" Width="18" Height="18" Background="{DynamicResource CheckBoxBgColor}" BorderBrush="{DynamicResource CheckBoxBorderColor}" BorderThickness="1" CornerRadius="4" Margin="0,0,8,0">
|
||||
<TextBlock x:Name="CheckMark" Text="" FontFamily="Segoe MDL2 Assets" FontSize="12" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
|
||||
</Border>
|
||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="0,0,0,1"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource CheckBoxHoverColor}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckMark" Property="Foreground" Value="White"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonHover}"/>
|
||||
</MultiTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- CheckBox style for apps panels -->
|
||||
<Style x:Key="AppsPanelCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="2,3,2,3"/>
|
||||
</Style>
|
||||
|
||||
<!-- Title Bar Button Style -->
|
||||
<Style x:Key="TitleBarButton" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
|
||||
@@ -180,20 +180,20 @@
|
||||
<StackPanel x:Name="ButtonPanel"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center">
|
||||
<Button x:Name="ApplyKofiBtn" Width="210" Height="32"
|
||||
Style="{DynamicResource SecondaryButtonStyle}"
|
||||
Margin="0,0,12,0"
|
||||
<Button x:Name="ApplyKofiBtn"
|
||||
Width="200" Height="32" Margin="4,0"
|
||||
Style="{DynamicResource SecondaryButtonStyle}"
|
||||
AutomationProperties.Name="Support the creator">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="" FontFamily="Segoe Fluent Icons" FontSize="14" VerticalAlignment="Center" Margin="0,0,8,-1"/>
|
||||
<TextBlock Text="Support the creator" VerticalAlignment="Center" FontSize="14" Margin="0,0,0,1"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="ApplyCloseBtn" Width="100" Height="32"
|
||||
<Button x:Name="ApplyCloseBtn"
|
||||
Content="Close"
|
||||
Width="200" Height="32" Margin="4,0"
|
||||
Style="{DynamicResource PrimaryButtonStyle}"
|
||||
AutomationProperties.Name="Close">
|
||||
<TextBlock Text="Close" VerticalAlignment="Center" FontSize="14" Margin="0,0,0,1"/>
|
||||
</Button>
|
||||
AutomationProperties.Name="Close"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
|
||||
Title="Win11Debloat"
|
||||
MinWidth="1130" MinHeight="600"
|
||||
MaxWidth="1400"
|
||||
ResizeMode="CanResize"
|
||||
SnapsToDevicePixels="True"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowStyle="None"
|
||||
AllowsTransparency="False"
|
||||
Background="{DynamicResource BgColor}"
|
||||
AllowsTransparency="True"
|
||||
Background="Transparent"
|
||||
Foreground="{DynamicResource FgColor}">
|
||||
<shell:WindowChrome.WindowChrome>
|
||||
<shell:WindowChrome ResizeBorderThickness="5"
|
||||
CaptionHeight="32"
|
||||
CornerRadius="8"
|
||||
GlassFrameThickness="0"
|
||||
UseAeroCaptionButtons="False"/>
|
||||
</shell:WindowChrome.WindowChrome>
|
||||
<Window.Resources>
|
||||
<!-- Sort column header hover style -->
|
||||
<Style x:Key="SortHeaderBtnStyle" TargetType="StackPanel">
|
||||
@@ -343,89 +336,6 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- CheckBox Style -->
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Padding" Value="4,2"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<Border Background="{TemplateBinding Background}" BorderThickness="0" CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="CheckBoxBorder" Grid.Column="0" Width="18" Height="18" Background="{DynamicResource CheckBoxBgColor}" BorderBrush="{DynamicResource CheckBoxBorderColor}" BorderThickness="1" CornerRadius="4" Margin="0,0,8,0">
|
||||
<Grid>
|
||||
<TextBlock x:Name="CheckMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="12" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
|
||||
<TextBlock x:Name="IndeterminateMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="11" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Margin="1,1,0,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="0,0,0,2"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource CheckBoxHoverColor}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckMark" Property="Foreground" Value="White"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="{x:Null}">
|
||||
<Setter TargetName="IndeterminateMark" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
||||
<Setter TargetName="IndeterminateMark" Property="Foreground" Value="White"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonDisabled}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource ButtonTextDisabled}"/>
|
||||
<Setter Property="Opacity" Value="0.6"/>
|
||||
<Setter TargetName="CheckMark" Property="Foreground" Value="{DynamicResource ButtonTextDisabled}"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonHover}"/>
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Condition Property="IsChecked" Value="{x:Null}"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
||||
</MultiTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- CheckBox style for feature toggles -->
|
||||
<Style x:Key="FeatureCheckboxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="-4,-2,-4,10"/>
|
||||
<Setter Property="Padding" Value="4,2"/>
|
||||
</Style>
|
||||
|
||||
<!-- CheckBox style for apps panels -->
|
||||
<Style x:Key="AppsPanelCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="2,3,2,3"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- TextBlock style for App ID column in apps table -->
|
||||
<Style x:Key="AppIdTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppIdColor}"/>
|
||||
@@ -465,11 +375,6 @@
|
||||
<Setter Property="Margin" Value="0,1,0,0"/>
|
||||
</Style>
|
||||
|
||||
<!-- Style for dynamically-created preset checkboxes in the Quick Select popup -->
|
||||
<Style x:Key="PresetCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="8,4"/>
|
||||
</Style>
|
||||
|
||||
<!-- Progress step indicator fill colors -->
|
||||
<SolidColorBrush x:Key="ProgressActiveColor" Color="#0067c0"/>
|
||||
<SolidColorBrush x:Key="ProgressInactiveColor" Color="#808080"/>
|
||||
@@ -608,11 +513,18 @@
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Border x:Name="MainBorder" BorderBrush="{DynamicResource BorderColor}"
|
||||
<Border BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Background="{DynamicResource BgColor}"
|
||||
Margin="0">
|
||||
Margin="25">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect Color="Black"
|
||||
Opacity="0.15"
|
||||
BlurRadius="20"
|
||||
ShadowDepth="0"
|
||||
Direction="0"/>
|
||||
</Border.Effect>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="32"/>
|
||||
@@ -621,18 +533,18 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Resize Borders -->
|
||||
<Rectangle x:Name="ResizeLeft" Width="5" HorizontalAlignment="Left" Fill="Transparent" Cursor="SizeWE" Grid.Row="0" Grid.RowSpan="3" Panel.ZIndex="100" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeRight" Width="5" HorizontalAlignment="Right" Fill="Transparent" Cursor="SizeWE" Grid.Row="0" Grid.RowSpan="3" Panel.ZIndex="100" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeTop" Height="5" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNS" Grid.Row="0" Panel.ZIndex="100" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeBottom" Height="5" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNS" Grid.Row="2" Panel.ZIndex="100" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeTopLeft" Width="8" Height="8" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNWSE" Grid.Row="0" Panel.ZIndex="101" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeTopRight" Width="8" Height="8" HorizontalAlignment="Right" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNESW" Grid.Row="0" Panel.ZIndex="101" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeBottomLeft" Width="8" Height="8" HorizontalAlignment="Left" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNESW" Grid.Row="2" Panel.ZIndex="101" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeBottomRight" Width="8" Height="8" HorizontalAlignment="Right" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNWSE" Grid.Row="2" Panel.ZIndex="101" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Rectangle x:Name="ResizeLeft" Width="5" HorizontalAlignment="Left" Fill="Transparent" Cursor="SizeWE" Grid.Row="0" Grid.RowSpan="3" Panel.ZIndex="100"/>
|
||||
<Rectangle x:Name="ResizeRight" Width="5" HorizontalAlignment="Right" Fill="Transparent" Cursor="SizeWE" Grid.Row="0" Grid.RowSpan="3" Panel.ZIndex="100"/>
|
||||
<Rectangle x:Name="ResizeTop" Height="5" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNS" Grid.Row="0" Panel.ZIndex="100"/>
|
||||
<Rectangle x:Name="ResizeBottom" Height="5" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNS" Grid.Row="2" Panel.ZIndex="100"/>
|
||||
<Rectangle x:Name="ResizeTopLeft" Width="8" Height="8" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNWSE" Grid.Row="0" Panel.ZIndex="101"/>
|
||||
<Rectangle x:Name="ResizeTopRight" Width="8" Height="8" HorizontalAlignment="Right" VerticalAlignment="Top" Fill="Transparent" Cursor="SizeNESW" Grid.Row="0" Panel.ZIndex="101"/>
|
||||
<Rectangle x:Name="ResizeBottomLeft" Width="8" Height="8" HorizontalAlignment="Left" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNESW" Grid.Row="2" Panel.ZIndex="101"/>
|
||||
<Rectangle x:Name="ResizeBottomRight" Width="8" Height="8" HorizontalAlignment="Right" VerticalAlignment="Bottom" Fill="Transparent" Cursor="SizeNWSE" Grid.Row="2" Panel.ZIndex="101"/>
|
||||
|
||||
<!-- Custom Title Bar -->
|
||||
<Grid Grid.Row="0" x:Name="TitleBar">
|
||||
<Border x:Name="TitleBarBackground" Background="{DynamicResource BgColor}" CornerRadius="8,8,0,0">
|
||||
<Border Background="{DynamicResource BgColor}" CornerRadius="8,8,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
@@ -645,8 +557,8 @@
|
||||
Margin="12,0,0,0"
|
||||
FontSize="12"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<Button x:Name="KofiBtn" shell:WindowChrome.IsHitTestVisibleInChrome="True" Content="" FontFamily="Segoe Fluent Icons" FontSize="15" Style="{StaticResource TitlebarButton}" ToolTip="Support the creator" AutomationProperties.Name="Support the creator"/>
|
||||
<Button x:Name="MenuBtn" shell:WindowChrome.IsHitTestVisibleInChrome="True" Content="" FontFamily="Segoe Fluent Icons" FontSize="15" Style="{StaticResource TitlebarButton}" ToolTip="Options" AutomationProperties.Name="Options">
|
||||
<Button x:Name="KofiBtn" Content="" FontFamily="Segoe Fluent Icons" FontSize="15" Style="{StaticResource TitlebarButton}" ToolTip="Support the creator" AutomationProperties.Name="Support the creator"/>
|
||||
<Button x:Name="MenuBtn" Content="" FontFamily="Segoe Fluent Icons" FontSize="15" Style="{StaticResource TitlebarButton}" ToolTip="Options" AutomationProperties.Name="Options">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu x:Name="MainMenu">
|
||||
<ContextMenu.Resources>
|
||||
@@ -695,7 +607,7 @@
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
<Button x:Name="CloseBtn" shell:WindowChrome.IsHitTestVisibleInChrome="True" Content="" Style="{StaticResource CloseButton}" ToolTip="Close" AutomationProperties.Name="Close"/>
|
||||
<Button x:Name="CloseBtn" Content="" Style="{StaticResource CloseButton}" ToolTip="Close" AutomationProperties.Name="Close"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
@@ -776,6 +688,11 @@
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Revert link -->
|
||||
<Button x:Name="HomeRevertLinkBtn" HorizontalAlignment="Center" Margin="0,11,0,0" Style="{DynamicResource ActionLinkButtonStyle}" AutomationProperties.Name="Revert previous changes">
|
||||
<TextBlock Text="Revert previous changes" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
@@ -1129,12 +1046,12 @@
|
||||
|
||||
<!-- Restore Point Option -->
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="RestorePointCheckBox" Style="{StaticResource FeatureCheckboxStyle}" IsChecked="True" Content="Create a system restore point (Recommended)" AutomationProperties.Name="Create a system restore point (Recommended)"/>
|
||||
<CheckBox x:Name="RestorePointCheckBox" Style="{DynamicResource FeatureCheckboxStyle}" IsChecked="True" Content="Create a system restore point (Recommended)" AutomationProperties.Name="Create a system restore point (Recommended)"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Restart Explorer Option -->
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="RestartExplorerCheckBox" Style="{StaticResource FeatureCheckboxStyle}" Content="Restart the Windows Explorer process to apply all changes immediately" AutomationProperties.Name="Restart the Windows Explorer process to apply all changes immediately"/>
|
||||
<CheckBox x:Name="RestartExplorerCheckBox" Style="{DynamicResource FeatureCheckboxStyle}" Content="Restart the Windows Explorer process to apply all changes immediately" AutomationProperties.Name="Restart the Windows Explorer process to apply all changes immediately"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
@@ -1163,20 +1080,8 @@
|
||||
|
||||
<!-- Review & Apply Section -->
|
||||
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" Background="{DynamicResource BgColor}">
|
||||
<Button x:Name="ReviewChangesBtn" Background="Transparent" BorderThickness="0" Cursor="Hand" HorizontalAlignment="Center" Margin="0,4,0,10" AutomationProperties.Name="Review selected changes">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<TextBlock x:Name="LinkText" Text="Review selected changes" FontSize="14" Foreground="{DynamicResource ButtonBg}" FontWeight="SemiBold" HorizontalAlignment="Center"/>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="LinkText" Property="Foreground" Value="{DynamicResource ButtonHover}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="LinkText" Property="Foreground" Value="{DynamicResource ButtonPressed}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
<Button x:Name="ReviewChangesBtn" Style="{DynamicResource ActionLinkButtonStyle}" HorizontalAlignment="Center" Margin="0,4,0,10" AutomationProperties.Name="Review selected changes">
|
||||
<TextBlock Text="Review selected changes" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||
</Button>
|
||||
<Button x:Name="DeploymentApplyBtn" Style="{DynamicResource PrimaryButtonStyle}" Width="190" Height="44" HorizontalAlignment="Center" AutomationProperties.Name="Apply Changes">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
|
||||
160
Schemas/RevertSettingsWindow.xaml
Normal file
160
Schemas/RevertSettingsWindow.xaml
Normal file
@@ -0,0 +1,160 @@
|
||||
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Revert Changes"
|
||||
Width="620"
|
||||
Height="620"
|
||||
MinWidth="560"
|
||||
MinHeight="420"
|
||||
ResizeMode="CanResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
WindowStyle="None"
|
||||
AllowsTransparency="True"
|
||||
Background="Transparent"
|
||||
Topmost="False"
|
||||
ShowInTaskbar="False">
|
||||
|
||||
<Window.Resources>
|
||||
<Style x:Key="RevertItemBorderStyle" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
||||
<Setter Property="Padding" Value="4,6,4,6"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="RevertItemRowStyle" TargetType="StackPanel">
|
||||
<Setter Property="Orientation" Value="Vertical"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="RevertItemUndoTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||
<Setter Property="Opacity" Value="0.75"/>
|
||||
<Setter Property="Margin" Value="26,-8,0,3"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="RevertEmptyTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||
<Setter Property="Opacity" Value="0.85"/>
|
||||
<Setter Property="Margin" Value="6,0,6,0"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Border BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Background="{DynamicResource CardBgColor}"
|
||||
Margin="25">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect Color="Black"
|
||||
Opacity="0.15"
|
||||
BlurRadius="20"
|
||||
ShadowDepth="0"
|
||||
Direction="0"/>
|
||||
</Border.Effect>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" x:Name="TitleBar" Height="40" Background="Transparent">
|
||||
<TextBlock x:Name="TitleText"
|
||||
Text="Revert Changes"
|
||||
Foreground="{DynamicResource FgColor}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
VerticalAlignment="Center"
|
||||
Margin="16,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="20,12,1,12">
|
||||
<TextBlock x:Name="MessageText"
|
||||
Grid.Column="1"
|
||||
Text="Select which previously applied tweaks should be reverted to Windows defaults."
|
||||
TextWrapping="Wrap"
|
||||
FontSize="14"
|
||||
LineHeight="20"
|
||||
Foreground="{DynamicResource FgColor}"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="2" Margin="20,0,20,10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<DockPanel Grid.Row="0" Margin="0,0,0,8">
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
|
||||
<Button x:Name="RevertSelectAllBtn"
|
||||
Content="Select All"
|
||||
Height="30"
|
||||
Padding="12,0"
|
||||
Style="{DynamicResource SecondaryButtonStyle}"
|
||||
Margin="0,0,8,0"
|
||||
AutomationProperties.Name="Select All"/>
|
||||
<Button x:Name="RevertClearBtn"
|
||||
Content="Clear"
|
||||
Height="30"
|
||||
Padding="12,0"
|
||||
Style="{DynamicResource SecondaryButtonStyle}"
|
||||
AutomationProperties.Name="Clear"/>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="RevertSelectionCount"
|
||||
Text="0 settings selected"
|
||||
Foreground="{DynamicResource FgColor}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
DockPanel.Dock="Right"
|
||||
Margin="0,0,6,0"/>
|
||||
</DockPanel>
|
||||
|
||||
<Border Grid.Row="1"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
CornerRadius="6"
|
||||
Background="{DynamicResource BgColor}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Padding="8" Margin="0,1,1,1">
|
||||
<StackPanel x:Name="RevertItemsPanel"/>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<CheckBox x:Name="RevertRestartExplorerCheckBox"
|
||||
Grid.Row="2"
|
||||
Content="Restart the Windows Explorer process to apply all changes immediately"
|
||||
IsChecked="False"
|
||||
Margin="2,10,0,0"
|
||||
AutomationProperties.Name="Restart the Windows Explorer process to apply all changes immediately"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Button Panel -->
|
||||
<Border Grid.Row="3"
|
||||
Background="{DynamicResource BgColor}"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="0,1,0,0"
|
||||
Padding="16,12"
|
||||
CornerRadius="0,0,8,8">
|
||||
<StackPanel x:Name="ButtonPanel"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button x:Name="RevertApplyBtn"
|
||||
Content="Revert Selected Settings"
|
||||
Height="32" MinWidth="200" Margin="4,0"
|
||||
Style="{DynamicResource PrimaryButtonStyle}"
|
||||
IsEnabled="False"
|
||||
AutomationProperties.Name="Revert Selected Settings"/>
|
||||
<Button x:Name="RevertCancelBtn"
|
||||
Content="Cancel"
|
||||
Height="32" MinWidth="80" Margin="4,0"
|
||||
Style="{DynamicResource SecondaryButtonStyle}"
|
||||
AutomationProperties.Name="Cancel"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
@@ -18,7 +18,7 @@
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="4"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,1"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
@@ -90,6 +90,32 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- Shared link-style button used for text actions like review/revert links -->
|
||||
<Style x:Key="ActionLinkButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Foreground" Value="{DynamicResource ButtonHover}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Foreground" Value="{DynamicResource ButtonPressed}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- ProgressBar Style -->
|
||||
<Style x:Key="ApplyProgressBarStyle" TargetType="ProgressBar">
|
||||
<Setter Property="Background" Value="{DynamicResource ButtonBorderColor}"/>
|
||||
@@ -125,6 +151,138 @@
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- Base CheckBox style used across windows -->
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Padding" Value="4,2"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<Border Background="{TemplateBinding Background}" BorderThickness="0" CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="CheckBoxBorder" Grid.Column="0" Width="18" Height="18" Background="{DynamicResource CheckBoxBgColor}" BorderBrush="{DynamicResource CheckBoxBorderColor}" BorderThickness="1" CornerRadius="4" Margin="0,0,8,0">
|
||||
<Grid>
|
||||
<TextBlock x:Name="CheckMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="12" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0">
|
||||
<TextBlock.Clip>
|
||||
<RectangleGeometry x:Name="CheckMarkClip" Rect="0,0,0,16"/>
|
||||
</TextBlock.Clip>
|
||||
</TextBlock>
|
||||
<TextBlock x:Name="IndeterminateMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="11" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0" Margin="1,1,0,0">
|
||||
<TextBlock.Clip>
|
||||
<RectangleGeometry x:Name="IndeterminateMarkClip" Rect="0,0,0,16"/>
|
||||
</TextBlock.Clip>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="0,0,0,2"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource CheckBoxHoverColor}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckMark" Property="Foreground" Value="White"/>
|
||||
<Setter TargetName="CheckMark" Property="Opacity" Value="1"/>
|
||||
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="0"/>
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||
<RectAnimation Storyboard.TargetName="CheckMarkClip" Storyboard.TargetProperty="Rect" From="0,0,0,16" To="0,0,16,16" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<RectAnimation Storyboard.TargetName="CheckMarkClip" Storyboard.TargetProperty="Rect" From="0,0,16,16" To="16,0,0,16" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||
<DoubleAnimation Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="{x:Null}">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
||||
<Setter TargetName="IndeterminateMark" Property="Foreground" Value="White"/>
|
||||
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="1"/>
|
||||
<Setter TargetName="CheckMark" Property="Opacity" Value="0"/>
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||
<RectAnimation Storyboard.TargetName="IndeterminateMarkClip" Storyboard.TargetProperty="Rect" From="0,0,0,16" To="0,0,16,16" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<RectAnimation Storyboard.TargetName="IndeterminateMarkClip" Storyboard.TargetProperty="Rect" From="0,0,16,16" To="16,0,0,16" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||
<DoubleAnimation Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="False">
|
||||
<Setter TargetName="CheckMark" Property="Opacity" Value="0"/>
|
||||
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="0"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonDisabled}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
||||
<Setter Property="Opacity" Value="0.4"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonHover}"/>
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Condition Property="IsChecked" Value="{x:Null}"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonHover}"/>
|
||||
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
||||
</MultiTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Shared checkbox style used for feature toggles across windows -->
|
||||
<Style x:Key="FeatureCheckboxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="-4,-2,-4,10"/>
|
||||
<Setter Property="Padding" Value="4,2"/>
|
||||
</Style>
|
||||
|
||||
<!-- Shared CheckBox style for app list items -->
|
||||
<Style x:Key="AppsPanelCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="2,3,2,3"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- Shared CheckBox style for preset picker entries -->
|
||||
<Style x:Key="PresetCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
|
||||
<Setter Property="Margin" Value="8,4"/>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollBar Style -->
|
||||
<Style TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
# Prints all pending changes that will be made by the script
|
||||
function PrintPendingChanges {
|
||||
Write-Output "Win11Debloat will make the following changes:"
|
||||
$skippedParams = @()
|
||||
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||
|
||||
if ($undoChanges) {
|
||||
Write-Output "Win11Debloat will make the following changes to revert the selected settings to Windows defaults:"
|
||||
}
|
||||
else {
|
||||
Write-Output "Win11Debloat will make the following changes:"
|
||||
}
|
||||
|
||||
if ($script:Params['CreateRestorePoint']) {
|
||||
Write-Output "- $($script:Features['CreateRestorePoint'].Label)"
|
||||
Write-Output "- $($script:Features['CreateRestorePoint'].Action)"
|
||||
}
|
||||
foreach ($parameterName in $script:Params.Keys) {
|
||||
if ($script:ControlParams -contains $parameterName) {
|
||||
continue
|
||||
}
|
||||
if ($parameterName -eq 'Apps' -or $parameterName -eq 'CreateRestorePoint') {
|
||||
continue
|
||||
}
|
||||
|
||||
if ($undoChanges) {
|
||||
$undoFeature = GetUndoFeatureForParam -paramKey $parameterName
|
||||
if (-not $undoFeature) {
|
||||
$skippedParams += $parameterName
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
# Print parameter description
|
||||
switch ($parameterName) {
|
||||
@@ -46,9 +65,18 @@ function PrintPendingChanges {
|
||||
}
|
||||
default {
|
||||
if ($script:Features -and $script:Features.ContainsKey($parameterName)) {
|
||||
$action = $script:Features[$parameterName].Action
|
||||
$message = $script:Features[$parameterName].Label
|
||||
Write-Output "- $action $message"
|
||||
$message = if ($undoChanges -and $script:Features[$parameterName].UndoAction) {
|
||||
$script:Features[$parameterName].UndoAction
|
||||
}
|
||||
else {
|
||||
$script:Features[$parameterName].Action
|
||||
}
|
||||
if ($message) {
|
||||
Write-Output "- $message"
|
||||
}
|
||||
else {
|
||||
Write-Output "- $parameterName"
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Fallback: show the parameter name if no feature description is available
|
||||
@@ -59,8 +87,18 @@ function PrintPendingChanges {
|
||||
}
|
||||
}
|
||||
|
||||
if ($undoChanges -and $skippedParams.Count -gt 0) {
|
||||
Write-Output ""
|
||||
Write-Output "The following changes cannot be automatically undone and will be skipped:"
|
||||
|
||||
$uniqueSkipped = $skippedParams | Sort-Object -Unique
|
||||
foreach ($skippedParam in $uniqueSkipped) {
|
||||
Write-Output "- $($script:Features[$skippedParam].Action)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
Write-Output ""
|
||||
Write-Output "Press enter to execute the script or press CTRL+C to quit..."
|
||||
Read-Host | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,35 @@ function ExecuteParameter {
|
||||
[string]$paramKey
|
||||
)
|
||||
|
||||
# Check if this feature has metadata in Features.json
|
||||
# Check if this feature exists in Features.json
|
||||
$feature = $null
|
||||
if ($script:Features.ContainsKey($paramKey)) {
|
||||
$feature = $script:Features[$paramKey]
|
||||
}
|
||||
|
||||
# Check if undo is requested and if this feature supports undo
|
||||
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||
|
||||
if ($undoChanges) {
|
||||
$undoFeature = GetUndoFeatureForParam -paramKey $paramKey
|
||||
|
||||
if ($null -eq $undoFeature) {
|
||||
# This parameter doesn't support undo, so skip it
|
||||
return
|
||||
}
|
||||
|
||||
$undoRegFile = $undoFeature.RegistryUndoKey
|
||||
$undoFolderPath = Join-Path $script:RegfilesPath (Join-Path 'Undo' $undoRegFile)
|
||||
|
||||
if (Test-Path $undoFolderPath) {
|
||||
$undoRegFile = Join-Path 'Undo' $undoRegFile
|
||||
}
|
||||
|
||||
ImportRegistryFile "> $($undoFeature.UndoText)" $undoRegFile
|
||||
return
|
||||
}
|
||||
|
||||
# If feature has RegistryKey and ApplyText, use dynamic ImportRegistryFile
|
||||
# If feature has RegistryKey and ApplyText, dynamically import the registry file for this feature
|
||||
if ($feature -and $feature.RegistryKey -and $feature.ApplyText) {
|
||||
ImportRegistryFile "> $($feature.ApplyText)" $feature.RegistryKey
|
||||
|
||||
@@ -139,13 +161,36 @@ function ExecuteParameter {
|
||||
# Executes all selected parameters/features
|
||||
function ExecuteAllChanges {
|
||||
# Build list of actionable parameters (skip control params and data-only params)
|
||||
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||
$actionableKeys = @()
|
||||
$paramsToRemove = @()
|
||||
foreach ($paramKey in $script:Params.Keys) {
|
||||
if ($script:ControlParams -contains $paramKey) { continue }
|
||||
if ($paramKey -eq 'Apps') { continue }
|
||||
if ($paramKey -eq 'CreateRestorePoint') { continue }
|
||||
|
||||
if ($undoChanges) {
|
||||
$undoFeature = GetUndoFeatureForParam -paramKey $paramKey
|
||||
if (-not $undoFeature) {
|
||||
$paramsToRemove += $paramKey
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
$actionableKeys += $paramKey
|
||||
}
|
||||
|
||||
if ($undoChanges -and $paramsToRemove.Count -gt 0) {
|
||||
foreach ($paramKey in ($paramsToRemove | Sort-Object -Unique)) {
|
||||
if ($script:Params.ContainsKey($paramKey)) {
|
||||
$null = $script:Params.Remove($paramKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($undoChanges -and $actionableKeys.Count -eq 0) {
|
||||
throw "Undo was requested but none of the selected parameters support undo. No changes were reverted."
|
||||
}
|
||||
|
||||
$totalSteps = $actionableKeys.Count
|
||||
if ($script:Params.ContainsKey("CreateRestorePoint")) { $totalSteps++ }
|
||||
@@ -174,16 +219,13 @@ function ExecuteAllChanges {
|
||||
$stepName = $paramKey
|
||||
if ($script:Features.ContainsKey($paramKey)) {
|
||||
$feature = $script:Features[$paramKey]
|
||||
if ($feature.ApplyText) {
|
||||
# Prefer explicit ApplyText when provided
|
||||
if ($undoChanges -and $feature.UndoText) {
|
||||
$stepName = $feature.UndoText
|
||||
}
|
||||
elseif ($feature.ApplyText) {
|
||||
$stepName = $feature.ApplyText
|
||||
} elseif ($feature.Label) {
|
||||
# Fallback: construct a name from Action and Label, or just Label
|
||||
if ($feature.Action) {
|
||||
$stepName = "$($feature.Action) $($feature.Label)"
|
||||
} else {
|
||||
$stepName = $feature.Label
|
||||
}
|
||||
} elseif ($feature.Action) {
|
||||
$stepName = $feature.Action
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,4 +235,4 @@ function ExecuteAllChanges {
|
||||
|
||||
ExecuteParameter -paramKey $paramKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ function RestartExplorer {
|
||||
foreach ($paramKey in $script:Params.Keys) {
|
||||
if ($script:Features.ContainsKey($paramKey) -and $script:Features[$paramKey].RequiresReboot -eq $true) {
|
||||
$feature = $script:Features[$paramKey]
|
||||
Write-Host "Warning: '$($feature.Action) $($feature.Label)' requires a reboot to take full effect" -ForegroundColor Yellow
|
||||
Write-Host "Warning: '$($feature.Action)' requires a reboot to take full effect" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ function Show-ApplyModal {
|
||||
foreach ($paramKey in $script:Params.Keys) {
|
||||
if ($script:Features.ContainsKey($paramKey) -and $script:Features[$paramKey].RequiresReboot -eq $true) {
|
||||
$feature = $script:Features[$paramKey]
|
||||
$rebootFeatures += "$($feature.Action) $($feature.Label)"
|
||||
$rebootFeatures += $feature.Action
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ function Show-ApplyModal {
|
||||
$applyRebootPanel.Visibility = 'Visible'
|
||||
}
|
||||
else {
|
||||
$script:ApplyCompletionMessageEl.Text = "Your clean system is ready. Thanks for using Win11Debloat!"
|
||||
$script:ApplyCompletionMessageEl.Text = "Your system is ready. Thanks for using Win11Debloat!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,6 @@ function Show-ImportExportConfigWindow {
|
||||
$dlg.Owner = $Owner
|
||||
SetWindowThemeResources -window $dlg -usesDarkMode $UsesDarkMode
|
||||
|
||||
# Copy the CheckBox default style from the main window so checkboxes get the themed template
|
||||
try {
|
||||
$mainCheckBoxStyle = $Owner.FindResource([type][System.Windows.Controls.CheckBox])
|
||||
if ($mainCheckBoxStyle) {
|
||||
$dlg.Resources.Add([type][System.Windows.Controls.CheckBox], $mainCheckBoxStyle)
|
||||
}
|
||||
} catch { }
|
||||
|
||||
# Populate named elements
|
||||
$dlg.Title = $Title
|
||||
$dlg.FindName('TitleText').Text = $Title
|
||||
@@ -70,6 +62,7 @@ function Show-ImportExportConfigWindow {
|
||||
$cb.Margin = [System.Windows.Thickness]::new(0,0,0,8)
|
||||
$cb.FontSize = 14
|
||||
$cb.Foreground = $dlg.FindResource('FgColor')
|
||||
$cb.Style = $window.Resources["AppsPanelCheckBoxStyle"]
|
||||
if ($DisabledCategories -contains $cat) {
|
||||
$cb.IsChecked = $false
|
||||
$cb.IsEnabled = $false
|
||||
|
||||
@@ -19,8 +19,7 @@ function Show-MainWindow {
|
||||
SetWindowThemeResources -window $window -usesDarkMode $usesDarkMode
|
||||
|
||||
# Get named elements
|
||||
$mainBorder = $window.FindName('MainBorder')
|
||||
$titleBarBackground = $window.FindName('TitleBarBackground')
|
||||
$titleBar = $window.FindName('TitleBar')
|
||||
$kofiBtn = $window.FindName('KofiBtn')
|
||||
$menuBtn = $window.FindName('MenuBtn')
|
||||
$closeBtn = $window.FindName('CloseBtn')
|
||||
@@ -31,86 +30,10 @@ function Show-MainWindow {
|
||||
$importConfigBtn = $window.FindName('ImportConfigBtn')
|
||||
$exportConfigBtn = $window.FindName('ExportConfigBtn')
|
||||
|
||||
$windowStateNormal = [System.Windows.WindowState]::Normal
|
||||
$windowStateMaximized = [System.Windows.WindowState]::Maximized
|
||||
$normalWindowShadow = $mainBorder.Effect
|
||||
$windowResizeBorder = [System.Windows.SystemParameters]::WindowResizeBorderThickness
|
||||
$maximizedChromeInset = [System.Windows.Thickness]::new($windowResizeBorder.Left, $windowResizeBorder.Top, $windowResizeBorder.Right, 0)
|
||||
$initialNormalMaxWidth = 1400.0
|
||||
|
||||
$convertScreenPixelsToDip = {
|
||||
param(
|
||||
[double]$width,
|
||||
[double]$height
|
||||
)
|
||||
|
||||
$source = [System.Windows.PresentationSource]::FromVisual($window)
|
||||
if ($null -eq $source -or $null -eq $source.CompositionTarget) {
|
||||
return [System.Windows.Size]::new($width, $height)
|
||||
}
|
||||
|
||||
$topLeft = $source.CompositionTarget.TransformFromDevice.Transform([System.Windows.Point]::new(0, 0))
|
||||
$bottomRight = $source.CompositionTarget.TransformFromDevice.Transform([System.Windows.Point]::new($width, $height))
|
||||
return [System.Windows.Size]::new($bottomRight.X - $topLeft.X, $bottomRight.Y - $topLeft.Y)
|
||||
}
|
||||
|
||||
$getWindowScreen = {
|
||||
$hwnd = (New-Object System.Windows.Interop.WindowInteropHelper($window)).Handle
|
||||
if ($hwnd -eq [IntPtr]::Zero) {
|
||||
return $null
|
||||
}
|
||||
|
||||
return [System.Windows.Forms.Screen]::FromHandle($hwnd)
|
||||
}
|
||||
|
||||
$updateWindowChrome = {
|
||||
if ($window.WindowState -eq $windowStateMaximized) {
|
||||
$mainBorder.Margin = $maximizedChromeInset
|
||||
$mainBorder.BorderThickness = [System.Windows.Thickness]::new(1)
|
||||
$mainBorder.CornerRadius = [System.Windows.CornerRadius]::new(0)
|
||||
$mainBorder.Effect = $null
|
||||
$titleBarBackground.CornerRadius = [System.Windows.CornerRadius]::new(0)
|
||||
}
|
||||
else {
|
||||
$mainBorder.Margin = [System.Windows.Thickness]::new(0)
|
||||
$mainBorder.BorderThickness = [System.Windows.Thickness]::new(1)
|
||||
$mainBorder.CornerRadius = [System.Windows.CornerRadius]::new(8)
|
||||
$mainBorder.Effect = $normalWindowShadow
|
||||
$titleBarBackground.CornerRadius = [System.Windows.CornerRadius]::new(8, 8, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
$updateMaximizedBounds = {
|
||||
& $updateWindowChrome
|
||||
}
|
||||
|
||||
$applyInitialWindowSize = {
|
||||
if ($window.WindowState -ne $windowStateNormal) {
|
||||
return
|
||||
}
|
||||
|
||||
$screen = & $getWindowScreen
|
||||
if ($null -eq $screen) {
|
||||
return
|
||||
}
|
||||
|
||||
$workingAreaDip = & $convertScreenPixelsToDip $screen.WorkingArea.Width $screen.WorkingArea.Height
|
||||
$window.Width = [Math]::Min($initialNormalMaxWidth, $workingAreaDip.Width)
|
||||
$window.Left = $screen.WorkingArea.Left + (($workingAreaDip.Width - $window.Width) / 2)
|
||||
}
|
||||
|
||||
$window.Add_SourceInitialized({
|
||||
& $applyInitialWindowSize
|
||||
& $updateMaximizedBounds
|
||||
})
|
||||
|
||||
$window.Add_StateChanged({
|
||||
& $updateMaximizedBounds
|
||||
})
|
||||
|
||||
$window.Add_LocationChanged({
|
||||
if ($window.WindowState -eq $windowStateMaximized) {
|
||||
& $updateMaximizedBounds
|
||||
# Title bar event handlers
|
||||
$titleBar.Add_MouseLeftButtonDown({
|
||||
if ($_.OriginalSource -is [System.Windows.Controls.Grid] -or $_.OriginalSource -is [System.Windows.Controls.Border] -or $_.OriginalSource -is [System.Windows.Controls.TextBlock]) {
|
||||
$window.DragMove()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -171,6 +94,135 @@ function Show-MainWindow {
|
||||
$script:CancelRequested = $true
|
||||
})
|
||||
|
||||
# Implement window resize functionality
|
||||
$resizeLeft = $window.FindName('ResizeLeft')
|
||||
$resizeRight = $window.FindName('ResizeRight')
|
||||
$resizeTop = $window.FindName('ResizeTop')
|
||||
$resizeBottom = $window.FindName('ResizeBottom')
|
||||
$resizeTopLeft = $window.FindName('ResizeTopLeft')
|
||||
$resizeTopRight = $window.FindName('ResizeTopRight')
|
||||
$resizeBottomLeft = $window.FindName('ResizeBottomLeft')
|
||||
$resizeBottomRight = $window.FindName('ResizeBottomRight')
|
||||
|
||||
$script:resizing = $false
|
||||
$script:resizeEdges = $null
|
||||
$script:resizeStart = $null
|
||||
$script:windowStart = $null
|
||||
$script:resizeElement = $null
|
||||
|
||||
$resizeHandler = {
|
||||
param($sender, $e)
|
||||
|
||||
$script:resizing = $true
|
||||
$script:resizeElement = $sender
|
||||
$script:resizeStart = [System.Windows.Forms.Cursor]::Position
|
||||
$script:windowStart = @{
|
||||
Left = $window.Left
|
||||
Top = $window.Top
|
||||
Width = $window.ActualWidth
|
||||
Height = $window.ActualHeight
|
||||
}
|
||||
|
||||
# Parse direction tag into edge flags for cleaner resize logic
|
||||
$direction = $sender.Tag
|
||||
$script:resizeEdges = @{
|
||||
Left = $direction -match 'Left'
|
||||
Right = $direction -match 'Right'
|
||||
Top = $direction -match 'Top'
|
||||
Bottom = $direction -match 'Bottom'
|
||||
}
|
||||
|
||||
$sender.CaptureMouse()
|
||||
$e.Handled = $true
|
||||
}
|
||||
|
||||
$moveHandler = {
|
||||
param($sender, $e)
|
||||
if (-not $script:resizing) { return }
|
||||
|
||||
$current = [System.Windows.Forms.Cursor]::Position
|
||||
$deltaX = $current.X - $script:resizeStart.X
|
||||
$deltaY = $current.Y - $script:resizeStart.Y
|
||||
|
||||
# Handle horizontal resize
|
||||
if ($script:resizeEdges.Left) {
|
||||
$newWidth = [Math]::Max($window.MinWidth, $script:windowStart.Width - $deltaX)
|
||||
if ($newWidth -ne $window.Width) {
|
||||
$window.Left = $script:windowStart.Left + ($script:windowStart.Width - $newWidth)
|
||||
$window.Width = $newWidth
|
||||
}
|
||||
}
|
||||
elseif ($script:resizeEdges.Right) {
|
||||
$window.Width = [Math]::Max($window.MinWidth, $script:windowStart.Width + $deltaX)
|
||||
}
|
||||
|
||||
# Handle vertical resize
|
||||
if ($script:resizeEdges.Top) {
|
||||
$newHeight = [Math]::Max($window.MinHeight, $script:windowStart.Height - $deltaY)
|
||||
if ($newHeight -ne $window.Height) {
|
||||
$window.Top = $script:windowStart.Top + ($script:windowStart.Height - $newHeight)
|
||||
$window.Height = $newHeight
|
||||
}
|
||||
}
|
||||
elseif ($script:resizeEdges.Bottom) {
|
||||
$window.Height = [Math]::Max($window.MinHeight, $script:windowStart.Height + $deltaY)
|
||||
}
|
||||
|
||||
$e.Handled = $true
|
||||
}
|
||||
|
||||
$releaseHandler = {
|
||||
param($sender, $e)
|
||||
if ($script:resizing -and $script:resizeElement) {
|
||||
$script:resizing = $false
|
||||
$script:resizeEdges = $null
|
||||
$script:resizeElement.ReleaseMouseCapture()
|
||||
$script:resizeElement = $null
|
||||
$e.Handled = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Set tags and add event handlers for resize borders
|
||||
$resizeLeft.Tag = 'Left'
|
||||
$resizeLeft.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeLeft.Add_MouseMove($moveHandler)
|
||||
$resizeLeft.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeRight.Tag = 'Right'
|
||||
$resizeRight.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeRight.Add_MouseMove($moveHandler)
|
||||
$resizeRight.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeTop.Tag = 'Top'
|
||||
$resizeTop.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeTop.Add_MouseMove($moveHandler)
|
||||
$resizeTop.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeBottom.Tag = 'Bottom'
|
||||
$resizeBottom.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeBottom.Add_MouseMove($moveHandler)
|
||||
$resizeBottom.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeTopLeft.Tag = 'TopLeft'
|
||||
$resizeTopLeft.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeTopLeft.Add_MouseMove($moveHandler)
|
||||
$resizeTopLeft.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeTopRight.Tag = 'TopRight'
|
||||
$resizeTopRight.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeTopRight.Add_MouseMove($moveHandler)
|
||||
$resizeTopRight.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeBottomLeft.Tag = 'BottomLeft'
|
||||
$resizeBottomLeft.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeBottomLeft.Add_MouseMove($moveHandler)
|
||||
$resizeBottomLeft.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
$resizeBottomRight.Tag = 'BottomRight'
|
||||
$resizeBottomRight.Add_PreviewMouseLeftButtonDown($resizeHandler)
|
||||
$resizeBottomRight.Add_MouseMove($moveHandler)
|
||||
$resizeBottomRight.Add_MouseLeftButtonUp($releaseHandler)
|
||||
|
||||
# Integrated App Selection UI
|
||||
$appsPanel = $window.FindName('AppSelectionPanel')
|
||||
$onlyInstalledAppsBox = $window.FindName('OnlyInstalledAppsBox')
|
||||
@@ -190,32 +242,6 @@ function Show-MainWindow {
|
||||
$presetsArrow = $window.FindName('PresetsArrow')
|
||||
$clearAppSelectionBtn = $window.FindName('ClearAppSelectionBtn')
|
||||
|
||||
function NormalizeCheckboxState {
|
||||
param([System.Windows.Controls.CheckBox]$checkBox)
|
||||
|
||||
$isChecked = ($checkBox.IsChecked -eq $true)
|
||||
if ($null -eq $checkBox.IsChecked) {
|
||||
$checkBox.IsChecked = $false
|
||||
return $false
|
||||
}
|
||||
|
||||
return $isChecked
|
||||
}
|
||||
|
||||
function AnimatePresetsArrow {
|
||||
param([double]$angle)
|
||||
|
||||
$animation = New-Object System.Windows.Media.Animation.DoubleAnimation
|
||||
$animation.To = $angle
|
||||
$animation.Duration = [System.Windows.Duration]::new([System.TimeSpan]::FromMilliseconds(200))
|
||||
|
||||
$ease = New-Object System.Windows.Media.Animation.CubicEase
|
||||
$ease.EasingMode = 'EaseOut'
|
||||
$animation.EasingFunction = $ease
|
||||
|
||||
$presetsArrow.RenderTransform.BeginAnimation([System.Windows.Media.RotateTransform]::AngleProperty, $animation)
|
||||
}
|
||||
|
||||
# Load JSON-defined presets and build dynamic preset checkboxes
|
||||
$script:JsonPresetCheckboxes = @()
|
||||
foreach ($preset in (LoadAppPresetsFromJson)) {
|
||||
@@ -230,7 +256,8 @@ function Show-MainWindow {
|
||||
|
||||
$checkbox.Add_Click({
|
||||
if ($script:UpdatingPresets) { return }
|
||||
$check = NormalizeCheckboxState -checkBox $this
|
||||
$check = ($this.IsChecked -eq $true)
|
||||
if ($this.IsChecked -eq $null) { $this.IsChecked = $false; $check = $false }
|
||||
$presetIds = $this.PresetAppIds
|
||||
ApplyPresetToApps -MatchFilter { param($c) (@($c.AppIds) | Where-Object { $presetIds -contains $_ }).Count -gt 0 }.GetNewClosure() -Check $check
|
||||
})
|
||||
@@ -419,7 +446,7 @@ function Show-MainWindow {
|
||||
|
||||
# Dynamically builds Tweaks UI from Features.json
|
||||
function BuildDynamicTweaks {
|
||||
$featuresJson = LoadJsonFile -filePath $script:FeaturesFilePath -expectedVersion "1.0"
|
||||
$featuresJson = LoadJsonFile -filePath $script:FeaturesFilePath -expectedVersion $script:FeaturesConfigVersion
|
||||
|
||||
if (-not $featuresJson) {
|
||||
Show-MessageBox -Message "Unable to load Features.json file!" -Title "Error" -Button 'OK' -Icon 'Error' | Out-Null
|
||||
@@ -563,8 +590,8 @@ function Show-MainWindow {
|
||||
$helpBtn.Tag = (GetWikiUrlForCategory -category $categoryName)
|
||||
$helpBtn.Style = $window.Resources['CategoryHelpLinkButtonStyle']
|
||||
$helpBtn.Add_Click({
|
||||
param($button, $e)
|
||||
if ($button.Tag) { Start-Process $button.Tag }
|
||||
param($sender, $e)
|
||||
if ($sender.Tag) { Start-Process $sender.Tag }
|
||||
})
|
||||
$headerRow.Children.Add($helpBtn) | Out-Null
|
||||
|
||||
@@ -682,7 +709,7 @@ function Show-MainWindow {
|
||||
if ($feature.FeatureId -match '^Disable') { $opt = 'Disable' } elseif ($feature.FeatureId -match '^Enable') { $opt = 'Enable' }
|
||||
$items = @('No Change', $opt)
|
||||
$comboName = ("Feature_{0}_Combo" -f $feature.FeatureId) -replace '[^a-zA-Z0-9_]',''
|
||||
$combo = CreateLabeledCombo -parent $panel -labelText ($feature.Action + ' ' + $feature.Label) -comboName $comboName -items $items
|
||||
$combo = CreateLabeledCombo -parent $panel -labelText $feature.Action -comboName $comboName -items $items
|
||||
# attach tooltip from Features.json if present
|
||||
if ($feature.ToolTip) {
|
||||
$tipBlock = New-Object System.Windows.Controls.TextBlock
|
||||
@@ -694,7 +721,7 @@ function Show-MainWindow {
|
||||
try { $lblBorderObj = $window.FindName("$comboName`_LabelBorder") } catch {}
|
||||
if ($lblBorderObj) { $lblBorderObj.ToolTip = $tipBlock }
|
||||
}
|
||||
$script:UiControlMappings[$comboName] = @{ Type='feature'; FeatureId = $feature.FeatureId; Action = $feature.Action; Label = $feature.Label }
|
||||
$script:UiControlMappings[$comboName] = @{ Type='feature'; FeatureId = $feature.FeatureId; Action = $feature.Action }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -702,7 +729,7 @@ function Show-MainWindow {
|
||||
# Build a feature-label lookup so GenerateOverview can resolve feature IDs without reloading JSON
|
||||
$script:FeatureLabelLookup = @{}
|
||||
foreach ($f in $featuresJson.Features) {
|
||||
$script:FeatureLabelLookup[$f.FeatureId] = $f.Action + ' ' + $f.Label
|
||||
$script:FeatureLabelLookup[$f.FeatureId] = $f.Action
|
||||
}
|
||||
}
|
||||
|
||||
@@ -891,19 +918,29 @@ function Show-MainWindow {
|
||||
# Animate arrow when popup opens/closes, and lazily update preset states
|
||||
$presetsPopup.Add_Opened({
|
||||
UpdatePresetStates
|
||||
AnimatePresetsArrow -angle 180
|
||||
$animation = New-Object System.Windows.Media.Animation.DoubleAnimation
|
||||
$animation.To = 180
|
||||
$animation.Duration = [System.Windows.Duration]::new([System.TimeSpan]::FromMilliseconds(200))
|
||||
$animation.EasingFunction = New-Object System.Windows.Media.Animation.CubicEase
|
||||
$animation.EasingFunction.EasingMode = 'EaseOut'
|
||||
$presetsArrow.RenderTransform.BeginAnimation([System.Windows.Media.RotateTransform]::AngleProperty, $animation)
|
||||
})
|
||||
$presetsPopup.Add_Closed({
|
||||
AnimatePresetsArrow -angle 0
|
||||
$animation = New-Object System.Windows.Media.Animation.DoubleAnimation
|
||||
$animation.To = 0
|
||||
$animation.Duration = [System.Windows.Duration]::new([System.TimeSpan]::FromMilliseconds(200))
|
||||
$animation.EasingFunction = New-Object System.Windows.Media.Animation.CubicEase
|
||||
$animation.EasingFunction.EasingMode = 'EaseOut'
|
||||
$presetsArrow.RenderTransform.BeginAnimation([System.Windows.Media.RotateTransform]::AngleProperty, $animation)
|
||||
$presetsBtn.IsChecked = $false
|
||||
})
|
||||
|
||||
# Close popup when clicking anywhere outside the popup or the presets button.
|
||||
$window.Add_PreviewMouseDown({
|
||||
if (-not $presetsPopup.IsOpen) { return }
|
||||
if ($null -ne $presetsPopup.Child -and $presetsPopup.Child.IsMouseOver) { return }
|
||||
if ($presetsPopup.Child -ne $null -and $presetsPopup.Child.IsMouseOver) { return }
|
||||
$src = $_.OriginalSource -as [System.Windows.DependencyObject]
|
||||
if ($null -ne $src) {
|
||||
if ($src -ne $null) {
|
||||
$inBtn = $presetsBtn.IsAncestorOf($src) -or [System.Object]::ReferenceEquals($presetsBtn, $src)
|
||||
if (-not $inBtn) { $presetsPopup.IsOpen = $false }
|
||||
}
|
||||
@@ -923,7 +960,8 @@ function Show-MainWindow {
|
||||
# Preset: Default selection
|
||||
$presetDefaultApps.Add_Click({
|
||||
if ($script:UpdatingPresets) { return }
|
||||
$check = NormalizeCheckboxState -checkBox $this
|
||||
$check = ($this.IsChecked -eq $true)
|
||||
if ($this.IsChecked -eq $null) { $this.IsChecked = $false; $check = $false }
|
||||
ApplyPresetToApps -MatchFilter { param($c) $c.SelectedByDefault -eq $true } -Check $check
|
||||
})
|
||||
|
||||
@@ -1040,7 +1078,7 @@ function Show-MainWindow {
|
||||
})
|
||||
|
||||
$appSearchBox.Add_KeyDown({
|
||||
param($sourceControl, $e)
|
||||
param($sender, $e)
|
||||
if ($e.Key -eq [System.Windows.Input.Key]::Enter -and $script:AppSearchMatches.Count -gt 0) {
|
||||
# Reset background of current active match
|
||||
$script:AppSearchMatches[$script:AppSearchMatchIndex].Background = $window.Resources["SearchHighlightColor"]
|
||||
@@ -1163,7 +1201,7 @@ function Show-MainWindow {
|
||||
|
||||
# Add Ctrl+F keyboard shortcut to focus search box on current tab
|
||||
$window.Add_KeyDown({
|
||||
param($sourceControl, $e)
|
||||
param($sender, $e)
|
||||
|
||||
# Check if Ctrl+F was pressed
|
||||
if ($e.Key -eq [System.Windows.Input.Key]::F -and
|
||||
@@ -1392,13 +1430,13 @@ function Show-MainWindow {
|
||||
if ($userSelectionCombo.SelectedIndex -ne 2) {
|
||||
$appRemovalScopeCombo.IsEnabled = $true
|
||||
}
|
||||
$appRemovalScopeSection.Opacity = 1.0
|
||||
$appRemovalScopeSection.Visibility = 'Visible'
|
||||
UpdateAppRemovalScopeDescription
|
||||
}
|
||||
else {
|
||||
# Disable app removal scope selection when no apps selected
|
||||
$appRemovalScopeCombo.IsEnabled = $false
|
||||
$appRemovalScopeSection.Opacity = 0.5
|
||||
$appRemovalScopeSection.Visibility = 'Collapsed'
|
||||
$appRemovalScopeDescription.Text = "No apps selected for removal."
|
||||
}
|
||||
|
||||
@@ -1428,8 +1466,7 @@ function Show-MainWindow {
|
||||
}
|
||||
elseif ($mapping.Type -eq 'feature') {
|
||||
$label = $script:FeatureLabelLookup[$mapping.FeatureId]
|
||||
if (-not $label) { $label = $mapping.Action + ' ' + $mapping.Label }
|
||||
$changesList += $label
|
||||
if ($label) { $changesList += $label }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1473,6 +1510,44 @@ function Show-MainWindow {
|
||||
UpdateNavigationButtons
|
||||
})
|
||||
|
||||
# Handle Home Revert link button
|
||||
$homeRevertLinkBtn = $window.FindName('HomeRevertLinkBtn')
|
||||
if ($homeRevertLinkBtn) {
|
||||
if (-not (Test-Path $script:SavedSettingsFilePath)) {
|
||||
$homeRevertLinkBtn.Visibility = 'Collapsed'
|
||||
}
|
||||
|
||||
$homeRevertLinkBtn.Add_Click({
|
||||
$savedSettings = LoadJsonFile -filePath $script:SavedSettingsFilePath -expectedVersion "1.0" -optionalFile
|
||||
if (-not $savedSettings -or -not $savedSettings.Settings) {
|
||||
return
|
||||
}
|
||||
|
||||
$revertSelection = Show-RevertSettingsModal -Owner $window -LastUsedSettings $savedSettings
|
||||
$selectedFeatureIds = @($revertSelection.SelectedFeatureIds)
|
||||
$shouldRestartExplorer = ($revertSelection.RestartExplorer -eq $true)
|
||||
|
||||
if (-not $selectedFeatureIds -or $selectedFeatureIds.Count -eq 0) {
|
||||
return
|
||||
}
|
||||
|
||||
AddParameter 'Undo'
|
||||
|
||||
foreach ($featureId in $selectedFeatureIds) {
|
||||
if ($script:Features.ContainsKey($featureId)) {
|
||||
$feature = $script:Features[$featureId]
|
||||
if ($feature.RegistryUndoKey -and $feature.UndoAction) {
|
||||
AddParameter $featureId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Show-ApplyModal -Owner $window -RestartExplorer $shouldRestartExplorer
|
||||
|
||||
$window.Close()
|
||||
})
|
||||
}
|
||||
|
||||
# Handle Home Default Mode button - apply defaults and navigate directly to overview
|
||||
$homeDefaultModeBtn = $window.FindName('HomeDefaultModeBtn')
|
||||
$homeDefaultModeBtn.Add_Click({
|
||||
@@ -1748,7 +1823,8 @@ function Show-MainWindow {
|
||||
|
||||
$presetLastUsed.Add_Click({
|
||||
if ($script:UpdatingPresets) { return }
|
||||
$check = NormalizeCheckboxState -checkBox $this
|
||||
$check = ($this.IsChecked -eq $true)
|
||||
if ($this.IsChecked -eq $null) { $this.IsChecked = $false; $check = $false }
|
||||
ApplyPresetToApps -MatchFilter { param($c) (@($c.AppIds) | Where-Object { $script:SavedAppIds -contains $_ }).Count -gt 0 } -Check $check
|
||||
})
|
||||
}
|
||||
@@ -1783,12 +1859,5 @@ function Show-MainWindow {
|
||||
}
|
||||
|
||||
# Show the window
|
||||
$frame = [System.Windows.Threading.DispatcherFrame]::new()
|
||||
$window.Add_Closed({
|
||||
$frame.Continue = $false
|
||||
})
|
||||
|
||||
$window.Show() | Out-Null
|
||||
[System.Windows.Threading.Dispatcher]::PushFrame($frame)
|
||||
return $null
|
||||
return $window.ShowDialog()
|
||||
}
|
||||
|
||||
198
Scripts/GUI/Show-RevertSettingsModal.ps1
Normal file
198
Scripts/GUI/Show-RevertSettingsModal.ps1
Normal file
@@ -0,0 +1,198 @@
|
||||
function Show-RevertSettingsModal {
|
||||
param (
|
||||
[Parameter(Mandatory=$false)]
|
||||
[System.Windows.Window]$Owner = $null,
|
||||
[Parameter(Mandatory=$true)]
|
||||
$LastUsedSettings
|
||||
)
|
||||
|
||||
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase | Out-Null
|
||||
|
||||
$usesDarkMode = GetSystemUsesDarkMode
|
||||
|
||||
# Determine owner window
|
||||
$ownerWindow = if ($Owner) { $Owner } else { $script:GuiWindow }
|
||||
|
||||
# Show overlay if owner window exists
|
||||
$overlay = $null
|
||||
$overlayWasAlreadyVisible = $false
|
||||
if ($ownerWindow) {
|
||||
try {
|
||||
$overlay = $ownerWindow.FindName('ModalOverlay')
|
||||
if ($overlay) {
|
||||
$overlayWasAlreadyVisible = ($overlay.Visibility -eq 'Visible')
|
||||
if (-not $overlayWasAlreadyVisible) {
|
||||
$ownerWindow.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Visible' })
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
# Load XAML from file
|
||||
$xaml = Get-Content -Path $script:RevertSettingsWindowSchema -Raw
|
||||
$reader = [System.Xml.XmlReader]::Create([System.IO.StringReader]::new($xaml))
|
||||
try {
|
||||
$revertWindow = [System.Windows.Markup.XamlReader]::Load($reader)
|
||||
}
|
||||
finally {
|
||||
$reader.Close()
|
||||
}
|
||||
|
||||
if ($ownerWindow) {
|
||||
try {
|
||||
$revertWindow.Owner = $ownerWindow
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
SetWindowThemeResources -window $revertWindow -usesDarkMode $usesDarkMode
|
||||
|
||||
$itemsPanel = $revertWindow.FindName('RevertItemsPanel')
|
||||
$countText = $revertWindow.FindName('RevertSelectionCount')
|
||||
$selectAllBtn = $revertWindow.FindName('RevertSelectAllBtn')
|
||||
$clearBtn = $revertWindow.FindName('RevertClearBtn')
|
||||
$applyBtn = $revertWindow.FindName('RevertApplyBtn')
|
||||
$cancelBtn = $revertWindow.FindName('RevertCancelBtn')
|
||||
$restartExplorerCheckbox = $revertWindow.FindName('RevertRestartExplorerCheckBox')
|
||||
$featureCheckboxStyle = $revertWindow.FindResource('FeatureCheckboxStyle')
|
||||
$restartExplorerCheckbox.Style = $featureCheckboxStyle
|
||||
$entryCheckboxes = @()
|
||||
|
||||
foreach ($setting in $LastUsedSettings.Settings) {
|
||||
if ($setting.Value -ne $true) { continue }
|
||||
if ($setting.Name -eq 'Apps' -or $setting.Name -eq 'RemoveApps' -or $setting.Name -eq 'CreateRestorePoint') { continue }
|
||||
|
||||
$feature = $null
|
||||
if ($script:Features.ContainsKey($setting.Name)) {
|
||||
$feature = $script:Features[$setting.Name]
|
||||
}
|
||||
$undoFeature = GetUndoFeatureForParam -paramKey $setting.Name
|
||||
|
||||
$label = $setting.Name
|
||||
if ($feature -and $feature.Action) {
|
||||
$label = $feature.Action
|
||||
}
|
||||
|
||||
$undoLabel = if ($undoFeature -and $undoFeature.UndoAction) {
|
||||
$undoFeature.UndoAction
|
||||
} else {
|
||||
'No revert action available'
|
||||
}
|
||||
|
||||
$canUndo = ($null -ne $undoFeature)
|
||||
|
||||
$itemBorder = New-Object System.Windows.Controls.Border
|
||||
$itemBorder.Style = $revertWindow.FindResource('RevertItemBorderStyle')
|
||||
|
||||
$row = New-Object System.Windows.Controls.StackPanel
|
||||
$row.Style = $revertWindow.FindResource('RevertItemRowStyle')
|
||||
|
||||
$checkbox = New-Object System.Windows.Controls.CheckBox
|
||||
$checkbox.Content = $label
|
||||
$checkbox.Tag = $setting.Name
|
||||
$checkbox.Style = $featureCheckboxStyle
|
||||
$checkbox.IsEnabled = $canUndo
|
||||
|
||||
$undoText = New-Object System.Windows.Controls.TextBlock
|
||||
$undoText.Text = if ($canUndo) { "Revert to: $undoLabel" } else { 'Revert not supported for this setting' }
|
||||
$undoText.Style = $revertWindow.FindResource('RevertItemUndoTextStyle')
|
||||
$undoText.Opacity = if ($canUndo) { 0.75 } else { 0.4 }
|
||||
|
||||
$row.Children.Add($checkbox) | Out-Null
|
||||
$row.Children.Add($undoText) | Out-Null
|
||||
$itemBorder.Child = $row
|
||||
|
||||
$itemsPanel.Children.Add($itemBorder) | Out-Null
|
||||
$entryCheckboxes += $checkbox
|
||||
}
|
||||
|
||||
# Remove the divider from the last entry for cleaner list termination.
|
||||
if ($itemsPanel.Children.Count -gt 0) {
|
||||
$lastItem = $itemsPanel.Children[$itemsPanel.Children.Count - 1]
|
||||
if ($lastItem -is [System.Windows.Controls.Border]) {
|
||||
$lastItem.BorderThickness = [System.Windows.Thickness]::new(0)
|
||||
}
|
||||
}
|
||||
|
||||
if ($entryCheckboxes.Count -eq 0) {
|
||||
$emptyText = New-Object System.Windows.Controls.TextBlock
|
||||
$emptyText.Text = 'No previously applied tweaks can be reverted'
|
||||
$emptyText.Style = $revertWindow.FindResource('RevertEmptyTextStyle')
|
||||
$itemsPanel.Children.Add($emptyText) | Out-Null
|
||||
$selectAllBtn.IsEnabled = $false
|
||||
$clearBtn.IsEnabled = $false
|
||||
}
|
||||
|
||||
$updateState = {
|
||||
$selectedCount = 0
|
||||
foreach ($cb in $entryCheckboxes) {
|
||||
if ($cb.IsEnabled -and $cb.IsChecked -eq $true) {
|
||||
$selectedCount++
|
||||
}
|
||||
}
|
||||
|
||||
$countText.Text = "$selectedCount settings selected"
|
||||
$applyBtn.IsEnabled = ($selectedCount -gt 0)
|
||||
}
|
||||
|
||||
foreach ($cb in $entryCheckboxes) {
|
||||
$cb.Add_Checked($updateState)
|
||||
$cb.Add_Unchecked($updateState)
|
||||
}
|
||||
|
||||
$selectAllBtn.Add_Click({
|
||||
foreach ($cb in $entryCheckboxes) {
|
||||
if ($cb.IsEnabled) {
|
||||
$cb.IsChecked = $true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$clearBtn.Add_Click({
|
||||
foreach ($cb in $entryCheckboxes) {
|
||||
if ($cb.IsEnabled) {
|
||||
$cb.IsChecked = $false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$cancelHandler = {
|
||||
$revertWindow.Close()
|
||||
}
|
||||
|
||||
$cancelBtn.Add_Click($cancelHandler)
|
||||
|
||||
$applyBtn.Add_Click({
|
||||
$selected = @()
|
||||
foreach ($cb in $entryCheckboxes) {
|
||||
if ($cb.IsEnabled -and $cb.IsChecked -eq $true -and $cb.Tag) {
|
||||
$selected += $cb.Tag
|
||||
}
|
||||
}
|
||||
|
||||
$revertWindow.Tag = [PSCustomObject]@{
|
||||
SelectedFeatureIds = $selected
|
||||
RestartExplorer = ($restartExplorerCheckbox -and $restartExplorerCheckbox.IsChecked -eq $true)
|
||||
}
|
||||
$revertWindow.Close()
|
||||
})
|
||||
|
||||
$revertWindow.ShowDialog() | Out-Null
|
||||
|
||||
if ($overlay -and -not $overlayWasAlreadyVisible) {
|
||||
try {
|
||||
$ownerWindow.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Collapsed' })
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
if ($revertWindow.Tag) {
|
||||
return $revertWindow.Tag
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
SelectedFeatureIds = @()
|
||||
RestartExplorer = $false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
param (
|
||||
[switch]$CLI,
|
||||
[switch]$Silent,
|
||||
[switch]$Undo,
|
||||
[switch]$Verbose,
|
||||
[switch]$Sysprep,
|
||||
[string]$LogPath,
|
||||
@@ -96,11 +97,7 @@ param (
|
||||
[switch]$HideMusic,
|
||||
[switch]$HideIncludeInLibrary,
|
||||
[switch]$HideGiveAccessTo,
|
||||
[switch]$HideShare,
|
||||
[switch]$ShowDriveLettersFirst,
|
||||
[switch]$ShowDriveLettersLast,
|
||||
[switch]$ShowNetworkDriveLettersFirst,
|
||||
[switch]$HideDriveLetters
|
||||
[switch]$HideShare
|
||||
)
|
||||
|
||||
# Show error if current powershell environment does not have LanguageMode set to FullLanguage
|
||||
|
||||
17
Scripts/Helpers/GetUndoFeatureForParam.ps1
Normal file
17
Scripts/Helpers/GetUndoFeatureForParam.ps1
Normal file
@@ -0,0 +1,17 @@
|
||||
# Returns the feature metadata for a parameter when it supports undo; otherwise returns $null.
|
||||
function GetUndoFeatureForParam {
|
||||
param (
|
||||
[string]$paramKey
|
||||
)
|
||||
|
||||
if (-not $script:Features -or -not $script:Features.ContainsKey($paramKey)) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$feature = $script:Features[$paramKey]
|
||||
if (-not ($feature.RegistryUndoKey -and ($feature.UndoText -or $feature.UndoAction))) {
|
||||
return $null
|
||||
}
|
||||
|
||||
return $feature
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
param (
|
||||
[switch]$CLI,
|
||||
[switch]$Silent,
|
||||
[switch]$Undo,
|
||||
[switch]$Sysprep,
|
||||
[string]$LogPath,
|
||||
[string]$User,
|
||||
@@ -98,17 +99,14 @@ param (
|
||||
[switch]$HideMusic,
|
||||
[switch]$HideIncludeInLibrary,
|
||||
[switch]$HideGiveAccessTo,
|
||||
[switch]$HideShare,
|
||||
[switch]$ShowDriveLettersFirst,
|
||||
[switch]$ShowDriveLettersLast,
|
||||
[switch]$ShowNetworkDriveLettersFirst,
|
||||
[switch]$HideDriveLetters
|
||||
[switch]$HideShare
|
||||
)
|
||||
|
||||
|
||||
|
||||
# Define script-level variables & paths
|
||||
$script:Version = "2026.03.15"
|
||||
$script:FeaturesConfigVersion = "2.0"
|
||||
$script:AppsListFilePath = "$PSScriptRoot/Config/Apps.json"
|
||||
$script:DefaultSettingsFilePath = "$PSScriptRoot/Config/DefaultSettings.json"
|
||||
$script:FeaturesFilePath = "$PSScriptRoot/Config/Features.json"
|
||||
@@ -122,12 +120,13 @@ $script:MainWindowSchema = "$PSScriptRoot/Schemas/MainWindow.xaml"
|
||||
$script:MessageBoxSchema = "$PSScriptRoot/Schemas/MessageBoxWindow.xaml"
|
||||
$script:AboutWindowSchema = "$PSScriptRoot/Schemas/AboutWindow.xaml"
|
||||
$script:ApplyChangesWindowSchema = "$PSScriptRoot/Schemas/ApplyChangesWindow.xaml"
|
||||
$script:RevertSettingsWindowSchema = "$PSScriptRoot/Schemas/RevertSettingsWindow.xaml"
|
||||
$script:SharedStylesSchema = "$PSScriptRoot/Schemas/SharedStyles.xaml"
|
||||
$script:BubbleHintSchema = "$PSScriptRoot/Schemas/BubbleHint.xaml"
|
||||
$script:ImportExportConfigSchema = "$PSScriptRoot/Schemas/ImportExportConfigWindow.xaml"
|
||||
$script:LoadAppsDetailsScriptPath = "$PSScriptRoot/Scripts/FileIO/LoadAppsDetailsFromJson.ps1"
|
||||
|
||||
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'Config', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
||||
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Undo', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'Config', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
||||
|
||||
# Script-level variables for GUI elements
|
||||
$script:GuiWindow = $null
|
||||
@@ -174,9 +173,23 @@ else {
|
||||
Start-Transcript -Path $script:DefaultLogPath -Append -IncludeInvocationHeader -Force | Out-Null
|
||||
}
|
||||
|
||||
# Check if script has all required files
|
||||
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:BubbleHintSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
||||
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
||||
# Check if script has all required files/directories.
|
||||
$optionalPathVariables = @('SavedSettingsFilePath', 'CustomAppsListFilePath', 'DefaultLogPath')
|
||||
$requiredPathVariables = @(Get-Variable -Scope Script | Where-Object {
|
||||
$_.Name -match '(FilePath|Schema|ScriptPath|RegfilesPath|AssetsPath)$' -and ($optionalPathVariables -notcontains $_.Name)
|
||||
} | Select-Object -ExpandProperty Name)
|
||||
|
||||
$missingRequiredPaths = @()
|
||||
foreach ($variableName in $requiredPathVariables) {
|
||||
$pathValue = Get-Variable -Name $variableName -Scope Script -ValueOnly
|
||||
|
||||
if ([String]::IsNullOrWhiteSpace($pathValue) -or -not (Test-Path $pathValue)) {
|
||||
$missingRequiredPaths += "$variableName => $pathValue"
|
||||
}
|
||||
}
|
||||
|
||||
if ($missingRequiredPaths.Count -gt 0) {
|
||||
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present. Missing: $($missingRequiredPaths -join '; ')"
|
||||
Write-Output ""
|
||||
Write-Output "Press any key to exit..."
|
||||
$null = [System.Console]::ReadKey()
|
||||
@@ -187,6 +200,15 @@ if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:Ap
|
||||
$script:Features = @{}
|
||||
try {
|
||||
$featuresData = Get-Content -Path $script:FeaturesFilePath -Raw | ConvertFrom-Json
|
||||
|
||||
if (-not $featuresData.Version -or $featuresData.Version -ne $script:FeaturesConfigVersion) {
|
||||
Write-Error "Features.json version mismatch (expected $($script:FeaturesConfigVersion), found $($featuresData.Version))"
|
||||
Write-Output ""
|
||||
Write-Output "Press any key to exit..."
|
||||
$null = [System.Console]::ReadKey()
|
||||
Exit
|
||||
}
|
||||
|
||||
foreach ($feature in $featuresData.Features) {
|
||||
$script:Features[$feature.FeatureId] = $feature
|
||||
}
|
||||
@@ -272,6 +294,7 @@ if (-not $script:WingetInstalled -and -not $Silent) {
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-MessageBox.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-ConfigWindow.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-ApplyModal.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-RevertSettingsModal.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-AppSelectionWindow.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-MainWindow.ps1"
|
||||
. "$PSScriptRoot/Scripts/GUI/Show-AboutDialog.ps1"
|
||||
@@ -285,6 +308,7 @@ if (-not $script:WingetInstalled -and -not $Silent) {
|
||||
. "$PSScriptRoot/Scripts/Helpers/GetFriendlyTargetUserName.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/ImportConfigToParams.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/GetTargetUserForAppRemoval.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/GetUndoFeatureForParam.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/GetUserDirectory.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/GetUserName.ps1"
|
||||
. "$PSScriptRoot/Scripts/Helpers/TestIfUserIsLoggedIn.ps1"
|
||||
@@ -325,6 +349,27 @@ foreach ($Param in $script:ControlParams) {
|
||||
}
|
||||
}
|
||||
|
||||
# Guard: Undo mode requires at least one actionable and cannot be combined with deployment-targeted parameters
|
||||
if ($script:Params.ContainsKey('Undo')) {
|
||||
$deploymentTargetParams = @('Sysprep', 'User', 'AppRemovalTarget')
|
||||
$selectedDeploymentParams = @($deploymentTargetParams | Where-Object { $script:Params.ContainsKey($_) })
|
||||
|
||||
if ($selectedDeploymentParams.Count -gt 0) {
|
||||
Write-Error "The -Undo parameter cannot be combined with deployment target parameters: -$($selectedDeploymentParams -join ', -')."
|
||||
AwaitKeyToExit
|
||||
}
|
||||
|
||||
$loadsSettingsFromPreset = $RunDefaults -or $RunDefaultsLite -or $RunSavedSettings
|
||||
$undoTargets = @($script:Params.Keys | Where-Object {
|
||||
($script:ControlParams -notcontains $_) -and $_ -ne 'Apps' -and $_ -ne 'CreateRestorePoint'
|
||||
})
|
||||
|
||||
if ($undoTargets.Count -eq 0 -and -not $loadsSettingsFromPreset) {
|
||||
Write-Error "The -Undo parameter requires at least one setting/feature parameter to revert."
|
||||
AwaitKeyToExit
|
||||
}
|
||||
}
|
||||
|
||||
# Hide progress bars for app removal, as they block Win11Debloat's output
|
||||
if (-not ($script:Params.ContainsKey("Verbose"))) {
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
@@ -423,7 +468,7 @@ if ((-not $script:Params.Count) -or $RunDefaults -or $RunDefaultsLite -or $RunSa
|
||||
Exit
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to load WPF GUI (not supported in this environment), falling back to CLI mode"
|
||||
Write-Warning "Something went wrong while loading the graphical interface, falling back to CLI mode: $_"
|
||||
if (-not $Silent) {
|
||||
Write-Host ""
|
||||
Write-Host "Press any key to continue..."
|
||||
@@ -464,9 +509,17 @@ if (($controlParamsCount -eq $script:Params.Keys.Count) -or ($script:Params.Keys
|
||||
AwaitKeyToExit
|
||||
}
|
||||
|
||||
# Execute all selected/provided parameters using the consolidated function
|
||||
# (This also handles restore point creation if requested)
|
||||
ExecuteAllChanges
|
||||
try {
|
||||
# Execute all selected/provided parameters using the consolidated function
|
||||
# (This also handles restore point creation if requested)
|
||||
ExecuteAllChanges
|
||||
}
|
||||
catch {
|
||||
Write-Error "An error occurred while applying changes: $_"
|
||||
|
||||
AwaitKeyToExit
|
||||
}
|
||||
|
||||
|
||||
RestartExplorer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user