From 4d8a0df31227fb3558b6976e63a29e22e78163cb Mon Sep 17 00:00:00 2001
From: MatthiasWM <visualc.git@matthiasm.com>
Date: Sat, 21 Dec 2024 12:14:31 -0600
Subject: [PATCH] FLUID: Improve path handling on Windows.

---
 fluid/fluid.cxx                               |  8 ++++
 .../WinAPI/Fl_WinAPI_System_Driver.cxx        | 38 +++++++++++++++++--
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index 9f20843f7..75bddd39e 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -1981,6 +1981,14 @@ void update_history(const char *flname) {
   if (max_files > 10) max_files = 10;
 
   fl_filename_absolute(absolute, sizeof(absolute), flname);
+#ifdef _WIN32
+  // Make path canonical.
+  for (char *s = absolute; *s; s++) {
+    if (*s == '\\')
+      *s = '/';
+  }
+#endif
+
 
   for (i = 0; i < max_files; i ++)
 #if defined(_WIN32) || defined(__APPLE__)
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
index 1985d23e0..2e3a35cb0 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
@@ -568,7 +568,7 @@ int Fl_WinAPI_System_Driver::filename_expand(char *to, int tolen, const char *fr
     switch (*a) {
       case '~': // a home directory name
         if (e <= a+1) { // current user's directory
-          value = getenv("HOME");
+          value = home_directory_name();
         }
         break;
       case '$':         /* an environment variable */
@@ -987,9 +987,39 @@ int Fl_WinAPI_System_Driver::file_type(const char *filename)
 
 const char *Fl_WinAPI_System_Driver::home_directory_name()
 {
-  const char *h = getenv("HOME");
-  if (!h) h = getenv("UserProfile");
-  return h;
+  static char *home = NULL;
+  if (home)
+    return home;
+  // Various ways to retrieve the HOME path.
+  if (!home) {
+    const char *home_drive = getenv("HOMEDRIVE");
+    const char *home_path = getenv("HOMEPATH");
+    if (home_path && home_drive) {
+      int n = strlen(home_drive) + strlen(home_path) + 2;
+      home = (char *)::malloc(n);
+      ::strncpy(home, home_drive, n);
+      ::strncat(home, home_path, n);
+    }
+  }
+  if (!home) {
+    const char *h = getenv("UserProfile");
+    if (h) 
+      home = ::strdup(h);
+  }
+  if (!home) {
+    const char *h = getenv("HOME");
+    if (h)
+      home = ::strdup(h);
+  }
+  if (!home) {
+    home = ::strdup("~/"); // last resort
+  }
+  // Make path canonical.
+  for (char *s = home; *s; s++) {
+    if (*s == '\\')
+      *s = '/';
+  }
+  return home;
 }
 
 void Fl_WinAPI_System_Driver::gettime(time_t *sec, int *usec) {
-- 
GitLab