2018-10-03 17:14:51 -04:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Copyright (c) 2012-2014 Richard Grenville <pyxlcy@gmail.com>
|
|
|
|
|
2022-07-17 12:49:35 -04:00
|
|
|
#include <limits.h>
|
2018-08-22 07:58:49 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2019-01-20 16:15:20 -05:00
|
|
|
#include <string.h>
|
2019-03-10 08:34:37 -04:00
|
|
|
#include <unistd.h>
|
2018-08-22 07:58:49 -04:00
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
#include <libconfig.h>
|
|
|
|
#include <libgen.h>
|
2018-08-22 07:58:49 -04:00
|
|
|
|
|
|
|
#include "common.h"
|
2019-01-20 11:53:39 -05:00
|
|
|
#include "compiler.h"
|
2018-08-22 07:58:49 -04:00
|
|
|
#include "config.h"
|
2019-03-10 08:34:37 -04:00
|
|
|
#include "err.h"
|
2018-12-15 12:53:17 -05:00
|
|
|
#include "log.h"
|
2019-03-10 08:34:37 -04:00
|
|
|
#include "options.h"
|
|
|
|
#include "string_utils.h"
|
2019-01-20 11:53:39 -05:00
|
|
|
#include "utils.h"
|
|
|
|
#include "win.h"
|
2018-08-22 07:58:49 -04:00
|
|
|
|
2018-12-21 11:25:28 -05:00
|
|
|
#pragma GCC diagnostic error "-Wunused-parameter"
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
/**
|
|
|
|
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
|
|
|
*
|
2018-10-23 17:12:42 -04:00
|
|
|
* So it takes a pointer to bool.
|
2018-08-22 07:58:49 -04:00
|
|
|
*/
|
2019-03-10 08:34:37 -04:00
|
|
|
static inline int lcfg_lookup_bool(const config_t *config, const char *path, bool *value) {
|
|
|
|
int ival;
|
2018-08-22 07:58:49 -04:00
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
int ret = config_lookup_bool(config, path, &ival);
|
2022-01-30 14:08:48 -05:00
|
|
|
if (ret) {
|
2019-03-10 08:34:37 -04:00
|
|
|
*value = ival;
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2018-08-22 07:58:49 -04:00
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
return ret;
|
2018-08-22 07:58:49 -04:00
|
|
|
}
|
|
|
|
|
2019-01-29 19:27:14 -05:00
|
|
|
/// Search for config file under a base directory
|
2019-03-10 08:34:37 -04:00
|
|
|
FILE *open_config_file_at(const char *base, char **out_path) {
|
2019-10-23 14:54:16 -04:00
|
|
|
static const char *config_paths[] = {"/picom.conf", "/picom/picom.conf",
|
|
|
|
"/compton.conf", "/compton/compton.conf"};
|
2019-03-10 08:34:37 -04:00
|
|
|
for (size_t i = 0; i < ARR_SIZE(config_paths); i++) {
|
|
|
|
char *path = mstrjoin(base, config_paths[i]);
|
|
|
|
FILE *ret = fopen(path, "r");
|
|
|
|
if (ret && out_path) {
|
|
|
|
*out_path = path;
|
|
|
|
} else {
|
|
|
|
free(path);
|
|
|
|
}
|
|
|
|
if (ret) {
|
2019-10-23 14:54:16 -04:00
|
|
|
if (strstr(config_paths[i], "compton")) {
|
|
|
|
log_warn("This compositor has been renamed to \"picom\", "
|
|
|
|
"the old config file paths is deprecated. "
|
|
|
|
"Please replace the \"compton\"s in the path "
|
|
|
|
"with \"picom\"");
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2019-01-29 19:27:14 -05:00
|
|
|
}
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
/**
|
|
|
|
* Get a file stream of the configuration file to read.
|
|
|
|
*
|
|
|
|
* Follows the XDG specification to search for the configuration file.
|
|
|
|
*/
|
2019-03-10 08:34:37 -04:00
|
|
|
FILE *open_config_file(const char *cpath, char **ppath) {
|
|
|
|
static const char config_filename_legacy[] = "/.compton.conf";
|
|
|
|
|
|
|
|
if (cpath) {
|
|
|
|
FILE *ret = fopen(cpath, "r");
|
2023-07-21 19:17:13 -04:00
|
|
|
if (ret && ppath) {
|
2019-03-10 08:34:37 -04:00
|
|
|
*ppath = strdup(cpath);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// First search for config file in user config directory
|
2020-03-01 08:48:04 -05:00
|
|
|
auto config_home = xdg_config_home();
|
2023-12-21 17:07:07 -05:00
|
|
|
if (config_home) {
|
|
|
|
auto ret = open_config_file_at(config_home, ppath);
|
|
|
|
free((void *)config_home);
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fall back to legacy config file in user home directory
|
|
|
|
const char *home = getenv("HOME");
|
|
|
|
if (home && strlen(home)) {
|
|
|
|
auto path = mstrjoin(home, config_filename_legacy);
|
2023-12-21 17:07:07 -05:00
|
|
|
auto ret = fopen(path, "r");
|
2019-03-10 08:34:37 -04:00
|
|
|
if (ret && ppath) {
|
|
|
|
*ppath = path;
|
|
|
|
} else {
|
|
|
|
free(path);
|
|
|
|
}
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fall back to config file in system config directory
|
2020-03-01 08:48:04 -05:00
|
|
|
auto config_dirs = xdg_config_dirs();
|
2019-03-10 08:34:37 -04:00
|
|
|
for (int i = 0; config_dirs[i]; i++) {
|
2023-12-21 17:07:07 -05:00
|
|
|
auto ret = open_config_file_at(config_dirs[i], ppath);
|
2019-03-10 08:34:37 -04:00
|
|
|
if (ret) {
|
2020-03-01 08:46:06 -05:00
|
|
|
free(config_dirs);
|
2019-03-10 08:34:37 -04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
2020-03-01 08:46:06 -05:00
|
|
|
free(config_dirs);
|
2019-03-10 08:34:37 -04:00
|
|
|
|
|
|
|
return NULL;
|
2018-08-22 07:58:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse a condition list in configuration file.
|
|
|
|
*/
|
2019-03-10 08:34:37 -04:00
|
|
|
void parse_cfg_condlst(const config_t *pcfg, c2_lptr_t **pcondlst, const char *name) {
|
|
|
|
config_setting_t *setting = config_lookup(pcfg, name);
|
|
|
|
if (setting) {
|
|
|
|
// Parse an array of options
|
|
|
|
if (config_setting_is_array(setting)) {
|
|
|
|
int i = config_setting_length(setting);
|
2023-07-21 19:17:13 -04:00
|
|
|
while (i--) {
|
2019-03-10 08:34:37 -04:00
|
|
|
condlst_add(pcondlst,
|
|
|
|
config_setting_get_string_elem(setting, i));
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
|
|
|
condlst_add(pcondlst, config_setting_get_string(setting));
|
|
|
|
}
|
|
|
|
}
|
2018-08-22 07:58:49 -04:00
|
|
|
}
|
|
|
|
|
2023-03-29 16:18:41 -04:00
|
|
|
/**
|
|
|
|
* Parse a window corner radius rule list in configuration file.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
parse_cfg_condlst_corner(options_t *opt, const config_t *pcfg, const char *name) {
|
|
|
|
config_setting_t *setting = config_lookup(pcfg, name);
|
|
|
|
if (setting) {
|
|
|
|
// Parse an array of options
|
|
|
|
if (config_setting_is_array(setting)) {
|
|
|
|
int i = config_setting_length(setting);
|
2023-07-21 19:17:13 -04:00
|
|
|
while (i--) {
|
2023-03-29 16:18:41 -04:00
|
|
|
if (!parse_numeric_window_rule(
|
|
|
|
&opt->corner_radius_rules,
|
2023-07-21 19:17:13 -04:00
|
|
|
config_setting_get_string_elem(setting, i), 0,
|
|
|
|
INT_MAX)) {
|
2023-03-29 16:18:41 -04:00
|
|
|
exit(1);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
|
|
|
}
|
2023-03-29 16:18:41 -04:00
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (config_setting_type(setting) == CONFIG_TYPE_STRING) {
|
|
|
|
if (!parse_numeric_window_rule(&opt->corner_radius_rules,
|
|
|
|
config_setting_get_string(setting),
|
2023-07-21 19:17:13 -04:00
|
|
|
0, INT_MAX)) {
|
2023-03-29 16:18:41 -04:00
|
|
|
exit(1);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2023-03-29 16:18:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
/**
|
|
|
|
* Parse an opacity rule list in configuration file.
|
|
|
|
*/
|
|
|
|
static inline void
|
2018-12-21 11:25:28 -05:00
|
|
|
parse_cfg_condlst_opct(options_t *opt, const config_t *pcfg, const char *name) {
|
2019-03-10 08:34:37 -04:00
|
|
|
config_setting_t *setting = config_lookup(pcfg, name);
|
|
|
|
if (setting) {
|
|
|
|
// Parse an array of options
|
|
|
|
if (config_setting_is_array(setting)) {
|
|
|
|
int i = config_setting_length(setting);
|
2023-07-21 19:17:13 -04:00
|
|
|
while (i--) {
|
2023-03-29 16:18:41 -04:00
|
|
|
if (!parse_numeric_window_rule(
|
2019-03-10 08:34:37 -04:00
|
|
|
&opt->opacity_rules,
|
2023-07-21 19:17:13 -04:00
|
|
|
config_setting_get_string_elem(setting, i), 0, 100)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
exit(1);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (config_setting_type(setting) == CONFIG_TYPE_STRING) {
|
2023-07-21 19:17:13 -04:00
|
|
|
if (!parse_numeric_window_rule(&opt->opacity_rules,
|
|
|
|
config_setting_get_string(setting),
|
|
|
|
0, 100)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
exit(1);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
}
|
2018-08-22 07:58:49 -04:00
|
|
|
}
|
|
|
|
|
2022-07-17 12:49:35 -04:00
|
|
|
/**
|
|
|
|
* Parse a window shader rule list in configuration file.
|
|
|
|
*/
|
|
|
|
static inline void parse_cfg_condlst_shader(options_t *opt, const config_t *pcfg,
|
|
|
|
const char *name, const char *include_dir) {
|
|
|
|
config_setting_t *setting = config_lookup(pcfg, name);
|
|
|
|
if (setting) {
|
|
|
|
// Parse an array of options
|
|
|
|
if (config_setting_is_array(setting)) {
|
|
|
|
int i = config_setting_length(setting);
|
|
|
|
while (i--) {
|
|
|
|
if (!parse_rule_window_shader(
|
|
|
|
&opt->window_shader_fg_rules,
|
|
|
|
config_setting_get_string_elem(setting, i),
|
|
|
|
include_dir)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (config_setting_type(setting) == CONFIG_TYPE_STRING) {
|
|
|
|
if (!parse_rule_window_shader(&opt->window_shader_fg_rules,
|
|
|
|
config_setting_get_string(setting),
|
|
|
|
include_dir)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 07:11:55 -05:00
|
|
|
static inline void parse_wintype_config(const config_t *cfg, const char *member_name,
|
|
|
|
win_option_t *o, win_option_mask_t *mask) {
|
|
|
|
char *str = mstrjoin("wintypes.", member_name);
|
|
|
|
const config_setting_t *setting = config_lookup(cfg, str);
|
|
|
|
free(str);
|
|
|
|
|
|
|
|
int ival = 0;
|
|
|
|
if (setting) {
|
|
|
|
if (config_setting_lookup_bool(setting, "shadow", &ival)) {
|
|
|
|
o->shadow = ival;
|
|
|
|
mask->shadow = true;
|
|
|
|
}
|
|
|
|
if (config_setting_lookup_bool(setting, "fade", &ival)) {
|
|
|
|
o->fade = ival;
|
|
|
|
mask->fade = true;
|
|
|
|
}
|
|
|
|
if (config_setting_lookup_bool(setting, "focus", &ival)) {
|
|
|
|
o->focus = ival;
|
|
|
|
mask->focus = true;
|
|
|
|
}
|
2020-10-01 16:51:15 -04:00
|
|
|
if (config_setting_lookup_bool(setting, "blur-background", &ival)) {
|
|
|
|
o->blur_background = ival;
|
|
|
|
mask->blur_background = true;
|
|
|
|
}
|
2020-03-07 07:11:55 -05:00
|
|
|
if (config_setting_lookup_bool(setting, "full-shadow", &ival)) {
|
|
|
|
o->full_shadow = ival;
|
|
|
|
mask->full_shadow = true;
|
|
|
|
}
|
|
|
|
if (config_setting_lookup_bool(setting, "redir-ignore", &ival)) {
|
|
|
|
o->redir_ignore = ival;
|
|
|
|
mask->redir_ignore = true;
|
|
|
|
}
|
2021-07-09 13:17:23 -04:00
|
|
|
if (config_setting_lookup_bool(setting, "clip-shadow-above", &ival)) {
|
|
|
|
o->clip_shadow_above = ival;
|
|
|
|
mask->clip_shadow_above = true;
|
|
|
|
}
|
2020-03-07 07:11:55 -05:00
|
|
|
|
|
|
|
double fval;
|
|
|
|
if (config_setting_lookup_float(setting, "opacity", &fval)) {
|
|
|
|
o->opacity = normalize_d(fval);
|
|
|
|
mask->opacity = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
/**
|
|
|
|
* Parse a configuration file from default location.
|
2018-12-21 11:25:28 -05:00
|
|
|
*
|
|
|
|
* Returns the actually config_file name
|
2018-08-22 07:58:49 -04:00
|
|
|
*/
|
2018-12-21 11:25:28 -05:00
|
|
|
char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shadow_enable,
|
2019-03-10 08:34:37 -04:00
|
|
|
bool *fading_enable, bool *conv_kern_hasneg,
|
|
|
|
win_option_mask_t *winopt_mask) {
|
2022-01-24 13:35:45 -05:00
|
|
|
|
|
|
|
const char *deprecation_message =
|
|
|
|
"option has been deprecated. Please remove it from your configuration file. "
|
|
|
|
"If you encounter any problems without this feature, please feel free to "
|
|
|
|
"open a bug report";
|
2019-03-10 08:34:37 -04:00
|
|
|
char *path = NULL;
|
|
|
|
FILE *f;
|
|
|
|
config_t cfg;
|
|
|
|
int ival = 0;
|
|
|
|
bool bval;
|
|
|
|
double dval = 0.0;
|
|
|
|
// libconfig manages string memory itself, so no need to manually free
|
|
|
|
// anything
|
|
|
|
const char *sval = NULL;
|
|
|
|
|
|
|
|
f = open_config_file(config_file, &path);
|
|
|
|
if (!f) {
|
|
|
|
free(path);
|
|
|
|
if (config_file) {
|
|
|
|
log_fatal("Failed to read configuration file \"%s\".", config_file);
|
|
|
|
return ERR_PTR(-1);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
config_init(&cfg);
|
2020-10-29 05:37:23 -04:00
|
|
|
#ifdef CONFIG_OPTION_ALLOW_OVERRIDES
|
|
|
|
config_set_options(&cfg, CONFIG_OPTION_ALLOW_OVERRIDES);
|
|
|
|
#endif
|
2019-03-10 08:34:37 -04:00
|
|
|
{
|
2022-07-14 13:28:56 -04:00
|
|
|
char *abspath = realpath(path, NULL);
|
|
|
|
char *parent = dirname(abspath); // path2 may be modified
|
2019-03-10 08:34:37 -04:00
|
|
|
|
2022-07-14 13:28:56 -04:00
|
|
|
if (parent) {
|
2019-03-10 08:34:37 -04:00
|
|
|
config_set_include_dir(&cfg, parent);
|
2022-07-14 13:28:56 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
|
2022-07-14 13:28:56 -04:00
|
|
|
free(abspath);
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
int read_result = config_read(&cfg, f);
|
|
|
|
fclose(f);
|
|
|
|
f = NULL;
|
|
|
|
if (read_result == CONFIG_FALSE) {
|
|
|
|
log_fatal("Error when reading configuration file \"%s\", line "
|
|
|
|
"%d: %s",
|
|
|
|
path, config_error_line(&cfg), config_error_text(&cfg));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
config_set_auto_convert(&cfg, 1);
|
|
|
|
|
|
|
|
// Get options from the configuration file. We don't do range checking
|
|
|
|
// right now. It will be done later
|
|
|
|
|
2022-01-30 14:08:48 -05:00
|
|
|
// --dbus
|
|
|
|
lcfg_lookup_bool(&cfg, "dbus", &opt->dbus);
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// -D (fade_delta)
|
2022-01-30 14:08:48 -05:00
|
|
|
if (config_lookup_int(&cfg, "fade-delta", &ival)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->fade_delta = ival;
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// -I (fade_in_step)
|
2022-01-30 14:08:48 -05:00
|
|
|
if (config_lookup_float(&cfg, "fade-in-step", &dval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->fade_in_step = normalize_d(dval);
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// -O (fade_out_step)
|
2022-01-30 14:08:48 -05:00
|
|
|
if (config_lookup_float(&cfg, "fade-out-step", &dval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->fade_out_step = normalize_d(dval);
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// -r (shadow_radius)
|
|
|
|
config_lookup_int(&cfg, "shadow-radius", &opt->shadow_radius);
|
|
|
|
// -o (shadow_opacity)
|
|
|
|
config_lookup_float(&cfg, "shadow-opacity", &opt->shadow_opacity);
|
|
|
|
// -l (shadow_offset_x)
|
|
|
|
config_lookup_int(&cfg, "shadow-offset-x", &opt->shadow_offset_x);
|
|
|
|
// -t (shadow_offset_y)
|
|
|
|
config_lookup_int(&cfg, "shadow-offset-y", &opt->shadow_offset_y);
|
|
|
|
// -i (inactive_opacity)
|
2022-01-30 14:08:48 -05:00
|
|
|
if (config_lookup_float(&cfg, "inactive-opacity", &dval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->inactive_opacity = normalize_d(dval);
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --active_opacity
|
2022-01-30 14:08:48 -05:00
|
|
|
if (config_lookup_float(&cfg, "active-opacity", &dval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->active_opacity = normalize_d(dval);
|
2022-01-30 14:08:48 -05:00
|
|
|
}
|
2020-09-30 11:39:47 -04:00
|
|
|
// --corner-radius
|
|
|
|
config_lookup_int(&cfg, "corner-radius", &opt->corner_radius);
|
2020-09-05 10:46:31 -04:00
|
|
|
// --rounded-corners-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->rounded_corners_blacklist, "rounded-corners-exclude");
|
2023-03-29 16:18:41 -04:00
|
|
|
// --corner-radius-rules
|
|
|
|
parse_cfg_condlst_corner(opt, &cfg, "corner-radius-rules");
|
|
|
|
|
2023-06-10 09:28:43 -04:00
|
|
|
// --no-frame-pacing
|
|
|
|
lcfg_lookup_bool(&cfg, "no-frame-pacing", &opt->no_frame_pacing);
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// -e (frame_opacity)
|
|
|
|
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
|
|
|
// -c (shadow_enable)
|
2022-01-30 14:08:48 -05:00
|
|
|
lcfg_lookup_bool(&cfg, "shadow", shadow_enable);
|
2019-03-10 08:34:37 -04:00
|
|
|
// -m (menu_opacity)
|
|
|
|
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
2022-01-24 13:38:32 -05:00
|
|
|
log_warn("Option `menu-opacity` is deprecated, and will be removed."
|
|
|
|
"Please use the wintype option `opacity` of `popup_menu`"
|
|
|
|
"and `dropdown_menu` instead.");
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->wintype_option[WINTYPE_DROPDOWN_MENU].opacity = dval;
|
|
|
|
opt->wintype_option[WINTYPE_POPUP_MENU].opacity = dval;
|
|
|
|
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
|
|
|
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
|
|
|
}
|
|
|
|
// -f (fading_enable)
|
2023-07-21 19:17:13 -04:00
|
|
|
if (config_lookup_bool(&cfg, "fading", &ival)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
*fading_enable = ival;
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --no-fading-open-close
|
|
|
|
lcfg_lookup_bool(&cfg, "no-fading-openclose", &opt->no_fading_openclose);
|
|
|
|
// --no-fading-destroyed-argb
|
|
|
|
lcfg_lookup_bool(&cfg, "no-fading-destroyed-argb", &opt->no_fading_destroyed_argb);
|
|
|
|
// --shadow-red
|
|
|
|
config_lookup_float(&cfg, "shadow-red", &opt->shadow_red);
|
|
|
|
// --shadow-green
|
|
|
|
config_lookup_float(&cfg, "shadow-green", &opt->shadow_green);
|
|
|
|
// --shadow-blue
|
|
|
|
config_lookup_float(&cfg, "shadow-blue", &opt->shadow_blue);
|
2020-08-17 21:28:01 -04:00
|
|
|
// --shadow-color
|
|
|
|
if (config_lookup_string(&cfg, "shadow-color", &sval)) {
|
2020-06-24 11:38:30 -04:00
|
|
|
struct color rgb;
|
|
|
|
rgb = hex_to_rgb(sval);
|
|
|
|
opt->shadow_red = rgb.red;
|
|
|
|
opt->shadow_green = rgb.green;
|
|
|
|
opt->shadow_blue = rgb.blue;
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --shadow-exclude-reg
|
2023-07-21 19:17:13 -04:00
|
|
|
if (config_lookup_string(&cfg, "shadow-exclude-reg", &sval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
opt->shadow_exclude_reg_str = strdup(sval);
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --inactive-opacity-override
|
|
|
|
lcfg_lookup_bool(&cfg, "inactive-opacity-override", &opt->inactive_opacity_override);
|
|
|
|
// --inactive-dim
|
|
|
|
config_lookup_float(&cfg, "inactive-dim", &opt->inactive_dim);
|
|
|
|
// --mark-wmwin-focused
|
|
|
|
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &opt->mark_wmwin_focused);
|
|
|
|
// --mark-ovredir-focused
|
|
|
|
lcfg_lookup_bool(&cfg, "mark-ovredir-focused", &opt->mark_ovredir_focused);
|
|
|
|
// --shadow-ignore-shaped
|
|
|
|
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped", &opt->shadow_ignore_shaped);
|
|
|
|
// --detect-rounded-corners
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opt->detect_rounded_corners);
|
2023-01-13 06:27:45 -05:00
|
|
|
// --crop-shadow-to-monitor
|
|
|
|
if (lcfg_lookup_bool(&cfg, "xinerama-shadow-crop", &opt->crop_shadow_to_monitor)) {
|
|
|
|
log_warn("xinerama-shadow-crop is deprecated. Use crop-shadow-to-monitor "
|
|
|
|
"instead.");
|
|
|
|
}
|
|
|
|
lcfg_lookup_bool(&cfg, "crop-shadow-to-monitor", &opt->crop_shadow_to_monitor);
|
2019-03-10 08:34:37 -04:00
|
|
|
// --detect-client-opacity
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-client-opacity", &opt->detect_client_opacity);
|
|
|
|
// --refresh-rate
|
2022-01-24 13:35:45 -05:00
|
|
|
if (config_lookup_int(&cfg, "refresh-rate", &ival)) {
|
|
|
|
log_warn("The refresh-rate %s", deprecation_message);
|
2019-03-30 05:07:21 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --vsync
|
|
|
|
if (config_lookup_string(&cfg, "vsync", &sval)) {
|
2022-01-24 13:49:18 -05:00
|
|
|
bool parsed_vsync = parse_vsync(sval);
|
|
|
|
log_error("vsync option will take a boolean from now on. \"%s\" in "
|
|
|
|
"your configuration should be changed to \"%s\"",
|
|
|
|
sval, parsed_vsync ? "true" : "false");
|
|
|
|
goto err;
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
2019-03-10 10:55:17 -04:00
|
|
|
lcfg_lookup_bool(&cfg, "vsync", &opt->vsync);
|
2019-03-10 08:34:37 -04:00
|
|
|
// --backend
|
|
|
|
if (config_lookup_string(&cfg, "backend", &sval)) {
|
|
|
|
opt->backend = parse_backend(sval);
|
|
|
|
if (opt->backend >= NUM_BKEND) {
|
|
|
|
log_fatal("Cannot parse backend");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// --log-level
|
|
|
|
if (config_lookup_string(&cfg, "log-level", &sval)) {
|
|
|
|
auto level = string_to_log_level(sval);
|
|
|
|
if (level == LOG_LEVEL_INVALID) {
|
|
|
|
log_warn("Invalid log level, defaults to WARN");
|
|
|
|
} else {
|
|
|
|
log_set_level_tls(level);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// --log-file
|
|
|
|
if (config_lookup_string(&cfg, "log-file", &sval)) {
|
|
|
|
if (*sval != '/') {
|
|
|
|
log_warn("The log-file in your configuration file is not an "
|
|
|
|
"absolute path");
|
|
|
|
}
|
|
|
|
opt->logpath = strdup(sval);
|
|
|
|
}
|
|
|
|
// --sw-opti
|
2022-01-24 12:57:46 -05:00
|
|
|
if (lcfg_lookup_bool(&cfg, "sw-opti", &bval)) {
|
2024-01-14 12:04:03 -05:00
|
|
|
log_error("The sw-opti %s", deprecation_message);
|
|
|
|
goto err;
|
2022-01-24 12:57:46 -05:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --use-ewmh-active-win
|
|
|
|
lcfg_lookup_bool(&cfg, "use-ewmh-active-win", &opt->use_ewmh_active_win);
|
|
|
|
// --unredir-if-possible
|
|
|
|
lcfg_lookup_bool(&cfg, "unredir-if-possible", &opt->unredir_if_possible);
|
|
|
|
// --unredir-if-possible-delay
|
2019-03-30 05:07:21 -04:00
|
|
|
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival)) {
|
|
|
|
if (ival < 0) {
|
|
|
|
log_warn("Invalid unredir-if-possible-delay %d", ival);
|
|
|
|
} else {
|
|
|
|
opt->unredir_if_possible_delay = ival;
|
|
|
|
}
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --inactive-dim-fixed
|
|
|
|
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &opt->inactive_dim_fixed);
|
|
|
|
// --detect-transient
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-transient", &opt->detect_transient);
|
|
|
|
// --detect-client-leader
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-client-leader", &opt->detect_client_leader);
|
2019-06-07 19:13:28 -04:00
|
|
|
// --no-ewmh-fullscreen
|
|
|
|
lcfg_lookup_bool(&cfg, "no-ewmh-fullscreen", &opt->no_ewmh_fullscreen);
|
2019-11-30 16:24:22 -05:00
|
|
|
// --transparent-clipping
|
|
|
|
lcfg_lookup_bool(&cfg, "transparent-clipping", &opt->transparent_clipping);
|
2022-11-30 00:28:57 -05:00
|
|
|
// --dithered_present
|
|
|
|
lcfg_lookup_bool(&cfg, "dithered-present", &opt->dithered_present);
|
2021-12-01 17:51:57 -05:00
|
|
|
// --transparent-clipping-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->transparent_clipping_blacklist,
|
|
|
|
"transparent-clipping-exclude");
|
2019-03-10 08:34:37 -04:00
|
|
|
// --shadow-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude");
|
2021-07-09 13:17:23 -04:00
|
|
|
// --clip-shadow-above
|
|
|
|
parse_cfg_condlst(&cfg, &opt->shadow_clip_list, "clip-shadow-above");
|
2019-03-10 08:34:37 -04:00
|
|
|
// --fade-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude");
|
|
|
|
// --focus-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude");
|
|
|
|
// --invert-color-include
|
|
|
|
parse_cfg_condlst(&cfg, &opt->invert_color_list, "invert-color-include");
|
|
|
|
// --blur-background-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->blur_background_blacklist, "blur-background-exclude");
|
|
|
|
// --opacity-rule
|
|
|
|
parse_cfg_condlst_opct(opt, &cfg, "opacity-rule");
|
|
|
|
// --unredir-if-possible-exclude
|
|
|
|
parse_cfg_condlst(&cfg, &opt->unredir_if_possible_blacklist,
|
|
|
|
"unredir-if-possible-exclude");
|
2019-12-20 13:07:35 -05:00
|
|
|
// --blur-method
|
|
|
|
if (config_lookup_string(&cfg, "blur-method", &sval)) {
|
|
|
|
enum blur_method method = parse_blur_method(sval);
|
|
|
|
if (method >= BLUR_METHOD_INVALID) {
|
|
|
|
log_fatal("Invalid blur method %s", sval);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
opt->blur_method = method;
|
|
|
|
}
|
|
|
|
// --blur-size
|
|
|
|
config_lookup_int(&cfg, "blur-size", &opt->blur_radius);
|
|
|
|
// --blur-deviation
|
|
|
|
config_lookup_float(&cfg, "blur-deviation", &opt->blur_deviation);
|
2019-12-20 14:31:00 -05:00
|
|
|
// --blur-strength
|
|
|
|
config_lookup_int(&cfg, "blur-strength", &opt->blur_strength);
|
2019-03-10 08:34:37 -04:00
|
|
|
// --blur-background
|
2019-05-31 19:39:00 -04:00
|
|
|
if (config_lookup_bool(&cfg, "blur-background", &ival) && ival) {
|
2019-12-20 13:07:35 -05:00
|
|
|
if (opt->blur_method == BLUR_METHOD_NONE) {
|
|
|
|
opt->blur_method = BLUR_METHOD_KERNEL;
|
|
|
|
}
|
2019-05-31 19:39:00 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
// --blur-background-frame
|
|
|
|
lcfg_lookup_bool(&cfg, "blur-background-frame", &opt->blur_background_frame);
|
|
|
|
// --blur-background-fixed
|
|
|
|
lcfg_lookup_bool(&cfg, "blur-background-fixed", &opt->blur_background_fixed);
|
|
|
|
// --blur-kern
|
2019-06-06 02:37:48 -04:00
|
|
|
if (config_lookup_string(&cfg, "blur-kern", &sval)) {
|
2019-06-07 16:53:23 -04:00
|
|
|
opt->blur_kerns =
|
|
|
|
parse_blur_kern_lst(sval, conv_kern_hasneg, &opt->blur_kernel_count);
|
2019-06-06 02:37:48 -04:00
|
|
|
if (!opt->blur_kerns) {
|
|
|
|
log_fatal("Cannot parse \"blur-kern\"");
|
|
|
|
goto err;
|
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
// --resize-damage
|
|
|
|
config_lookup_int(&cfg, "resize-damage", &opt->resize_damage);
|
|
|
|
// --glx-no-stencil
|
|
|
|
lcfg_lookup_bool(&cfg, "glx-no-stencil", &opt->glx_no_stencil);
|
|
|
|
// --glx-no-rebind-pixmap
|
|
|
|
lcfg_lookup_bool(&cfg, "glx-no-rebind-pixmap", &opt->glx_no_rebind_pixmap);
|
2020-04-04 21:32:54 -04:00
|
|
|
lcfg_lookup_bool(&cfg, "force-win-blend", &opt->force_win_blend);
|
2019-03-10 08:34:37 -04:00
|
|
|
// --glx-swap-method
|
|
|
|
if (config_lookup_string(&cfg, "glx-swap-method", &sval)) {
|
2019-03-11 20:29:59 -04:00
|
|
|
char *endptr;
|
|
|
|
long val = strtol(sval, &endptr, 10);
|
2022-01-24 13:12:31 -05:00
|
|
|
bool should_remove = true;
|
2019-03-11 20:29:59 -04:00
|
|
|
if (*endptr || !(*sval)) {
|
|
|
|
// sval is not a number, or an empty string
|
|
|
|
val = -1;
|
|
|
|
}
|
|
|
|
if (strcmp(sval, "undefined") != 0 && val != 0) {
|
|
|
|
// If not undefined, we will use damage and buffer-age to limit
|
|
|
|
// the rendering area.
|
2022-01-24 13:12:31 -05:00
|
|
|
should_remove = false;
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
2022-01-24 13:12:31 -05:00
|
|
|
log_error("glx-swap-method has been removed, your setting "
|
|
|
|
"\"%s\" should be %s.",
|
|
|
|
sval,
|
|
|
|
!should_remove ? "replaced by `use-damage = true`" : "removed");
|
|
|
|
goto err;
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
2019-03-11 20:29:59 -04:00
|
|
|
// --use-damage
|
|
|
|
lcfg_lookup_bool(&cfg, "use-damage", &opt->use_damage);
|
2019-11-06 19:19:20 -05:00
|
|
|
|
|
|
|
// --max-brightness
|
2019-12-20 13:07:35 -05:00
|
|
|
if (config_lookup_float(&cfg, "max-brightness", &opt->max_brightness) &&
|
2020-12-03 00:46:17 -05:00
|
|
|
opt->use_damage && opt->max_brightness < 1) {
|
2019-12-20 13:07:35 -05:00
|
|
|
log_warn("max-brightness requires use-damage = false. Falling back to "
|
|
|
|
"1.0");
|
2019-11-06 19:19:20 -05:00
|
|
|
opt->max_brightness = 1.0;
|
|
|
|
}
|
|
|
|
|
2022-07-17 12:49:35 -04:00
|
|
|
// --window-shader-fg
|
|
|
|
if (config_lookup_string(&cfg, "window-shader-fg", &sval)) {
|
|
|
|
opt->window_shader_fg =
|
|
|
|
locate_auxiliary_file("shaders", sval, config_get_include_dir(&cfg));
|
|
|
|
}
|
|
|
|
|
|
|
|
// --window-shader-fg-rule
|
|
|
|
parse_cfg_condlst_shader(opt, &cfg, "window-shader-fg-rule",
|
|
|
|
config_get_include_dir(&cfg));
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// --glx-use-gpushader4
|
2022-01-24 13:04:57 -05:00
|
|
|
if (config_lookup_bool(&cfg, "glx-use-gpushader4", &ival)) {
|
|
|
|
log_error("glx-use-gpushader4 has been removed, please remove it "
|
|
|
|
"from your config file");
|
|
|
|
goto err;
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
// --xrender-sync-fence
|
|
|
|
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &opt->xrender_sync_fence);
|
|
|
|
|
2023-07-21 19:17:13 -04:00
|
|
|
if (lcfg_lookup_bool(&cfg, "clear-shadow", &bval)) {
|
2019-03-10 08:34:37 -04:00
|
|
|
log_warn("\"clear-shadow\" is removed as an option, and is always"
|
|
|
|
" enabled now. Consider removing it from your config file");
|
2023-07-21 19:17:13 -04:00
|
|
|
}
|
2019-03-10 08:34:37 -04:00
|
|
|
|
2019-05-31 19:39:00 -04:00
|
|
|
config_setting_t *blur_cfg = config_lookup(&cfg, "blur");
|
|
|
|
if (blur_cfg) {
|
|
|
|
if (config_setting_lookup_string(blur_cfg, "method", &sval)) {
|
|
|
|
enum blur_method method = parse_blur_method(sval);
|
|
|
|
if (method >= BLUR_METHOD_INVALID) {
|
|
|
|
log_warn("Invalid blur method %s, ignoring.", sval);
|
|
|
|
} else {
|
|
|
|
opt->blur_method = method;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
config_setting_lookup_int(blur_cfg, "size", &opt->blur_radius);
|
|
|
|
|
|
|
|
if (config_setting_lookup_string(blur_cfg, "kernel", &sval)) {
|
2019-06-07 16:53:23 -04:00
|
|
|
opt->blur_kerns = parse_blur_kern_lst(sval, conv_kern_hasneg,
|
|
|
|
&opt->blur_kernel_count);
|
2019-06-06 02:37:48 -04:00
|
|
|
if (!opt->blur_kerns) {
|
2019-05-31 19:39:00 -04:00
|
|
|
log_warn("Failed to parse blur kernel: %s", sval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
config_setting_lookup_float(blur_cfg, "deviation", &opt->blur_deviation);
|
2019-12-20 14:31:00 -05:00
|
|
|
config_setting_lookup_int(blur_cfg, "strength", &opt->blur_strength);
|
2019-05-31 19:39:00 -04:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:35:35 -04:00
|
|
|
// --write-pid-path
|
|
|
|
if (config_lookup_string(&cfg, "write-pid-path", &sval)) {
|
|
|
|
if (*sval != '/') {
|
|
|
|
log_warn("The write-pid-path in your configuration file is not"
|
|
|
|
" an absolute path");
|
|
|
|
}
|
|
|
|
opt->write_pid_path = strdup(sval);
|
|
|
|
}
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// Wintype settings
|
|
|
|
|
|
|
|
// XXX ! Refactor all the wintype_* arrays into a struct
|
|
|
|
for (wintype_t i = 0; i < NUM_WINTYPES; ++i) {
|
2020-03-07 07:11:55 -05:00
|
|
|
parse_wintype_config(&cfg, WINTYPES[i], &opt->wintype_option[i],
|
|
|
|
&winopt_mask[i]);
|
2019-03-10 08:34:37 -04:00
|
|
|
}
|
|
|
|
|
2020-03-07 07:11:55 -05:00
|
|
|
// Compatibility with the old name for notification windows.
|
|
|
|
parse_wintype_config(&cfg, "notify", &opt->wintype_option[WINTYPE_NOTIFICATION],
|
|
|
|
&winopt_mask[WINTYPE_NOTIFICATION]);
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
config_destroy(&cfg);
|
|
|
|
return path;
|
2019-02-12 21:04:05 -05:00
|
|
|
|
|
|
|
err:
|
2019-03-10 08:34:37 -04:00
|
|
|
config_destroy(&cfg);
|
|
|
|
free(path);
|
|
|
|
return ERR_PTR(-1);
|
2018-08-22 07:58:49 -04:00
|
|
|
}
|