path-unix: support ~~desktop path expansion

xdg-user-dirs is basically the standard for defining user desktop
directories on linux/bsd. To account for locales and languages, we
basically have to parse the config file (~/.config/user-dirs.dirs)
directly. That or call xdg-user-dir. Either way, it's a little more
complicated than the others, but still doable enough.
This commit is contained in:
Dudemanguy committed 2025-08-17 16:58:00 +00:00
1 parent 07572dc83c
commit ce7ea3d8ea
2 files changed
+36 -2

No files matched your search

+1 -1
View File
@@ -590,7 +590,7 @@ Name Meaning
``~~global/`` The global config path (such as ``/etc/mpv``), if available
(not on win32).
``~~osxbundle/`` The macOS bundle resource path (macOS only).
``~~desktop/`` The path to the desktop (win32, macOS).
``~~desktop/`` The path to the desktop.
``~~exe_dir/`` The path to the directory containing ``mpv.exe`` (for config
file purposes, ``$MPV_HOME`` will override this) (win32 only).
``~~cache/`` The path to application cache data (``~/.cache/mpv/``).
+35 -1
View File
@@ -17,6 +17,7 @@
#include <string.h>
#include "misc/bstr.h"
#include "options/path.h"
#include "osdep/threads.h"
#include "path.h"
@@ -30,6 +31,7 @@ static char mpv_home[CONF_MAX];
static char old_home[CONF_MAX];
static char mpv_cache[CONF_MAX];
static char old_cache[CONF_MAX];
static char mpv_desktop[CONF_MAX];
static char mpv_state[CONF_MAX];
#define MKPATH(BUF, ...) (snprintf((BUF), CONF_MAX, __VA_ARGS__) >= CONF_MAX)
@@ -65,6 +67,38 @@ static void path_init(void)
err = err || MKPATH(mpv_state, "%s/.local/state/mpv", home);
}
char xdg_user_dirs[CONF_MAX];
if (xdg_config && xdg_config[0]) {
err = err || MKPATH(xdg_user_dirs, "%s/user-dirs.dirs", xdg_config);
} else if (home && home[0]) {
err = err || MKPATH(xdg_user_dirs, "%s/.config/user-dirs.dirs", home);
}
// Attempt to read user-dirs for XDG_DESKTOP_DIR
mpv_desktop[0] = '\0';
if (mp_path_exists(xdg_user_dirs)) {
char line[4096];
FILE *user_dirs = fopen(xdg_user_dirs, "r");
while (fgets(line, sizeof(line), user_dirs)) {
bstr data = bstr0(line);
if (bstr_eatstart0(&data, "XDG_DESKTOP_DIR=")) {
bstr value = bstr_strip_linebreaks(data);
if (bstr_eatstart0(&value, "\"") && bstr_eatend0(&value, "\"")) {
bool home_prefix = bstr_eatstart0(&value, "$HOME/");
if (home_prefix) {
err = err || MKPATH(mpv_desktop, "%s/%.*s", home, BSTR_P(value));
} else {
err = err || MKPATH(mpv_desktop, "%.*s", BSTR_P(value));
}
}
break;
}
}
}
if (!mpv_desktop[0])
err = err || MKPATH(mpv_desktop, "%s/%s", home, "Desktop");
// If the old ~/.mpv exists, and the XDG config dir doesn't, use the old
// config dir only. Also do not use any other XDG directories.
if (mp_path_exists(old_home) && !mp_path_exists(mpv_home)) {
@@ -95,6 +129,6 @@ const char *mp_get_platform_path_unix(void *talloc_ctx, const char *type)
if (strcmp(type, "global") == 0)
return MPV_CONFDIR;
if (strcmp(type, "desktop") == 0)
return getenv("HOME");
return mpv_desktop;
return NULL;
}