Obey the XDG Base Directory Specification for config file paths
This means you can now put your i3 config into $XDG_CONFIG_HOME/i3/config, which probably is ~/.config/i3/config if not set otherwise.
This commit is contained in:
parent
ba2dd3a3eb
commit
7c130fb540
83
src/config.c
83
src/config.c
|
@ -15,8 +15,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/* We need Xlib for XStringToKeysym */
|
/* We need Xlib for XStringToKeysym */
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
@ -47,6 +49,15 @@ static char *glob_path(const char *path) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the given path exists by calling stat().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static bool path_exists(const char *path) {
|
||||||
|
struct stat buf;
|
||||||
|
return (stat(path, &buf) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ungrabs all keys, to be called before re-grabbing the keys because of a
|
* Ungrabs all keys, to be called before re-grabbing the keys because of a
|
||||||
* mapping_notify event or a configuration file reload
|
* mapping_notify event or a configuration file reload
|
||||||
|
@ -148,6 +159,61 @@ void switch_mode(xcb_connection_t *conn, const char *new_mode) {
|
||||||
ELOG("ERROR: Mode not found\n");
|
ELOG("ERROR: Mode not found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the path of the first configuration file found. Checks the XDG folders
|
||||||
|
* first ($XDG_CONFIG_HOME, $XDG_CONFIG_DIRS), then the traditional paths.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static char *get_config_path() {
|
||||||
|
/* 1: check for $XDG_CONFIG_HOME/i3/config */
|
||||||
|
char *xdg_config_home, *xdg_config_dirs, *config_path;
|
||||||
|
|
||||||
|
if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL)
|
||||||
|
xdg_config_home = "~/.config";
|
||||||
|
|
||||||
|
xdg_config_home = glob_path(xdg_config_home);
|
||||||
|
if (asprintf(&config_path, "%s/i3/config", xdg_config_home) == -1)
|
||||||
|
die("asprintf() failed");
|
||||||
|
free(xdg_config_home);
|
||||||
|
|
||||||
|
if (path_exists(config_path))
|
||||||
|
return config_path;
|
||||||
|
free(config_path);
|
||||||
|
|
||||||
|
/* 2: check for $XDG_CONFIG_DIRS/i3/config */
|
||||||
|
if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL)
|
||||||
|
xdg_config_dirs = "/etc/xdg";
|
||||||
|
|
||||||
|
char *buf = strdup(xdg_config_dirs);
|
||||||
|
char *tok = strtok(buf, ":");
|
||||||
|
while (tok != NULL) {
|
||||||
|
tok = glob_path(tok);
|
||||||
|
if (asprintf(&config_path, "%s/i3/config", tok) == -1)
|
||||||
|
die("asprintf() failed");
|
||||||
|
free(tok);
|
||||||
|
if (path_exists(config_path)) {
|
||||||
|
free(buf);
|
||||||
|
return config_path;
|
||||||
|
}
|
||||||
|
free(config_path);
|
||||||
|
tok = strtok(NULL, ":");
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
/* 3: check traditional paths */
|
||||||
|
config_path = glob_path("~/.i3/config");
|
||||||
|
if (path_exists(config_path))
|
||||||
|
return config_path;
|
||||||
|
|
||||||
|
config_path = strdup("/etc/i3/config");
|
||||||
|
if (!path_exists(config_path))
|
||||||
|
die("Neither $XDG_CONFIG_HOME/i3/config, nor "
|
||||||
|
"$XDG_CONFIG_DIRS/i3/config, nor ~/.i3/config nor "
|
||||||
|
"/etc/i3/config exist.");
|
||||||
|
|
||||||
|
return config_path;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finds the configuration file to use (either the one specified by
|
* Finds the configuration file to use (either the one specified by
|
||||||
* override_configpath), the user’s one or the system default) and calls
|
* override_configpath), the user’s one or the system default) and calls
|
||||||
|
@ -160,19 +226,10 @@ static void parse_configuration(const char *override_configpath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *handle;
|
char *path = get_config_path();
|
||||||
char *globbed = glob_path("~/.i3/config");
|
DLOG("Parsing configfile %s\n", path);
|
||||||
if ((handle = fopen(globbed, "r")) == NULL) {
|
parse_file(path);
|
||||||
if ((handle = fopen("/etc/i3/config", "r")) == NULL)
|
free(path);
|
||||||
die("Neither \"%s\" nor /etc/i3/config could be opened\n", globbed);
|
|
||||||
|
|
||||||
parse_file("/etc/i3/config");
|
|
||||||
fclose(handle);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_file(globbed);
|
|
||||||
fclose(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue