Skip to content

Commit 493dd34

Browse files
committed
Bug fix again for OSX.
1 parent b1c4efc commit 493dd34

File tree

3 files changed

+87
-38
lines changed

3 files changed

+87
-38
lines changed

Hexa.NET.ImGui.Widgets.Tests/FileUtilitiesTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void EnumerateEntriesOSXTest()
2323
});
2424

2525
// Optional: Print the path and file name for verification
26-
Console.WriteLine($"Path: {entry.Path}, File Name: {fileName}");
26+
Console.WriteLine($"Path: {entry.Path}, File Name: {fileName}, {entry.Attributes}");
2727
}
2828
}
2929

@@ -45,7 +45,7 @@ public void EnumerateEntriesWinTest()
4545
});
4646

4747
// Optional: Print the path and file name for verification
48-
Console.WriteLine($"Path: {entry.Path}, File Name: {fileName}");
48+
Console.WriteLine($"Path: {entry.Path}, File Name: {fileName}, {entry.Attributes}");
4949
}
5050
}
5151
}

Hexa.NET.ImGui.Widgets/Dialogs/FileSystemHelper.cs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,23 @@ public static string GetDownloadsFolderPath()
8484
}
8585
else
8686
{
87-
throw new PlatformNotSupportedException("This platform is not supported.");
87+
return string.Empty;
8888
}
8989
}
9090

9191
private static readonly List<string> ignoredDrives = ["sys", "proc", "dev", "run", "snap", "tmp", "boot", "System"];
92-
92+
9393
public static void ClearCache()
9494
{
9595
List<FileSystemItem> drives = new();
9696
foreach (var drive in DriveInfo.GetDrives())
9797
{
98-
// shouldn't be a performance concern, but if it ever gets to the point use a trie.
98+
// shouldn't be a performance concern, but if it ever gets to the point use a trie.
9999
if (drive.Name.StartsWith('/') && ignoredDrives.Any(x => drive.Name.AsSpan(1).StartsWith(x)))
100100
{
101-
continue;
101+
continue;
102102
}
103-
103+
104104
try
105105
{
106106
if (drive.IsReady && drive.RootDirectory != null)
@@ -147,7 +147,6 @@ public static void ClearCache()
147147
{
148148
name += $" ({drive.Name})";
149149
}
150-
151150

152151
drives.Add(new FileSystemItem(drive.RootDirectory.FullName, driveIcon, name, FileSystemItemFlags.Folder));
153152
}
@@ -158,35 +157,43 @@ public static void ClearCache()
158157
}
159158

160159
logicalDrives = [.. drives];
161-
160+
162161
List<FileSystemItem> items = [];
163162
AddSpecialDir(items, Environment.SpecialFolder.Desktop, $"{MaterialIcons.DesktopWindows}");
164-
AddSpecialDir(items, GetDownloadsFolderPath, $"{MaterialIcons.DesktopWindows}");
165-
AddSpecialDir(items, Environment.SpecialFolder.MyDocuments, $"{MaterialIcons.DesktopWindows}");
166-
AddSpecialDir(items, Environment.SpecialFolder.MyMusic, $"{MaterialIcons.DesktopWindows}");
167-
AddSpecialDir(items, Environment.SpecialFolder.MyPictures, $"{MaterialIcons.DesktopWindows}");
168-
AddSpecialDir(items, Environment.SpecialFolder.MyVideos, $"{MaterialIcons.DesktopWindows}");
163+
AddSpecialDir(items, GetDownloadsFolderPath, $"{MaterialIcons.Download}");
164+
AddSpecialDir(items, Environment.SpecialFolder.MyDocuments, $"{MaterialIcons.Description}");
165+
AddSpecialDir(items, Environment.SpecialFolder.MyMusic, $"{MaterialIcons.LibraryMusic}");
166+
AddSpecialDir(items, Environment.SpecialFolder.MyPictures, $"{MaterialIcons.Image}");
167+
AddSpecialDir(items, Environment.SpecialFolder.MyVideos, $"{MaterialIcons.VideoLibrary}");
169168
specialDirs = [.. items];
170-
169+
171170
cache.Clear();
172171
}
173172

174173
private static void AddSpecialDir(List<FileSystemItem> items, Environment.SpecialFolder folder, string icon)
175174
{
176175
try
177176
{
178-
items.Add(new (Environment.GetFolderPath(folder), icon, FileSystemItemFlags.Folder));
177+
var path = Environment.GetFolderPath(folder);
178+
if (!string.IsNullOrWhiteSpace(path))
179+
{
180+
items.Add(new(path, icon, FileSystemItemFlags.Folder));
181+
}
179182
}
180183
catch (Exception)
181184
{
182185
}
183186
}
184-
187+
185188
private static void AddSpecialDir(List<FileSystemItem> items, Func<string> getPath, string icon)
186189
{
187190
try
188191
{
189-
items.Add(new (getPath(), icon, FileSystemItemFlags.Folder));
192+
var path = getPath();
193+
if (!string.IsNullOrWhiteSpace(path))
194+
{
195+
items.Add(new(path, icon, FileSystemItemFlags.Folder));
196+
}
190197
}
191198
catch (Exception)
192199
{

Hexa.NET.ImGui.Widgets/Dialogs/FileUtilities.cs

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -726,35 +726,75 @@ private static FileMetadata GetFileMetadataOSX(string filePath)
726726
}
727727
}
728728

729-
private const int OSX_IFDIR = 0x4000; // Directory
730-
private const int OSX_IFREG = 0x8000; // Regular file
731-
private const int OSX_IfLNK = 0xA000; // Symbolic link (Unix)
732-
private const int OSX_IRUSR = 0x0100; // Owner read permission
733-
private const int OSX_IWUSR = 0x0080; // Owner write permission
734-
private const int OSX_IXUSR = 0x0040; // Owner execute permission
729+
public const int OSX_S_IFMT = 0xF000; // type of file
730+
public const int OSX_S_IFIFO = 0x1000; // named pipe (fifo)
731+
public const int OSX_S_IFCHR = 0x2000; // character special
732+
public const int OSX_S_IFDIR = 0x4000; // directory
733+
public const int OSX_S_IFBLK = 0x6000; // block special
734+
public const int OSX_S_IFREG = 0x8000; // regular file
735+
public const int OSX_S_IFLNK = 0xA000; // symbolic link
736+
public const int OSX_S_IFSOCK = 0xC000; // socket
737+
public const int OSX_S_IFWHT = 0xE000; // whiteout
738+
739+
public const int OSX_S_ISUID = 0x0800; // set user ID on execution
740+
public const int OSX_S_ISGID = 0x0400; // set group ID on execution
741+
public const int OSX_S_ISVTX = 0x0200; // save swapped text even after use
742+
743+
public const int OSX_S_IRUSR = 0x0100; // read permission, owner
744+
public const int OSX_S_IWUSR = 0x0080; // write permission, owner
745+
public const int OSX_S_IXUSR = 0x0040; // execute/search permission, owner
746+
747+
public static bool OSXIsBlockSpecial(int mode) => (mode & OSX_S_IFMT) == OSX_S_IFBLK;
748+
749+
public static bool OSXIsCharSpecial(int mode) => (mode & OSX_S_IFMT) == OSX_S_IFCHR;
750+
751+
public static bool OSXIsDirectory(int mode) => (mode & OSX_S_IFMT) == S_IFDIR;
752+
753+
public static bool OSXIsFifo(int mode) => (mode & OSX_S_IFMT) == OSX_S_IFIFO;
754+
755+
public static bool OSXIsRegularFile(int mode) => (mode & OSX_S_IFMT) == S_IFREG;
756+
757+
public static bool OSXIsSymbolicLink(int mode) => (mode & OSX_S_IFMT) == S_IFLNK;
758+
759+
public static bool OSXIsSocket(int mode) => (mode & OSX_S_IFMT) == OSX_S_IFSOCK;
760+
761+
public static bool OSXIsWhiteout(int mode) => (mode & OSX_S_IFMT) == OSX_S_IFWHT;
762+
763+
// Helper methods to check permissions
764+
public static bool OSXIsSetUserID(int mode) => (mode & OSX_S_ISUID) != 0;
765+
766+
public static bool OSXIsSetGroupID(int mode) => (mode & OSX_S_ISGID) != 0;
767+
768+
public static bool OSXIsStickyBitSet(int mode) => (mode & OSX_S_ISVTX) != 0;
769+
770+
public static bool OSXCanRead(int mode) => (mode & S_IRUSR) != 0;
771+
772+
public static bool OSXCanWrite(int mode) => (mode & S_IWUSR) != 0;
773+
774+
public static bool OSXCanExecute(int mode) => (mode & S_IXUSR) != 0;
735775

736776
public static FileAttributes OSXConvertStatModeToAttributes(int st_mode, ReadOnlySpan<char> fileName)
737777
{
738778
FileAttributes attributes = FileAttributes.None;
739779

740780
// File type determination
741-
if ((st_mode & OSX_IFDIR) == OSX_IFDIR)
781+
if (OSXIsDirectory(st_mode))
742782
{
743783
attributes |= FileAttributes.Directory;
744784
}
745-
else if ((st_mode & OSX_IFREG) == OSX_IFREG)
785+
else if (OSXIsRegularFile(st_mode))
746786
{
747-
attributes |= FileAttributes.Normal;
787+
attributes |= FileAttributes.Normal; // Used for symbolic links
748788
}
749-
else if ((st_mode & OSX_IfLNK) == OSX_IfLNK)
789+
else if (OSXIsSymbolicLink(st_mode))
750790
{
751-
attributes |= FileAttributes.ReparsePoint; // Symbolic links in Unix can be mapped to ReparsePoint in Windows
791+
attributes |= FileAttributes.ReparsePoint; // Used for symbolic links
752792
}
753793

754794
// Permission handling - If no write permission for the owner, mark as ReadOnly
755-
if ((st_mode & OSX_IRUSR) == 0)
795+
if ((st_mode & OSX_S_IRUSR) == 0)
756796
{
757-
attributes |= FileAttributes.ReadOnly;
797+
attributes |= FileAttributes.ReadOnly; // If the owner has no read permission, mark it as read-only
758798
}
759799

760800
// Hidden file detection (Unix files that start with '.' are treated as hidden)
@@ -763,16 +803,18 @@ public static FileAttributes OSXConvertStatModeToAttributes(int st_mode, ReadOnl
763803
attributes |= FileAttributes.Hidden;
764804
}
765805

766-
// Add other attributes as necessary, but keep in mind Unix-like systems may not have equivalents for:
767-
// - FileAttributes.Compressed
768-
// - FileAttributes.Encrypted
769-
// - FileAttributes.Offline
770-
// - FileAttributes.NotContentIndexed
771-
772806
return attributes;
773807
}
774808

809+
public const int OSX_DT_UNKNOWN = 0;
810+
public const int OSX_DT_FIFO = 1;
811+
public const int OSX_DT_CHR = 2;
775812
public const int OSX_DT_DIR = 4;
813+
public const int OSX_DT_BLK = 6;
814+
public const int OSX_DT_REG = 8;
815+
public const int OSX_DT_LNK = 10;
816+
public const int OSX_DT_SOCK = 12;
817+
public const int OSX_DT_WHT = 14;
776818

777819
public const int DARWIN_MAXPATHLEN = 1024;
778820

@@ -799,7 +841,7 @@ public bool ShouldIgnore(string pattern, out bool result)
799841
result = !FileSystemSearcher.IsMatch(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(p), pattern, StringComparison.CurrentCulture);
800842
}
801843

802-
if (d_type == DT_DIR)
844+
if (d_type == OSX_DT_DIR)
803845
{
804846
return false;
805847
}

0 commit comments

Comments
 (0)