1
1
using System ;
2
+ using System . Collections . Generic ;
3
+ using System . IO ;
2
4
using System . Linq ;
3
5
using System . Runtime . InteropServices ;
4
- using System . Text ;
5
- using System . Windows . Documents ;
6
+ using System . Windows ;
6
7
using System . Windows . Media ;
8
+ using System . Windows . Media . Imaging ;
7
9
using Microsoft . Win32 ;
8
10
using Windows . Win32 ;
9
11
using Windows . Win32 . UI . WindowsAndMessaging ;
@@ -13,8 +15,70 @@ namespace Flow.Launcher.Helper;
13
15
public static class WallpaperPathRetrieval
14
16
{
15
17
private static readonly int MAX_PATH = 260 ;
18
+ private static readonly int MAX_CACHE_SIZE = 3 ;
16
19
17
- public static unsafe string GetWallpaperPath ( )
20
+ private static readonly Dictionary < ( string , DateTime ) , ImageBrush > wallpaperCache = new ( ) ;
21
+
22
+ public static Brush GetWallpaperBrush ( )
23
+ {
24
+ // Invoke the method on the UI thread
25
+ if ( ! Application . Current . Dispatcher . CheckAccess ( ) )
26
+ {
27
+ return Application . Current . Dispatcher . Invoke ( GetWallpaperBrush ) ;
28
+ }
29
+
30
+ try
31
+ {
32
+ var wallpaperPath = GetWallpaperPath ( ) ;
33
+ if ( wallpaperPath is not null && File . Exists ( wallpaperPath ) )
34
+ {
35
+ // Since the wallpaper file name can be the same (TranscodedWallpaper),
36
+ // we need to add the last modified date to differentiate them
37
+ var dateModified = File . GetLastWriteTime ( wallpaperPath ) ;
38
+ wallpaperCache . TryGetValue ( ( wallpaperPath , dateModified ) , out var cachedWallpaper ) ;
39
+ if ( cachedWallpaper != null )
40
+ {
41
+ return cachedWallpaper ;
42
+ }
43
+
44
+ // We should not dispose the memory stream since the bitmap is still in use
45
+ var memStream = new MemoryStream ( File . ReadAllBytes ( wallpaperPath ) ) ;
46
+ var bitmap = new BitmapImage ( ) ;
47
+ bitmap . BeginInit ( ) ;
48
+ bitmap . StreamSource = memStream ;
49
+ bitmap . DecodePixelWidth = 800 ;
50
+ bitmap . DecodePixelHeight = 600 ;
51
+ bitmap . EndInit ( ) ;
52
+ bitmap . Freeze ( ) ; // Make the bitmap thread-safe
53
+ var wallpaperBrush = new ImageBrush ( bitmap ) { Stretch = Stretch . UniformToFill } ;
54
+ wallpaperBrush . Freeze ( ) ; // Make the brush thread-safe
55
+
56
+ // Manage cache size
57
+ if ( wallpaperCache . Count >= MAX_CACHE_SIZE )
58
+ {
59
+ // Remove the oldest wallpaper from the cache
60
+ var oldestCache = wallpaperCache . Keys . OrderBy ( k => k . Item2 ) . FirstOrDefault ( ) ;
61
+ if ( oldestCache != default )
62
+ {
63
+ wallpaperCache . Remove ( oldestCache ) ;
64
+ }
65
+ }
66
+
67
+ wallpaperCache . Add ( ( wallpaperPath , dateModified ) , wallpaperBrush ) ;
68
+ return wallpaperBrush ;
69
+ }
70
+
71
+ var wallpaperColor = GetWallpaperColor ( ) ;
72
+ return new SolidColorBrush ( wallpaperColor ) ;
73
+ }
74
+ catch ( Exception ex )
75
+ {
76
+ App . API . LogException ( nameof ( WallpaperPathRetrieval ) , "Error retrieving wallpaper" , ex ) ;
77
+ return new SolidColorBrush ( Colors . Transparent ) ;
78
+ }
79
+ }
80
+
81
+ private static unsafe string GetWallpaperPath ( )
18
82
{
19
83
var wallpaperPtr = stackalloc char [ MAX_PATH ] ;
20
84
PInvoke . SystemParametersInfo ( SYSTEM_PARAMETERS_INFO_ACTION . SPI_GETDESKWALLPAPER , ( uint ) MAX_PATH ,
@@ -25,7 +89,7 @@ public static unsafe string GetWallpaperPath()
25
89
return wallpaper . ToString ( ) ;
26
90
}
27
91
28
- public static Color GetWallpaperColor ( )
92
+ private static Color GetWallpaperColor ( )
29
93
{
30
94
RegistryKey key = Registry . CurrentUser . OpenSubKey ( @"Control Panel\Colors" , true ) ;
31
95
var result = key ? . GetValue ( "Background" , null ) ;
0 commit comments