Skip to content

Commit

Permalink
Merge pull request #3279 from Jack251970/wallpaper__retrieval
Browse files Browse the repository at this point in the history
Improve Wallpaper Retrieval
  • Loading branch information
Jack251970 authored Feb 28, 2025
2 parents 65f85cf + d8c547f commit dbf51a3
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 44 deletions.
72 changes: 68 additions & 4 deletions Flow.Launcher/Helper/WallpaperPathRetrieval.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;
Expand All @@ -13,8 +15,70 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
private static readonly int MAX_CACHE_SIZE = 3;

public static unsafe string GetWallpaperPath()
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();

public static Brush GetWallpaperBrush()
{
// Invoke the method on the UI thread
if (!Application.Current.Dispatcher.CheckAccess())
{
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}

try
{
var wallpaperPath = GetWallpaperPath();
if (wallpaperPath is not null && File.Exists(wallpaperPath))
{
// 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);
if (cachedWallpaper != null)
{
return cachedWallpaper;
}

// 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

// Manage cache size
if (wallpaperCache.Count >= MAX_CACHE_SIZE)
{
// Remove the oldest wallpaper from the cache
var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
if (oldestCache != default)
{
wallpaperCache.Remove(oldestCache);
}
}

wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
return wallpaperBrush;
}

var wallpaperColor = GetWallpaperColor();
return new SolidColorBrush(wallpaperColor);
}
catch (Exception ex)
{
App.API.LogException(nameof(WallpaperPathRetrieval), "Error retrieving wallpaper", ex);
return new SolidColorBrush(Colors.Transparent);
}
}

private static unsafe string GetWallpaperPath()
{
var wallpaperPtr = stackalloc char[MAX_PATH];
PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH,
Expand All @@ -25,7 +89,7 @@ public static unsafe string GetWallpaperPath()
return wallpaper.ToString();
}

public static Color GetWallpaperColor()
private static Color GetWallpaperColor()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", true);
var result = key?.GetValue("Background", null);
Expand Down
21 changes: 1 addition & 20 deletions Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows.Media;

namespace Flow.Launcher.Resources.Pages
Expand All @@ -33,24 +31,7 @@ private static void SetTogglingHotkey(HotkeyModel hotkey)

public Brush PreviewBackground
{
get
{
var wallpaper = WallpaperPathRetrieval.GetWallpaperPath();
if (wallpaper is not null && File.Exists(wallpaper))
{
var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = memStream;
bitmap.DecodePixelWidth = 800;
bitmap.DecodePixelHeight = 600;
bitmap.EndInit();
return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
}

var wallpaperColor = WallpaperPathRetrieval.GetWallpaperColor();
return new SolidColorBrush(wallpaperColor);
}
get => WallpaperPathRetrieval.GetWallpaperBrush();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.IO;
using System.Linq;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
Expand All @@ -14,7 +13,6 @@
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using ModernWpf;
using Flow.Launcher.Core;
using ThemeManager = Flow.Launcher.Core.Resource.ThemeManager;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;

Expand Down Expand Up @@ -212,24 +210,7 @@ public bool UseDate

public Brush PreviewBackground
{
get
{
var wallpaper = WallpaperPathRetrieval.GetWallpaperPath();
if (wallpaper is not null && File.Exists(wallpaper))
{
var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = memStream;
bitmap.DecodePixelWidth = 800;
bitmap.DecodePixelHeight = 600;
bitmap.EndInit();
return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
}

var wallpaperColor = WallpaperPathRetrieval.GetWallpaperColor();
return new SolidColorBrush(wallpaperColor);
}
get => WallpaperPathRetrieval.GetWallpaperBrush();
}

public ResultsViewModel PreviewResults
Expand Down

0 comments on commit dbf51a3

Please sign in to comment.