diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 151ce97dd83..77bebe2d37d 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -12,9 +12,9 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
- private static readonly int MAX_CACHE_SIZE = 3;
-
- private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
+ private const int MaxCacheSize = 3;
+ private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new();
+ private static readonly object CacheLock = new();
public static Brush GetWallpaperBrush()
{
@@ -27,46 +27,71 @@ public static Brush GetWallpaperBrush()
try
{
var wallpaperPath = Win32Helper.GetWallpaperPath();
- if (wallpaperPath is not null && File.Exists(wallpaperPath))
+ if (string.IsNullOrEmpty(wallpaperPath) || !File.Exists(wallpaperPath))
+ {
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Wallpaper path is invalid: {wallpaperPath}");
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+
+ // 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)
{
- // 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);
- wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
+ WallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
if (cachedWallpaper != null)
{
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
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- 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
+ if (originalWidth == 0 || originalHeight == 0)
+ {
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}");
+ return new SolidColorBrush(Colors.Transparent);
+ }
+
+ // Calculate the scaling factor to fit the image within 800x600 while preserving aspect ratio
+ 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
- if (wallpaperCache.Count >= MAX_CACHE_SIZE)
+ // Manage cache size
+ lock (CacheLock)
+ {
+ if (WallpaperCache.Count >= MaxCacheSize)
{
// 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)
{
- wallpaperCache.Remove(oldestCache);
+ WallpaperCache.Remove(oldestCache);
}
}
- wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ WallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
return wallpaperBrush;
}
-
- var wallpaperColor = GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
}
catch (Exception ex)
{
@@ -77,7 +102,7 @@ public static Brush GetWallpaperBrush()
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);
if (result is string strResult)
{
@@ -86,8 +111,9 @@ private static Color GetWallpaperColor()
var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList();
return Color.FromRgb(parts[0], parts[1], parts[2]);
}
- catch
+ catch (Exception ex)
{
+ App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
index 1728195bde9..32fdb62fc71 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
@@ -110,8 +110,8 @@
-
-
+
+
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
index 04c76d0277f..f62cec3bf12 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
@@ -60,7 +60,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
-
+
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
index c898ac9a02e..3df4b506ed2 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
@@ -58,10 +58,10 @@
-
+
-
-
+
+