Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better integration with xdg dirs. #10838

Merged
merged 4 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions DOCS/interface-changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ Interface changes
`--gamma` to float.
- add `platform` property
- add `--auto-window-resize`
- `--save-position-on-quit` and its associated commands now store state files in
the XDG_STATE_HOME directory by default. This only has an effect on linux/bsd
systems.
- mpv now implictly saves cache files in XDG_CACHE_HOME by default. This only has
an effect if the user enables options that would lead to cache being stored and
only makes a difference on linux/bsd systems.
- `--cache-on-disk` no longer requires explictly setting the `--cache-dir` option
- add `--icc-cache` and `--gpu-shader-cache` options to control whether or not to
save cache files for these features; explictly setting `--icc-cache-dir` and
`--gpu-shader-cache` is no longer required
--- mpv 0.35.0 ---
- add the `--vo=gpu-next` video output driver, as well as the options
`--allow-delayed-peak-detect`, `--builtin-scalers`,
Expand Down
6 changes: 5 additions & 1 deletion DOCS/man/mpv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,10 @@ Name Meaning
``~~desktop/`` the path to the desktop (win32, macOS)
``~~exe_dir/`` win32 only: the path to the directory containing the exe (for
config file purposes; ``$MPV_HOME`` overrides it)
``~~cache/`` the path to application cache data (``~/.cache/mpv/``)
On some platforms, this will be the same as ``~~home/``.
``~~state/`` the path to application state data (``~/.local/state/mpv/``)
On some platforms, this will be the same as ``~~home/``.
``~~old_home/`` do not use
================ ===============================================================

Expand Down Expand Up @@ -1584,7 +1588,7 @@ For Windows-specifics, see `FILES ON WINDOWS`_ section.

See `Script location`_ for details.

``~/.config/mpv/watch_later/``
``~/.local/state/mpv/watch_later/``
Contains temporary config files needed for resuming playback of files with
the watch later feature. See for example the ``Q`` key binding, or the
``quit-watch-later`` input command.
Expand Down
35 changes: 22 additions & 13 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,9 @@ Watch Later
``--watch-later-directory=<path>``
The directory in which to store the "watch later" temporary files.

The default is a subdirectory named "watch_later" underneath the
config directory (usually ``~/.config/mpv/``).
If this option is unset, the files will be stored in a subdirectory
named "watch_later" underneath the local state directory
(usually ``~/.local/state/mpv/``).

``--no-resume-playback``
Do not restore playback position from the ``watch_later`` configuration
Expand Down Expand Up @@ -4770,8 +4771,6 @@ Cache
This makes sense only with ``--cache``. If the normal cache is disabled,
this option is ignored.

You need to set ``--cache-dir`` to use this.

The cache file is append-only. Even if the player appears to prune data, the
file space freed by it is not reused. The cache file is deleted when
playback is closed.
Expand All @@ -4794,7 +4793,8 @@ Cache
continue to use the cache file that was opened first.

``--cache-dir=<path>``
Directory where to create temporary files (default: none).
Directory where to create temporary files. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.

Currently, this is used for ``--cache-on-disk`` only.

Expand Down Expand Up @@ -6633,15 +6633,20 @@ them.
Applications using libmpv with the render API need to provide the ICC
profile via ``MPV_RENDER_PARAM_ICC_PROFILE``.

``--icc-cache-dir=<dirname>``
Store and load the 3D LUTs created from the ICC profile in this directory.
This can be used to speed up loading, since LittleCMS 2 can take a while to
create a 3D LUT. Note that these files contain uncompressed LUTs. Their
size depends on the ``--icc-3dlut-size``, and can be very big.
``--icc-cache``
Store and load 3D LUTs created from the ICC profile on disk in the
cache directory. This can be used to speed up loading, since LittleCMS
2 can take a while to create a 3D LUT. Note that these files contain
uncompressed LUTs. Their size depends on the ``--icc-3dlut-size``, and
can be very big.

NOTE: This is not cleaned automatically, so old, unused cache files may
stick around indefinitely.

``--icc-cache-dir``
The directory where icc cache is stored. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.

``--icc-intent=<value>``
Specifies the ICC intent used for the color transformation (when using
``--icc-profile``).
Expand Down Expand Up @@ -6774,16 +6779,20 @@ them.

This option might be silently removed in the future.

``--gpu-shader-cache-dir=<dirname>``
Store and load compiled GLSL shaders in this directory. Normally, shader
compilation is very fast, so this is usually not needed. It mostly matters
``--gpu-shader-cache``
Store and load compiled GLSL shaders in the cache directory. Normally, shader
compilation is very fast, so this is not usually needed. It mostly matters
for GPU APIs that require internally recompiling shaders to other languages,
for example anything based on ANGLE or Vulkan. Enabling this can improve
startup performance on these platforms.

NOTE: This is not cleaned automatically, so old, unused cache files may
stick around indefinitely.

``--gpu-shader-cache-dir``
The directory where gpu shader cache is stored. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.

Miscellaneous
-------------

Expand Down
2 changes: 2 additions & 0 deletions common/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct mpv_global {
struct mp_client_api *client_api;
char *configdir;
struct stats_base *stats;
bool no_cachedir;
bool no_statedir;
};

#endif
8 changes: 5 additions & 3 deletions demux/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ struct demux_cache *demux_cache_create(struct mpv_global *global,
cache->fd = -1;

char *cache_dir = cache->opts->cache_dir;
if (!(cache_dir && cache_dir[0])) {
MP_ERR(cache, "No cache data directory supplied.\n");
goto fail;
if (cache_dir && cache_dir[0]) {
cache_dir = mp_get_user_path(NULL, global, cache_dir);
} else {
cache_dir = mp_find_user_file(NULL, global, "cache", "");
}
mp_mkdirp(cache_dir);

cache->filename = mp_path_join(cache, cache_dir, "mpv-cache-XXXXXX.dat");
cache->fd = mp_mkostemps(cache->filename, 4, O_CLOEXEC);
Expand Down
9 changes: 7 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ endif
darwin = host_machine.system() == 'darwin'
win32 = host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
posix = not win32

features += {'darwin': darwin}
features += {'posix': posix}
features += {'dos-paths': win32, 'win32': win32}

Expand Down Expand Up @@ -407,11 +409,14 @@ if posix and not features['cocoa']
endif

if darwin
sources += files('osdep/timer-darwin.c')
path_source = files('osdep/path-darwin.c')
sources += path_source + files('osdep/timer-darwin.c')

endif

if posix and not darwin
sources += files('osdep/timer-linux.c')
sources += files('osdep/path-unix.c',
'osdep/timer-linux.c')
endif

cd_devices = {
Expand Down
63 changes: 42 additions & 21 deletions options/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ static const mp_get_platform_path_cb path_resolvers[] = {
#if HAVE_COCOA
mp_get_platform_path_osx,
#endif
#if !defined(_WIN32) || defined(__CYGWIN__)
#if HAVE_DARWIN
mp_get_platform_path_darwin,
#elif !defined(_WIN32) || defined(__CYGWIN__)
mp_get_platform_path_unix,
#endif
#if HAVE_UWP
Expand All @@ -63,19 +65,6 @@ static const char *const config_dirs[] = {
"global",
};

void mp_init_paths(struct mpv_global *global, struct MPOpts *opts)
{
TA_FREEP(&global->configdir);

const char *force_configdir = getenv("MPV_HOME");
if (opts->force_configdir && opts->force_configdir[0])
force_configdir = opts->force_configdir;
if (!opts->load_config)
force_configdir = "";

global->configdir = talloc_strdup(global, force_configdir);
}

// Return a platform specific path using a path type as defined in osdep/path.h.
// Keep in mind that the only way to free the return value is freeing talloc_ctx
// (or its children), as this function can return a statically allocated string.
Expand All @@ -85,13 +74,21 @@ static const char *mp_get_platform_path(void *talloc_ctx,
{
assert(talloc_ctx);

if (global->configdir) {
bool config_dir = strcmp(type, "cache") != 0 && strcmp(type, "state") != 0;
if (global->configdir && config_dir) {
for (int n = 0; n < MP_ARRAY_SIZE(config_dirs); n++) {
if (strcmp(config_dirs[n], type) == 0)
return (n == 0 && global->configdir[0]) ? global->configdir : NULL;
}
}

// Return the native config path if the platform doesn't support the
// type we are trying to fetch.
if (strcmp(type, "cache") == 0 && global->no_cachedir)
type = "home";
if (strcmp(type, "state") == 0 && global->no_statedir)
type = "home";

for (int n = 0; n < MP_ARRAY_SIZE(path_resolvers); n++) {
const char *path = path_resolvers[n](talloc_ctx, type);
if (path && path[0])
Expand All @@ -100,15 +97,39 @@ static const char *mp_get_platform_path(void *talloc_ctx,
return NULL;
}

char *mp_find_user_config_file(void *talloc_ctx, struct mpv_global *global,
const char *filename)
void mp_init_paths(struct mpv_global *global, struct MPOpts *opts)
{
TA_FREEP(&global->configdir);

// Check if the platform has unique directories that differ from
// the standard config directory.
void *tmp = talloc_new(NULL);
const char *cache = mp_get_platform_path(tmp, global, "cache");
const char *state = mp_get_platform_path(tmp, global, "state");
if (!cache)
global->no_cachedir = true;
if (!state)
global->no_statedir = true;
talloc_free(tmp);

const char *force_configdir = getenv("MPV_HOME");
if (opts->force_configdir && opts->force_configdir[0])
force_configdir = opts->force_configdir;
if (!opts->load_config)
force_configdir = "";

global->configdir = talloc_strdup(global, force_configdir);
}

char *mp_find_user_file(void *talloc_ctx, struct mpv_global *global,
const char *type, const char *filename)
{
void *tmp = talloc_new(NULL);
char *res = (char *)mp_get_platform_path(tmp, global, config_dirs[0]);
char *res = (char *)mp_get_platform_path(tmp, global, type);
if (res)
res = mp_path_join(talloc_ctx, res, filename);
talloc_free(tmp);
MP_DBG(global, "config path: '%s' -> '%s'\n", filename, res ? res : "-");
MP_DBG(global, "path: '%s' -> '%s'\n", filename, res ? res : "-");
return res;
}

Expand Down Expand Up @@ -376,9 +397,9 @@ void mp_mkdirp(const char *dir)
talloc_free(path);
}

void mp_mk_config_dir(struct mpv_global *global, char *subdir)
void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir)
{
char *dir = mp_find_user_config_file(NULL, global, subdir);
char *dir = mp_find_user_file(NULL, global, type, subdir);
if (dir)
mp_mkdirp(dir);
talloc_free(dir);
Expand Down
13 changes: 7 additions & 6 deletions options/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ void mp_init_paths(struct mpv_global *global, struct MPOpts *opts);
char *mp_find_config_file(void *talloc_ctx, struct mpv_global *global,
const char *filename);

// Like mp_find_config_file(), but search only the local writable user config
// dir. Also, this returns a result even if the file does not exist. Calling
// it with filename="" is equivalent to retrieving the user config dir.
char *mp_find_user_config_file(void *talloc_ctx, struct mpv_global *global,
const char *filename);
// Search for local writable user files within a specific kind of user dir
// as documented in osdep/path.h. This returns a result even if the file does
// not exist. Calling it with filename="" is equivalent to retrieving the path
// to the dir.
char *mp_find_user_file(void *talloc_ctx, struct mpv_global *global,
const char *type, const char *filename);

// Find all instances of the given config file. Paths are returned in order
// from lowest to highest priority. filename can contain multiple names
Expand Down Expand Up @@ -90,6 +91,6 @@ bool mp_is_url(bstr path);
bstr mp_split_proto(bstr path, bstr *out_url);

void mp_mkdirp(const char *dir);
void mp_mk_config_dir(struct mpv_global *global, char *subdir);
void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir);

#endif /* MPLAYER_PATH_H */
66 changes: 66 additions & 0 deletions osdep/path-darwin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include <string.h>
#include <pthread.h>

#include "options/path.h"
#include "path.h"

#include "config.h"

static pthread_once_t path_init_once = PTHREAD_ONCE_INIT;

static char mpv_home[512];
static char old_home[512];

static void path_init(void)
{
char *home = getenv("HOME");
char *xdg_dir = getenv("XDG_CONFIG_HOME");

if (xdg_dir && xdg_dir[0]) {
snprintf(mpv_home, sizeof(mpv_home), "%s/mpv", xdg_dir);
} else if (home && home[0]) {
snprintf(mpv_home, sizeof(mpv_home), "%s/.config/mpv", home);
}

// Maintain compatibility with old ~/.mpv
if (home && home[0])
snprintf(old_home, sizeof(old_home), "%s/.mpv", home);

// If the old ~/.mpv exists, and the XDG config dir doesn't, use the old
// config dir only.
if (mp_path_exists(old_home) && !mp_path_exists(mpv_home)) {
snprintf(mpv_home, sizeof(mpv_home), "%s", old_home);
old_home[0] = '\0';
}
}

const char *mp_get_platform_path_darwin(void *talloc_ctx, const char *type)
{
pthread_once(&path_init_once, path_init);
if (strcmp(type, "home") == 0)
return mpv_home;
if (strcmp(type, "old_home") == 0)
return old_home;
if (strcmp(type, "global") == 0)
return MPV_CONFDIR;
if (strcmp(type, "desktop") == 0)
return getenv("HOME");
return NULL;
}
Loading