Skip to content

Commit

Permalink
Fix: Use correct DPI settings when requesting icons (#14779)
Browse files Browse the repository at this point in the history
  • Loading branch information
yaira2 committed Feb 21, 2024
1 parent 7f51b08 commit 64ea60a
Show file tree
Hide file tree
Showing 21 changed files with 40 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/DriveItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public int CompareTo(INavigationControlItem other)
public async Task LoadThumbnailAsync()
{
if (!string.IsNullOrEmpty(DeviceID) && !string.Equals(DeviceID, "network-folder"))
IconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(DeviceID, Constants.ShellIconSizes.Large, false, false, true);
IconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(DeviceID, Constants.ShellIconSizes.Small, false, false, true, true);

if (Root is not null)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/SidebarLibraryItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task<bool> CheckDefaultSaveFolderAccess()

public async Task LoadLibraryIconAsync()
{
IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Large, false, false, true);
IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Small, false, false, true, true);

if (IconData is not null)
Icon = await IconData.ToBitmapAsync();
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/WidgetDriveCardItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public WidgetDriveCardItem(DriveItem item)

public async Task LoadCardThumbnailAsync()
{
thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.Path, Constants.ShellIconSizes.Jumbo, true, false, true);
thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.Path, Constants.ShellIconSizes.Large, true, false, true, true);

// Thumbnail data is valid, set the item icon
if (thumbnailData is not null && thumbnailData.Length > 0)
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/WidgetFolderCardItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public WidgetFolderCardItem(LocationItem item, string text, bool isPinned)

public async Task LoadCardThumbnailAsync()
{
_thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Jumbo, true, false, true);
_thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Large, true, false, true, true);

if (_thumbnailData is not null && _thumbnailData.Length > 0)
Thumbnail = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => _thumbnailData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
Expand Down
8 changes: 8 additions & 0 deletions src/Files.App/Data/Models/AppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,13 @@ public string PCloudDrivePath
get => pCloudDrivePath;
set => SetProperty(ref pCloudDrivePath, value);
}

/// <summary>
/// Gets or sets a value indicating the AppWindow DPI.
/// </summary>
public float AppWindowDpi
{
get => InteropHelpers.GetDpiForWindow(MainWindow.Instance.WindowHandle) / 96f;
}
}
}
2 changes: 1 addition & 1 deletion src/Files.App/Data/Models/ItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,7 @@ await SafetyExtensions.IgnoreExceptions(() =>
ImageSource? groupImage = null;
if (item.PrimaryItemAttribute != StorageItemTypes.Folder || item.IsArchive)
{
var headerIconInfo = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.ItemPath, Constants.ShellIconSizes.ExtraLarge, false, false, true);
var headerIconInfo = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.ItemPath, Constants.ShellIconSizes.Large, false, false, true, true);

if (headerIconInfo is not null && !item.IsShortcut)
groupImage = await dispatcherQueue.EnqueueOrInvokeAsync(() => headerIconInfo.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Models/SidebarPinnedModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
locationItem.IsInvalid = false;
if (res && res.Result is not null)
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(res.Result.Path, 28u, true, false, true);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(res.Result.Path, Constants.ShellIconSizes.Small, true, false, true, true);
locationItem.IconData = iconData;

if (locationItem.IconData is not null)
Expand Down
3 changes: 3 additions & 0 deletions src/Files.App/Helpers/Interop/InteropHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public static class InteropHelpers
[DllImport("user32.dll", SetLastError = true)]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool altTab);

[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetDpiForWindow(IntPtr hwnd);

[DllImport("ole32.dll")]
public static extern uint CoWaitForMultipleObjects(uint dwFlags, uint dwMilliseconds, ulong nHandles, IntPtr[] pHandles, out uint dwIndex);

Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Helpers/Navigation/NavigationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private static async Task UpdateTabInfoAsync(TabBarItem tabItem, object navigati

if (iconSource.ImageSource is null)
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(currentPath, 28u, true, false, true);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(currentPath, Constants.ShellIconSizes.Small, true, false, true, true);
if (iconData is not null)
iconSource.ImageSource = await iconData.ToBitmapAsync();
}
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/UserControls/Widgets/DrivesWidget.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
<Image
Grid.RowSpan="3"
Grid.Column="0"
Width="32"
Height="32"
HorizontalAlignment="Center"
VerticalAlignment="Center"
x:Phase="1"
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/Cloud/CloudDrivesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static async Task UpdateDrivesAsync()
ShowProperties = true,
};

var iconData = provider.IconData ?? await FileThumbnailHelper.LoadIconWithoutOverlayAsync(provider.SyncFolder, Constants.ShellIconSizes.Large, false, false, true);
var iconData = provider.IconData ?? await FileThumbnailHelper.LoadIconWithoutOverlayAsync(provider.SyncFolder, Constants.ShellIconSizes.Small, false, false, true, true);
if (iconData is not null)
{
cloudProviderItem.IconData = iconData;
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/RecentItem/RecentItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public RecentItem(ShellFileItem fileItem) : base()

public async Task LoadRecentItemIconAsync()
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(RecentPath, Constants.ShellIconSizes.Large, false, false, false);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(RecentPath, Constants.ShellIconSizes.Large, false, false, false, false);
if (iconData is not null)
{
EmptyImgVis = false;
Expand Down
14 changes: 9 additions & 5 deletions src/Files.App/Utils/Storage/Helpers/FileThumbnailHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ namespace Files.App.Utils.Storage
{
public static class FileThumbnailHelper
{
public static Task<(byte[] IconData, byte[] OverlayData, bool isIconCached)> LoadIconAndOverlayAsync(string filePath, uint thumbnailSize, bool isFolder = false, bool getThumbnailOnly = false, bool getIconOnly = false)
=> Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(filePath, (int)thumbnailSize, isFolder, getThumbnailOnly, getIconOnly));
public static Task<(byte[] IconData, byte[] OverlayData, bool isIconCached)> LoadIconAndOverlayAsync(string filePath, uint thumbnailSize, bool isFolder = false, bool getThumbnailOnly = false, bool getIconOnly = false, bool useCurrentScale = false)
{
var size = useCurrentScale ? thumbnailSize * App.AppModel.AppWindowDpi : thumbnailSize;
return Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(filePath, (int)size, isFolder, getThumbnailOnly, getIconOnly));
}

public static async Task<byte[]> LoadIconWithoutOverlayAsync(string filePath, uint thumbnailSize, bool isFolder, bool getThumbnailOnly, bool getIconOnly)
public static async Task<byte[]> LoadIconWithoutOverlayAsync(string filePath, uint thumbnailSize, bool isFolder, bool getThumbnailOnly, bool getIconOnly, bool useCurrentScale)
{
return (await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(filePath, (int)thumbnailSize, isFolder, getThumbnailOnly, getIconOnly))).icon;
var size = useCurrentScale ? thumbnailSize * App.AppModel.AppWindowDpi : thumbnailSize;
return (await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(filePath, (int)size, isFolder, getThumbnailOnly, getIconOnly))).icon;
}

public static async Task<byte[]> LoadIconFromStorageItemAsync(IStorageItem item, uint thumbnailSize, ThumbnailMode thumbnailMode, ThumbnailOptions thumbnailOptions)
Expand Down Expand Up @@ -54,7 +58,7 @@ public static async Task<byte[]> LoadIconFromPathAsync(string filePath, uint thu
}
}
}
return await LoadIconWithoutOverlayAsync(filePath, thumbnailSize, isFolder, false, false);
return await LoadIconWithoutOverlayAsync(filePath, thumbnailSize, isFolder, false, false, false);
}
}
}
2 changes: 1 addition & 1 deletion src/Files.App/ViewModels/Properties/BasePropertiesPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
ViewModel.IsAblumCoverModified = true;
ViewModel.ModifiedAlbumCover = new Picture(file.Path);
ViewModel.IconData = await FileThumbnailHelper.LoadIconFromPathAsync(file.Path, 80, ThumbnailMode.DocumentsView, ThumbnailOptions.ResizeThumbnail, false);
ViewModel.IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(file.Path, Constants.ShellIconSizes.ExtraLarge, false, false, false, true);
}
});

Expand Down
12 changes: 2 additions & 10 deletions src/Files.App/ViewModels/Properties/Items/DriveProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,8 @@ public async override Task GetSpecialPropertiesAsync()

if (ViewModel.LoadFileIcon)
{
if (diskRoot is not null)
{
ViewModel.IconData = await FileThumbnailHelper.LoadIconFromStorageItemAsync(diskRoot, 80, ThumbnailMode.SingleItem, ThumbnailOptions.ResizeThumbnail);
}
else
{
ViewModel.IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Drive.Path, 80, false, false, false);
}

ViewModel.IconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Drive.DeviceID, 80, false, false, false); // For network shortcuts
ViewModel.IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Drive.Path, Constants.ShellIconSizes.ExtraLarge, true, false, true, true);
ViewModel.IconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Drive.DeviceID, Constants.ShellIconSizes.ExtraLarge, true, false, true, true); // For network shortcuts
}

if (diskRoot is null || diskRoot.Properties is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public override async Task GetSpecialPropertiesAsync()
ViewModel.ItemSizeOnDisk = NativeFileOperationsHelper.GetFileSizeOnDisk(Item.ItemPath)?.ToLongSizeString() ??
string.Empty;

var fileIconData = await FileThumbnailHelper.LoadIconFromPathAsync(Item.ItemPath, 80, Windows.Storage.FileProperties.ThumbnailMode.DocumentsView, Windows.Storage.FileProperties.ThumbnailOptions.ResizeThumbnail, false);
var fileIconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.ExtraLarge, false, false, false, true);
if (fileIconData is not null)
{
ViewModel.IconData = fileIconData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public async override Task GetSpecialPropertiesAsync()
ViewModel.IsHidden = NativeFileOperationsHelper.HasFileAttribute(
Item.ItemPath, System.IO.FileAttributes.Hidden);

var fileIconData = await FileThumbnailHelper.LoadIconFromPathAsync(Item.ItemPath, 80, Windows.Storage.FileProperties.ThumbnailMode.SingleItem, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale, true);
var fileIconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.ExtraLarge, true, false, false, true);
if (fileIconData is not null)
{
ViewModel.IconData = fileIconData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public async override Task GetSpecialPropertiesAsync()
ViewModel.IsReadOnly = NativeFileOperationsHelper.HasFileAttribute(Library.ItemPath, System.IO.FileAttributes.ReadOnly);
ViewModel.IsHidden = NativeFileOperationsHelper.HasFileAttribute(Library.ItemPath, System.IO.FileAttributes.Hidden);

var fileIconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Library.ItemPath, 80, false, false, false);
var fileIconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Library.ItemPath, Constants.ShellIconSizes.ExtraLarge, true, false, true, true);
if (fileIconData is not null)
{
ViewModel.IconData = fileIconData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ await Task.Run(async () =>
public async virtual Task<List<FileProperty>> LoadPreviewAndDetailsAsync()
{
// Requesting sizes larger than 220 may result in a small thumbnail
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, false, false, false);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, false, false, false, false);
if (iconData is not null)
await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(async () => FileImage = await iconData.ToBitmapAsync());
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private async Task LoadPreviewAndDetailsAsync()
var items = await Folder.GetItemsAsync();

// Requesting sizes larger than 220 may result in a thumbnail with a small folder
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, true, false, false);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, true, false, false, false);
if (iconData is not null)
Thumbnail = await iconData.ToBitmapAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public override async Task LoadAsync()

private async Task LoadItemThumbnailAsync()
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, false, false, false);
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, Constants.ShellIconSizes.Jumbo, false, false, false, false);
if (iconData is not null)
{
FileImage = await iconData.ToBitmapAsync();
Expand Down

0 comments on commit 64ea60a

Please sign in to comment.