[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:
Родитель
bf3474b134
Коммит
7c6af6580e
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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="" />
|
||||
</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
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче