Merge branch 'default-xdg-config'

Use XDG-compliant location by default in wxFileConfig.

See #24195.
This commit is contained in:
Vadim Zeitlin 2024-01-12 18:31:58 +01:00
commit d7cff61267
6 changed files with 83 additions and 11 deletions

View file

@ -31,6 +31,12 @@ Changes in behaviour not resulting in compilation errors
wxGLAttributes::Samplers(1).SampleBuffers(4) explicitly if you need to keep
using the same attributes that were previously used by default.
- Default location of file used by wxFileConfig under Unix has changed to
XDG-compliant ~/.config/appname.conf instead of ~/.appname but note that
any existing files at the old location will still continue to be used.
See wxCONFIG_USE_XDG and wxCONFIG_USE_HOME for how to customize this
behaviour. You may also find wxFileConfig::MigrateLocalFile() useful.
- As first mentioned in 3.0 release notes, the value of wxTHREAD_WAIT_DEFAULT,
used by wxThread::Delete() and Wait() by default, has changed from
wxTHREAD_WAIT_YIELD to wxTHREAD_WAIT_BLOCK for safety and consistency.

View file

@ -63,7 +63,8 @@ enum
wxCONFIG_USE_RELATIVE_PATH = 4,
wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8,
wxCONFIG_USE_SUBDIR = 16,
wxCONFIG_USE_XDG = 32
wxCONFIG_USE_XDG = 32,
wxCONFIG_USE_HOME = 64
};
// ----------------------------------------------------------------------------

View file

@ -137,7 +137,9 @@ public:
wxString error;
};
static MigrationResult
MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0);
MigrateLocalFile(const wxString& name,
int newStyle,
int oldStyle = wxCONFIG_USE_HOME);
// ctor & dtor
// New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or

View file

@ -28,7 +28,7 @@ enum
wxCONFIG_USE_SUBDIR = 16,
/**
Use XDG-compliant file location on Unix systems.
Always use XDG-compliant file location on Unix systems.
If wxCONFIG_USE_SUBDIR is not specified, using this flag has the same
effect as calling wxStandardPaths::SetFileLayout() with
@ -38,9 +38,29 @@ enum
In combination with wxCONFIG_USE_SUBDIR, this flag changes the default
configuration file location to ~/.config/appname/appname.conf`.
If neither this flag nor wxCONFIG_USE_HOME is specified, XDG-compliant
configuration file path will be used by default, but if there is an
existing file in the home directory, then it will continue to be used
instead.
@since 3.3.0
*/
wxCONFIG_USE_XDG = 32
wxCONFIG_USE_XDG = 32,
/**
Use home directory for the local file location on Unix systems.
Using this flag is not recommended, it exists only for compatibility
with the previous wxWidgets versions which created configuration files
in the home directory (i.e. `~/.appname`) by default.
Note that any already existing files in the home directory will still
be used, even if this file is not specified, unless wxCONFIG_USE_XDG is
used.
@since 3.3.0
*/
wxCONFIG_USE_HOME = 64
};

View file

@ -90,8 +90,8 @@ public:
parameter in the constructor.
@a style has the same meaning as in @ref wxConfigBase::wxConfigBase "wxConfig constructor"
and can contain any combination of styles but only wxCONFIG_USE_SUBDIR
and wxCONFIG_USE_XDG are really used by this function.
and can contain any combination of styles but only wxCONFIG_USE_SUBDIR,
wxCONFIG_USE_XDG and wxCONFIG_USE_HOME are really used by this function.
Notice that this function cannot be used if @a basename is already a full path name.
*/
@ -146,9 +146,8 @@ public:
}
}
// Note that this must be done after calling MigrateLocalFile(),
// otherwise the old style would use XDG layout already and the actual
// file at non-XDG-compliant location wouldn't be migrated.
// Prefer doing it only after successfully calling MigrateLocalFile(),
// otherwise, i.e. if it failed, the old config file wouldn't be used.
wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG);
@endcode
@ -157,12 +156,15 @@ public:
program, typically including ::wxCONFIG_USE_XDG and possibly also
including ::wxCONFIG_USE_SUBDIR.
@param oldStyle Style which was used by the previous versions of the
program, possibly including ::wxCONFIG_USE_SUBDIR.
program, possibly including ::wxCONFIG_USE_SUBDIR and typically
including ::wxCONFIG_USE_HOME.
@since 3.3.0
*/
static MigrationResult
MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0);
MigrateLocalFile(const wxString& name,
int newStyle,
int oldStyle = wxCONFIG_USE_HOME);
/**
Saves all config data to the given stream, returns @true if data was saved

View file

@ -261,6 +261,18 @@ wxString wxFileConfig::GetLocalDir(int style)
return dir;
}
if ( style & wxCONFIG_USE_HOME )
{
// When traditional layout is requested, don't use wxStandardPaths as
// it could be using XDG layout.
wxString dir = wxGetHomeDir();
if ( style & wxCONFIG_USE_HOME )
dir = stdp.AppendAppInfo(dir);
return dir;
}
// Normally we'd like to use GetUserConfigDir() and just append app info
// subdirectories to it, but we can't do it for compatibility reasons:
// there are existing configuration files in the locations returned by
@ -499,8 +511,22 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName,
{
// Make up names for files if empty
if ( !m_fnLocalFile.IsOk() && (style & wxCONFIG_USE_LOCAL_FILE) )
{
m_fnLocalFile = GetLocalFile(GetAppName(), style);
// If none of the styles explicitly selecting the location to use is
// specified, default to XDG unless the file already exists in the
// traditional location in the home directory:
if ( !(style & (wxCONFIG_USE_XDG | wxCONFIG_USE_HOME)) )
{
if ( !m_fnLocalFile.FileExists() )
{
style |= wxCONFIG_USE_XDG;
m_fnLocalFile = GetLocalFile(GetAppName(), style);
}
}
}
if ( !m_fnGlobalFile.IsOk() && (style & wxCONFIG_USE_GLOBAL_FILE) )
m_fnGlobalFile = GetGlobalFile(GetAppName());
@ -1112,6 +1138,21 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
if ( !IsDirty() || !m_fnLocalFile.GetFullPath() )
return true;
// Create the directory containing the file if it doesn't exist. Although we
// don't always use XDG, it seems sensible to follow the XDG specification
// and create it with permissions 700 if it doesn't exist.
const wxString& outPath = m_fnLocalFile.GetPath();
if ( !wxFileName::DirExists(outPath) )
{
if ( !wxFileName::Mkdir(outPath,
wxS_IRUSR | wxS_IWUSR | wxS_IXUSR,
wxPATH_MKDIR_FULL) )
{
wxLogWarning(_("Failed to create configuration file directory."));
return false;
}
}
// set the umask if needed
wxCHANGE_UMASK(m_umask);