Skip to content

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

Merged
merged 5 commits into from
Feb 28, 2025

Conversation

Jack251970
Copy link
Contributor

@Jack251970 Jack251970 commented Feb 25, 2025

Follow suggestions in #3277

  • Cache wallpapers
  • Freeze images & brushes
  • Invoke on UI Thread
  • Error handling

Test

  • Reopen settings & navigate to appearance page, the wallpaper is loaded

This comment has been minimized.

Copy link

gitstream-cm bot commented Feb 25, 2025

🥷 Code experts: Yusyuriv

Jack251970, Yusyuriv have most 👩‍💻 activity in the files.
Yusyuriv, Jack251970 have most 🧠 knowledge in the files.

See details

Flow.Launcher/Helper/WallpaperPathRetrieval.cs

Activity based on git-commit:

Jack251970 Yusyuriv
FEB
JAN
DEC 7 additions & 10 deletions
NOV
OCT
SEP

Knowledge based on git-blame:
Yusyuriv: 35%
Jack251970: 9%

Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs

Activity based on git-commit:

Jack251970 Yusyuriv
FEB 25 additions & 2 deletions
JAN
DEC
NOV
OCT
SEP

Knowledge based on git-blame:
Jack251970: 45%
Yusyuriv: 11%

Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs

Activity based on git-commit:

Jack251970 Yusyuriv
FEB
JAN 1 additions & 1 deletions
DEC 3 additions & 1 deletions
NOV 2 additions & 2 deletions
OCT
SEP

Knowledge based on git-blame:
Yusyuriv: 73%

To learn more about /:\ gitStream - Visit our Docs

Copy link

gitstream-cm bot commented Feb 25, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@Jack251970 Jack251970 changed the title Wallpaper retrieval Improve Wallpaper Retrieval Feb 25, 2025
@Jack251970 Jack251970 enabled auto-merge February 25, 2025 10:17
@Jack251970 Jack251970 added the enhancement New feature or request label Feb 25, 2025
@Jack251970 Jack251970 requested a review from jjw24 February 25, 2025 10:18
Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

📝 Walkthrough

Walkthrough

This pull request introduces a new method, GetWallpaperBrush(), in the WallpaperPathRetrieval class, which retrieves the current wallpaper as a Brush. It includes checks for UI thread execution and caching for efficiency. The PreviewBackground properties in two UI components are simplified to directly call this new method, eliminating previous complex logic for wallpaper retrieval. Additionally, the access levels of GetWallpaperPath() and GetWallpaperColor() have been changed to private.

Changes

File(s) Change Summary
Flow.Launcher/Helper/WallpaperPathRetrieval.cs Added GetWallpaperBrush() with UI thread handling and caching. Changed GetWallpaperPath() and GetWallpaperColor() from public to private.
Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs,
Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
Simplified PreviewBackground property to call GetWallpaperBrush(), removing redundant file I/O, bitmap processing, and unused namespace imports.

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)
Loading

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • jjw24
  • taooceros

Poem

I'm a bunny with a hop,
Skipping through lines of code nonstop.
Caching wallpapers with a clever brush,
Simplifying views in a gentle hush.
CodeRabbit sings in ASCII glee, 🐰
Celebrating clean changes merrily!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9dbc174 and d8c547f.

📒 Files selected for processing (1)
  • Flow.Launcher/Helper/WallpaperPathRetrieval.cs (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (1)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3279
File: Flow.Launcher/Helper/WallpaperPathRetrieval.cs:44-46
Timestamp: 2025-02-28T07:47:24.148Z
Learning: In Flow.Launcher's WallpaperPathRetrieval class, using a `using` statement with MemoryStream when loading images with BitmapImage does not work properly, even when using BitmapCacheOption.OnLoad. The stream needs to remain open while the bitmap is in use.
🔇 Additional comments (10)
Flow.Launcher/Helper/WallpaperPathRetrieval.cs (10)

2-3: Well-organized imports for the new functionality.

The added imports support the new caching mechanism, UI thread handling, and image processing functionality.

Also applies to: 6-8


18-18: Good implementation of cache size management.

Setting a reasonable limit of 3 entries for the cache addresses the reviewer's concern about preventing unbounded growth. This is appropriate for a wallpaper cache since users typically don't switch between many different wallpapers frequently.


20-20: Effective cache key design.

Using a tuple of (path, dateModified) as the cache key is a good approach that handles cases where the wallpaper file name remains the same but the content changes.


22-29: Good thread safety implementation.

The UI thread check and dispatcher invocation ensure that the bitmap and brush creation happen on the UI thread, which is critical for WPF resources.


30-42: Well-implemented caching logic.

The caching implementation correctly checks for existing wallpapers based on both path and modification date, returning cached instances when available to improve performance.


44-55: Appropriate resource management and thread safety for images.

The implementation correctly:

  1. Avoids disposing the MemoryStream as the bitmap depends on it
  2. Freezes both the bitmap and brush to make them thread-safe
  3. Sets appropriate image parameters for performance

This aligns with the learning that using a using statement with MemoryStream doesn't work properly in this context.


56-69: Well-implemented cache management strategy.

The cache management logic appropriately:

  1. Checks if the cache size has reached the limit
  2. Removes the oldest entry based on modification date
  3. Adds the new entry to the cache

This prevents unbounded growth while maintaining the most recently used wallpapers.


70-79: Robust error handling with appropriate fallback.

The implementation includes:

  1. A fallback to a solid color when no wallpaper is available
  2. Comprehensive exception handling that logs errors and provides a transparent fallback
  3. Proper exception context with class name and descriptive message

This ensures the application remains stable even when wallpaper retrieval fails.


81-81: Appropriate access level modification.

Changing GetWallpaperPath() from public to private is consistent with the new design, as this method is now an implementation detail of GetWallpaperBrush().


92-92: Appropriate access level modification.

Changing GetWallpaperColor() from public to private is consistent with the new design, as this method is now an implementation detail of GetWallpaperBrush().

✨ Finishing Touches
  • 📝 Generate Docstrings

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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 new GetWallpaperBrush() method correctly enforces UI-thread execution and caches the resulting ImageBrush. 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

📥 Commits

Reviewing files that changed from the base of the PR and between c143aa4 and ff45f5f.

📒 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 additional using 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: Restricting GetWallpaperPath() to private scope.
Making this method private is sensible, as external code should use the higher-level GetWallpaperBrush() API.


71-71: Limiting GetWallpaperColor() to internal use.
This change further ensures that the wallpaper logic remains encapsulated within this class.

This comment has been minimized.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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:

  1. Proper UI thread handling ensures thread-safe UI operations
  2. Efficient caching based on file path and modification date
  3. Appropriate freezing of image resources for thread safety
  4. Fallback to solid color when no wallpaper is available

However, there are a few concerns to address:

Consider implementing:

  1. Cache size management to prevent unbounded growth
  2. Error handling for file operations and image loading
  3. 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

📥 Commits

Reviewing files that changed from the base of the PR and between ff45f5f and 0fddb84.

📒 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() and GetWallpaperColor() methods is a good encapsulation practice. These methods are now implementation details of the class, and external code should use the new GetWallpaperBrush() 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 cs

Length 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 through Dispatcher.Invoke, centralizing execution on the UI thread.
    • All call sites (verified in SettingsPaneThemeViewModel.cs and WelcomePage2.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.

@jjw24
Copy link
Member

jjw24 commented Feb 28, 2025

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:

  1. Proper UI thread handling ensures thread-safe UI operations
  2. Efficient caching based on file path and modification date
  3. Appropriate freezing of image resources for thread safety
  4. Fallback to solid color when no wallpaper is available

However, there are a few concerns to address:
Consider implementing:

  1. Cache size management to prevent unbounded growth
  2. Error handling for file operations and image loading
  3. 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

@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.

@Jack251970
Copy link
Contributor Author

// Manage cache size
+            if (wallpaperCache.Count >= MaxCacheSize)
+            {
+                var oldestKey = wallpaperCache.Keys.FirstOrDefault();
+                if (oldestKey != default)
+                {
+                    wallpaperCache.Remove(oldestKey);
+                }
+            }

Well, please check.

This comment has been minimized.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 0fddb84 and 9dbc174.

📒 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() and GetWallpaperColor() methods from public to private is a good encapsulation practice since they're now only used internally by the new GetWallpaperBrush() method.

Also applies to: 92-92

Copy link

@check-spelling-bot Report

🔴 Please review

See the 📂 files view, the 📜action log, or 📝 job summary for details.

❌ Errors Count
❌ forbidden-pattern 22
⚠️ ignored-expect-variant 1
⚠️ non-alpha-in-dictionary 19

See ❌ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

@Jack251970 Jack251970 merged commit dbf51a3 into Flow-Launcher:dev Feb 28, 2025
4 checks passed
@jjw24 jjw24 removed enhancement New feature or request 5 min review labels Feb 28, 2025
@jjw24 jjw24 added the Dev branch only An issue or fix for the Dev branch build label Feb 28, 2025
@jjw24 jjw24 added this to the 1.20.0 milestone Feb 28, 2025
@Jack251970 Jack251970 deleted the wallpaper__retrieval branch February 28, 2025 10:38
@coderabbitai coderabbitai bot mentioned this pull request Mar 17, 2025
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dev branch only An issue or fix for the Dev branch build
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants