celenity/Phoenix
7
198
Fork
You've already forked Phoenix
18

[ENHANCEMENT] Ship a unified file with OS specific checks #231

Closed
opened 2026年01月26日 18:52:15 +01:00 by any1here · 23 comments
Contributor
Copy link

Confirmation Checklist

Please explain your proposal with as many details as necessary (Ex. what you're suggesting, why you're suggesting it, what need you thinks it will fill, who it will benefit, etc...).

It should be possible to differentiate between the different supported platforms by reading the environment value using getenv.

OS can be used for Windows and OSTYPE for macOS/Linux.
Not sure about Android.

### Confirmation Checklist - [x] I confirm that this feature is not already present on the **latest release** of Phoenix. You can check what the latest version is on [the `Releases` page](https://codeberg.org/celenity/Phoenix/releases). - [x] I confirm that this feature has **NOT** already been suggested on [the Codeberg issue tracker](https://codeberg.org/celenity/Phoenix/issues), [the GitLab issue tracker](https://gitlab.com/celenityy/Phoenix/-/issues), **and/or** [the GitHub issue tracker](https://github.com/celenityy/Phoenix/issues). ### Please explain your proposal with as many details as necessary (Ex. what you're suggesting, why you're suggesting it, what need you thinks it will fill, who it will benefit, etc...). It should be possible to differentiate between the different supported platforms by reading the environment value using `getenv`. `OS` can be used for Windows and `OSTYPE` for macOS/Linux. Not sure about Android.

Agreed - we need to do this.

OS can be used for Windows and OSTYPE for macOS/Linux.
Not sure about Android.

Perhaps we can use MOZ_ANDROID_PACKAGE_NAME? This variable is only set on Android (ex. I'm using it to set IronFox's release channel here), so I think it may be a good option.

Agreed - we need to do this. > `OS` can be used for Windows and `OSTYPE` for macOS/Linux. Not sure about Android. Perhaps we can use `MOZ_ANDROID_PACKAGE_NAME`? This variable is only set on Android *(ex. I'm using it to set IronFox's release channel [here](https://gitlab.com/ironfox-oss/IronFox/-/blob/90a9fef56137f50194cb2536d312204a14697d15/patches/build/gecko/ironfox.cfg#L44))*, so I think it may be a good option.

I did some testing, and I'm not having any luck using OS or OSTYPE. For now, this is what I've come up with:

// Determine our operating system
// If MOZ_ANDROID_PACKAGE_NAME is defined, we know we're on Android
if (getenv("MOZ_ANDROID_PACKAGE_NAME" != "")) {
 PHOENIX_OS = 'android'
};
// For other platforms, we can check the geolocation provider prefs
try {
 if (getPref("geo.provider.ms-windows-location") == true || getPref("geo.provider.ms-windows-location") == false) {
 PHOENIX_OS = 'windows'
 } else if (getPref("geo.provider.use_geoclue") == true || getPref("geo.provider.use_geoclue") == false) {
 PHOENIX_OS = 'linux'
 } else if (getPref("geo.provider.use_corelocation") == true || getPref("geo.provider.use_corelocation") == false) {
 PHOENIX_OS = 'osx'
 }
} catch (e) {
 PHOENIX_OS = 'unknown'
};
lockPref("browser.phoenix.OS", `${PHOENIX_OS}`);

(I chose the geo provider prefs specifically here because they're usually only defined on their respective platforms).

This approach appears to work, but I don't think it's perfectly ideal - will be interested to hear your thoughts/ideas/suggestions.

I did some testing, and I'm not having any luck using `OS` or `OSTYPE`. For now, this is what I've come up with: ```sh // Determine our operating system // If MOZ_ANDROID_PACKAGE_NAME is defined, we know we're on Android if (getenv("MOZ_ANDROID_PACKAGE_NAME" != "")) { PHOENIX_OS = 'android' }; // For other platforms, we can check the geolocation provider prefs try { if (getPref("geo.provider.ms-windows-location") == true || getPref("geo.provider.ms-windows-location") == false) { PHOENIX_OS = 'windows' } else if (getPref("geo.provider.use_geoclue") == true || getPref("geo.provider.use_geoclue") == false) { PHOENIX_OS = 'linux' } else if (getPref("geo.provider.use_corelocation") == true || getPref("geo.provider.use_corelocation") == false) { PHOENIX_OS = 'osx' } } catch (e) { PHOENIX_OS = 'unknown' }; lockPref("browser.phoenix.OS", `${PHOENIX_OS}`); ``` *(I chose the geo provider prefs specifically here because they're usually only defined on their respective platforms)*. This approach appears to work, but I don't think it's perfectly ideal - will be interested to hear your thoughts/ideas/suggestions.
Author
Contributor
Copy link

Yeah, it seems OS or OSTYPE is not available from Firefox, my bad.

A list of ways to detect platforms:

  • getenv("USERPROFILE") is set on Windows.
  • getenv("HOME") is set on macOS and Linux.
  • widget.support-xdg-config is locked true on Linux.

I use those here

if (getenv("USERPROFILE")) {
 // Windows
} else if (getenv("HOME")) {
 if (getPref("widget.support-xdg-config")) {
 // Linux
 } else if (getPref("network.dns.native_https_timeout_mac_msec")) {
 // macOS
 }
} else {
 // Other
}
Yeah, it seems OS or OSTYPE is not available from Firefox, my bad. A list of ways to detect platforms: - getenv("USERPROFILE") is set on Windows. - getenv("HOME") is set on macOS and Linux. - widget.support-xdg-config is locked true on Linux. I use those [here](https://codeberg.org/librewolf/settings/src/commit/8ab7156e595fd13f5a1990809ff5412fa4ddf6f2/librewolf.cfg#L690) ``` if (getenv("USERPROFILE")) { // Windows } else if (getenv("HOME")) { if (getPref("widget.support-xdg-config")) { // Linux } else if (getPref("network.dns.native_https_timeout_mac_msec")) { // macOS } } else { // Other } ```

@any1here Interesting. After some more work and testing on this, here's what I was able to come up with:

// Determine our operating system
defaultPref("browser.phoenix.OS", "unknown");
defaultPref("browser.phoenix.OS.current", "unknown");
defaultPref("browser.phoenix.osSet", false);
try {
 // If MOZ_ANDROID_PACKAGE_NAME is defined, we know we're on Android
 if (getenv("MOZ_ANDROID_PACKAGE_NAME")) {
 PHOENIX_OS = 'android'
 // If USERPROFILE is defined, we know we're on Windows
 } else if (getenv("USERPROFILE")) {
 PHOENIX_OS = 'windows'
 // Otherwise, check prefs
 // I don't love checking prefs for this, but I don't see a better way to handle it
 } else if (getPref("browser.low_commit_space_threshold_percent")) {
 PHOENIX_OS = 'linux'
 } else if (getPref("network.dns.native_https_timeout_mac_msec")) {
 PHOENIX_OS = 'osx'
 } else {
 // If we're still not sure at this point, fall-back to geo provider prefs
 // These are usually only defined on their respective platforms by default, but they are defined everywhere by some common user.js files (ex. Arkenfox), some forks (LibreWolf), and elsewhere, so we should only use them as a last resort
 if (getPref("geo.provider.use_geoclue") == true || getPref("geo.provider.use_geoclue") == false) {
 PHOENIX_OS='linux'
 } else if (getPref("geo.provider.use_corelocation") == true || getPref("geo.provider.use_corelocation") == false) {
 PHOENIX_OS='osx'
 } else {
 PHOENIX_OS = 'unknown'
 }
 }
} catch (e) {
 PHOENIX_OS = 'unknown'
};
pref("browser.phoenix.OS.current", `${PHOENIX_OS}`);
phoenixOsPrefCurrentValue = getPref("browser.phoenix.OS.current");
if (getPref("browser.phoenix.osSet") == false || getPref("browser.phoenix.OS") == "unknown") {
 pref("browser.phoenix.OS", `${phoenixOsPrefCurrentValue}`);
 pref("browser.phoenix.osSet", true); 
};

I decided to use browser.low_commit_space_threshold_percent instead of widget.support-xdg-config for Linux, as widget.support-xdg-config only appears to be defined for browser (Firefox Desktop), which would cause issues for ex. Thunderbird/Dove (and maybe other projects?), while browser.low_commit_space_threshold_percent is a static pref always set everywhere.

So, essentially, the way this works is:

  • If the MOZ_ANDROID_PACKAGE_NAME env variable is defined, we set PHOENIX_OS to android.
  • If the USERPROFILE env variable is defined, we set PHOENIX_OS to windows.
  • If the browser.low_commit_space_threshold_percent pref is defined (or geo.provider.use_geoclue as a fall-back), we set PHOENIX_OS to linux.
  • If the network.dns.native_https_timeout_mac_msec pref is defined (or geo.provider.use_corelocation as a fall-back), we set PHOENIX_OS to osx.
  • Otherwise, we set PHOENIX_OS to unknown.
  • We set the browser.phoenix.OS.current pref to the value of PHOENIX_OS.
  • If the browser.phoenix.osSet pref is set to false (which it is by default) or the browser.phoenix.OSpref is set to unknown, we set the browser.phoenix.OS pref to the value of browser.phoenix.OS.current, and we set the browser.phoenix.osSet pref to true (The check for browser.phoenix.OS is added here so that if something went wrong and the OS hasn't been identified, it'll still try to set the OS on every launch).
  • If the browser.phoenix.osSet pref is set to true (which it will be at this point/after the first run), we still update the value of browser.phoenix.OS.current, but we don't touch browser.phoenix.OS - so this ensures that if something goes wrong and the prefs/env variables we're using to set the OS stop working for whatever reason, we still have the OS set from before. If a user does need to force the OS to be set again for whatever reason, they can reset the browser.phoenix.osSet pref, and restart the browser.

So, with this implementation, we'll be able to use the value of browser.phoenix.OS to check the current OS, and we can apply OS-specific prefs from there.

@any1here Will be curious to hear your thoughts on this.


I think the only potential problems for this ATM are:

  • To support vanilla Firefox for Android, we'll unfortunately still need to keep a separate prefs file for Android. I bet we can modify the convert.py script to convert the prefs from the new unified cfg file to the Android .js file (IronFox will be able to use the new unified .cfg file directly though).
  • For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory.
    • We do still use a .cfg file for Linux though (which we apply manually to the common installation directories), but only for user prefs (as user prefs can't be set via prefs .js files ATM).
    • So, while I would really like to move Linux to using the .cfg file for all configuration (like Phoenix does on macOS and Windows), we'll need to do some research/testing and ensure the .cfg file is always being applied properly. Maybe we could use some kind of script to always copy the .cfg file at boot? IDK
@any1here Interesting. After some more work and testing on this, here's what I was able to come up with: ```sh // Determine our operating system defaultPref("browser.phoenix.OS", "unknown"); defaultPref("browser.phoenix.OS.current", "unknown"); defaultPref("browser.phoenix.osSet", false); try { // If MOZ_ANDROID_PACKAGE_NAME is defined, we know we're on Android if (getenv("MOZ_ANDROID_PACKAGE_NAME")) { PHOENIX_OS = 'android' // If USERPROFILE is defined, we know we're on Windows } else if (getenv("USERPROFILE")) { PHOENIX_OS = 'windows' // Otherwise, check prefs // I don't love checking prefs for this, but I don't see a better way to handle it } else if (getPref("browser.low_commit_space_threshold_percent")) { PHOENIX_OS = 'linux' } else if (getPref("network.dns.native_https_timeout_mac_msec")) { PHOENIX_OS = 'osx' } else { // If we're still not sure at this point, fall-back to geo provider prefs // These are usually only defined on their respective platforms by default, but they are defined everywhere by some common user.js files (ex. Arkenfox), some forks (LibreWolf), and elsewhere, so we should only use them as a last resort if (getPref("geo.provider.use_geoclue") == true || getPref("geo.provider.use_geoclue") == false) { PHOENIX_OS='linux' } else if (getPref("geo.provider.use_corelocation") == true || getPref("geo.provider.use_corelocation") == false) { PHOENIX_OS='osx' } else { PHOENIX_OS = 'unknown' } } } catch (e) { PHOENIX_OS = 'unknown' }; pref("browser.phoenix.OS.current", `${PHOENIX_OS}`); phoenixOsPrefCurrentValue = getPref("browser.phoenix.OS.current"); if (getPref("browser.phoenix.osSet") == false || getPref("browser.phoenix.OS") == "unknown") { pref("browser.phoenix.OS", `${phoenixOsPrefCurrentValue}`); pref("browser.phoenix.osSet", true); }; ``` I decided to use `browser.low_commit_space_threshold_percent` instead of `widget.support-xdg-config` for Linux, as `widget.support-xdg-config` only appears to be defined for `browser` *(Firefox Desktop)*, which would cause issues for ex. Thunderbird/Dove *(and maybe other projects?)*, while `browser.low_commit_space_threshold_percent` is a static pref always set everywhere. So, essentially, the way this works is: - If the `MOZ_ANDROID_PACKAGE_NAME` env variable is defined, we set `PHOENIX_OS` to `android`. - If the `USERPROFILE` env variable is defined, we set `PHOENIX_OS` to `windows`. - If the `browser.low_commit_space_threshold_percent` pref is defined *(or `geo.provider.use_geoclue` as a fall-back)*, we set `PHOENIX_OS` to `linux`. - If the `network.dns.native_https_timeout_mac_msec` pref is defined *(or `geo.provider.use_corelocation` as a fall-back)*, we set `PHOENIX_OS` to `osx`. - Otherwise, we set `PHOENIX_OS` to `unknown`. - We set the `browser.phoenix.OS.current` pref to the value of `PHOENIX_OS`. - If the `browser.phoenix.osSet` pref is set to `false` *(which it is by default)* or the `browser.phoenix.OS`pref is set to `unknown`, we set the `browser.phoenix.OS` pref to the value of `browser.phoenix.OS.current`, and we set the `browser.phoenix.osSet` pref to `true` *(The check for `browser.phoenix.OS` is added here so that if something went wrong and the OS hasn't been identified, it'll still try to set the OS on every launch)*. - If the `browser.phoenix.osSet` pref is set to `true` *(which it will be at this point/after the first run)*, we still update the value of `browser.phoenix.OS.current`, but we don't touch `browser.phoenix.OS` - so this ensures that if something goes wrong and the prefs/env variables we're using to set the OS stop working for whatever reason, we still have the OS set from before. If a user does need to force the OS to be set again for whatever reason, they can reset the `browser.phoenix.osSet` pref, and restart the browser. So, with this implementation, we'll be able to use the value of `browser.phoenix.OS` to check the current OS, and we can apply OS-specific prefs from there. @any1here Will be curious to hear your thoughts on this. ___ I think the only potential problems for this ATM are: - [To support vanilla Firefox for Android](https://codeberg.org/celenity/Phoenix/src/branch/dev/android), we'll unfortunately still need to keep a separate prefs file for Android. I bet we can modify [the `convert.py` script](https://codeberg.org/celenity/Phoenix/src/branch/dev/build/convert.py) to convert the prefs from the new unified `cfg` file to the Android `.js` file *(IronFox will be able to use the new unified `.cfg` file directly though)*. - For Linux, Phoenix currently sets its prefs via a `.js` file. The reason we do this is because we can apply it to a system directory *(`/etc/firefox`)*, which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a `.cfg` file like this; on desktop Linux, Firefox will only read it from the installation directory. - We do still use a `.cfg` file for Linux though *(which we apply manually to the common installation directories)*, but only for `user` prefs *(as `user` prefs can't be set via prefs `.js` files ATM)*. - So, while I would really like to move Linux to using the `.cfg` file for all configuration *(like Phoenix does on macOS and Windows)*, we'll need to do some research/testing and ensure the `.cfg` file is always being applied properly. Maybe we could use some kind of script to always copy the `.cfg` file at boot? IDK

how would be potential further same-os config granularity handled, e.g. INTEL-OSX || SILICON-OSX, LINUX || LINUX-FLATPAK ?

how would be potential further same-os config granularity handled, e.g. `INTEL-OSX || SILICON-OSX`, `LINUX || LINUX-FLATPAK` ?
Author
Contributor
Copy link

I would maybe add something like font.name-list.emoji to the else fall-back case for each check, so there are multiple prefs that should be unique for the given OS and reduce the likelihood of setting the wrong OS.

@celenity wrote in #231 (comment):

  • To support vanilla Firefox for Android, we'll unfortunately still need to keep a separate prefs file for Android. I bet we can modify the convert.py script to convert the prefs from the new unified cfg file to the Android .js file (IronFox will be able to use the new unified .cfg file directly though).

I had no idea this was even a thing.

@celenity wrote in #231 (comment):

  • For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory.

Is there a reason it behaves differently on Linux Desktop only? Do you know if there is a bugzilla issue regarding this?

I would maybe add something like `font.name-list.emoji` to the else fall-back case for each check, so there are multiple prefs that should be unique for the given OS and reduce the likelihood of setting the wrong OS. @celenity wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-10627763: > * [To support vanilla Firefox for Android](https://codeberg.org/celenity/Phoenix/src/branch/dev/android), we'll unfortunately still need to keep a separate prefs file for Android. I bet we can modify [the `convert.py` script](https://codeberg.org/celenity/Phoenix/src/branch/dev/build/convert.py) to convert the prefs from the new unified `cfg` file to the Android `.js` file _(IronFox will be able to use the new unified `.cfg` file directly though)_. I had no idea this was even a thing. @celenity wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-10627763: > * For Linux, Phoenix currently sets its prefs via a `.js` file. The reason we do this is because we can apply it to a system directory _(`/etc/firefox`)_, which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a `.cfg` file like this; on desktop Linux, Firefox will only read it from the installation directory. Is there a reason it behaves differently on Linux Desktop only? Do you know if there is a bugzilla issue regarding this?

@any1here wrote in #231 (comment):

I would maybe add something like font.name-list.emoji to the else fall-back case for each check, so there are multiple prefs that should be unique for the given OS and reduce the likelihood of setting the wrong OS.

Good idea!

@celenity wrote in #231 (comment):

I had no idea this was even a thing.

Yeah, it's not very practical to install/update and use (since it requires debugging), but I know some people do use it.

@celenity wrote in #231 (comment):

  • For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory.

Is there a reason it behaves differently on Linux Desktop only? Do you know if there is a bugzilla issue regarding this?

I actually filed a bug for this here - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet.

@any1here wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-10668404: > I would maybe add something like `font.name-list.emoji` to the else fall-back case for each check, so there are multiple prefs that should be unique for the given OS and reduce the likelihood of setting the wrong OS. Good idea! > > @celenity wrote in #231 (comment): > > > * [To support vanilla Firefox for Android](https://codeberg.org/celenity/Phoenix/src/branch/dev/android)... > > I had no idea this was even a thing. Yeah, it's not very practical to install/update and use *(since it requires debugging)*, but I know some people do use it. > > @celenity wrote in #231 (comment): > > > * For Linux, Phoenix currently sets its prefs via a `.js` file. The reason we do this is because we can apply it to a system directory _(`/etc/firefox`)_, which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a `.cfg` file like this; on desktop Linux, Firefox will only read it from the installation directory. > > Is there a reason it behaves differently on Linux Desktop only? Do you know if there is a bugzilla issue regarding this? I actually filed a bug for this [here](https://bugzilla.mozilla.org/show_bug.cgi?id=1965449) - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet.

I did some research/testing, and I was actually able to find some macOS and Linux-specific env variables we can leverage - as well as some additional ones for Android and Windows. Here's what I have now:

// Determine our operating system
defaultPref("browser.phoenix.OS", "unknown");
defaultPref("browser.phoenix.OS.current", "unknown");
defaultPref("browser.phoenix.osSet", false);
try {
 // If any of the following env variables are defined, we know we're on Android:
 // (For general ANDROID_ vars, see ex.: https://android.googlesource.com/platform/system/core/+/refs/heads/main/rootdir/init.environ.rc.in)
 // ANDROID_ART_ROOT
 // ANDROID_ASSETS
 // ANDROID_BOOTLOGO
 // ANDROID_DATA
 // ANDROID_I18N_ROOT
 // ANDROID_ROOT
 // ANDROID_STORAGE
 // ANDROID_TZDATA_ROOT
 // MOZ_ANDROID_CPU_ABI
 // MOZ_ANDROID_CRASH_HANDLER
 // MOZ_ANDROID_LIBDIR
 // MOZ_ANDROID_LIBDIR_OVERRIDE
 // MOZ_ANDROID_PACKAGE_NAME
 // MOZ_ANDROID_USER_SERIAL_NUMBER
 if (getenv("ANDROID_ART_ROOT") || getenv("ANDROID_ASSETS") || getenv("ANDROID_BOOTLOGO") || getenv("ANDROID_DATA") || getenv("ANDROID_I18N_ROOT") || getenv("ANDROID_ROOT") || getenv("ANDROID_STORAGE") || getenv("ANDROID_TZDATA_ROOT") || getenv("MOZ_ANDROID_CPU_ABI") || getenv("MOZ_ANDROID_CRASH_HANDLER") || getenv("MOZ_ANDROID_LIBDIR") || getenv("MOZ_ANDROID_LIBDIR_OVERRIDE") || getenv("MOZ_ANDROID_PACKAGE_NAME") || getenv("MOZ_ANDROID_USER_SERIAL_NUMBER")) {
 PHOENIX_OS = 'android'
 // If any of the following env variables are defined, we know we're on Windows:
 // MOZ_ENABLE_WIN32K
 // USERPROFILE
 // XRE_NO_DLL_READAHEAD
 // XRE_NO_WINDOWS_CRASH_DIALOG
 } else if (getenv("MOZ_ENABLE_WIN32K") || getenv("USERPROFILE") || getenv("XRE_NO_DLL_READAHEAD") || getenv("XRE_NO_WINDOWS_CRASH_DIALOG")) {
 PHOENIX_OS = 'windows'
 // If any of the following env variables are defined, we know we're on Linux:
 // DESKTOP_SESSION
 // GDK_BACKEND
 // GDMSESSION
 // GNOME_DESKTOP_SESSION_ID
 // GTK_USE_PORTAL
 // KDE_FULL_SESSION
 // LXQT_SESSION_CONFIG
 // MATE_DESKTOP_SESSION_ID
 // MOZ_DISABLE_WAYLAND_PROXY
 // MOZ_ENABLE_WAYLAND
 // MOZ_GDK_DISPLAY
 // MOZ_USE_XINPUT2
 // MOZ_X_SYNC
 // MOZ_X11_EGL
 // SNAP
 // SNAP_DESKTOP_RUNTIME
 // SNAP_INSTANCE_NAME
 // SNAP_NAME
 // SNAP_REAL_HOME
 // SYSTEMD_EXEC_PID
 // WAYLAND_DISPLAY
 // WAYLAND_PROXY_LOG
 // XDG_ACTIVATION_TOKEN
 // XDG_CACHE_HOME
 // XDG_CONFIG_DIRS
 // XDG_CONFIG_HOME
 // XDG_CURRENT_DESKTOP
 // XDG_DATA_DIRS
 // XDG_DATA_HOME
 // XDG_MENU_PREFIX
 // XDG_RUNTIME_DIR
 // XDG_SESSION_CLASS
 // XDG_SESSION_DESKTOP
 // XDG_SESSION_TYPE
 } else if (getenv("DESKTOP_SESSION") || getenv("GDK_BACKEND") || getenv("GDMSESSION") || getenv("GNOME_DESKTOP_SESSION_ID") || getenv("GTK_USE_PORTAL") || getenv("KDE_FULL_SESSION") || getenv("LXQT_SESSION_CONFIG") || getenv("MATE_DESKTOP_SESSION_ID") || getenv("MOZ_DISABLE_WAYLAND_PROXY") || getenv("MOZ_ENABLE_WAYLAND") || getenv("MOZ_GDK_DISPLAY") || getenv("MOZ_USE_XINPUT2") || getenv("MOZ_X_SYNC") || getenv("MOZ_X11_EGL") || getenv("SNAP") || getenv("SNAP_DESKTOP_RUNTIME") || getenv("SNAP_INSTANCE_NAME") || getenv("SNAP_NAME") || getenv("SNAP_REAL_HOME") || getenv("SYSTEMD_EXEC_PID") || getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_PROXY_LOG") || getenv("XDG_ACTIVATION_TOKEN") || getenv("XDG_CACHE_HOME") || getenv("XDG_CONFIG_DIRS") || getenv("XDG_CONFIG_HOME") || getenv("XDG_CURRENT_DESKTOP") || getenv("XDG_DATA_DIRS") || getenv("XDG_DATA_HOME") || getenv("XDG_MENU_PREFIX") || getenv("XDG_RUNTIME_DIR") || getenv("XDG_SESSION_CLASS") || getenv("XDG_SESSION_DESKTOP") || getenv("XDG_SESSION_TYPE")) {
 PHOENIX_OS = 'linux'
 // If any of the following env variables are defined, we know we're on OS X:
 // __CFBundleIdentifier
 // MOZ_APP_NO_DOCK
 // MOZ_NO_GLOBAL_MOUSE_MONITOR
 // XPC_FLAGS
 // XPC_SERVICE_NAME
 } else if (getenv("__CFBundleIdentifier") || getenv("MOZ_APP_NO_DOCK") || getenv("MOZ_NO_GLOBAL_MOUSE_MONITOR") || getenv("XPC_FLAGS") || getenv("XPC_SERVICE_NAME")) {
 PHOENIX_OS = 'osx'
 // At this point, we should have our OS, but in case we don't for some reason, check prefs
 // In practice, these shouldn't be used
 } else if (getPref("apz.android.chrome_fling_physics.friction") || getPref("apz.android.chrome_fling_physics.inflexion") || getPref("apz.android.chrome_fling_physics.stop_threshold") || getPref("network.dns.native_https_timeout_android")) {
 PHOENIX_OS = 'android'
 } else if (getPref("browser.low_commit_space_threshold_percent") || getPref("media.ffmpeg.vaapi.force-surface-zero-copy") || getPref("widget.gtk.file-manager-show-items-timeout-ms")) {
 PHOENIX_OS = 'linux'
 } else if (getPref("network.dns.native_https_timeout_mac_msec") || getPref("widget.macos.shift-by-menubar-on-fullscreen") || getPref("widget.macos.automatic.text_substitution_fetch_length")) {
 PHOENIX_OS = 'osx'
 } else if (getPref("accessibility.windows.suppress-after-clipboard-copy") || getPref("accessibility.windows.suppress-for-snap-layout")) {
 PHOENIX_OS = 'windows'
 } else {
 PHOENIX_OS = 'unknown'
 }
} catch (e) {
 PHOENIX_OS = 'unknown'
};
pref("browser.phoenix.OS.current", `${PHOENIX_OS}`);
phoenixOsPrefCurrentValue = getPref("browser.phoenix.OS.current");
if (getPref("browser.phoenix.osSet") == false || getPref("browser.phoenix.OS") == "unknown") {
 pref("browser.phoenix.OS", `${phoenixOsPrefCurrentValue}`);
 pref("browser.phoenix.osSet", true); 
};

After some thought, I don't think we should use font.name-list.emoji, since that pref could be changed by users (IDK why anyone would edit it, and they shouldn't, but IG you never know - I'd rather avoid the pref checks being value dependent like this if possible).

Will be curious to hear your thoughts @any1here.

I did some research/testing, and I was actually able to find some macOS and Linux-specific env variables we can leverage - as well as some additional ones for Android and Windows. Here's what I have now: ```sh // Determine our operating system defaultPref("browser.phoenix.OS", "unknown"); defaultPref("browser.phoenix.OS.current", "unknown"); defaultPref("browser.phoenix.osSet", false); try { // If any of the following env variables are defined, we know we're on Android: // (For general ANDROID_ vars, see ex.: https://android.googlesource.com/platform/system/core/+/refs/heads/main/rootdir/init.environ.rc.in) // ANDROID_ART_ROOT // ANDROID_ASSETS // ANDROID_BOOTLOGO // ANDROID_DATA // ANDROID_I18N_ROOT // ANDROID_ROOT // ANDROID_STORAGE // ANDROID_TZDATA_ROOT // MOZ_ANDROID_CPU_ABI // MOZ_ANDROID_CRASH_HANDLER // MOZ_ANDROID_LIBDIR // MOZ_ANDROID_LIBDIR_OVERRIDE // MOZ_ANDROID_PACKAGE_NAME // MOZ_ANDROID_USER_SERIAL_NUMBER if (getenv("ANDROID_ART_ROOT") || getenv("ANDROID_ASSETS") || getenv("ANDROID_BOOTLOGO") || getenv("ANDROID_DATA") || getenv("ANDROID_I18N_ROOT") || getenv("ANDROID_ROOT") || getenv("ANDROID_STORAGE") || getenv("ANDROID_TZDATA_ROOT") || getenv("MOZ_ANDROID_CPU_ABI") || getenv("MOZ_ANDROID_CRASH_HANDLER") || getenv("MOZ_ANDROID_LIBDIR") || getenv("MOZ_ANDROID_LIBDIR_OVERRIDE") || getenv("MOZ_ANDROID_PACKAGE_NAME") || getenv("MOZ_ANDROID_USER_SERIAL_NUMBER")) { PHOENIX_OS = 'android' // If any of the following env variables are defined, we know we're on Windows: // MOZ_ENABLE_WIN32K // USERPROFILE // XRE_NO_DLL_READAHEAD // XRE_NO_WINDOWS_CRASH_DIALOG } else if (getenv("MOZ_ENABLE_WIN32K") || getenv("USERPROFILE") || getenv("XRE_NO_DLL_READAHEAD") || getenv("XRE_NO_WINDOWS_CRASH_DIALOG")) { PHOENIX_OS = 'windows' // If any of the following env variables are defined, we know we're on Linux: // DESKTOP_SESSION // GDK_BACKEND // GDMSESSION // GNOME_DESKTOP_SESSION_ID // GTK_USE_PORTAL // KDE_FULL_SESSION // LXQT_SESSION_CONFIG // MATE_DESKTOP_SESSION_ID // MOZ_DISABLE_WAYLAND_PROXY // MOZ_ENABLE_WAYLAND // MOZ_GDK_DISPLAY // MOZ_USE_XINPUT2 // MOZ_X_SYNC // MOZ_X11_EGL // SNAP // SNAP_DESKTOP_RUNTIME // SNAP_INSTANCE_NAME // SNAP_NAME // SNAP_REAL_HOME // SYSTEMD_EXEC_PID // WAYLAND_DISPLAY // WAYLAND_PROXY_LOG // XDG_ACTIVATION_TOKEN // XDG_CACHE_HOME // XDG_CONFIG_DIRS // XDG_CONFIG_HOME // XDG_CURRENT_DESKTOP // XDG_DATA_DIRS // XDG_DATA_HOME // XDG_MENU_PREFIX // XDG_RUNTIME_DIR // XDG_SESSION_CLASS // XDG_SESSION_DESKTOP // XDG_SESSION_TYPE } else if (getenv("DESKTOP_SESSION") || getenv("GDK_BACKEND") || getenv("GDMSESSION") || getenv("GNOME_DESKTOP_SESSION_ID") || getenv("GTK_USE_PORTAL") || getenv("KDE_FULL_SESSION") || getenv("LXQT_SESSION_CONFIG") || getenv("MATE_DESKTOP_SESSION_ID") || getenv("MOZ_DISABLE_WAYLAND_PROXY") || getenv("MOZ_ENABLE_WAYLAND") || getenv("MOZ_GDK_DISPLAY") || getenv("MOZ_USE_XINPUT2") || getenv("MOZ_X_SYNC") || getenv("MOZ_X11_EGL") || getenv("SNAP") || getenv("SNAP_DESKTOP_RUNTIME") || getenv("SNAP_INSTANCE_NAME") || getenv("SNAP_NAME") || getenv("SNAP_REAL_HOME") || getenv("SYSTEMD_EXEC_PID") || getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_PROXY_LOG") || getenv("XDG_ACTIVATION_TOKEN") || getenv("XDG_CACHE_HOME") || getenv("XDG_CONFIG_DIRS") || getenv("XDG_CONFIG_HOME") || getenv("XDG_CURRENT_DESKTOP") || getenv("XDG_DATA_DIRS") || getenv("XDG_DATA_HOME") || getenv("XDG_MENU_PREFIX") || getenv("XDG_RUNTIME_DIR") || getenv("XDG_SESSION_CLASS") || getenv("XDG_SESSION_DESKTOP") || getenv("XDG_SESSION_TYPE")) { PHOENIX_OS = 'linux' // If any of the following env variables are defined, we know we're on OS X: // __CFBundleIdentifier // MOZ_APP_NO_DOCK // MOZ_NO_GLOBAL_MOUSE_MONITOR // XPC_FLAGS // XPC_SERVICE_NAME } else if (getenv("__CFBundleIdentifier") || getenv("MOZ_APP_NO_DOCK") || getenv("MOZ_NO_GLOBAL_MOUSE_MONITOR") || getenv("XPC_FLAGS") || getenv("XPC_SERVICE_NAME")) { PHOENIX_OS = 'osx' // At this point, we should have our OS, but in case we don't for some reason, check prefs // In practice, these shouldn't be used } else if (getPref("apz.android.chrome_fling_physics.friction") || getPref("apz.android.chrome_fling_physics.inflexion") || getPref("apz.android.chrome_fling_physics.stop_threshold") || getPref("network.dns.native_https_timeout_android")) { PHOENIX_OS = 'android' } else if (getPref("browser.low_commit_space_threshold_percent") || getPref("media.ffmpeg.vaapi.force-surface-zero-copy") || getPref("widget.gtk.file-manager-show-items-timeout-ms")) { PHOENIX_OS = 'linux' } else if (getPref("network.dns.native_https_timeout_mac_msec") || getPref("widget.macos.shift-by-menubar-on-fullscreen") || getPref("widget.macos.automatic.text_substitution_fetch_length")) { PHOENIX_OS = 'osx' } else if (getPref("accessibility.windows.suppress-after-clipboard-copy") || getPref("accessibility.windows.suppress-for-snap-layout")) { PHOENIX_OS = 'windows' } else { PHOENIX_OS = 'unknown' } } catch (e) { PHOENIX_OS = 'unknown' }; pref("browser.phoenix.OS.current", `${PHOENIX_OS}`); phoenixOsPrefCurrentValue = getPref("browser.phoenix.OS.current"); if (getPref("browser.phoenix.osSet") == false || getPref("browser.phoenix.OS") == "unknown") { pref("browser.phoenix.OS", `${phoenixOsPrefCurrentValue}`); pref("browser.phoenix.osSet", true); }; ``` After some thought, I don't think we should use `font.name-list.emoji`, since that pref could be changed by users *(IDK why anyone would edit it, and they *shouldn't*, but IG you never know - I'd rather avoid the pref checks being value dependent like this if possible)*. Will be curious to hear your thoughts @any1here.
Author
Contributor
Copy link

I would still test that at least two of the needed environment variables are set, in case someone has a variable that matches another platform. Or, idk if this would be overkill, check after detecting a platform that it cannot also be interpreted as a different platform; if it could match multiple platforms, set it to unknown.

I would still test that at least two of the needed environment variables are set, in case someone has a variable that matches another platform. Or, idk if this would be overkill, check after detecting a platform that it cannot also be interpreted as a different platform; if it could match multiple platforms, set it to `unknown`.
Author
Contributor
Copy link

@degausser wrote in #231 (comment):

how would be potential further same-os config granularity handled, e.g. INTEL-OSX || SILICON-OSX, LINUX || LINUX-FLATPAK ?

For flatpak we could maybe check the value of one of the XDG_* environment variables it sets and see if it matches a flatpak value.

@degausser wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-10652396: > how would be potential further same-os config granularity handled, e.g. `INTEL-OSX || SILICON-OSX`, `LINUX || LINUX-FLATPAK` ? For flatpak we could maybe check the value of one of the `XDG_*` environment variables it sets and see if it matches a flatpak value.

@celenity

For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory.

We do still use a .cfg file for Linux though (which we apply manually to the common installation directories), but only for user prefs (as user prefs can't be set via prefs .js files ATM).

I actually filed a bug for this here - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet.

with the bug fixed (thanks @any1here !) in firefox 150, due april 21, is it now possible to ship next phoenix on linux as /etc/firefox/phoenix.cfg, to mirror the other supported platforms?

@celenity >For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory. >We do still use a .cfg file for Linux though (which we apply manually to the common installation directories), but only for user prefs (as user prefs can't be set via prefs .js files ATM). >I actually filed a bug for this here - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet. with the [bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1965449) fixed (thanks @any1here !) in firefox 150, due april 21, is it now possible to ship next phoenix on linux as `/etc/firefox/phoenix.cfg`, to mirror the other supported platforms?

@degausser wrote in #231 (comment):

@celenity

For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory.

We do still use a .cfg file for Linux though (which we apply manually to the common installation directories), but only for user prefs (as user prefs can't be set via prefs .js files ATM).

I actually filed a bug for this here - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet.

with the bug fixed (thanks @any1here !) in firefox 150, due april 21, is it now possible to ship next phoenix on linux as /etc/firefox/phoenix.cfg, to mirror the other supported platforms?

Apologies for not getting back to you on this, but, yep, this is done as of the latest release!

So we're now very close to realizing this goal/having a unified config file for all platforms. Will aim to have this complete for next release!

@degausser wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-12471768: > @celenity > > > For Linux, Phoenix currently sets its prefs via a .js file. The reason we do this is because we can apply it to a system directory (/etc/firefox), which ensures that the prefs are always applied and we don't have to worry about ex. conflicts, issues if the user has to re-install Firefox, issues if the user installs Firefox to a different directory than the standard ones, etc. Unfortunately, it's not currently possible to apply a .cfg file like this; on desktop Linux, Firefox will only read it from the installation directory. > > > We do still use a .cfg file for Linux though (which we apply manually to the common installation directories), but only for user prefs (as user prefs can't be set via prefs .js files ATM). > > > I actually filed a bug for this here - it seems like something upstream is open to fixing, just hasn't been a priority or worked on yet. > > with the [bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1965449) fixed (thanks @any1here !) in firefox 150, due april 21, is it now possible to ship next phoenix on linux as `/etc/firefox/phoenix.cfg`, to mirror the other supported platforms? Apologies for not getting back to you on this, but, yep, this is done as of the latest release! So we're now very close to realizing this goal/having a unified config file for all platforms. Will aim to have this complete for next release!

As of 9a6feb16cf, this is officially done for the core Phoenix config itself!

Still need to tie up a couple loose ends - notably, will need to migrate the files for Phoenix Extended/specialized configs as well (Will keep this issue open until those are resolved). Since we're now using a unified .cfg file like this, we can also set ESR prefs dynamically as well (based on the value of app.update.channel) - so would like to implement those too.

But this is obviously the biggest step towards that goal, so glad we've reached it!

As of https://codeberg.org/celenity/Phoenix/commit/9a6feb16cf7ab7d0935945e6fc872811e927b060, this is officially done for the core Phoenix config itself! Still need to tie up a couple loose ends - notably, will need to migrate the files for Phoenix `Extended`/specialized configs as well *(Will keep this issue open until those are resolved)*. Since we're now using a unified `.cfg` file like this, we can also set ESR prefs dynamically as well *(based on the value of `app.update.channel`)* - so would like to implement those too. But this is obviously the biggest step towards that goal, so glad we've reached it!

@celenity wrote in #231 (comment):

Still need to tie up a couple loose ends

Happy to report this work is officially done!

Also finally completed a (very much needed...) overhaul of the build system, both to better support these changes and be significantly better + more efficient.

@celenity wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-14587629: > Still need to tie up a couple loose ends Happy to report this work is officially done! Also finally completed a *(very much needed...)* overhaul of the build system, both to better support these changes and be significantly better + more efficient.

@celenity While I understand this might come off as a controversial opinion, I am not convinced that shipping an "uber"-config is a good idea. This is different from not shipping *.cfg everywhere (and dealing with everything being user pref() on linux). The distinctions are brittle (and frankly unelegant) and add runtime bloat (even being cached in the browser.phoenix.* prefs; prefs guarding prefs guarding functionality...), but more importantly while the config might be more maintainable to you, with the added conditionals it is less externally reviewable (and hackable). Distinctions at the build system stage and producing essentially static config files should always be preferable to runtime checks. This feels like Phoenix becoming more of a packaged product, as opposed to an auditable "knowledge base" to build upon. (e.g. grep-ing phoenix-unified). At the end of the day, it is your project; hopefully you'll at least keep the tags meaningful, and git commit messages verbose.

@celenity While I understand this might come off as a controversial opinion, I am not convinced that shipping an "uber"-config is a good idea. _This is different from not shipping *.cfg everywhere (and dealing with everything being user pref() on linux)._ The distinctions are brittle (and frankly _unelegant_) and add runtime bloat (even being cached in the browser.phoenix.* prefs; _prefs guarding prefs guarding functionality..._), but more importantly while the config might be more maintainable _to you_, with the added conditionals it is less externally reviewable (and hackable). Distinctions at the build system stage and producing essentially static config files should always be preferable to runtime checks. This feels like Phoenix becoming more of a packaged product, as opposed to an auditable "knowledge base" to build upon. (e.g. `grep`-ing phoenix-unified). At the end of the day, it is your project; hopefully you'll at least keep the tags meaningful, and git commit messages verbose.

@degausser Hey, thanks for taking the time to share your thoughts on this!

The distinctions are brittle (and frankly unelegant)

Can you please provide more details on this? In particular, which distinctions do you think are brittle/inelegant, and do you have any suggestions/ideas for how we can improve them?

and add runtime bloat (even being cached in the browser.phoenix.* prefs; prefs guarding prefs guarding functionality...)

For reference, the newly added browser.phoenix prefs are documented here.

Generally, those prefs are added because they either support functionality that can't easily be achieved by setting the corresponding prefs directly, or they meaningfully improve the user experience (in terms of ex. configuring/overriding certain behavior).

I think the biggest example of the former is the browser.phoenix.trr.autoBootstrap preference. Thanks to that preference, we can automatically set the DoH bootstrap IP address depending on the user's selected resolver, which directly improves privacy (and helps circumvent censorship) for users. Of course, for those who prefer setting the address manually/just don't want to use this functionality for whatever reason, they can simply set that preference to false (which they can do ex. from about:config directly, from a user.js file, etc...).

Another example of this is the browser.phoenix.reset preferences, which simply reset the values for their corresponding preference per-session (so ex. if desired, users can relax hardening per-session, and not worry about having to manually override it later). While this can technically already be accomplished with ex. a user.js file, this makes it significantly easier/more convenient and removes the need for setting up an additional file.

For an example of the latter, you can see the browser.phoenix.enableNativeMessaging preference. Without this preference, in order to re-enable native messaging (which, as we've actually discussed before, is important/desirable for some users), users would not only have to override the values of both webextensions.native-messaging.max-input-message-bytes and webextensions.native-messaging.max-output-message-bytes, they'd also have to know the specific values they need to set those preferences to. So now instead of having to worry about that, all a user has to do is toggle browser.phoenix.enableNativeMessaging (which, like the other Phoenix-specific preferences, can be set from ex. about:config directly, a user.js, etc...).

There's also the preferences for the FPP overrides, which A: provide more control by allowing users decide which types of default granular overrides they'd like to be enabled (This was a major request we received for ex. IronFox), and B: allows them to append their own granular/global overrides without overriding our defaults.

One another notable example is browser.phoenix.extended, which has now made it possible for users to set preferences from Phoenix Extended by simply changing the value of that one preference, and without requiring them to set up ex. an additional file (especially useful for those with manual installations).

So, the point of these preferences isn't to add "runtime bloat", they're added due to the benefits in terms of privacy, control, and convenience/user experience that they provide.

but more importantly while the config might be more maintainable to you, with the added conditionals it is less externally reviewable.

How so?

In terms of the platforms checks, the logic behind them can be reviewed directly here.

For the Phoenix-specific preferences, in addition to the Preferences page, they're also documented in that same file here, and the logic behind them can be reviewed at phoenix-unified.cfg (where they're also further documented).

I'd definitely like Phoenix to be as easy to review/audit as possible, so please do let me know if there's a way this can be improved.

I also do want to clarify that the major driving factor for these changes wasn't simply to make things easier for me to maintain. While that is definitely a very positive side effect of this, I think there's significant value for users as well in terms of having one config file that works seamlessly across platforms, in addition to the additional functionality (like the Phoenix-specific preferences) that we can now provide. Having a universal file that works across all platforms also makes it significantly easier/viable for downstream projects to use/adopt Phoenix if they wish to (Of course, I strongly believe that the interests of users always come first, above the interests of downstream projects/anyone else - but this is still a nice side effect).

(and hackable)

What do you think makes it less hackable? Do you mind providing an example of how its less hackable now than it was before? I definitely want Phoenix to be as flexible/configurable as possible, so please let me know.

This feels like Phoenix becoming more of a packaged product, as opposed to an auditable "knowledge base" to build upon. (e.g. grep-ing phoenix-unified).

Could you not just grep phoenix-unified.cfg similar to how you did with phoenix-unified.js before?

I would definitely like Phoenix to remain, as you described it, an auditable "knowledge base" to build upon, but I'm not sure how these changes compromise that, so I'd appreciate if you could elaborate on this point.

hopefully you'll at least keep the tags meaningful, and git commit messages verbose.

Definitely - nothing should change in that regard. Each pref Phoenix sets will still be thoroughly documented at phoenix-unified.cfg and in the wiki/elsewhere if applicable, and this applies for Phoenix-specific preferences as well, which will remain documented at the Preferences page, at phoenix-preferences.cfg, and at phoenix-unified.cfg/wherever else is applicable.


I want to thank you again for providing your thoughts/feedback here - really appreciate your insight as always, and I look forward to your response.

@degausser Hey, thanks for taking the time to share your thoughts on this! > The distinctions are brittle (and frankly *unelegant*) Can you please provide more details on this? In particular, which distinctions do you think are brittle/inelegant, and do you have any suggestions/ideas for how we can improve them? > and add runtime bloat (even being cached in the browser.phoenix.* prefs; *prefs guarding prefs guarding functionality*...) For reference, the newly added `browser.phoenix` prefs are [documented here](https://codeberg.org/celenity/Phoenix/src/branch/dev/docs/Preferences.md). Generally, those prefs are added because they either support functionality that can't easily be achieved by setting the corresponding prefs directly, or they meaningfully improve the user experience *(in terms of ex. configuring/overriding certain behavior)*. I think the biggest example of the former is the [`browser.phoenix.trr.autoBootstrap` preference](https://codeberg.org/celenity/Phoenix/src/branch/dev/docs/Preferences.md#browser-phoenix-trr-autobootstrap). Thanks to that preference, [we can automatically set the DoH bootstrap IP address depending on the user's selected resolver](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-unified.cfg#L2123), which directly improves privacy *(and helps circumvent censorship)* for users. Of course, for those who prefer setting the address manually/just don't want to use this functionality for whatever reason, they can simply set that preference to false *(which they can do ex. from `about:config` directly, from a `user.js` file, etc...)*. Another example of this is the `browser.phoenix.reset` preferences, which simply reset the values for their corresponding preference per-session *(so ex. if desired, users can relax hardening per-session, and not worry about having to manually override it later)*. While this can technically already be accomplished with ex. a `user.js` file, this makes it significantly easier/more convenient and removes the need for setting up an additional file. For an example of the latter, you can see the [`browser.phoenix.enableNativeMessaging`](https://codeberg.org/celenity/Phoenix/src/branch/dev/docs/Preferences.md#browser-phoenix-enablenativemessaging) preference. Without this preference, in order to re-enable native messaging *(which, as we've actually discussed before, is important/desirable for some users)*, [users would not only have to override the values of both `webextensions.native-messaging.max-input-message-bytes` and `webextensions.native-messaging.max-output-message-bytes`, they'd also have to know the specific values they need to set those preferences to](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-unified.cfg#L3625). So now instead of having to worry about that, all a user has to do is toggle `browser.phoenix.enableNativeMessaging` *(which, like the other Phoenix-specific preferences, can be set from ex. `about:config` directly, a `user.js`, etc...)*. There's also the preferences for the FPP overrides, which A: provide more control by allowing users decide which types of default granular overrides they'd like to be enabled *(This was a major request we received for ex. IronFox)*, and B: allows them to append their own granular/global overrides without overriding our defaults. One another notable example is [`browser.phoenix.extended`](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-unified.cfg#L3625), which has now made it possible for users to set preferences from Phoenix `Extended` by simply changing the value of that one preference, and without requiring them to set up ex. an additional file *(especially useful for those with manual installations)*. So, the point of these preferences isn't to add "runtime bloat", they're added due to the benefits in terms of privacy, control, and convenience/user experience that they provide. > but more importantly while the config might be more maintainable to *you*, with the added conditionals it is less externally reviewable. How so? In terms of the platforms checks, the logic behind them can be reviewed directly [here](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L26). For the Phoenix-specific preferences, in addition to the [`Preferences` page](https://codeberg.org/celenity/Phoenix/src/branch/dev/docs/Preferences.md), they're also documented in that same file [here](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L376), and the logic behind them can be reviewed at [`phoenix-unified.cfg`](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-unified.cfg) *(where they're also further documented)*. I'd definitely like Phoenix to be as easy to review/audit as possible, so please do let me know if there's a way this can be improved. I also do want to clarify that the major driving factor for these changes wasn't simply to make things easier for me to maintain. While that is definitely a very positive side effect of this, I think there's significant value for users as well in terms of having one config file that works seamlessly across platforms, in addition to the additional functionality *(like the Phoenix-specific preferences)* that we can now provide. Having a universal file that works across all platforms also makes it significantly easier/viable for downstream projects to use/adopt Phoenix if they wish to *(Of course, I strongly believe that the interests of users always come first, above the interests of downstream projects/anyone else - but this is still a nice side effect)*. > (and hackable) What do you think makes it less hackable? Do you mind providing an example of how its less hackable now than it was before? I definitely want Phoenix to be as flexible/configurable as possible, so please let me know. > This feels like Phoenix becoming more of a packaged product, as opposed to an auditable "knowledge base" to build upon. (e.g. `grep`-ing phoenix-unified). Could you not just `grep` `phoenix-unified.cfg` similar to how you did with `phoenix-unified.js` before? I would definitely like Phoenix to remain, as you described it, an auditable "knowledge base" to build upon, but I'm not sure how these changes compromise that, so I'd appreciate if you could elaborate on this point. > hopefully you'll at least keep the tags meaningful, and git commit messages verbose. Definitely - nothing should change in that regard. Each pref Phoenix sets will still be thoroughly documented at `phoenix-unified.cfg` and in the wiki/elsewhere if applicable, and this applies for Phoenix-specific preferences as well, which will remain documented at the `Preferences` page, at `phoenix-preferences.cfg`, and at `phoenix-unified.cfg`/wherever else is applicable. ___ I want to thank you again for providing your thoughts/feedback here - really appreciate your insight as always, and I look forward to your response.

@celenity A bit rant-y at times, I apologize, but since you asked for more in-depth reasoning

brittle conditionals

getenv() is (ab)used well beyond its intended use of picking up debug/functionality-gating envvars with FOO=bar ./firefox, or having per-$USER prefs. What prevents anyone from having any of the "blessed" variables defined on other platforms? Surely USERPROFILE=~ ./firefox should not imply Windows. Also, checks for prefs that are subject to change at any point in time are absolutely arbitrary. For example - not necessarily those used in conditionals in Phoenix, but many widget.gtk.* prefs are unintuitively also defined on Windows. This too clearly cannot be relied on for platform detection on its own, and is "solved" by checking a combination of a whole lot of fallbacks (hence inelegant).
It's not like there is a more robust way; it's indicative that it shouldn't be done that way at all. Maybe upstream can be persuaded to reliably expose platform to the autoconfig; until then it will always be hacky.[1]

added arbitrary prefs

about:config entries are already sometimes complex and hard to understand, adding a "simplifying" layer of on top of them will not help[2]. Shouldn't phoenix encourage knowledge of the underlying prefs, instead of hiding them behind its own, bound to get complex as well (but now also non-portable)?
I think there should be a fundamental approach distinction between Phoenix and IronFox - with IronFox, you control the UI, bespoke prefs (maybe even wired to bespoke UI) aren't that much of a stretch. With Phoenix and the inclusion of a middleman about:config layer (and now apparently onboarding for said layer...), users become dependant on your abstractions on a more generic target. Looking up stuff on searchfox becomes looking up stuff in Preferences.md (but still also on searchfox).
Speaking of bootstrapAddr, what if the hardcoded lockpref()'d IPs or their fallbacks ever change / get deprecated / removed? Would users be dependant on your intervention?. It seems locking deterministic (un)desirable program settings is one thing, external values another.
AFAIU browser.phoenix.reset is redundant with setting stuff as pref() - if the user overwrites pref() with a different user value, it results in a custom state in current session, and a reverted config-enforced state after restart - unless the setting itself needs a browser restart, then user.js is a perfectly standard, portable (== Phoenix-agnostic) solution.
Native messaging[3] is a typical example of the "simplifying" layer approach: the original prefs have meaning, the Phoenix pref is just conveniently named. Phoenix has/had stellar portable documentation, maybe the user should be trusted to make their own judgements based on it. (also .NOTEs and .examples continue to be used, no reason not to use them for informing of default values).
Obviously the user could disregard the prefs set by browser.phoenix* prefs, and change values on their own - if they change only some prefs, this results in an in-between state - set phoenix pref would imply one thing, individual actual "sub" prefs something different. Not to mention broadening or shrinking what a browser.phoenix.* pref affects, and then dealing with normalizing the user configuration to a common state (stuff happens, and Phoenix truly doesn't need any more migration code)[4]
We likely fundamentally disagree about FPP overrides, but basically one everlong overrides list became extendable by another; doesn't make the sum of both any shorter.

utility to users and downstream platforms[5]

How often would a single config file be deployed across platforms? Why would scoop/debian/aur packagers care, if their configs can be run as-is elsewhere? On merging in Android prefs: how likely is it, that a significant number of people run phoenixed Firefox on Android at all, as opposed to IronFox, and then care which config they have to manually sideload via console?
Underlying platform doesn't change after install, cross-platform whole profile migration is not advised. While I appreciate your reasoning, the biggest tangible (user?)[6] improvement after the change is the simplification of repository / build system.

maintain, audit, hack, extend

Old Phoenix was a more or less a flat listing; understandable in a few afternoons. Deploying a modified config was a matter of sed -e '/match/d' -e 's/oldvalue/newvalue/'. Custom prefs were limited to some branding, a version string and parsing bugs prevention (~= _userjs.parrot*).
Now grep-ing for any particular pref, and finding it indented (or finding multiple instances), means possible context somewhere above in a conditional (or in another file, ~preferences.cfg). Also missing [ESR] tags for example is a genuine regression.

To give a specific example, the way I compared Phoenix against the Arkenfox diffs was essentially only:

# pr.txt = pasted 'modified' and/or 'removed' prefs blocks from the PR text
awk -F'"' '{print 2ドル}' pr.txt|sort >1.txt
awk -F'"' '{print 2ドル}' phoenix-unified.js|sort >2.txt
comm -12 1.txt 2.txt

This would be a bit more complicated now.

It is interesting that while the config got unified, policies didn't really follow; thankfully JSON doesn't allow for conditional branching :)[7]

I am aware that the direction taken will likely not change[8]. Please, do not take any of this personally. I still highly value your understanding, time and effort you put into the research, and consider your efforts to be very important for future developments around Firefox and its community forks.


[1] e.g. librewolf's profile-directory is at least born out of necessity: nonstandard profile path, then xdg migration upstream, there had to be a way to resolve the mess
[2] reminds me of the debate about solutions to linux user-unfriendliness with new users - "if we just build yet another ui abstraction with only a selection of settings hiding the complexity, laymen will have an easier time..."
[3] i think native messaging clearly shouldn't be disabled at all, but that's neither here nor there
[4] applies to browser.phoenix.extended as well
[5] i assume a hint at librewolf - phoenix not being cross-platform does not seem to be the primary blocker there, to an external observer
[6] helps the maintainer, so by extension it helps the user... (isn't that the justification for telemetry too?)
[7] oh no
[8] i'll likely just have to roll yet another, more involved downstream phoenix config parser...

@celenity A bit rant-y at times, I apologize, but since you asked for more in-depth reasoning >brittle conditionals `getenv()` is (ab)used well beyond its intended use of picking up debug/functionality-gating envvars with `FOO=bar ./firefox`, or having per-`$USER` prefs. What prevents anyone from having any of the "blessed" variables defined on other platforms? Surely `USERPROFILE=~ ./firefox` should not imply Windows. Also, checks for prefs that are subject to change at any point in time are absolutely arbitrary. For example - not necessarily those used in conditionals in Phoenix, but many `widget.gtk.*` prefs are unintuitively also defined on Windows. This too clearly cannot be relied on for platform detection on its own, and is "solved" by checking a combination of a whole lot of fallbacks (hence _inelegant_). It's not like there is a more robust way; it's indicative that it shouldn't be done that way at all. Maybe upstream can be persuaded to reliably expose platform to the autoconfig; until then it will always be hacky.[1] >added arbitrary prefs `about:config` entries are already sometimes complex and hard to understand, adding a "simplifying" layer of on top of them will not help[2]. Shouldn't phoenix encourage knowledge of the underlying prefs, instead of hiding them behind its own, bound to get complex as well (but now also non-portable)? I think there should be a fundamental approach distinction between Phoenix and IronFox - with IronFox, you control the UI, bespoke prefs (maybe even wired to bespoke UI) aren't that much of a stretch. With Phoenix and the inclusion of a middleman `about:config` layer (and now apparently onboarding for said layer...), users become dependant on your abstractions on a more generic target. Looking up stuff on searchfox becomes looking up stuff in `Preferences.md` (but still also on searchfox). Speaking of `bootstrapAddr`, what if the hardcoded `lockpref()`'d IPs or their fallbacks ever change / get deprecated / removed? Would users be dependant on your intervention?. It seems locking deterministic (un)desirable program settings is one thing, external values another. AFAIU `browser.phoenix.reset` is redundant with setting stuff as `pref()` - if the user overwrites `pref()` with a different user value, it results in a custom state in current session, and a reverted config-enforced state after restart - unless the setting itself needs a browser restart, then `user.js` is a perfectly standard, portable (== Phoenix-agnostic) solution. Native messaging[3] is a typical example of the "simplifying" layer approach: the original prefs have meaning, the Phoenix pref is just conveniently named. Phoenix has/had stellar portable documentation, maybe the user should be trusted to make their own judgements based on it. (also `.NOTE`s and `.example`s continue to be used, no reason not to use them for informing of default values). Obviously the user could disregard the prefs set by `browser.phoenix*` prefs, and change values on their own - if they change only _some_ prefs, this results in an in-between state - set phoenix pref would imply one thing, individual actual "sub" prefs something different. Not to mention broadening or shrinking what a `browser.phoenix.*` pref affects, and then dealing with normalizing the user configuration to a common state (stuff happens, and Phoenix truly doesn't need any more migration code)[4] We likely fundamentally disagree about FPP overrides, but basically one everlong overrides list became extendable by another; doesn't make the sum of both any shorter. >utility to users and downstream platforms[5] How often would a single config file be deployed across platforms? Why would scoop/debian/aur packagers care, if their configs can be run as-is elsewhere? On merging in Android prefs: how likely is it, that a significant number of people run phoenixed Firefox on Android at all, as opposed to IronFox, and then care which config they have to manually sideload via console? Underlying platform doesn't change after install, cross-platform whole profile migration is not advised. While I appreciate your reasoning, the biggest tangible (user?)[6] improvement after the change is the simplification of repository / build system. >maintain, audit, hack, extend Old Phoenix was a more or less a flat listing; understandable in a few afternoons. Deploying a modified config was a matter of `sed -e '/match/d' -e 's/oldvalue/newvalue/'`. Custom prefs were limited to some branding, a version string and parsing bugs prevention (~= `_userjs.parrot*`). Now `grep`-ing for any particular pref, and finding it indented (or finding multiple instances), means possible context somewhere above in a conditional (or in another file, ~`preferences.cfg`). Also missing `[ESR]` tags for example is a genuine regression. To give a specific example, the way I compared Phoenix against the Arkenfox diffs was essentially only: ```sh # pr.txt = pasted 'modified' and/or 'removed' prefs blocks from the PR text awk -F'"' '{print 2ドル}' pr.txt|sort >1.txt awk -F'"' '{print 2ドル}' phoenix-unified.js|sort >2.txt comm -12 1.txt 2.txt ``` This would be a bit more complicated now. It is interesting that while the config got unified, policies didn't really follow; thankfully JSON doesn't allow for conditional branching :)[7] I am aware that the direction taken will likely not change[8]. **Please, do not take any of this personally. I still highly value your understanding, time and effort you put into the research, and consider your efforts to be very important for future developments around Firefox and its community forks.** ___ [1] e.g. librewolf's [profile-directory](https://codeberg.org/librewolf/source/src/branch/main/patches/profile-directory.patch) is at least born out of necessity: nonstandard profile path, then xdg migration upstream, there had to be a way to resolve the mess [2] reminds me of the debate about solutions to linux user-unfriendliness with new users - _"if we just build yet another ui abstraction with only a selection of settings hiding the complexity, laymen will have an easier time..."_ [3] i think native messaging clearly shouldn't be disabled at all, but that's neither here nor there [4] applies to `browser.phoenix.extended` as well [5] i assume a hint at librewolf - phoenix not being cross-platform does not seem to be the primary blocker there, to an external observer [6] helps the maintainer, so by extension it helps the user... (isn't that the justification for telemetry too?) [7] [oh no](https://stackoverflow.com/a/52218007) [8] i'll likely just have to roll yet another, more involved downstream phoenix config parser...

@degausser wrote in #231 (comment):

getenv() is (ab)used well beyond its intended use of picking up debug/functionality-gating envvars with FOO=bar ./firefox, or having per-$USER prefs.

Well, according to the documentation:

getenv(name) – queries environment variables. This can allow access to things like usernames and other system information.

The example they provide even sets a preference's value based on an environment variable:

var user = getenv("USER");
lockPref("mail.identity.useremail", user);

So I'm not sure how this is abuse/out of scope of getenv's purpose/functionality?

What prevents anyone from having any of the "blessed" variables defined on other platforms?

First, I'd like to clarify:

So, ideally, none of the fall-back/"blessed" environment variables should be used at all.

But, in the case that they are used for whatever reason, to answer your question: technically nothing prevents them from being defined on other platforms, which isn't ideal - but I'm not sure why they would be? I think we've tried to avoid use of generic environment variables for these fall-back variables due to this, and I'm not aware of the ones we check for being defined on other platforms. To confirm, are you aware of any that we currently check for which you know are set/used across multiple platforms? Would like to take care of it if so.

But you're right that it's not perfect, ultimately you never know what could happen/change (though FWIW: we have shipped these OS checks for a few releases now, and so far they seem to work reliably - but your point still stands). Do you have any ideas/suggestions for how we can further strengthen these platform checks/mitigate your concerns?

I will note that there is protection in the event that these methods change/stop working in the future - The value of browser.phoenix.platform is only set based on the first-run - so if our methods suddenly broke/stopped working as expected, the platform would still be set correctly from before. This also means that technically the platform checks can be skipped entirely by manually setting the value of browser.phoenix.platform.

TBH @degausser, because Phoenix is still being built/packaged separately for each platform anyways (due to ex. platform-specific policies and files in some cases), what I might do is manually set/lock browser.phoenix.platform to the desired platform at build-time - we could keep the OS checks, but only enable them with a separate build option/setting (or maybe we could just fall-back to them directly only if the OS isn't set like this at build-time?). This would ensure the value for the platform is being set/hardcoded by us directly and not relying on ex. external environment variables - do you think this would help alleviate your concerns?

Not sure if this would be a solution long-term or not - ideally, it'd be great to unify the policies/other files as well at some point - but that's a bridge we could cross when we come to it. Curious to hear your thoughts.

Surely USERPROFILE=~ ./firefox should not imply Windows.

I guess, technically yes (because AFAIK that env variable isn't defined on other platforms)? To confirm, do you know of USERPROFILE being set/defined/used outside of Windows?

But, regardless, I do see your point (the naming feels generic), and again I agree it's not perfectly ideal.

Also, checks for prefs that are subject to change at any point in time are absolutely arbitrary. For example - not necessarily those used in conditionals in Phoenix, but many widget.gtk.* prefs are unintuitively also defined on Windows. This too clearly cannot be relied on for platform detection on its own, and is "solved" by checking a combination of a whole lot of fallbacks (hence inelegant).

True - this is why they're only used as the last resort if the platform can't be set from the other checks. I agree they're not the most reliable by themselves.

about:config entries are already sometimes complex and hard to understand, adding a "simplifying" layer of on top of them will not help[2]. Shouldn't phoenix encourage knowledge of the underlying prefs, instead of hiding them behind its own, bound to get complex as well (but now also non-portable)?

Yes, it absolutely should encourage knowledge of the underlying prefs instead of hiding them behind our own, and I think it's important to prefer using the underlying prefs directly where possible. I intend to keep the Phoenix-specific preferences to a minimum for these reasons; only adding them in instances where they genuinely provide meaningful value and/or accomplish functionality that can't be achieved otherwise.

To help with this, I think I might update the Preferences documentation page to be more detailed and mention/reference the preferences directly controlled by Phoenix-specific preferences (ex. I could mention that browser.phoenix.enableNativeMessaging modifies the values of webextensions.native-messaging.max-input-message-bytes + webextensions.native-messaging.max-output-message-bytes) - @degausser do you think this would help/be of any value?

Also, in terms of portability, I agree with you that it's more portable to use the underlying prefs directly (which is the one of the reasons I think we should keep the Phoenix-specific preferences to a minimum and prefer the underlying prefs where possible) - but I think the Phoenix-specific preferences do also offer portability to some extent, simply due to how portable Phoenix is itself. Phoenix can be effectively applied and adapted to nearly any Firefox derivative on any platform, with minimal changes and work needed to set-up.

There's also cases where these Phoenix-specific preferences can directly improve portability as well, ex. with derivatives/downstream projects using Phoenix. For instance, to set user-specified global FPP overrides for IronFox (without overriding our defaults), users currently have to use the IronFox-specific preference (browser.ironfox.fingerprintingProtection.userGlobalOverrides). Thanks to these changes though, IronFox users can now just use browser.phoenix.fingerprintingProtection.global.userOverrides. That same preference will also be used/supported for Dove/Thunderbird users as well, etc.

But you're right it does unfortunately decrease portability with non-Phoenix users/installs, which is again why I agree with you and intend to keep these Phoenix-specific preferences to a minimum, in favor of setting the underlying prefs directly.

I think there should be a fundamental approach distinction between Phoenix and IronFox - with IronFox, you control the UI, bespoke prefs (maybe even wired to bespoke UI) aren't that much of a stretch. With Phoenix and the inclusion of a middleman about:config layer (and now apparently onboarding for said layer...), users become dependant on your abstractions on a more generic target. Looking up stuff on searchfox becomes looking up stuff in Preferences.md (but still also on searchfox).

I understand your point here, and I agree there is a fundamental distinction between Phoenix's approach and the approach of forks like IronFox - that is something I keep in mind/consider.

Ultimately, I don't want to users to become dependent on "abstractions"/Phoenix-specific preferences over the generic targets/standard preferences, which is precisely why I'd like to A: keep the Phoenix-specific preferences to a minimum and B: thoroughly document the Phoenix-specific preferences we do add, and what their functionality is/which standard preferences they set. But like I said before, I think this could be made clearer in Preferences.md, so I intend to expand on that there and ex. directly list the underlying prefs. But if you have any ideas of how we can streamline this/make it clearer, please let me know.

Another idea I have is we could maybe also add dummy .NOTE preferences that appear beside the Phoenix-specific preferences (like we do now in some cases for certain prefs set by Phoenix), which could list the underlying standard/prefs and maybe explain more of their purpose/rationale. Curious to hear what you think.

Speaking of bootstrapAddr, what if the hardcoded lockpref()'d IPs or their fallbacks ever change / get deprecated / removed? Would users be dependant on your intervention?. It seems locking deterministic (un)desirable program settings is one thing, external values another.

To clarify, network.trr.bootstrapAddr is only locked when network.trr.uri is set to a supported provider, and when browser.phoenix.trr.autoBootstrap is set to true. If either condition is not met, network.trr.bootstrapAddr will be unlocked and set to an empty value.

So, in the event that the IPs (or fallback IPs) change/become deprecated/removed/go offline/etc, users can set browser.phoenix.trr.autoBootstrap to false, and just manually set network.trr.bootstrapAddr to their preferred value (if desired). I don't think this is really different than how we ex. set the default DoH provider and customize the list of built-in providers as well - if those URLs changed or became inaccessible for whatever reason, users could just update the value of network.trr.uri.

AFAIU browser.phoenix.reset is redundant with setting stuff as pref() - if the user overwrites pref() with a different user value, it results in a custom state in current session, and a reverted config-enforced state after restart - unless the setting itself needs a browser restart, then user.js is a perfectly standard, portable (== Phoenix-agnostic) solution.

You're right, it is redundant with ex. a user.js file - the point is to simply add convenience/alleviate the need for setting up an additional external file. It also provides more control for preferences we currently/previously just always reset anyways (ex. xpinstall.enabled - we've unconditionally reset that pref per-session for a while now, but now with browser.phoenix.reset.xpinstall.enabled, if someone wants to disable that behavior/prevent it from resetting, they can).

But I agree that in general, using a user.js file is a perfectly acceptable solution, and likely preferable due to the increased portability. Resetting any of the impacted preferences with a user.js file still works perfectly as expected (regardless of these new browser.phoenix.reset prefs), and I think we can probably document/recommend use of user.js files over the browser.phoenix.reset prefs where possible, while still offering the browser.phoenix.reset prefs for users who prefer the extra convenience (and again to offer more control in cases where we'd always reset the pref anyways).

Native messaging[3] is a typical example of the "simplifying" layer approach: the original prefs have meaning, the Phoenix pref is just conveniently named. Phoenix has/had stellar portable documentation, maybe the user should be trusted to make their own judgements based on it. (also .NOTEs and .examples continue to be used, no reason not to use them for informing of default values).

TBH: you convinced me on this one - I think I'm going to remove browser.phoenix.enableNativeMessaging, in favor of just adding NOTEs for the standard webextensions.native-messaging. prefs. Out of the Phoenix-specific preferences, I think this provides the least value, and you're right that the problem of setting the default values could probably be solved by just adding NOTEs. Thank you for making this point!

How often would a single config file be deployed across platforms? Why would scoop/debian/aur packagers care, if their configs can be run as-is elsewhere? On merging in Android prefs: how likely is it, that a significant number of people run phoenixed Firefox on Android at all, as opposed to IronFox, and then care which config they have to manually sideload via console?
Underlying platform doesn't change after install, cross-platform whole profile migration is not advised. While I appreciate your reasoning, the biggest tangible (user?)[6] improvement after the change is the simplification of repository / build system.

Well, back in the day, the primary way people set-up/installed Phoenix was through manual installations - so I guess the thinking in terms of how it benefits users, at least from my POV, was that it'd make things easier for those cases. But I suspect the amount of users with manual installations has dwindled with time, and due to us still relying on ex. OS-specific policies anyways, you're right this probably doesn't provide tangible value (Honestly I think our recent changes to have users of manual installs download/extract the archives directly has already heavily streamlined/simplified that process anyways). I'll be curious to hear your thoughts on my solution above of potentially hardcoding the value of browser.phoenix.platform directly at build-time (and only using the checks for ex. environment variables/preferences as a fall-back or if a certain build variable is set) - even once we do that, the repo / build system will still be significantly cleaner and simpler than it was before, and we can still take advantage of the dynamic checks/advanced functionality of the .cfg format.

Old Phoenix was a more or less a flat listing; understandable in a few afternoons. Deploying a modified config was a matter of sed -e '/match/d' -e 's/oldvalue/newvalue/'. Custom prefs were limited to some branding, a version string and parsing bugs prevention (~= _userjs.parrot*).
Now grep-ing for any particular pref, and finding it indented (or finding multiple instances), means possible context somewhere above in a conditional (or in another file, ~preferences.cfg). Also missing [ESR] tags for example is a genuine regression.

In case it helps, most conditional/dynamic prefs should be indicated with [FN]. I'll make sure to add the [ESR] tags back, but if you think of anything else I can do to help make it easier to audit/evaluate like this, please let me know.

I am aware that the direction taken will likely not change[8]. Please, do not take any of this personally. I still highly value your understanding, time and effort you put into the research, and consider your efforts to be very important for future developments around Firefox and its community forks.

Thank you again for taking the time to share your thoughts and perspective! In general, you've provided a lot of valuable insight to the project, which I have genuinely appreciated.

[5] i assume a hint at librewolf - phoenix not being cross-platform does not seem to be the primary blocker there, to an external observer

At the time this issue was opened, my understanding was that it was indeed one of the primary blockers for them - not sure how much has changed since that point though, I haven't kept up with the public discussion in their issue about it. I will say though that LibreWolf isn't the only browser/downstream project which has expressed interest in adopting Phoenix, there have been a couple others as well.

@degausser wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-15217217: > `getenv()` is (ab)used well beyond its intended use of picking up debug/functionality-gating envvars with `FOO=bar ./firefox`, or having per-`$USER` prefs. Well, according to the [documentation](https://support.mozilla.org/kb/customizing-firefox-using-autoconfig#w_functions-of-autoconfig): > getenv(name) – queries environment variables. This can allow access to things like usernames and other system information. [The example they provide](https://support.mozilla.org/kb/customizing-firefox-using-autoconfig#w_user-specific-preferences) even sets a preference's value based on an environment variable: ``` var user = getenv("USER"); lockPref("mail.identity.useremail", user); ``` So I'm not sure how this is abuse/out of scope of `getenv`'s purpose/functionality? > What prevents anyone from having any of the "blessed" variables defined on other platforms? First, I'd like to clarify: - The value of [`PHOENIX_HOST_PLATFORM`](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L33) is always checked first, it takes precedence over everything else. This variable is set by ex. Phoenix's packaging for all platforms, and can be set manually by users with manual installations. - It's only *then* that if `PHOENIX_HOST_PLATFORM` can't be found *(or its value is unrecognized)* that [it will fall-back to the remaining "blessed" environment variables](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L44). - Finally, if none of the "blessed" environment variables can be found, the [platform-specific prefs are used](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L115). So, ideally, none of the fall-back/"blessed" environment variables should be used at all. But, in the case that they are used for whatever reason, to answer your question: technically nothing prevents them from being defined on other platforms, which isn't ideal - but I'm not sure *why* they would be? I think we've tried to avoid use of generic environment variables for these fall-back variables due to this, and I'm not aware of the ones we check for being defined on other platforms. To confirm, are you aware of any that we currently check for which you know are set/used across multiple platforms? Would like to take care of it if so. But you're right that it's not perfect, ultimately you never know what could happen/change *(though FWIW: we have shipped these OS checks for a few releases now, and so far they seem to work reliably - but your point still stands)*. Do you have any ideas/suggestions for how we can further strengthen these platform checks/mitigate your concerns? I will note that there is protection in the event that these methods change/stop working in the future - The value of `browser.phoenix.platform` [is only set based on the first-run](https://codeberg.org/celenity/Phoenix/src/commit/0617178637b310018c87573915cb699212a3660e/build-resources/phoenix-preferences.cfg#L135) - so if our methods suddenly broke/stopped working as expected, the platform would still be set correctly from before. This also means that technically the platform checks can be skipped entirely by manually setting the value of `browser.phoenix.platform`. TBH @degausser, because Phoenix is still being built/packaged separately for each platform anyways *(due to ex. platform-specific policies and files in some cases)*, what I might do is manually set/lock `browser.phoenix.platform` to the desired platform at build-time - we could keep the OS checks, but only enable them with a separate build option/setting *(or maybe we could just fall-back to them directly only if the OS isn't set like this at build-time?)*. This would ensure the value for the platform is being set/hardcoded by us directly and not relying on ex. external environment variables - do you think this would help alleviate your concerns? Not sure if this would be a solution long-term or not - ideally, it'd be great to unify the policies/other files as well at some point - but that's a bridge we could cross when we come to it. Curious to hear your thoughts. > Surely `USERPROFILE=~ ./firefox` should not imply Windows. I guess, technically yes *(because AFAIK that env variable isn't defined on other platforms)*? To confirm, do you know of `USERPROFILE` being set/defined/used outside of Windows? But, regardless, I do see your point *(the naming feels generic)*, and again I agree it's not perfectly ideal. > Also, checks for prefs that are subject to change at any point in time are absolutely arbitrary. For example - not necessarily those used in conditionals in Phoenix, but many `widget.gtk.*` prefs are unintuitively also defined on Windows. This too clearly cannot be relied on for platform detection on its own, and is "solved" by checking a combination of a whole lot of fallbacks (hence _inelegant_). True - this is why they're only used as the last resort if the platform can't be set from the other checks. I agree they're not the most reliable by themselves. > `about:config` entries are already sometimes complex and hard to understand, adding a "simplifying" layer of on top of them will not help[2]. Shouldn't phoenix encourage knowledge of the underlying prefs, instead of hiding them behind its own, bound to get complex as well (but now also non-portable)? Yes, it absolutely should encourage knowledge of the underlying prefs instead of hiding them behind our own, and I think it's important to prefer using the underlying prefs directly where possible. I intend to keep the Phoenix-specific preferences to a minimum for these reasons; only adding them in instances where they genuinely provide meaningful value and/or accomplish functionality that can't be achieved otherwise. To help with this, I think I might update the `Preferences` documentation page to be more detailed and mention/reference the preferences directly controlled by Phoenix-specific preferences *(ex. I could mention that `browser.phoenix.enableNativeMessaging` modifies the values of `webextensions.native-messaging.max-input-message-bytes` + `webextensions.native-messaging.max-output-message-bytes`)* - @degausser do you think this would help/be of any value? Also, in terms of portability, I agree with you that it's more portable to use the underlying prefs directly *(which is the one of the reasons I think we should keep the Phoenix-specific preferences to a minimum and prefer the underlying prefs where possible)* - but I think the Phoenix-specific preferences do also offer portability to some extent, simply due to how portable Phoenix is itself. Phoenix can be effectively applied and adapted to nearly any Firefox derivative on any platform, with minimal changes and work needed to set-up. There's also cases where these Phoenix-specific preferences can directly *improve* portability as well, ex. with derivatives/downstream projects using Phoenix. For instance, to set user-specified global FPP overrides for IronFox *(without overriding our defaults)*, users currently have to use the IronFox-specific preference *(`browser.ironfox.fingerprintingProtection.userGlobalOverrides`)*. Thanks to these changes though, IronFox users can now just use `browser.phoenix.fingerprintingProtection.global.userOverrides`. That same preference will also be used/supported for Dove/Thunderbird users as well, etc. But you're right it does unfortunately decrease portability with non-Phoenix users/installs, which is again why I agree with you and intend to keep these Phoenix-specific preferences to a minimum, in favor of setting the underlying prefs directly. > I think there should be a fundamental approach distinction between Phoenix and IronFox - with IronFox, you control the UI, bespoke prefs (maybe even wired to bespoke UI) aren't that much of a stretch. With Phoenix and the inclusion of a middleman about:config layer (and now apparently onboarding for said layer...), users become dependant on your abstractions on a more generic target. Looking up stuff on searchfox becomes looking up stuff in `Preferences.md` (but still also on searchfox). I understand your point here, and I agree there is a fundamental distinction between Phoenix's approach and the approach of forks like IronFox - that is something I keep in mind/consider. Ultimately, I don't want to users to become dependent on "abstractions"/Phoenix-specific preferences over the generic targets/standard preferences, which is precisely why I'd like to A: keep the Phoenix-specific preferences to a minimum and B: thoroughly document the Phoenix-specific preferences we do add, and what their functionality is/which standard preferences they set. But like I said before, I think this could be made clearer in `Preferences.md`, so I intend to expand on that there and ex. directly list the underlying prefs. But if you have any ideas of how we can streamline this/make it clearer, please let me know. Another idea I have is we could maybe also add dummy `.NOTE` preferences that appear beside the Phoenix-specific preferences *(like we do now in some cases for certain prefs set by Phoenix)*, which could list the underlying standard/prefs and maybe explain more of their purpose/rationale. Curious to hear what you think. > Speaking of `bootstrapAddr`, what if the hardcoded `lockpref()`'d IPs or their fallbacks ever change / get deprecated / removed? Would users be dependant on your intervention?. It seems locking deterministic (un)desirable program settings is one thing, external values another. To clarify, `network.trr.bootstrapAddr` is only locked when `network.trr.uri` is set to a supported provider, *and* when `browser.phoenix.trr.autoBootstrap` is set to `true`. If either condition is not met, `network.trr.bootstrapAddr` will be unlocked and set to an empty value. So, in the event that the IPs *(or fallback IPs)* change/become deprecated/removed/go offline/etc, users can set `browser.phoenix.trr.autoBootstrap` to `false`, and just manually set `network.trr.bootstrapAddr` to their preferred value *(if desired)*. I don't think this is really different than how we ex. set the default DoH provider and customize the list of built-in providers as well - if those URLs changed or became inaccessible for whatever reason, users could just update the value of `network.trr.uri`. > AFAIU `browser.phoenix.reset` is redundant with setting stuff as `pref()` - if the user overwrites `pref()` with a different user value, it results in a custom state in current session, and a reverted config-enforced state after restart - unless the setting itself needs a browser restart, then `user.js` is a perfectly standard, portable (== Phoenix-agnostic) solution. You're right, it is redundant with ex. a `user.js` file - the point is to simply add convenience/alleviate the need for setting up an additional external file. It also provides more control for preferences we currently/previously just always reset anyways *(ex. `xpinstall.enabled` - we've unconditionally reset that pref per-session for a while now, but now with `browser.phoenix.reset.xpinstall.enabled`, if someone wants to disable that behavior/prevent it from resetting, they can)*. But I agree that in general, using a `user.js` file is a perfectly acceptable solution, and likely preferable due to the increased portability. Resetting any of the impacted preferences with a `user.js` file still works perfectly as expected *(regardless of these new `browser.phoenix.reset` prefs)*, and I think we can probably document/recommend use of `user.js` files over the `browser.phoenix.reset` prefs where possible, while still offering the `browser.phoenix.reset` prefs for users who prefer the extra convenience *(and again to offer more control in cases where we'd always reset the pref anyways)*. > Native messaging[3] is a typical example of the "simplifying" layer approach: the original prefs have meaning, the Phoenix pref is just conveniently named. Phoenix has/had stellar portable documentation, maybe the user should be trusted to make their own judgements based on it. (also `.NOTE`s and `.example`s continue to be used, no reason not to use them for informing of default values). TBH: you convinced me on this one - I think I'm going to remove `browser.phoenix.enableNativeMessaging`, in favor of just adding `NOTE`s for the standard `webextensions.native-messaging.` prefs. Out of the Phoenix-specific preferences, I think this provides the least value, and you're right that the problem of setting the default values could probably be solved by just adding `NOTE`s. Thank you for making this point! > How often would a single config file be deployed across platforms? Why would scoop/debian/aur packagers care, if their configs can be run as-is elsewhere? On merging in Android prefs: how likely is it, that a significant number of people run phoenixed Firefox on Android at all, as opposed to IronFox, and then care which config they have to manually sideload via console? Underlying platform doesn't change after install, cross-platform whole profile migration is not advised. While I appreciate your reasoning, the biggest tangible (user?)[6] improvement after the change is the simplification of repository / build system. Well, back in the day, the primary way people set-up/installed Phoenix was through manual installations - so I guess the thinking in terms of how it benefits users, at least from my POV, was that it'd make things easier for those cases. But I suspect the amount of users with manual installations has dwindled with time, and due to us still relying on ex. OS-specific policies anyways, you're right this probably doesn't provide tangible value *(Honestly I think our recent changes to have users of manual installs download/extract the archives directly has already heavily streamlined/simplified that process anyways)*. I'll be curious to hear your thoughts on my solution above of potentially hardcoding the value of `browser.phoenix.platform` directly at build-time *(and only using the checks for ex. environment variables/preferences as a fall-back or if a certain build variable is set)* - even once we do that, the repo / build system will still be significantly cleaner and simpler than it was before, and we can still take advantage of the dynamic checks/advanced functionality of the `.cfg` format. > Old Phoenix was a more or less a flat listing; understandable in a few afternoons. Deploying a modified config was a matter of `sed -e '/match/d' -e 's/oldvalue/newvalue/'`. Custom prefs were limited to some branding, a version string and parsing bugs prevention (`~= _userjs.parrot*`). > Now `grep`-ing for any particular pref, and finding it indented (or finding multiple instances), means possible context somewhere above in a conditional (or in another file, ~`preferences.cfg`). Also missing `[ESR]` tags for example is a genuine regression. In case it helps, most conditional/dynamic prefs should be indicated with `[FN]`. I'll make sure to add the `[ESR]` tags back, but if you think of anything else I can do to help make it easier to audit/evaluate like this, please let me know. > I am aware that the direction taken will likely not change[8]. **Please, do not take any of this personally. I still highly value your understanding, time and effort you put into the research, and consider your efforts to be very important for future developments around Firefox and its community forks**. Thank you again for taking the time to share your thoughts and perspective! In general, you've provided a lot of valuable insight to the project, which I have genuinely appreciated. > [5] i assume a hint at librewolf - phoenix not being cross-platform does not seem to be the primary blocker there, to an external observer At the time this issue was opened, my understanding was that it was indeed one of the primary blockers for them - not sure how much has changed since that point though, I haven't kept up with the public discussion in their issue about it. I will say though that LibreWolf isn't the only browser/downstream project which has expressed interest in adopting Phoenix, there have been a couple others as well.

@degausser FYI: As of 84f903db4d, I added a mechanism to hardcode/set the OS directly at build-time (enabled by default).

So, basically, when PHOENIX_HARDCODE_PLATFORM is set to 1 (which it is by default), the platform is set at build-time, and the OS checks based on envs/prefs are only used as a fall-back (In practice, they shouldn't/won't be used at all).

For derivatives who do want the unified file/want to enable the env and pref-based OS checks, they can just set PHOENIX_HARDCODE_PLATFORM to 0 at build-time.

Thanks again for your feedback here!

@degausser FYI: As of https://codeberg.org/celenity/Phoenix/commit/84f903db4def5f3abe7690c4b0709800dba4ef66, I added a mechanism to hardcode/set the OS directly at build-time *(enabled by default)*. So, basically, when `PHOENIX_HARDCODE_PLATFORM` is set to `1` *(which it is by default)*, the platform is set at build-time, and the OS checks based on envs/prefs are only used as a fall-back *(In practice, they shouldn't/won't be used at all)*. For derivatives who do want the unified file/want to enable the env and pref-based OS checks, they can just set `PHOENIX_HARDCODE_PLATFORM` to `0` at build-time. Thanks again for your feedback here!

So I just made an interesting discovery while working on Dove.

It looks like Thunderbird is setting prefs to indicate whether the user is on Flatpak or Snap:

// Whether Thunderbird is running under Flatpak or Snap.
// These are set at startup each run so they reflect the current runtime.
// Used to notify about upcoming changes via in-app notification.
pref("mail.inappnotifications.isFlatpak", false);
pref("mail.inappnotifications.isSnap", false);

Out of curiosity, I looked into it, and the logic behind setting these prefs can be found here:

 _setFlatpakOrSnapPref() {
 if (AppConstants.platform != "linux") {
 Services.prefs.setBoolPref("mail.inappnotifications.isFlatpak", false);
 Services.prefs.setBoolPref("mail.inappnotifications.isSnap", false);
 return;
 }
 let isFlatpak = Services.env.exists("FLATPAK_ID");
 let isSnap =
 Services.env.exists("SNAP") || Services.env.exists("SNAP_NAME");
 if (!isFlatpak && !isSnap) {
 const distId = Services.prefs
 .getDefaultBranch("")
 .getCharPref("distribution.id", "")
 .toLowerCase();
 isFlatpak = distId.includes("flatpak");
 isSnap = distId.includes("snap");
 }
 Services.prefs.setBoolPref("mail.inappnotifications.isFlatpak", isFlatpak);
 Services.prefs.setBoolPref("mail.inappnotifications.isSnap", isSnap);
 },

So they seem to be setting this based on environment variables, similar to our approach for automatically setting the OS - except feels less comprehensive and more fragile (though they do have the benefit of being able to check Linux via AppConstants).

Not saying this invalidates your points @degausser - I think your concerns are still valid, regardless of Mozilla's own implementation here being quite similar (which is why we still hardcode the OS now as described above), but I do think this is worth pointing out for reference.

So I just made an interesting discovery while working on Dove. It looks like Thunderbird [is setting prefs to indicate whether the user is on Flatpak or Snap](https://searchfox.org/comm-central/rev/90a16053/mail/app/profile/all-thunderbird.js#1506): ``` // Whether Thunderbird is running under Flatpak or Snap. // These are set at startup each run so they reflect the current runtime. // Used to notify about upcoming changes via in-app notification. pref("mail.inappnotifications.isFlatpak", false); pref("mail.inappnotifications.isSnap", false); ``` Out of curiosity, I looked into it, and the logic behind setting these prefs can be found [here](https://searchfox.org/comm-central/rev/90a16053/mail/components/MailGlue.sys.mjs#600): ```sh _setFlatpakOrSnapPref() { if (AppConstants.platform != "linux") { Services.prefs.setBoolPref("mail.inappnotifications.isFlatpak", false); Services.prefs.setBoolPref("mail.inappnotifications.isSnap", false); return; } let isFlatpak = Services.env.exists("FLATPAK_ID"); let isSnap = Services.env.exists("SNAP") || Services.env.exists("SNAP_NAME"); if (!isFlatpak && !isSnap) { const distId = Services.prefs .getDefaultBranch("") .getCharPref("distribution.id", "") .toLowerCase(); isFlatpak = distId.includes("flatpak"); isSnap = distId.includes("snap"); } Services.prefs.setBoolPref("mail.inappnotifications.isFlatpak", isFlatpak); Services.prefs.setBoolPref("mail.inappnotifications.isSnap", isSnap); }, ``` So they seem to be setting this based on environment variables, similar to our approach for automatically setting the OS - except feels less comprehensive and more fragile *(though they do have the benefit of being able to check `Linux` via `AppConstants`)*. Not saying this invalidates your points @degausser - I think your concerns are still valid, regardless of Mozilla's own implementation here being quite similar *(which is why we still hardcode the OS now as described above)*, but I do think this is worth pointing out for reference.

@celenity

Well, AppConstants.platform == "linux" as platform detection is no getenv("HOME") // linux (hyperbole); as said

Maybe upstream can be persuaded to reliably expose platform to the autoconfig

Platform-checked conditionals itself are not the bigger part of issue, the roundabout way to get to them is. Actually knowing your host platform first, and then checking for possible OS-specific envvars for functionality once is fine - they didn't just poll arbitrary prefs and assume flatpak/snap on Linux. IMHO not so similar to the Phoenix implementation at all.

they do have the benefit of being able to check Linux via AppConstants

does a lot of heavy lifting here. Platform-defined vars != platform-specific vars necessarily, is the gist of my original point. In Phoenix, a notable proper check might just be (getenv("OS") = "Windows_NT"). You mention OS/OSTYPE not working for you in the 3rd comment, how have things changed there?

In any case,

conditional/dynamic prefs should be indicated with [FN]. I'll make sure to add the [ESR] tags

helped significantly, thank you. Hopefully the tag will remain, should the android config be merged in. Hard-coding the platform seems reasonable for now, albeit temporary. Minor formatting nitpick, you missed a terminating semicolon here :)


OT: during the "unification", some otherwise default prefs got locked, I assume influenced by the specialized config. What stands out are the prefs enabling the new tab page (browser.newtabpage.enabled, ~shouldInitializeFeeds and ~disableNewTabAsAddon). Is there a (data collection?) reason for not allowing disabling it + some activity-stream feeds, in standard?

@celenity Well, `AppConstants.platform == "linux"` as platform detection is no `getenv("HOME") // linux` (hyperbole); as said >Maybe upstream can be persuaded to reliably expose platform to the autoconfig Platform-checked conditionals itself are not the bigger part of issue, the roundabout way to get to them is. Actually knowing your host platform [first](https://searchfox.org/comm-central/source/mozilla/toolkit/modules/AppConstants.sys.mjs#76-93), and then checking for possible OS-specific envvars for functionality once is fine - they didn't just poll arbitrary prefs and assume _flatpak/snap on Linux_. IMHO not so similar to the Phoenix implementation at all. >_they do have the benefit of being able to check `Linux` via AppConstants_ does a lot of heavy lifting here. `Platform-defined vars != platform-specific vars` necessarily, is the gist of my original point. In Phoenix, a notable proper check might just be [`(getenv("OS") = "Windows_NT")`](https://codeberg.org/celenity/Phoenix/src/commit/5d939c30993b5cf1c8789c787262160409cffc9d/phoenix-preferences.cfg#L94). You mention `OS`/`OSTYPE` not working for you in the 3rd comment, how have things [changed](https://codeberg.org/celenity/Phoenix/commit/6a0520aab86bac8e9929dc3d45c6df0627d9653a) there? In any case, >conditional/dynamic prefs should be indicated with [FN]. I'll make sure to add the [ESR] tags helped significantly, thank you. Hopefully the tag will remain, should the android config be merged in. Hard-coding the platform seems reasonable for now, albeit temporary. Minor formatting nitpick, you missed a terminating semicolon [here](https://codeberg.org/celenity/Phoenix/src/commit/5d939c30993b5cf1c8789c787262160409cffc9d/phoenix-unified.cfg#L185) :) ___ OT: during the "unification", some otherwise default prefs got locked, I assume influenced by the specialized config. What stands out are the prefs enabling the new tab page (`browser.newtabpage.enabled`, ~`shouldInitializeFeeds` and ~`disableNewTabAsAddon`). Is there a (data collection?) reason for not allowing disabling it + some activity-stream feeds, in standard?

@degausser wrote in #231 (comment):

Platform-checked conditionals itself are not the bigger part of issue, the roundabout way to get to them is. Actually knowing your host platform first, and then checking for possible OS-specific envvars for functionality once is fine - they didn't just poll arbitrary prefs and assume flatpak/snap on Linux. IMHO not so similar to the Phoenix implementation at all.

That's fair - I probably did understate the benefit of them also being able to check AppConstants.

In Phoenix, a notable proper check might just be (getenv("OS") = "Windows_NT"). You mention OS/OSTYPE not working for you in the 3rd comment, how have things changed there?

I did some research and testing in a Windows 11 VM, and found that the OS variable was defined there (set to Windows_NT). I was then able to confirm that its value could be accessed by Firefox, and thus used for our checks. Unfortunately, this only appears to be the case for Windows; OS doesn't seem to be defined on Android, Linux, and OS X - and Firefox doesn't seem to be able to access OSTYPE (like it can for OS on Windows).

That being said, I think many of the variables we check for other platforms are evidently platform-specific (Windows seemed to be the weakest, which is why I looked into it specifically) - so we may be able to look into removing some of the more generic/vague ones (like USERPROFILE) - @degausser please LMK if there's any other generic/vague variables like that one which you think are worth removing.

In any case,

conditional/dynamic prefs should be indicated with [FN]. I'll make sure to add the [ESR] tags

helped significantly, thank you. Hopefully the tag will remain, should the android config be merged in.

Glad to hear that! Don't worry, I'll make sure the tags remain.

Minor formatting nitpick, you missed a terminating semicolon here :)

Thank you! Fixed for 2026年05月21日.2.

OT: during the "unification", some otherwise default prefs got locked, I assume influenced by the specialized config. What stands out are the prefs enabling the new tab page (browser.newtabpage.enabled, ~shouldInitializeFeeds and ~disableNewTabAsAddon). Is there a (data collection?) reason for not allowing disabling it + some activity-stream feeds, in standard?

Thank you for letting me know! Those definitely shouldn't have been locked. The issue actually wasn't related to any specialized config functionality, I had just mistakenly locked them when migrating formats for whatever reason. Due to the severity of the issue (For reference, someone else actually mentioned/noticed this as well), I released 2026年05月21日.2 for Desktop, where it should be fixed.

@degausser wrote in https://codeberg.org/celenity/Phoenix/issues/231#issuecomment-15630719: > Platform-checked conditionals itself are not the bigger part of issue, the roundabout way to get to them is. Actually knowing your host platform [first](https://searchfox.org/comm-central/source/mozilla/toolkit/modules/AppConstants.sys.mjs#76-93), and then checking for possible OS-specific envvars for functionality once is fine - they didn't just poll arbitrary prefs and assume _flatpak/snap on Linux_. IMHO not so similar to the Phoenix implementation at all. That's fair - I probably did understate the benefit of them also being able to check `AppConstants`. > In Phoenix, a notable proper check might just be [`(getenv("OS") = "Windows_NT")`](https://codeberg.org/celenity/Phoenix/src/commit/5d939c30993b5cf1c8789c787262160409cffc9d/phoenix-preferences.cfg#L94). You mention `OS`/`OSTYPE` not working for you in the 3rd comment, how have things [changed](https://codeberg.org/celenity/Phoenix/commit/6a0520aab86bac8e9929dc3d45c6df0627d9653a) there? I did some research and testing in a Windows 11 VM, and found that the `OS` variable was defined there *(set to `Windows_NT`)*. I was then able to confirm that its value could be accessed by Firefox, and thus used for our checks. Unfortunately, this only appears to be the case for Windows; `OS` doesn't seem to be defined on Android, Linux, and OS X - and Firefox doesn't seem to be able to access `OSTYPE` *(like it can for `OS` on Windows)*. That being said, I think many of the variables we check for other platforms are evidently platform-specific *(Windows seemed to be the weakest, which is why I looked into it specifically)* - so we may be able to look into removing some of the more generic/vague ones *(like `USERPROFILE`)* - @degausser please LMK if there's any other generic/vague variables like that one which you think are worth removing. > In any case, > > > conditional/dynamic prefs should be indicated with [FN]. I'll make sure to add the [ESR] tags > > helped significantly, thank you. Hopefully the tag will remain, should the android config be merged in. Glad to hear that! Don't worry, I'll make sure the tags remain. > Minor formatting nitpick, you missed a terminating semicolon [here](https://codeberg.org/celenity/Phoenix/src/commit/5d939c30993b5cf1c8789c787262160409cffc9d/phoenix-unified.cfg#L185) :) Thank you! [Fixed for `2026年05月21日.2`](https://codeberg.org/celenity/Phoenix/commit/e3ecbb0c733bf23a754113d28d3bbe7372d9f1af). > OT: during the "unification", some otherwise default prefs got locked, I assume influenced by the specialized config. What stands out are the prefs enabling the new tab page (`browser.newtabpage.enabled`, ~`shouldInitializeFeeds` and ~`disableNewTabAsAddon`). Is there a (data collection?) reason for not allowing disabling it + some activity-stream feeds, in standard? Thank you for letting me know! Those definitely shouldn't have been locked. The issue actually wasn't related to any specialized config functionality, [I had just mistakenly locked them when migrating formats](https://codeberg.org/celenity/Phoenix/commit/41a4e54e9c2c811a276ddd1dfac157610e7575ca) for whatever reason. Due to the severity of the issue *(For reference, someone else actually mentioned/noticed this as well)*, I released [`2026年05月21日.2`](https://codeberg.org/celenity/Phoenix/releases/tag/2026.05.21.2) for Desktop, where it should be fixed.

FYI @degausser: I've recently done a lot of work to overhaul/improve the OS/platform checks - curious to hear your thoughts. You can see most of the recent changes and the explanations/rationale here: a47784a482.

FYI @degausser: I've recently done a lot of work to overhaul/improve the OS/platform checks - curious to hear your thoughts. You can see most of the recent changes and the explanations/rationale here: https://codeberg.org/celenity/Phoenix/commit/a47784a4825e11046c8bcd27f1aa8578525a7124.
Sign in to join this conversation.
No Branch/Tag specified
dev
pages
2026年07月08日.1
2026年06月10日.1
2026年05月21日.2
2026年05月21日.1
2026年04月27日.1
2026年03月31日.1
2026年03月30日.1
2026年02月23日.1
2026年02月16日.1
2026年01月21日.1
2025年12月23日.1
2025年11月27日.1
2025年11月07日.1
2025年10月26日.1
2025年10月12日.1
2025年10月03日.1
2025年09月07日.1
2025年08月06日.1
2025年07月30日.1
2025年07月11日.1
2025年06月24日.1
2025年06月12日.1
2025年06月10日.1
2025年06月06日.1
2025年06月02日.2
2025年06月02日.1
2025年05月11日.1
2025年04月27日.1
2025年04月15日.1
2025年04月11日.1
2025年04月02日.1
2025年03月25日.1
2025年03月20日.1
2025年03月12日.1
2025年03月05日.1
2025年02月28日.1
2025年02月21日.1
2024年02月18日.1
2025年02月14日.1
2025年02月13日.1
2025年02月01日.1
2025年01月30日.1
2025年01月27日.1
2025年01月24日.1
2025年01月22日.2
2025年01月22日.1
2025年01月20日.2
2025年01月20日.1
2025年01月19日.1
2025年01月14日.1
2025年01月13日.1
2025年01月12日.2
2025年01月12日.1
2025年01月06日.1
05January2025v1
20240103.2
20250103.1
20241229-1
20241225-1
20241216-1
20241211-1
20241204-1
20241203-1
31November2024v1
20241103-1
20240924-1
20240914-1
20240907-1
20240902-1
20240831-1
20240825-1
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
celenity/Phoenix#231
Reference in a new issue
celenity/Phoenix
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?