From 3093d7ad4f75c4ede88bb02a8d510413782e79d1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 02:18:45 +0100 Subject: [PATCH] Add wxCONFIG_USE_XDG to use with wxFileConfig Using this style allows to tell wxFileConfig to use XDG-compliant location for the user configuration file, even when not using XDG file layout for wxStandardPaths, which can be convenient when modifying the existing application using wxStandardPaths for other files locations too. And using it in combination with wxCONFIG_USE_SUBDIR allows to put the config file in a XDG-compliant subdirectory, which wasn't easily possible at all before. --- include/wx/confbase.h | 3 ++- interface/wx/config.h | 47 +++++++++++++++++++++++++++++++++-------- interface/wx/fileconf.h | 22 +++++++++++++++++-- src/common/fileconf.cpp | 25 +++++++++++++++++----- 4 files changed, 80 insertions(+), 17 deletions(-) diff --git a/include/wx/confbase.h b/include/wx/confbase.h index 584ca07d89..bc00ec1413 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -62,7 +62,8 @@ enum wxCONFIG_USE_GLOBAL_FILE = 2, wxCONFIG_USE_RELATIVE_PATH = 4, wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8, - wxCONFIG_USE_SUBDIR = 16 + wxCONFIG_USE_SUBDIR = 16, + wxCONFIG_USE_XDG = 32 }; // ---------------------------------------------------------------------------- diff --git a/interface/wx/config.h b/interface/wx/config.h index 4b9e052ab1..3e86aa9434 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -6,14 +6,41 @@ ///////////////////////////////////////////////////////////////////////////// -// Flags for constructor style parameter +/// Flags for wxConfig constructor style parameter. enum { wxCONFIG_USE_LOCAL_FILE = 1, wxCONFIG_USE_GLOBAL_FILE = 2, wxCONFIG_USE_RELATIVE_PATH = 4, wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8, - wxCONFIG_USE_SUBDIR = 16 + + /** + Use subdirectory for the local configuration file location. + + Specifying this flag changes the default local configuration file + location to `~/.appname/appname.conf`. Please note that this path is + _not_ affected by layout set using wxStandardPaths::SetFileLayout() and + it is recommended to use wxCONFIG_USE_XDG flag in addition to this file + on contemporary Linux systems. + + @since 2.8.2 + */ + wxCONFIG_USE_SUBDIR = 16, + + /** + 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 + wxStandardPaths::FileLayout_XDG, i.e. it changes the default local + configuration file location to `~/.config/appname.conf`. + + In combination with wxCONFIG_USE_SUBDIR, this flag changes the default + configuration file location to ~/.config/appname/appname.conf`. + + @since 3.3.0 + */ + wxCONFIG_USE_XDG = 32 }; @@ -296,14 +323,16 @@ public: @n For wxFileConfig you can also add @c wxCONFIG_USE_RELATIVE_PATH by logically or'ing it to either of the _FILE options to tell wxFileConfig to use relative instead of absolute paths. - @n On non-VMS Unix systems, the default local configuration file is - "~/.appname". However, this path may be also used as user data + @n On Unix-like systems, the default local configuration file is + `~/.appname` unless wxStandardPaths::SetFileLayout() is called with + wxStandardPaths::FileLayout_XDG parameter in which case the default + becomes `~/.config/appname.conf`. + @n Note that this default path may be also used as user data directory (see wxStandardPaths::GetUserDataDir()) if the - application has several data files. In this case - @c wxCONFIG_USE_SUBDIR flag, which changes the default local - configuration file to "~/.appname/appname" should be used. Notice - that this flag is ignored if @a localFilename is provided. - @c wxCONFIG_USE_SUBDIR is new since wxWidgets version 2.8.2. + application has several data files. In this case it is recommended + to use ::wxCONFIG_USE_XDG flag (available since wxWidgets 3.3.0) + and/or older ::wxCONFIG_USE_SUBDIR (available since 2.8.2) to + change the default local configuration file location. @n For wxFileConfig, you can also add @c wxCONFIG_USE_NO_ESCAPE_CHARACTERS which will turn off character escaping for the values of entries stored in the config file: for diff --git a/interface/wx/fileconf.h b/interface/wx/fileconf.h index caef821174..ae91b8e481 100644 --- a/interface/wx/fileconf.h +++ b/interface/wx/fileconf.h @@ -18,6 +18,24 @@ used explicitly if you want to use files and not the registry even under Windows. + @section fileconf_paths Configuration Files Paths + + The default path for local (or user) configuration file is `~/.appname`, + i.e. it is stored directly in the user home directory. This default + path is backwards-compatible but not recommended any more and it is advised + to call wxStandardPaths::SetFileLayout() with + wxStandardPaths::FileLayout_XDG parameter to change the default path to + `~/.config/appname.conf`. + + Alternatively, it is possible to specify ::wxCONFIG_USE_XDG flag in the + style parameter of the constructor to use this XDG-compliant path without + changing the global file layout. + + And for the programs using multiple configuration files it is recommended + to use both ::wxCONFIG_USE_XDG and ::wxCONFIG_USE_SUBDIR which change the + default file path to `~/.config/appname/appname.conf` -- and allow the + program to store other files in the same `~/.config/appname` directory. + @library{wxbase} @category{cfg} @@ -71,8 +89,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 bit is - examined by this function. + and can contain any combination of styles but only wxCONFIG_USE_SUBDIR + and wxCONFIG_USE_XDG are really used by this function. Notice that this function cannot be used if @a basename is already a full path name. */ diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index e0c610d031..08154612e3 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -249,8 +249,22 @@ wxString wxFileConfig::GetLocalDir(int style) { wxStandardPathsBase& stdp = wxStandardPaths::Get(); - // it so happens that user data directory is a subdirectory of user config - // directory on all supported platforms, which explains why we use it here + if ( style & wxCONFIG_USE_XDG ) + { + // When XDG-compliant layout is requested, we need to use this function + // as GetUserDataDir() doesn't support it. + wxString dir = stdp.GetUserDir(wxStandardPaths::Dir_Config); + + if ( style & wxCONFIG_USE_SUBDIR ) + 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 + // these functions already, so return the same values as we always did. return style & wxCONFIG_USE_SUBDIR ? stdp.GetUserDataDir() : stdp.GetUserConfigDir(); } @@ -271,10 +285,11 @@ wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style) // directly in the home directory. Note that if wxStandardPaths is // configured to follow XDG specification, all config files go to a // subdirectory of XDG_CONFIG_HOME anyhow, so in this case we'll still end - // up using the extension even if wxCONFIG_USE_SUBDIR is not set, but this - // is the correct and expected (if a little confusing) behaviour. + // up using the extension even if neither wxCONFIG_USE_SUBDIR nor + // wxCONFIG_USE_XDG is set, but this is the correct and expected (if a + // little confusing) behaviour. const wxStandardPaths::ConfigFileConv - conv = style & wxCONFIG_USE_SUBDIR + conv = style & (wxCONFIG_USE_SUBDIR | wxCONFIG_USE_XDG) ? wxStandardPaths::ConfigFileConv_Ext : wxStandardPaths::ConfigFileConv_Dot;