Skip to content

Conversation

@PrayagCodes
Copy link

@PrayagCodes PrayagCodes commented Nov 25, 2025

Add 'Set as Desktop Background' Context Menu Item for Images

Summary

This PR adds a "Set as Desktop Background" option to the context menu when right-clicking on image files in the file system. This feature allows users to quickly personalize their desktop by setting any image as their background directly from the file explorer, without navigating through settings menus.

Motivation

Users currently have no quick way to set an image as their desktop background directly from the file system. They must navigate through settings or other indirect methods to change their wallpaper. Adding a context menu option when right-clicking on image files provides a convenient, intuitive way for users to personalize their desktop environment.

This feature enhances the user experience by reducing friction in a common personalization task. It follows familiar desktop environment patterns where users expect to be able to right-click images and set them as backgrounds, making the interface more intuitive and user-friendly.

Changes Made

Core Implementation

  • Added isImageFile() helper function (src/gui/src/UI/UIItem.js)

    • Detects image files by extension (supports: jpg, jpeg, png, gif, bmp, webp, svg, ico, tif, tiff, heic, heif)
    • Case-insensitive matching
    • Pure function with no side effects
  • Added context menu item (src/gui/src/UI/UIItem.js)

    • Appears only for image files (not folders, non-images, or trashed items)
    • Positioned after "Download" menu item
    • Uses signed URLs from /sign endpoint for proper authentication
  • Implemented background change with UX improvements

    • Image preloading to prevent gray flash on slow networks
    • Smooth fade transition (0.4s) for polished user experience
    • Persists background preference to server via /set-desktop-bg endpoint
    • Updates window.user object with new background settings

Internationalization

  • Added set_as_desktop_background translation key to all 37 language files
    • Includes major languages (English, French, Spanish, German, Italian, Portuguese, Russian, Chinese, Japanese, Korean)
    • European languages (Dutch, Polish, Swedish, Turkish, Danish, Finnish, etc.)
    • Middle Eastern languages (Arabic, Hebrew, Persian, Kurdish)
    • Asian languages (Hindi, Bengali, Thai, Indonesian, Vietnamese, Tamil)
    • Other languages (Armenian, Igbo, Urdu, Traditional Chinese, Ukrainian, Norwegian variants)
    • Emoji translation file

Technical Details

Implementation Approach

  • Follows the same pattern as UIWindowDesktopBGSettings for consistency
  • Uses /sign endpoint to generate authenticated URLs that work in CSS background-image
  • No backend changes required (uses existing /set-desktop-bg API endpoint)
  • No CSS changes required (uses existing window.set_desktop_background() function)

Files Modified

  • src/gui/src/UI/UIItem.js - Main implementation (helper function + context menu item)
  • src/gui/src/i18n/translations/*.js - Translation strings (37 files)

Files NOT Modified

  • Backend code (API already exists)
  • CSS (uses existing background system)
  • Other UI components

Testing

Manual Testing Performed

Context Menu Visibility

  • Right-clicked on various image files (PNG, JPG, GIF, WebP, SVG) → Menu item appears
  • Right-clicked on non-image files (PDF, TXT, folders) → Menu item does NOT appear
  • Right-clicked on images in Trash folder → Menu item does NOT appear
  • Right-clicked on trashed items → Menu item does NOT appear

Functionality

  • Clicked "Set as Desktop Background" on various images → Background changes immediately
  • Verified smooth fade transition works correctly
  • Verified no gray flash on slow network connections (image preloading works)
  • Refreshed page → Background persists
  • Logged out and logged back in → Background persists

Internationalization

  • Verified menu item text displays correctly in English
  • Verified translation key exists in all 37 language files

Test Cases Covered

Scenario Expected Result Status
Right-click on .jpg file Menu item appears ✅ Pass
Right-click on .png file Menu item appears ✅ Pass
Right-click on .gif file Menu item appears ✅ Pass
Right-click on .webp file Menu item appears ✅ Pass
Right-click on .PDF file Menu item does NOT appear ✅ Pass
Right-click on folder Menu item does NOT appear ✅ Pass
Right-click on image in Trash Menu item does NOT appear ✅ Pass
Click menu item Background changes immediately ✅ Pass
Refresh after setting Background persists ✅ Pass
Log out/in after setting Background persists ✅ Pass
Slow network connection No gray flash, smooth transition ✅ Pass

Acceptance Criteria

  • ✅ Menu item appears when right-clicking on image files
  • ✅ Menu item does NOT appear for non-image files, folders, or trashed items
  • ✅ Clicking the menu item immediately updates the desktop background
  • ✅ Background preference persists across sessions
  • ✅ Properly internationalized text (all 37 languages)

UX Improvements

  1. Image Preloading: Prevents the gray background flash that occurred on slow networks
  2. Smooth Transition: Added 0.4s fade transition for a polished, professional feel

Related Issues

Link to related GitHub issues or feature requests here

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated (if applicable)
  • No new warnings generated
  • Tests pass (manual testing completed)
  • All 37 translation files updated
  • No breaking changes introduced
  • Backward compatible

Notes

  • The implementation uses signed URLs from the /sign endpoint to ensure proper authentication for CSS background-image requests
  • Image preloading ensures a smooth user experience even on slow network connections
  • The feature follows existing patterns in the codebase for consistency and maintainability

Add a new context menu option that allows users to set any image file
as their desktop background directly from the file explorer.

Changes:
- Add isImageFile() helper function to detect image files by extension
- Add set_as_desktop_background i18n translation string
- Add context menu item that appears only for image files (not folders,
  non-images, or trashed items)
- Implement background change with image preloading to prevent gray flash
- Add smooth fade transition (0.4s) for polished UX
- Persist background preference to server via /set-desktop-bg endpoint
- Update window.user object with new background settings

The implementation follows the same pattern as UIWindowDesktopBGSettings
and uses signed URLs from the /sign endpoint to ensure proper
authentication for CSS background-image requests.

Files modified:
- src/gui/src/UI/UIItem.js
- src/gui/src/i18n/translations/en.js
Add the set_as_desktop_background translation key to all 37 translation
files to support the new 'Set as Desktop Background' context menu
feature.
@PrayagCodes PrayagCodes changed the title Feat/desktop background context menu feat: desktop background context menu Nov 25, 2025
const read_url = sign_res.signatures[0].read_url;

// Preload image before setting as background to avoid gray flash
await new Promise((resolve, reject) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary? why do we need to wrap the logic below into a promise? — img operation seem to be sync

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The promise wrapper is necessary because we need to wait for the asynchronous image download to complete before setting the background. Here's why:

  1. new Image() and img.src = read_url are synchronous operations (they just create the object and set the property)
  2. The actual image download happens asynchronously in the browser
  3. The onload callback fires when that async download completes
  4. The Promise wrapper lets us await that async event

Without this, we'd set the background before the image finishes downloading, causing a gray flash while the browser loads it. By preloading, the image is cached and ready, so the background change is instant.

Copy link

@israx israx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job raising PRs so far

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants