This commit is contained in:
Jack Ye 2026-03-09 10:54:14 +00:00 committed by GitHub
commit 4d44d9d71b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 52 deletions

View file

@ -477,11 +477,58 @@ namespace Flow.Launcher.Core.Resource
public void AddDropShadowEffectToCurrentTheme() public void AddDropShadowEffectToCurrentTheme()
{ {
var dict = GetCurrentResourceDictionary(); // Get current theme's WindowBorderStyle
var theme = _settings.Theme;
var dict = GetThemeResourceDictionary(theme);
var windowBorderStyle = dict.Contains("WindowBorderStyle") ? dict["WindowBorderStyle"] as Style : null;
if (windowBorderStyle == null) return;
var windowBorderStyle = dict["WindowBorderStyle"] as Style; // Get a new unsealed style based on the old one, and copy Resources and Triggers
var newWindowBorderStyle = new Style(typeof(Border));
ThemeHelper.CopyStyle(windowBorderStyle, newWindowBorderStyle);
var effectSetter = new Setter // Identify existing Margin to calculate new Margin, and copy other setters
Setter existingMarginSetter = null;
foreach (var setterBase in windowBorderStyle.Setters)
{
if (setterBase is Setter setter)
{
// Skip existing Margin (we'll replace it)
if (setter.Property == FrameworkElement.MarginProperty)
{
existingMarginSetter = setter;
continue;
}
// Skip existing Effect (we'll ensure strictly one is added)
if (setter.Property == UIElement.EffectProperty) continue;
}
// Add other setters (e.g. Background, BorderThickness)
newWindowBorderStyle.Setters.Add(setterBase);
}
// Calculate new Margin
Thickness newMargin;
if (existingMarginSetter == null)
{
newMargin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
}
else
{
var baseMargin = (Thickness)existingMarginSetter.Value;
newMargin = new Thickness(
baseMargin.Left + ShadowExtraMargin,
baseMargin.Top + ShadowExtraMargin,
baseMargin.Right + ShadowExtraMargin,
baseMargin.Bottom + ShadowExtraMargin);
}
// Add new Margin Setter
ThemeHelper.ReplaceSetter(newWindowBorderStyle, new Setter(FrameworkElement.MarginProperty, newMargin));
// Add Drop Shadow Effect Setter
ThemeHelper.ReplaceSetter(newWindowBorderStyle, new Setter
{ {
Property = UIElement.EffectProperty, Property = UIElement.EffectProperty,
Value = new DropShadowEffect Value = new DropShadowEffect
@ -491,62 +538,53 @@ namespace Flow.Launcher.Core.Resource
Direction = 270, Direction = 270,
BlurRadius = 30 BlurRadius = 30
} }
}; });
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is not Setter marginSetter) SetResizeBoarderThickness(newMargin);
{
var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
marginSetter = new Setter()
{
Property = FrameworkElement.MarginProperty,
Value = margin,
};
windowBorderStyle.Setters.Add(marginSetter);
SetResizeBoarderThickness(margin); Application.Current.Resources["WindowBorderStyle"] = newWindowBorderStyle;
}
else
{
var baseMargin = (Thickness)marginSetter.Value;
var newMargin = new Thickness(
baseMargin.Left + ShadowExtraMargin,
baseMargin.Top + ShadowExtraMargin,
baseMargin.Right + ShadowExtraMargin,
baseMargin.Bottom + ShadowExtraMargin);
marginSetter.Value = newMargin;
SetResizeBoarderThickness(newMargin);
}
windowBorderStyle.Setters.Add(effectSetter);
UpdateResourceDictionary(dict);
} }
public void RemoveDropShadowEffectFromCurrentTheme() public void RemoveDropShadowEffectFromCurrentTheme()
{ {
var dict = GetCurrentResourceDictionary(); // Get current theme's WindowBorderStyle
var windowBorderStyle = dict["WindowBorderStyle"] as Style; var theme = _settings.Theme;
var dict = GetThemeResourceDictionary(theme);
var windowBorderStyle = dict.Contains("WindowBorderStyle") ? dict["WindowBorderStyle"] as Style : null;
if (windowBorderStyle == null) return;
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == UIElement.EffectProperty) is Setter effectSetter) // Get a new unsealed style based on the old one, and copy Resources and Triggers
{ var newWindowBorderStyle = new Style(typeof(Border));
windowBorderStyle.Setters.Remove(effectSetter); ThemeHelper.CopyStyle(windowBorderStyle, newWindowBorderStyle);
}
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is Setter marginSetter) // Copy Setters, excluding the Effect setter and updating the Margin setter
foreach (var setterBase in windowBorderStyle.Setters)
{ {
var currentMargin = (Thickness)marginSetter.Value; if (setterBase is Setter setter)
var newMargin = new Thickness( {
currentMargin.Left - ShadowExtraMargin, // Skip existing Effect (We'll remove it)
currentMargin.Top - ShadowExtraMargin, if (setter.Property == UIElement.EffectProperty) continue;
currentMargin.Right - ShadowExtraMargin,
currentMargin.Bottom - ShadowExtraMargin); // Update Margin by subtracting the extra margin we added for the shadow
marginSetter.Value = newMargin; if (setter.Property == FrameworkElement.MarginProperty)
{
var currentMargin = (Thickness)setter.Value;
var newMargin = new Thickness(
currentMargin.Left - ShadowExtraMargin,
currentMargin.Top - ShadowExtraMargin,
currentMargin.Right - ShadowExtraMargin,
currentMargin.Bottom - ShadowExtraMargin);
ThemeHelper.ReplaceSetter(newWindowBorderStyle, new Setter(FrameworkElement.MarginProperty, newMargin));
continue;
}
}
newWindowBorderStyle.Setters.Add(setterBase);
} }
SetResizeBoarderThickness(null); SetResizeBoarderThickness(null);
UpdateResourceDictionary(dict); Application.Current.Resources["WindowBorderStyle"] = newWindowBorderStyle;
} }
public void SetResizeBorderThickness(WindowChrome windowChrome, bool fixedWindowSize) public void SetResizeBorderThickness(WindowChrome windowChrome, bool fixedWindowSize)
@ -673,13 +711,11 @@ namespace Flow.Launcher.Core.Resource
// If the BackdropType is Mica or MicaAlt, set the windowborderstyle's background to transparent // If the BackdropType is Mica or MicaAlt, set the windowborderstyle's background to transparent
if (backdropType is BackdropTypes.Mica or BackdropTypes.MicaAlt) if (backdropType is BackdropTypes.Mica or BackdropTypes.MicaAlt)
{ {
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property == Control.BackgroundProperty)); ThemeHelper.ReplaceSetter(windowBorderStyle, new Setter(Border.BackgroundProperty, ThemeHelper.GetFrozenSolidColorBrush(Color.FromArgb(1, 0, 0, 0))));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, ThemeHelper.GetFrozenSolidColorBrush(Color.FromArgb(1, 0, 0, 0))));
} }
else if (backdropType == BackdropTypes.Acrylic) else if (backdropType == BackdropTypes.Acrylic)
{ {
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property == Control.BackgroundProperty)); ThemeHelper.ReplaceSetter(windowBorderStyle, new Setter(Border.BackgroundProperty, Brushes.Transparent));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, Brushes.Transparent));
} }
// For themes with blur enabled, the window border is rendered by the system, so it's treated as a simple rectangle regardless of thickness. // For themes with blur enabled, the window border is rendered by the system, so it's treated as a simple rectangle regardless of thickness.

View file

@ -8,10 +8,10 @@ public static class ThemeHelper
{ {
public static void CopyStyle(Style originalStyle, Style targetStyle) public static void CopyStyle(Style originalStyle, Style targetStyle)
{ {
// If the style is based on another style, copy the base style first // If the style is based on another style, use the same base style for the target style
if (originalStyle.BasedOn != null) if (originalStyle.BasedOn != null)
{ {
CopyStyle(originalStyle.BasedOn, targetStyle); targetStyle.BasedOn = originalStyle.BasedOn;
} }
// Copy the setters from the original style // Copy the setters from the original style
@ -21,6 +21,15 @@ public static class ThemeHelper
} }
} }
public static void ReplaceSetter(Style style, Setter setter)
{
var existingSetter = style.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == setter.Property);
if (existingSetter != null)
style.Setters.Remove(existingSetter);
style.Setters.Add(setter);
}
public static SolidColorBrush GetFrozenSolidColorBrush(Color color) public static SolidColorBrush GetFrozenSolidColorBrush(Color color)
{ {
var brush = new SolidColorBrush(color); var brush = new SolidColorBrush(color);