[SOLVED] Best way to store a config for the user machine

I’m trying to save the scaling factor of the GUI, so the user doesn’t have to set it each time.

What’s the best way to achieve this? I thought about storing it in a file in acertain location, but I imagine I’ll run into file-permission issues at some point because every system is different.

Is there a location which is guaranteed to be accessible by the plugin for Win/Mac/Linux?
Is there a better way to store such configs?

A common approach is to create a folder for your application in the user’s application data directory (which varies by platform, but you can use File::getSpecialLocation (File::SpecialLocationType::userApplicationDataDirectory) and let JUCE worry about that). Then you can store a config file there to save your scaling factor and anything else you might want to add in the future.

1 Like

Rather use the shared documents folder. We had issues with the users documents folder, so shared documents was the only one left that is reachable.

Modern OSes are getting more and more secure and an unfortunate consequence is less and less places to save your data.

3 Likes

I use a ValueTree to store non-parameter settings such as UI scale, and save the value tree as XML:

// NB: pluginSettings is a ValueTree, settingsDirectory is a file path String
std::unique_ptr<XmlElement> xml (pluginSettings.createXml());
return (xml->writeTo(settingsDirectory + File::getSeparatorString() + "settings.xml"));

I load that XML file on startup and convert it back into a value tree:

File settingsFile = File (settingsDirectory + File::getSeparatorString() + "settings.xml");
auto xml (XmlDocument::parse (settingsFile));

if (!settingsFile.existsAsFile() || xml == nullptr) {
    return false;
}

// Replace default settings ValueTree with loaded settings
pluginSettings.copyPropertiesAndChildrenFrom (ValueTree::fromXml (*xml), nullptr);

As @reFX cautioned, I have had problems saving presets etc in the user’s home directory. For instance the same macOS installer can’t write files to both a shared location (e.g. /Library) and the user’s home directory (e.g. ~/Library). There might be some way around this (e.g. write data to a tmp directory and use a post-install script to move it into the user’s home directory), but everything I have read suggests it’s a bad idea.

So I choose to store plugin data in a shared location, in my case /Library/Application Support/My Company/My Plugin on macOS, C:\ProgramData\My Company\My Plugin on Windows.

2 Likes

Cool, thanks to all for your suggestions / code!

Just to double check as you write shared documents folder: What you mean is

juce::File::SpecialLocationType::userDocumentsDirectory

?

Also, this is handy:
https://docs.juce.com/master/classPropertiesFile.html

3 Likes

No, I meant “commonDocumentsDirectory”

1 Like

On my local Ubuntu18 machine this resolves to /opt, which only sudoers have write permmissions to…

I take it this is different on Mac/Windows, which you are targeting?

Nice! Hadn’t come across this class before.

Yes, it’s different on Mac/Windows. I’m surprised it would lead to something so different on Linux.

To elaborate on the common vs. user folder thing, I believe you can safely write to the user’s home directory from within your plugin. My decision to use a common folder was influenced by the limitations of macOS installers: plugins are installed to a common location, therefore my presets had to be installed to a common location, and for the sake of tidiness I chose to store settings alongside the presets.

However I have not had any issues writing from my plugin to the user’s home directory, so I think that’s a perfectly viable option for storing settings. The class @jesusginard mentioned writes to the user’s directory by default.

@reFX might have had other reasons for avoiding the home directory, though.

1 Like

Ok thanks for elaborating! I’ll use userDocumentsDirectory then!