-
-
Notifications
You must be signed in to change notification settings - Fork 366
Improve Wallpaper Retrieval #3279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Wallpaper Retrieval #3279
Conversation
This comment has been minimized.
This comment has been minimized.
🥷 Code experts: Yusyuriv Jack251970, Yusyuriv have most 👩💻 activity in the files. See details
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame: To learn more about /:\ gitStream - Visit our Docs |
Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX. |
📝 WalkthroughWalkthroughThis pull request introduces a new method, Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as UI Component
participant WPGetter as WallpaperPathRetrieval
participant Cache
Caller->>WPGetter: GetWallpaperBrush()
WPGetter-->>WPGetter: Check if on UI thread
alt Not on UI Thread
WPGetter->>WPGetter: Re-invoke on UI thread
end
WPGetter->>WPGetter: Call GetWallpaperPath()
alt Wallpaper file exists
WPGetter->>Cache: Check for cached brush (using last modified date)
alt Cache hit
Cache-->>WPGetter: Return cached ImageBrush
else
WPGetter->>WPGetter: Read file, create BitmapImage and wrap in ImageBrush
WPGetter->>Cache: Cache the new brush
end
else
WPGetter->>WPGetter: Get wallpaper solid color via GetWallpaperColor()
end
WPGetter-->>Caller: Return Brush (ImageBrush or SolidColorBrush)
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (1)Flow.Launcher/Helper/WallpaperPathRetrieval.cs (1)
🔇 Additional comments (10)
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (1)
21-58
: Robust approach for retrieving and caching wallpapers, with a minor edge case.
The newGetWallpaperBrush()
method correctly enforces UI-thread execution and caches the resultingImageBrush
. However, if the user changes wallpapers multiple times within the same second, the last write time may collide, and the cache could serve an outdated image. Consider using both the path and last write time as a cache key or including sub-second precision. Also, it may be helpful to add error handling around file reading for cases of file lock or corruption.Would you like me to propose a revised caching solution or add try-catch fallback behavior?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs
(3 hunks)Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
(1 hunks)Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: gitStream.cm
- GitHub Check: gitStream.cm
- GitHub Check: gitStream.cm
🔇 Additional comments (6)
Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs (1)
34-34
: Nice simplification of the property.
Delegating wallpaper retrieval to a centralized method enhances maintainability and clarity, reducing code duplication.Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs (1)
213-213
: Consistent approach to wallpaper retrieval.
This maintains a uniform implementation across the application and promotes better code reuse.Flow.Launcher/Helper/WallpaperPathRetrieval.cs (4)
2-3
: Essential namespaces for brush and bitmap handling.
These additionalusing
directives are necessary for the new brush and image logic. Nicely done.Also applies to: 6-6, 8-8
19-19
: Caching wallpaper brushes to enhance performance.
Using a dictionary keyed by modification date is a good starting point. Since wallpaper changes are forced onto the UI thread, concurrency concerns are low. Great improvement for performance.
60-60
: RestrictingGetWallpaperPath()
to private scope.
Making this method private is sensible, as external code should use the higher-levelGetWallpaperBrush()
API.
71-71
: LimitingGetWallpaperColor()
to internal use.
This change further ensures that the wallpaper logic remains encapsulated within this class.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (1)
21-58
: Well-implemented centralized wallpaper brush retrieval with thread-safety and caching.The new
GetWallpaperBrush()
method effectively consolidates wallpaper retrieval logic with several important optimizations:
- Proper UI thread handling ensures thread-safe UI operations
- Efficient caching based on file path and modification date
- Appropriate freezing of image resources for thread safety
- Fallback to solid color when no wallpaper is available
However, there are a few concerns to address:
Consider implementing:
- Cache size management to prevent unbounded growth
- Error handling for file operations and image loading
- A parameter for image resolution instead of hardcoded 800x600
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new(); +private const int MaxCacheSize = 5; // Limit cache to reasonable size public static Brush GetWallpaperBrush() { // Invoke the method on the UI thread if (!Application.Current.Dispatcher.CheckAccess()) { return Application.Current.Dispatcher.Invoke(GetWallpaperBrush); } - var wallpaperPath = GetWallpaperPath(); - if (wallpaperPath is not null && File.Exists(wallpaperPath)) + try { - // 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) + var wallpaperPath = GetWallpaperPath(); + if (wallpaperPath is not null && File.Exists(wallpaperPath)) { - return 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); + 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 - wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush); - return wallpaperBrush; + // 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 >= MaxCacheSize) + { + var oldestKey = wallpaperCache.Keys.FirstOrDefault(); + if (oldestKey != default) + { + wallpaperCache.Remove(oldestKey); + } + } + + wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush); + return wallpaperBrush; + } + + var wallpaperColor = GetWallpaperColor(); + return new SolidColorBrush(wallpaperColor); + } + catch (Exception ex) + { + // Log the exception + System.Diagnostics.Debug.WriteLine($"Error retrieving wallpaper: {ex.Message}"); + // Fall back to default color + return new SolidColorBrush(Colors.Transparent); } - - var wallpaperColor = GetWallpaperColor(); - return new SolidColorBrush(wallpaperColor); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs
(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: gitStream.cm
🔇 Additional comments (3)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (3)
2-3
: Good additions of necessary imports and caching mechanism.The added imports and the wallpaper cache dictionary are well-structured for the new functionality. Using a tuple of (path, datetime) as the cache key is a good approach to handle cases where the wallpaper file name remains the same but the content changes.
Also applies to: 6-6, 8-8, 19-19
60-60
: Appropriate access level reduction.Changing access modifiers from public to private for
GetWallpaperPath()
andGetWallpaperColor()
methods is a good encapsulation practice. These methods are now implementation details of the class, and external code should use the newGetWallpaperBrush()
method instead.Also applies to: 71-71
21-58
:✅ Verification successful
Verify cache thread safety when accessing from multiple threads.
The wallpaper cache is accessed without any synchronization mechanism. While the bitmap and brush are frozen for thread safety, the dictionary operations are not protected against concurrent access.
🏁 Script executed:
#!/bin/bash # Check if there are any places where GetWallpaperBrush might be called from multiple threads rg -n "GetWallpaperBrush\(\)" --type csLength of output: 383
Thread-Safety Confirmed: Dispatcher Marshals All Access to the Cache
After verification, it appears that every call to
GetWallpaperBrush
is marshaled to the UI thread via the dispatcher check. This guarantees that wallpaperCache is only accessed serially on the UI thread, so the unsynchronized dictionary operations do not pose a concurrent access risk under the current usage.
- Key Findings:
- The dispatcher check (
if (!Application.Current.Dispatcher.CheckAccess())
) ensures that non-UI thread callers route throughDispatcher.Invoke
, centralizing execution on the UI thread.- All call sites (verified in
SettingsPaneThemeViewModel.cs
andWelcomePage2.xaml.cs
) consequently operate on the UI thread before performing any cache read/write.No immediate locking mechanism is required. However, if future changes allow direct (non-dispatched) access to wallpaperCache, consider revising to a thread-safe collection.
@Jack251970 can we consider adding this suggestion in please (1 & 2, don't think 3 is necessary). Maybe for cache size just 2 or 3 will do. |
Well, please check. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (1)
44-55
: Consider parameterizing the image dimensions.The implementation correctly loads and freezes the bitmap and brush for thread safety. However, the decode dimensions (800x600) are hard-coded, which might not be optimal for all scenarios.
- bitmap.DecodePixelWidth = 800; - bitmap.DecodePixelHeight = 600; + // Consider making these configurable or calculated based on screen resolution + bitmap.DecodePixelWidth = 800; + bitmap.DecodePixelHeight = 600;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs
(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: gitStream.cm
- GitHub Check: gitStream.cm
🔇 Additional comments (6)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (6)
19-20
: Good implementation of bounded cache.The implementation of a dictionary for caching wallpaper brushes with a maximum size limit is a good practice to prevent memory leaks. Using a tuple of file path and modification date as the key is a robust approach to handle wallpaper changes.
22-29
: Excellent thread safety handling.The method correctly ensures it's running on the UI thread by checking access and invoking itself on the UI thread if needed. This prevents potential threading issues when manipulating UI elements.
30-42
: Well-designed caching approach.Good implementation of caching that checks for existence of the wallpaper file and uses the last modified date to differentiate between wallpapers with the same filename. The cache lookup is efficient.
56-69
: Effective cache management strategy.The implementation properly manages the cache size by removing the oldest wallpaper when the cache reaches its maximum size. Using OrderBy to find the oldest entry based on modification date is an efficient approach.
71-79
: Robust error handling and fallback mechanism.The method includes comprehensive error handling with appropriate logging and provides a fallback to a transparent color brush when exceptions occur. It also handles the case when no wallpaper file exists by returning a solid color brush based on the system wallpaper color.
81-81
: Appropriate visibility changes.Changing the visibility of
GetWallpaperPath()
andGetWallpaperColor()
methods from public to private is a good encapsulation practice since they're now only used internally by the newGetWallpaperBrush()
method.Also applies to: 92-92
@check-spelling-bot Report🔴 Please reviewSee the 📂 files view, the 📜action log, or 📝 job summary for details.
See ❌ Event descriptions for more information. If the flagged items are 🤯 false positivesIf items relate to a ...
|
Follow suggestions in #3277
Test