[Launcher]Port from WPF-UI to .NET 9 WPF (#36215)

* Initial implementation

* Fix fluent style

* Fix no endline

* Update expect.txt

* Fix formatting

* Fix light theme looking bad on Windows 10

* fix formatting

* test change

* Now really fixed W10

* Add a comment

* Fix typos

* Fix spellcheck errors

* Fix spellcheck pattern for websites

* Change patterns for spellcheck in the right file

* Fix XAML styling

* Fix contrast colors on W11

* Fix formatting

* Removed emty line

* Fix formatting

* Added comment to fluentHC file

* fix comment

* Fix Windows10 again.
Adress feedback.

* W11 fix chaning from high contrast to normal not having correct background

* W10 Fix high contrast not working after switching from light/dark moed

* Address feedback

* Fix formatting

* Second W11 fix chaning from high contrast to normal not having correct background
This commit is contained in:
Ionuț Manța 2024-12-11 11:47:08 +02:00 коммит произвёл GitHub
Родитель bf3474b134
Коммит 7c6af6580e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
20 изменённых файлов: 7098 добавлений и 142 удалений

4
.github/actions/spell-check/expect.txt поставляемый
Просмотреть файл

@ -127,6 +127,7 @@ boxmodel
BPBF
bpmf
bpp
Breadcrumb
Browsable
BROWSEINFO
bsd
@ -328,6 +329,7 @@ DEVMODEW
DEVMON
devpkey
DEVSOURCE
DGR
DIIRFLAG
dimm
DISABLEASACTIONKEY
@ -1842,3 +1844,5 @@ zonable
zoneset
Zoneszonabletester
zzz

2
.github/actions/spell-check/patterns.txt поставляемый
Просмотреть файл

@ -131,7 +131,7 @@ _mm_(?!dd)\w+
# hit-count: 4 file-count: 4
# microsoft
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]*
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|developer|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]*
aka\.ms/[a-zA-Z0-9]+

Просмотреть файл

@ -8,8 +8,6 @@
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
<ResourceDictionary Source="pack://application:,,,/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Просмотреть файл

@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Controls/AnimationFactorToValueConverter.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace Fluent.Controls
#pragma warning restore IDE0130 // Namespace does not match folder structure
{
internal sealed class AnimationFactorToValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is not double completeValue)
{
return 0.0;
}
if (values[1] is not double factor)
{
return 0.0;
}
if (parameter is "negative")
{
factor = -factor;
}
return factor * completeValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Copied from https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Controls/FallbackBrushConverter.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;
#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace Fluent.Controls
#pragma warning restore IDE0130 // Namespace does not match folder structure
{
internal sealed class FallbackBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is SolidColorBrush brush)
{
return brush;
}
if (value is Color color)
{
return new SolidColorBrush(color);
}
// We draw red to visibly see an invalid bind in the UI.
return Brushes.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -2,46 +2,71 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Linq;
using ManagedCommon;
using Microsoft.Win32;
using Wpf.Ui.Appearance;
namespace PowerLauncher.Helper
{
public static class ThemeExtensions
{
public static Theme ToTheme(this ApplicationTheme applicationTheme)
public static Theme GetCurrentTheme()
{
return applicationTheme switch
// Check for high-contrast mode
Theme highContrastTheme = GetHighContrastBaseType();
if (highContrastTheme != Theme.Light)
{
ApplicationTheme.Dark => Theme.Dark,
ApplicationTheme.Light => Theme.Light,
ApplicationTheme.HighContrast => GetHighContrastBaseType(),
return highContrastTheme;
}
// Check if the system is using dark or light mode
return IsSystemDarkMode() ? Theme.Dark : Theme.Light;
}
private static bool IsSystemDarkMode()
{
const string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
const string registryValue = "AppsUseLightTheme";
// Retrieve the registry value, which is a DWORD (0 or 1)
object registryValueObj = Registry.GetValue(registryKey, registryValue, null);
if (registryValueObj != null)
{
// 0 = Dark mode, 1 = Light mode
bool isLightMode = Convert.ToBoolean((int)registryValueObj, CultureInfo.InvariantCulture);
return !isLightMode; // Invert because 0 = Dark
}
else
{
// Default to Light theme if the registry key is missing
return false; // Default to dark mode assumption
}
}
public static Theme GetHighContrastBaseType()
{
const string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes";
const string registryValue = "CurrentTheme";
string themePath = (string)Registry.GetValue(registryKey, registryValue, string.Empty);
if (string.IsNullOrEmpty(themePath))
{
return Theme.Light; // Default to light theme if missing
}
string theme = themePath.Split('\\').Last().Split('.').First().ToLowerInvariant();
return theme switch
{
"hc1" => Theme.HighContrastOne,
"hc2" => Theme.HighContrastTwo,
"hcwhite" => Theme.HighContrastWhite,
"hcblack" => Theme.HighContrastBlack,
_ => Theme.Light,
};
}
private static Theme GetHighContrastBaseType()
{
string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes";
string theme = (string)Registry.GetValue(registryKey, "CurrentTheme", string.Empty);
theme = theme.Split('\\').Last().Split('.').First().ToString();
switch (theme)
{
case "hc1":
return Theme.HighContrastOne;
case "hc2":
return Theme.HighContrastTwo;
case "hcwhite":
return Theme.HighContrastWhite;
case "hcblack":
return Theme.HighContrastBlack;
default:
return Theme.HighContrastOne;
}
}
}
}

Просмотреть файл

@ -3,11 +3,12 @@
// See the LICENSE file in the project root for more information.
using System;
using ManagedCommon;
using System.IO;
using System.Windows;
using System.Windows.Media;
using Microsoft.Win32;
using Wox.Infrastructure.Image;
using Wox.Infrastructure.UserSettings;
using Wpf.Ui.Appearance;
namespace PowerLauncher.Helper
{
@ -15,10 +16,10 @@ namespace PowerLauncher.Helper
{
private readonly PowerToysRunSettings _settings;
private readonly MainWindow _mainWindow;
private Theme _currentTheme;
private ManagedCommon.Theme _currentTheme;
private bool _disposed;
public Theme CurrentTheme => _currentTheme;
public ManagedCommon.Theme CurrentTheme => _currentTheme;
public event Common.UI.ThemeChangedHandler ThemeChanged;
@ -26,33 +27,106 @@ namespace PowerLauncher.Helper
{
_settings = settings;
_mainWindow = mainWindow;
_currentTheme = ApplicationThemeManager.GetAppTheme().ToTheme();
SetTheme(false);
ApplicationThemeManager.Changed += ApplicationThemeManager_Changed;
UpdateTheme();
SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged;
}
public void SetTheme(bool fromSettings)
private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (_settings.Theme == Theme.Light)
if (e.Category == UserPreferenceCategory.General)
{
_currentTheme = Theme.Light;
_mainWindow?.Dispatcher.Invoke(() => ApplicationThemeManager.Apply(ApplicationTheme.Light, _mainWindow.WindowBackdropType));
// When switching from high contrast to dark mode we have to use UserPreferenceCategory.General otherwise it will crash when loading fluent.xaml
UpdateTheme();
}
else if (_settings.Theme == Theme.Dark)
else if (e.Category == UserPreferenceCategory.Color)
{
_currentTheme = Theme.Dark;
_mainWindow?.Dispatcher.Invoke(() => ApplicationThemeManager.Apply(ApplicationTheme.Dark, _mainWindow.WindowBackdropType));
// https://github.com/dotnet/wpf/issues/10043 When switching to high contrast we have to use UserPreferenceCategory.Color or it will crash due to fluent.xaml being already loaded.
if (_currentTheme is ManagedCommon.Theme.Dark or ManagedCommon.Theme.Light)
{
UpdateTheme();
}
}
else if (fromSettings)
}
private void SetSystemTheme(ManagedCommon.Theme theme)
{
_mainWindow.Background = Common.UI.OSVersionHelper.IsWindows11() is false ? SystemColors.WindowBrush : null;
_mainWindow.Resources.MergedDictionaries.Clear();
_mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary
{
_mainWindow?.Dispatcher.Invoke(ApplicationThemeManager.ApplySystemTheme);
Source = new Uri("Styles/Styles.xaml", UriKind.Relative),
});
if (theme is ManagedCommon.Theme.Dark or ManagedCommon.Theme.Light)
{
string themeString = theme == ManagedCommon.Theme.Light ? "pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Light.xaml"
: "pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Dark.xaml";
ResourceDictionary fluentThemeDictionary = new()
{
Source = new Uri(themeString, UriKind.Absolute),
};
_mainWindow.Resources.MergedDictionaries.Add(fluentThemeDictionary);
if (!Common.UI.OSVersionHelper.IsWindows11())
{
// Apply background only on Windows 10
// Windows theme does not work properly for dark and light mode so right now set the background color manual.
_mainWindow.Background = new SolidColorBrush
{
Color = theme is ManagedCommon.Theme.Dark ? (Color)ColorConverter.ConvertFromString("#202020") : (Color)ColorConverter.ConvertFromString("#fafafa"),
};
}
}
else
{
_mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source = new Uri("Styles/FluentHC.xaml", UriKind.Relative),
});
string styleThemeString = theme switch
{
ManagedCommon.Theme.Light => "Themes/Light.xaml",
ManagedCommon.Theme.Dark => "Themes/Dark.xaml",
ManagedCommon.Theme.HighContrastOne => "Themes/HighContrast1.xaml",
ManagedCommon.Theme.HighContrastTwo => "Themes/HighContrast2.xaml",
ManagedCommon.Theme.HighContrastWhite => "Themes/HighContrastWhite.xaml",
_ => "Themes/HighContrastBlack.xaml",
};
_mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source = new Uri(styleThemeString, UriKind.Relative),
});
if (Common.UI.OSVersionHelper.IsWindows11())
{
// Apply background only on Windows 11 to keep the same style as WPFUI
_mainWindow.Background = new SolidColorBrush
{
Color = (Color)_mainWindow.FindResource("LauncherBackgroundColor"), // Use your DynamicResource key here
};
}
}
ImageLoader.UpdateIconPath(_currentTheme);
ImageLoader.UpdateIconPath(theme);
ThemeChanged?.Invoke(_currentTheme, theme);
_currentTheme = theme;
}
// oldTheme isn't used
ThemeChanged?.Invoke(_currentTheme, _currentTheme);
public void UpdateTheme()
{
ManagedCommon.Theme newTheme = _settings.Theme;
ManagedCommon.Theme theme = ThemeExtensions.GetHighContrastBaseType();
if (theme != ManagedCommon.Theme.Light)
{
newTheme = theme;
}
else if (_settings.Theme == ManagedCommon.Theme.System)
{
newTheme = ThemeExtensions.GetCurrentTheme();
}
_mainWindow.Dispatcher.Invoke(() =>
{
SetSystemTheme(newTheme);
});
}
public void Dispose()
@ -61,18 +135,6 @@ namespace PowerLauncher.Helper
GC.SuppressFinalize(this);
}
private void ApplicationThemeManager_Changed(ApplicationTheme currentApplicationTheme, System.Windows.Media.Color systemAccent)
{
var newTheme = currentApplicationTheme.ToTheme();
if (_currentTheme == newTheme)
{
return;
}
_currentTheme = newTheme;
SetTheme(false);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
@ -82,7 +144,7 @@ namespace PowerLauncher.Helper
if (disposing)
{
ApplicationThemeManager.Changed -= ApplicationThemeManager_Changed;
SystemEvents.UserPreferenceChanged -= OnUserPreferenceChanged;
}
_disposed = true;

Просмотреть файл

@ -6,7 +6,6 @@
xmlns:local="clr-namespace:PowerLauncher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:PowerLauncher.Properties"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
d:DesignHeight="300"
d:DesignWidth="720"
mc:Ignorable="d">
@ -40,7 +39,7 @@
<Setter Property="Foreground" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}}" Value="">
<Setter Property="Foreground" Value="{DynamicResource TextPlaceholderColorBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextControlPlaceholderForeground}" />
</DataTrigger>
</Style.Triggers>
</Style>
@ -115,11 +114,14 @@
x:FieldModifier="public"
Canvas.ZIndex="-1"
FontSize="{DynamicResource TitleFontSize}"
Foreground="{DynamicResource TextPlaceholderColorBrush}" />
<ui:SymbolIcon
Foreground="{DynamicResource TextControlPlaceholderForeground}" />
<TextBlock
Grid.Column="0"
Margin="10,7,0,0"
AutomationProperties.Name="{x:Static p:Resources.SearchIcon}"
FontFamily="Segoe Fluent Icons, Segoe MDL2 Assets"
FontSize="20"
Foreground="{DynamicResource TextPlaceholderColorBrush}"
Symbol="Search12" />
Foreground="{DynamicResource TextControlPlaceholderForeground}"
Text="&#xE094;" />
</Grid>
</UserControl>

Просмотреть файл

@ -1,4 +1,4 @@
<ui:FluentWindow
<Window
x:Class="PowerLauncher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -6,13 +6,11 @@
xmlns:local="clr-namespace:PowerLauncher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:PowerLauncher.Properties"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:vm="clr-namespace:PowerLauncher.ViewModel"
Title="PowerToys Run"
Width="640"
MinHeight="0"
d:DataContext="{d:DesignInstance vm:MainViewModel}"
ui:ExtendsContentIntoTitleBar="True"
AllowDrop="True"
Closed="OnClosed"
Closing="OnClosing"
@ -29,12 +27,7 @@
WindowStartupLocation="Manual"
WindowStyle="None"
mc:Ignorable="d">
<Grid x:Name="RootGrid" MouseDown="OnMouseDown">
<!-- We set the background here because the Acrylic can be too translucent / background too bright on Light theme -->
<Grid.Background>
<SolidColorBrush Opacity="0.8" Color="{DynamicResource ApplicationBackgroundColor}" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@ -71,7 +64,6 @@
<ListView
x:Name="pluginsHintsList"
Grid.Row="1"
Margin="16,0,0,0"
Background="Transparent"
BorderBrush="Transparent"
ItemContainerStyle="{StaticResource PluginsListViewItemStyle}"
@ -138,12 +130,12 @@
Visibility="{Binding Results.Visibility}" />
</Grid>
<ui:FluentWindow.InputBindings>
<Window.InputBindings>
<KeyBinding Key="Escape" Command="{Binding EscCommand}" />
<KeyBinding Key="Enter" Command="{Binding OpenResultWithKeyboardCommand}" />
<KeyBinding
Key="F4"
Command="{Binding IgnoreCommand}"
Modifiers="Alt" />
</ui:FluentWindow.InputBindings>
</ui:FluentWindow>
</Window.InputBindings>
</Window>

Просмотреть файл

@ -25,7 +25,6 @@ using PowerToys.Interop;
using Wox.Infrastructure.UserSettings;
using Wox.Plugin;
using Wox.Plugin.Interfaces;
using Wpf.Ui.Appearance;
using CancellationToken = System.Threading.CancellationToken;
using Image = Wox.Infrastructure.Image;
@ -50,6 +49,31 @@ namespace PowerLauncher
private Point _mouseDownPosition;
private ResultViewModel _mouseDownResultViewModel;
// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
public enum DWMWINDOWATTRIBUTE
{
DWMWA_WINDOW_CORNER_PREFERENCE = 33,
}
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
// Copied from dwmapi.h
public enum DWM_WINDOW_CORNER_PREFERENCE
{
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3,
}
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
internal static extern void DwmSetWindowAttribute(
IntPtr hwnd,
DWMWINDOWATTRIBUTE attribute,
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
uint cbAttribute);
public MainWindow(PowerToysRunSettings settings, MainViewModel mainVM, CancellationToken nativeWaiterCancelToken)
: this()
{
@ -63,17 +87,6 @@ namespace PowerLauncher
InitializeComponent();
if (OSVersionHelper.IsWindows11())
{
WindowBackdropType = Wpf.Ui.Controls.WindowBackdropType.Acrylic;
}
else
{
WindowBackdropType = Wpf.Ui.Controls.WindowBackdropType.None;
}
SystemThemeWatcher.Watch(this, WindowBackdropType);
_firstDeleteTimer.Elapsed += CheckForFirstDelete;
_firstDeleteTimer.Interval = 1000;
NativeEventWaiter.WaitForEventLoop(
@ -179,6 +192,14 @@ namespace PowerLauncher
// Call RegisterHotKey only after a window handle can be used, so that a global hotkey can be registered.
_viewModel.RegisterHotkey(_hwndSource.Handle);
if (OSVersionHelper.IsWindows11())
{
// ResizeMode="NoResize" removes rounded corners. So force them to rounded.
IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
DWMWINDOWATTRIBUTE attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
DWM_WINDOW_CORNER_PREFERENCE preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
}
}
private void OnLoaded(object sender, RoutedEventArgs e)
@ -471,7 +492,7 @@ namespace PowerLauncher
private void OnLocationChanged(object sender, EventArgs e)
{
if (_settings.RememberLastLaunchLocation)
if (_settings != null && _settings.RememberLastLaunchLocation)
{
_settings.WindowLeft = Left;
_settings.WindowTop = Top;

Просмотреть файл

@ -58,7 +58,6 @@
<PackageReference Include="System.Data.OleDb" />
<PackageReference Include="System.ServiceProcess.ServiceController" />
<PackageReference Include="UnitsNet" />
<PackageReference Include="WPF-UI" />
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
<PackageReference Include="System.Text.Json" />
</ItemGroup>

Просмотреть файл

@ -183,10 +183,11 @@
</ToolTip>
</ToolTipService.ToolTip>
<Button.Content>
<ui:FontIcon
<TextBlock
AutomationProperties.Name="{x:Static p:Resources.ContextMenuIcon}"
FontFamily="{Binding FontFamily}"
Glyph="{Binding Glyph}" />
FontSize="14"
Text="{Binding Glyph}" />
</Button.Content>
</Button>
</DataTemplate>

Просмотреть файл

@ -159,7 +159,7 @@ namespace PowerLauncher
if (_settings.Theme != overloadSettings.Properties.Theme)
{
_settings.Theme = overloadSettings.Properties.Theme;
_themeManager.SetTheme(true);
_themeManager.UpdateTheme();
}
if (_settings.StartupPosition != overloadSettings.Properties.Position)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2,9 +2,98 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:core="clr-namespace:System;assembly=mscorlib">
<core:Double x:Key="TitleFontSize">16</core:Double>
<Style
x:Key="CaptionTextBlockStyle"
BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="12" />
<Setter Property="LineHeight" Value="16" />
<Setter Property="FontWeight" Value="Regular" />
</Style>
<Style x:Key="DefaultTextBoxStyle" TargetType="{x:Type TextBox}">
<!-- Universal WPF UI focus -->
<Setter Property="FocusVisualStyle" Value="{DynamicResource DefaultControlFocusVisualStyle}" />
<!-- Universal WPF UI focus -->
<!-- Universal WPF UI ContextMenu -->
<Setter Property="ContextMenu" Value="{DynamicResource DefaultControlContextMenu}" />
<!-- Universal WPF UI ContextMenu -->
<Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" />
<Setter Property="CaretBrush" Value="{DynamicResource TextControlForeground}" />
<Setter Property="Background" Value="{DynamicResource TextControlBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource TextControlElevationBorderBrush}" />
<Setter Property="BorderThickness" Value="{StaticResource TextBoxBorderThemeThickness}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="MinHeight" Value="{DynamicResource TextControlThemeMinHeight}" />
<Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" />
<Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" />
<Setter Property="Border.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Border
x:Name="ContentBorder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding Border.CornerRadius}">
<Grid
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<!-- The Accent Border is a separate element so that changes to the border thickness do not affect the position of the element -->
<Border
x:Name="AccentBorder"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
BorderThickness="{StaticResource TextBoxAccentBorderThemeThickness}"
CornerRadius="{TemplateBinding Border.CornerRadius}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="AccentBorder" Property="BorderThickness" Value="0,0,0,2" />
<Setter TargetName="AccentBorder" Property="BorderBrush" Value="{DynamicResource TextControlFocusedBorderBrush}" />
<Setter TargetName="ContentBorder" Property="Background" Value="{DynamicResource TextControlBackgroundFocused}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEnabled" Value="True" />
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsFocused" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="ContentBorder" Property="Background" Value="{DynamicResource TextControlBackgroundPointerOver}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Cursor" Value="IBeam" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentBorder" Property="Background" Value="{DynamicResource TextControlBackgroundDisabled}" />
<Setter TargetName="ContentBorder" Property="BorderBrush" Value="{DynamicResource TextControlBorderBrushDisabled}" />
<Setter TargetName="AccentBorder" Property="BorderBrush" Value="{DynamicResource TextControlBorderBrushDisabled}" />
<Setter Property="Foreground" Value="{DynamicResource TextControlForegroundDisabled}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PluginsListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Foreground" Value="{DynamicResource ListViewItemForeground}" />
<Setter Property="Background" Value="Transparent" />

Просмотреть файл

@ -6,6 +6,7 @@
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="options">
<Color x:Key="LauncherBackgroundColor">#505b5e</Color>
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent2</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>

Просмотреть файл

@ -6,6 +6,7 @@
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="options">
<Color x:Key="LauncherBackgroundColor">#1b1c33</Color>
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent3</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>

Просмотреть файл

@ -6,6 +6,7 @@
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="options">
<Color x:Key="LauncherBackgroundColor">#4b4122</Color>
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent4</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>

Просмотреть файл

@ -6,6 +6,7 @@
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="options">
<Color x:Key="LauncherBackgroundColor">#d7dad7</Color>
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent5</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>

Просмотреть файл

@ -1008,46 +1008,6 @@ namespace PowerLauncher.ViewModel
if (MainWindowVisibility != Visibility.Visible)
{
MainWindowVisibility = Visibility.Visible;
// HACK: The following code in this if is a fix for https://github.com/microsoft/PowerToys/issues/30206 and https://github.com/microsoft/PowerToys/issues/33135
// WPF UI theme watcher removes the composition target background color, among other weird stuff.
// https://github.com/lepoco/wpfui/blob/303f0aefcd59a142bc681415dc4360a34a15f33d/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs#L280
// So we set it back with https://github.com/lepoco/wpfui/blob/303f0aefcd59a142bc681415dc4360a34a15f33d/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs#L191
var window = Application.Current.MainWindow;
// Only makes sense for Windows 11 or greater, since Windows 10 doesn't have Mica.
if (OSVersionHelper.IsWindows11())
{
Wpf.Ui.Controls.WindowBackdrop.RemoveBackground(window);
}
// Setting uint titlebarPvAttribute = 0xFFFFFFFE; works on 22H2 or higher, 21H2 (aka SV1) this value causes a crash
if (OSVersionHelper.IsGreaterThanWindows11_21H2())
{
// Taken from WPFUI's fix for the title bar issue. We should be able to remove this fix when WPF UI 4 is integrated.
// https://github.com/lepoco/wpfui/pull/1122/files#diff-196b404f4db09632665ef546da6c8e57302b2f3e3d082eb4b5c295ae3482d94a
IntPtr windowHandle = new WindowInteropHelper(window).Handle;
if (windowHandle == IntPtr.Zero)
{
return;
}
HwndSource windowSource = HwndSource.FromHwnd(windowHandle);
// Remove background from client area
if (windowSource != null && windowSource.Handle != IntPtr.Zero && windowSource?.CompositionTarget != null)
{
// NOTE: https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
// Specifying DWMWA_COLOR_DEFAULT (value 0xFFFFFFFF) for the color will reset the window back to using the system's default behavior for the caption color.
uint titlebarPvAttribute = 0xFFFFFFFE;
_ = Wox.Plugin.Common.Win32.NativeMethods.DwmSetWindowAttribute(
windowSource.Handle,
(int)Wox.Plugin.Common.Win32.DwmWindowAttributes.CaptionColor, // CaptionColor attribute is only available on Windows 11.
ref titlebarPvAttribute,
Marshal.SizeOf(typeof(uint)));
}
}
}
else
{