Skip to content

Commit

Permalink
Code Quality: Introduced IWindowsWallpaperService (#15811)
Browse files Browse the repository at this point in the history
  • Loading branch information
0x5bfa authored and yaira2 committed Jul 22, 2024
1 parent f7cac70 commit 98eb6b4
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 87 deletions.
18 changes: 18 additions & 0 deletions src/Files.App/Actions/Content/Background/BaseSetAsAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml.Controls;
using Windows.Foundation.Metadata;

namespace Files.App.Actions
{
internal abstract class BaseSetAsAction : ObservableObject, IAction
Expand Down Expand Up @@ -28,6 +31,21 @@ public BaseSetAsAction()

public abstract Task ExecuteAsync(object? parameter = null);

protected async void ShowErrorDialog(string message)
{
var errorDialog = new ContentDialog()
{
Title = "FailedToSetBackground".GetLocalizedResource(),
Content = message,
PrimaryButtonText = "OK".GetLocalizedResource(),
};

if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
errorDialog.XamlRoot = MainWindow.Instance.Content.XamlRoot;

await errorDialog.TryShowAsync();
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace Files.App.Actions
{
internal sealed class SetAsLockscreenBackgroundAction : BaseSetAsAction
{
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();

public override string Label
=> "SetAsLockscreen".GetLocalizedResource();

Expand All @@ -20,10 +22,19 @@ public override RichGlyph Glyph

public override Task ExecuteAsync(object? parameter = null)
{
if (context.SelectedItem is not null)
return WallpaperHelpers.SetAsBackgroundAsync(WallpaperType.LockScreen, context.SelectedItem.ItemPath);
if (context.SelectedItem is null)
return Task.CompletedTask;

try
{
return WindowsWallpaperService.SetLockScreenWallpaper(context.SelectedItem.ItemPath);
}
catch (Exception ex)
{
ShowErrorDialog(ex.Message);

return Task.CompletedTask;
return Task.CompletedTask;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace Files.App.Actions
{
internal sealed class SetAsSlideshowBackgroundAction : BaseSetAsAction
{
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();

public override string Label
=> "SetAsSlideshow".GetLocalizedResource();

Expand All @@ -21,7 +23,15 @@ public override RichGlyph Glyph
public override Task ExecuteAsync(object? parameter = null)
{
var paths = context.SelectedItems.Select(item => item.ItemPath).ToArray();
WallpaperHelpers.SetSlideshow(paths);

try
{
WindowsWallpaperService.SetDesktopSlideshow(paths);
}
catch (Exception ex)
{
ShowErrorDialog(ex.Message);
}

return Task.CompletedTask;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace Files.App.Actions
{
internal sealed class SetAsWallpaperBackgroundAction : BaseSetAsAction
{
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();

public override string Label
=> "SetAsBackground".GetLocalizedResource();

Expand All @@ -20,8 +22,17 @@ public override RichGlyph Glyph

public override Task ExecuteAsync(object? parameter = null)
{
if (context.SelectedItem is not null)
return WallpaperHelpers.SetAsBackgroundAsync(WallpaperType.Desktop, context.SelectedItem.ItemPath);
if (context.SelectedItem is null)
return Task.CompletedTask;

try
{
WindowsWallpaperService.SetDesktopWallpaper(context.SelectedItem.ItemPath);
}
catch (Exception ex)
{
ShowErrorDialog(ex.Message);
}

return Task.CompletedTask;
}
Expand Down
29 changes: 29 additions & 0 deletions src/Files.App/Data/Contracts/IWindowsWallpaperService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Data.Contracts
{
/// <summary>
/// Provides service for manipulating shell wallpapers on Windows.
/// </summary>
public interface IWindowsWallpaperService
{
/// <summary>
/// Sets desktop wallpaper using the specified image path.
/// </summary>
/// <param name="szPath">The image path to assign as the desktop wallpaper.</param>
void SetDesktopWallpaper(string szPath);

/// <summary>
/// Sets desktop slideshow using the specified image paths.
/// </summary>
/// <param name="aszPaths">The image paths to use to set as slideshow.</param>
void SetDesktopSlideshow(string[] aszPaths);

/// <summary>
/// Gets lock screen wallpaper using the specified image path.
/// </summary>
/// <param name="szPath">The image path to use to set as lock screen wallpaper.</param>
Task SetLockScreenWallpaper(string szPath);
}
}
1 change: 1 addition & 0 deletions src/Files.App/Helpers/Application/AppLifecycleHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public static IHost ConfigureHost()
.AddSingleton<ISidebarContext, SidebarContext>()
// Services
.AddSingleton<IWindowsIniService, WindowsIniService>()
.AddSingleton<IWindowsWallpaperService, WindowsWallpaperService>()
.AddSingleton<IAppThemeModeService, AppThemeModeService>()
.AddSingleton<IDialogService, DialogService>()
.AddSingleton<ICommonDialogService, CommonDialogService>()
Expand Down
5 changes: 5 additions & 0 deletions src/Files.App/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,8 @@ LocalAlloc
InitializeAcl
AddAce
LocalFree
IDesktopWallpaper
DesktopWallpaper
SHCreateShellItemArrayFromIDLists
ILCreateFromPath
CLSIDFromString
79 changes: 79 additions & 0 deletions src/Files.App/Services/Windows/WindowsWallpaperService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Windows.Storage;
using Windows.System.UserProfile;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Com;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.Shell.Common;

namespace Files.App.Services
{
/// <inheritdoc cref="IWindowsWallpaperService"/>
public sealed class WindowsWallpaperService : IWindowsWallpaperService
{
/// <inheritdoc/>
public unsafe void SetDesktopWallpaper(string szPath)
{
PInvoke.CoCreateInstance(
new Guid("{C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD}"),
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
out IDesktopWallpaper desktopWallpaper)
.ThrowOnFailure();

desktopWallpaper.GetMonitorDevicePathCount(out var dwMonitorCount);

fixed (char* pszPath = szPath)
{
var pwszPath = new PWSTR(pszPath);

for (uint dwIndex = 0; dwIndex < dwMonitorCount; dwIndex++)
{
desktopWallpaper.GetMonitorDevicePathAt(dwIndex, out var pMonitorID);
desktopWallpaper.SetWallpaper(pMonitorID, pwszPath);
}
}
}

/// <inheritdoc/>
public unsafe void SetDesktopSlideshow(string[] aszPaths)
{
PInvoke.CoCreateInstance(
new Guid("{C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD}"),
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
out IDesktopWallpaper desktopWallpaper)
.ThrowOnFailure();

var dwCount = (uint)aszPaths.Length;

fixed (ITEMIDLIST** idList = new ITEMIDLIST*[dwCount])
{
for (uint dwIndex = 0u; dwIndex < dwCount; dwIndex++)
{
var id = PInvoke.ILCreateFromPath(aszPaths[dwIndex]);
idList[dwIndex] = id;
}

// Get shell item array from images to use for slideshow
PInvoke.SHCreateShellItemArrayFromIDLists(dwCount, idList, out var shellItemArray);

// Set slideshow
desktopWallpaper.SetSlideshow(shellItemArray);
}

// Set wallpaper to fill desktop.
desktopWallpaper.SetPosition(DESKTOP_WALLPAPER_POSITION.DWPOS_FILL);
}

/// <inheritdoc/>
public async Task SetLockScreenWallpaper(string szPath)
{
IStorageFile sourceFile = await StorageFile.GetFileFromPathAsync(szPath);
await LockScreen.SetImageFileAsync(sourceFile);
}
}
}
81 changes: 0 additions & 81 deletions src/Files.App/Utils/Global/WallpaperHelpers.cs

This file was deleted.

0 comments on commit 98eb6b4

Please sign in to comment.