Merge branch 'dev' into 050328-NewHotkeyDesign

This commit is contained in:
DB P 2025-03-29 23:37:34 +09:00 committed by GitHub
commit ebb11250da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 35 deletions

View file

@ -12,9 +12,9 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval public static class WallpaperPathRetrieval
{ {
private static readonly int MAX_CACHE_SIZE = 3; private const int MaxCacheSize = 3;
private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new();
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new(); private static readonly object CacheLock = new();
public static Brush GetWallpaperBrush() public static Brush GetWallpaperBrush()
{ {
@ -27,46 +27,71 @@ public static class WallpaperPathRetrieval
try try
{ {
var wallpaperPath = Win32Helper.GetWallpaperPath(); var wallpaperPath = Win32Helper.GetWallpaperPath();
if (wallpaperPath is not null && File.Exists(wallpaperPath)) if (string.IsNullOrEmpty(wallpaperPath) || !File.Exists(wallpaperPath))
{ {
// Since the wallpaper file name can be the same (TranscodedWallpaper), App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Wallpaper path is invalid: {wallpaperPath}");
// we need to add the last modified date to differentiate them var wallpaperColor = GetWallpaperColor();
var dateModified = File.GetLastWriteTime(wallpaperPath); return new SolidColorBrush(wallpaperColor);
wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper); }
// Since the wallpaper file name can be the same (TranscodedWallpaper),
// we need to add the last modified date to differentiate them
var dateModified = File.GetLastWriteTime(wallpaperPath);
lock (CacheLock)
{
WallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
if (cachedWallpaper != null) if (cachedWallpaper != null)
{ {
return cachedWallpaper; return cachedWallpaper;
} }
}
using var fileStream = File.OpenRead(wallpaperPath);
var decoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
var frame = decoder.Frames[0];
var originalWidth = frame.PixelWidth;
var originalHeight = frame.PixelHeight;
// We should not dispose the memory stream since the bitmap is still in use if (originalWidth == 0 || originalHeight == 0)
var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath)); {
var bitmap = new BitmapImage(); App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}");
bitmap.BeginInit(); return new SolidColorBrush(Colors.Transparent);
bitmap.StreamSource = memStream; }
bitmap.DecodePixelWidth = 800;
bitmap.DecodePixelHeight = 600;
bitmap.EndInit();
bitmap.Freeze(); // Make the bitmap thread-safe
var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
wallpaperBrush.Freeze(); // Make the brush thread-safe
// Manage cache size // Calculate the scaling factor to fit the image within 800x600 while preserving aspect ratio
if (wallpaperCache.Count >= MAX_CACHE_SIZE) var widthRatio = 800.0 / originalWidth;
var heightRatio = 600.0 / originalHeight;
var scaleFactor = Math.Min(widthRatio, heightRatio);
var decodedPixelWidth = (int)(originalWidth * scaleFactor);
var decodedPixelHeight = (int)(originalHeight * scaleFactor);
// Set DecodePixelWidth and DecodePixelHeight to resize the image while preserving aspect ratio
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(wallpaperPath);
bitmap.DecodePixelWidth = decodedPixelWidth;
bitmap.DecodePixelHeight = decodedPixelHeight;
bitmap.EndInit();
bitmap.Freeze(); // Make the bitmap thread-safe
var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
wallpaperBrush.Freeze(); // Make the brush thread-safe
// Manage cache size
lock (CacheLock)
{
if (WallpaperCache.Count >= MaxCacheSize)
{ {
// Remove the oldest wallpaper from the cache // Remove the oldest wallpaper from the cache
var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault(); var oldestCache = WallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
if (oldestCache != default) if (oldestCache != default)
{ {
wallpaperCache.Remove(oldestCache); WallpaperCache.Remove(oldestCache);
} }
} }
wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush); WallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
return wallpaperBrush; return wallpaperBrush;
} }
var wallpaperColor = GetWallpaperColor();
return new SolidColorBrush(wallpaperColor);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -77,7 +102,7 @@ public static class WallpaperPathRetrieval
private static Color GetWallpaperColor() private static Color GetWallpaperColor()
{ {
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", true); RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", false);
var result = key?.GetValue("Background", null); var result = key?.GetValue("Background", null);
if (result is string strResult) if (result is string strResult)
{ {
@ -86,8 +111,9 @@ public static class WallpaperPathRetrieval
var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList(); var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList();
return Color.FromRgb(parts[0], parts[1], parts[2]); return Color.FromRgb(parts[0], parts[1], parts[2]);
} }
catch catch (Exception ex)
{ {
App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
} }
} }

View file

@ -110,8 +110,8 @@
<Border.Background> <Border.Background>
<LinearGradientBrush StartPoint="0 0" EndPoint="1 1"> <LinearGradientBrush StartPoint="0 0" EndPoint="1 1">
<LinearGradientBrush.GradientStops> <LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#1494df" /> <GradientStop Offset="0.0" Color="#2A4D8C" />
<GradientStop Offset="1.0" Color="#1073bd" /> <GradientStop Offset="1.0" Color="#1E3160" />
</LinearGradientBrush.GradientStops> </LinearGradientBrush.GradientStops>
</LinearGradientBrush> </LinearGradientBrush>
</Border.Background> </Border.Background>

View file

@ -60,7 +60,7 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Orientation="Horizontal"> Orientation="Horizontal">
<Border Width="450" Style="{DynamicResource WindowBorderStyle}"> <Border Width="450" Style="{DynamicResource PreviewWindowBorderStyle}">
<Border Style="{DynamicResource WindowRadius}"> <Border Style="{DynamicResource WindowRadius}">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>

View file

@ -58,10 +58,10 @@
<Border Grid.Row="0" HorizontalAlignment="Stretch"> <Border Grid.Row="0" HorizontalAlignment="Stretch">
<Border.Background> <Border.Background>
<LinearGradientBrush StartPoint="0 0" EndPoint="1 1"> <LinearGradientBrush StartPoint="0 1" EndPoint="0 0">
<LinearGradientBrush.GradientStops> <LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#7b83eb" /> <GradientStop Offset="0.0" Color="#E5F3F7" />
<GradientStop Offset="1.0" Color="#555dc0" /> <GradientStop Offset="1.0" Color="#FAFAFD" />
</LinearGradientBrush.GradientStops> </LinearGradientBrush.GradientStops>
</LinearGradientBrush> </LinearGradientBrush>
</Border.Background> </Border.Background>