From ce7ea3d8ea69e4fc2e98473035b5542ffce86073 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Thu, 7 Aug 2025 20:59:19 -0500 Subject: [PATCH] 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. --- DOCS/man/mpv.rst | 2 +- osdep/path-unix.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index b70fc4001b..6b17eb6158 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -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/``). diff --git a/osdep/path-unix.c b/osdep/path-unix.c index eae8b6004d..fc28c442fc 100644 --- a/osdep/path-unix.c +++ b/osdep/path-unix.c @@ -17,6 +17,7 @@ #include +#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; }