summaryrefslogtreecommitdiff
path: root/indra/llfilesystem/lldir_mac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llfilesystem/lldir_mac.cpp')
-rw-r--r--indra/llfilesystem/lldir_mac.cpp96
1 files changed, 95 insertions, 1 deletions
diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp
index f6181d7be4..44ef2feefe 100644
--- a/indra/llfilesystem/lldir_mac.cpp
+++ b/indra/llfilesystem/lldir_mac.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -137,6 +137,100 @@ LLDir_Mac::LLDir_Mac()
// mOSUserAppDir
mOSUserAppDir = mOSUserDir;
+ // mExecutableDir == .../MyApp.app/Contents/MacOS
+ std::string bundle_root; // .../MyApp.app
+ if (!mExecutableDir.empty())
+ {
+ std::string contents_dir = getDirName(mExecutableDir); // .../MyApp.app/Contents
+ if (!contents_dir.empty())
+ {
+ bundle_root = getDirName(contents_dir); // .../MyApp.app
+ }
+ }
+ std::string install_root = bundle_root.empty() ? std::string() : getDirName(bundle_root);
+ bool is_applications_install = (install_root.rfind("/Applications", 0) == 0);
+ bool is_dmg = (mExecutablePathAndName.rfind("/Volumes/", 0) == 0);
+ bool is_translocated = (mExecutablePathAndName.find("/AppTranslocation/") != std::string::npos);
+
+#if LL_VELOPACK
+ // Detect a portable (Velopack) install: the executable lives at
+ // ".../MyApp.app/Contents/MacOS/<exe>". If the portable package
+ // dropped a ".portable" marker next to "MyApp.app" (i.e. one level
+ // above the bundle itself), keep user data (settings, logs, etc.)
+ // beside the bundle instead of ~/Library/Application Support. This
+ // only applies to Velopack-portable builds; a DMG/NSIS-style
+ // install never produces this marker, so a normally-installed
+ // viewer is unaffected.if (!is_dmg && !is_translocated && !is_applications_install && !install_root.empty())
+
+ // macos doesn't have the .portable marker , but check it just in case.
+ // Todo: fix this, portable installs should have a marker file.
+ bool is_portable = isPortableInstall(install_root);
+
+ if (is_portable)
+ {
+ std::string portable_dir;
+ if (CreateDirectory(install_root, PORTABLE_USER_DATA_DIRNAME, &portable_dir))
+ {
+ mOSUserAppDir = portable_dir;
+
+ // Replicate the sub-dirs already created above under the
+ // default mOSUserDir, but under the portable folder instead.
+ CreateDirectory(portable_dir, std::string("data"), NULL);
+ CreateDirectory(portable_dir, std::string("logs"), NULL);
+ CreateDirectory(portable_dir, std::string("user_settings"), NULL);
+ CreateDirectory(portable_dir, std::string("browser_profile"), NULL);
+ }
+ }
+#endif // LL_VELOPACK
+
+ if (is_dmg)
+ {
+ // Running directly off a still-mounted DMG; the user never
+ // dragged the app out to install it.
+ mRunContextDescription = "Mounted disk image (DMG)";
+ }
+ else if (is_translocated)
+ {
+ // Gatekeeper's App Translocation makes an unregistered, quarantined
+ // app (e.g. one simply unzipped in Downloads/ and double-clicked
+ // without ever being moved) appear to run from a randomized
+ // read-only path under
+ // "/private/var/folders/.../AppTranslocation/.../d/MyApp.app",
+ // even though the on-disk bundle still lives wherever it was
+ // extracted.
+ mRunContextDescription = "App Translocation (unregistered/quarantined copy)";
+ }
+ else if (is_applications_install)
+ {
+ // Bundle lives directly under /Applications: a normal, properly
+ // installed copy.
+ mRunContextDescription = "Standard install (/Applications)";
+ }
+#if LL_VELOPACK
+ else if (is_portable)
+ {
+ mRunContextDescription = "Portable (extracted archive, " + install_root + ")";
+ }
+#endif // LL_VELOPACK
+ else if (!is_dmg && !is_translocated && !is_applications_install && !install_root.empty())
+ {
+ mRunContextDescription = "Running from a non-standard folder (" + install_root + ")";
+ }
+ else if (!install_root.empty())
+ {
+ // Bundle is present on local disk, intact, and not translocated
+ // or mounted from a DMG, but it is NOT under /Applications. This
+ // is the classic "downloaded a zip/tar, extracted it somewhere,
+ // and ran the .app directly from that folder" case - i.e. what
+ // users may call a "portable" install even though no formal
+ // portable packaging was used.
+ mRunContextDescription = "Running from extracted archive or non-standard folder (" + install_root + ")";
+ }
+ else
+ {
+ mRunContextDescription = "Unknown install location";
+ }
+
// mTempDir
//Aura 120920 std::filesystem::temp_directory_path() not yet implemented on mac. :(
std::string tmpdir = getSystemTempFolder();