2018-10-03 17:14:51 -04:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Copyright (c) 2012-2014 Richard Grenville <pyxlcy@gmail.com>
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <libgen.h>
|
|
|
|
#include <libconfig.h>
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
*/
|
2018-10-23 17:12:42 -04:00
|
|
|
static inline int
|
|
|
|
lcfg_lookup_bool(const config_t *config, const char *path, bool *value) {
|
2018-08-22 07:58:49 -04:00
|
|
|
int ival;
|
|
|
|
|
2018-10-23 17:12:42 -04:00
|
|
|
int ret = config_lookup_bool(config, path, &ival);
|
|
|
|
if (ret)
|
2018-08-22 07:58:49 -04:00
|
|
|
*value = ival;
|
|
|
|
|
2018-10-23 17:12:42 -04:00
|
|
|
return ret;
|
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.
|
|
|
|
*/
|
|
|
|
FILE *
|
|
|
|
open_config_file(char *cpath, char **ppath) {
|
2018-08-22 10:26:08 -04:00
|
|
|
static const char *config_filename = "/compton.conf";
|
|
|
|
static const char *config_filename_legacy = "/.compton.conf";
|
|
|
|
static const char *config_home_suffix = "/.config";
|
|
|
|
static const char *config_system_dir = "/etc/xdg";
|
2018-08-22 07:58:49 -04:00
|
|
|
|
|
|
|
char *dir = NULL, *home = NULL;
|
|
|
|
char *path = cpath;
|
|
|
|
FILE *f = NULL;
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check user configuration file in $XDG_CONFIG_HOME firstly
|
|
|
|
if (!((dir = getenv("XDG_CONFIG_HOME")) && strlen(dir))) {
|
|
|
|
if (!((home = getenv("HOME")) && strlen(home)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
path = mstrjoin3(home, config_home_suffix, config_filename);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
path = mstrjoin(dir, config_filename);
|
|
|
|
|
|
|
|
f = fopen(path, "r");
|
|
|
|
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
|
|
|
|
// Then check user configuration file in $HOME
|
|
|
|
if ((home = getenv("HOME")) && strlen(home)) {
|
|
|
|
path = mstrjoin(home, config_filename_legacy);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check system configuration file in $XDG_CONFIG_DIRS at last
|
|
|
|
if ((dir = getenv("XDG_CONFIG_DIRS")) && strlen(dir)) {
|
|
|
|
char *part = strtok(dir, ":");
|
|
|
|
while (part) {
|
|
|
|
path = mstrjoin(part, config_filename);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
part = strtok(NULL, ":");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
path = mstrjoin(config_system_dir, config_filename);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse a condition list in configuration file.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
parse_cfg_condlst(session_t *ps, 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);
|
|
|
|
while (i--)
|
|
|
|
condlst_add(ps, pcondlst, config_setting_get_string_elem(setting, i));
|
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
|
|
|
condlst_add(ps, pcondlst, config_setting_get_string(setting));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse an opacity rule list in configuration file.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
parse_cfg_condlst_opct(session_t *ps, 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);
|
|
|
|
while (i--)
|
|
|
|
if (!parse_rule_opacity(ps, config_setting_get_string_elem(setting,
|
|
|
|
i)))
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
|
|
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
|
|
|
parse_rule_opacity(ps, config_setting_get_string(setting));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse a configuration file from default location.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
parse_config(session_t *ps, struct options_tmp *pcfgtmp) {
|
|
|
|
char *path = NULL;
|
|
|
|
FILE *f;
|
|
|
|
config_t cfg;
|
|
|
|
int ival = 0;
|
2018-10-23 17:12:42 -04:00
|
|
|
bool bval;
|
2018-08-22 07:58:49 -04:00
|
|
|
double dval = 0.0;
|
|
|
|
// libconfig manages string memory itself, so no need to manually free
|
|
|
|
// anything
|
|
|
|
const char *sval = NULL;
|
|
|
|
|
|
|
|
f = open_config_file(ps->o.config_file, &path);
|
|
|
|
if (!f) {
|
|
|
|
if (ps->o.config_file) {
|
|
|
|
printf_errfq(1, "(): Failed to read configuration file \"%s\".",
|
|
|
|
ps->o.config_file);
|
|
|
|
free(ps->o.config_file);
|
|
|
|
ps->o.config_file = NULL;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
config_init(&cfg);
|
|
|
|
{
|
|
|
|
// dirname() could modify the original string, thus we must pass a
|
|
|
|
// copy
|
|
|
|
char *path2 = mstrcpy(path);
|
|
|
|
char *parent = dirname(path2);
|
|
|
|
|
|
|
|
if (parent)
|
|
|
|
config_set_include_dir(&cfg, parent);
|
|
|
|
|
|
|
|
free(path2);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
int read_result = config_read(&cfg, f);
|
|
|
|
fclose(f);
|
|
|
|
f = NULL;
|
|
|
|
if (CONFIG_FALSE == read_result) {
|
|
|
|
printf("Error when reading configuration file \"%s\", line %d: %s\n",
|
|
|
|
path, config_error_line(&cfg), config_error_text(&cfg));
|
|
|
|
config_destroy(&cfg);
|
|
|
|
free(path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
config_set_auto_convert(&cfg, 1);
|
|
|
|
|
|
|
|
if (path != ps->o.config_file) {
|
|
|
|
free(ps->o.config_file);
|
|
|
|
ps->o.config_file = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get options from the configuration file. We don't do range checking
|
|
|
|
// right now. It will be done later
|
|
|
|
|
|
|
|
// -D (fade_delta)
|
2018-10-23 17:12:42 -04:00
|
|
|
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
2018-08-22 07:58:49 -04:00
|
|
|
ps->o.fade_delta = ival;
|
|
|
|
// -I (fade_in_step)
|
|
|
|
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
|
|
|
ps->o.fade_in_step = normalize_d(dval) * OPAQUE;
|
|
|
|
// -O (fade_out_step)
|
|
|
|
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
|
|
|
ps->o.fade_out_step = normalize_d(dval) * OPAQUE;
|
|
|
|
// -r (shadow_radius)
|
2018-10-23 17:12:42 -04:00
|
|
|
config_lookup_int(&cfg, "shadow-radius", &ps->o.shadow_radius);
|
2018-08-22 07:58:49 -04:00
|
|
|
// -o (shadow_opacity)
|
|
|
|
config_lookup_float(&cfg, "shadow-opacity", &ps->o.shadow_opacity);
|
|
|
|
// -l (shadow_offset_x)
|
2018-10-23 17:12:42 -04:00
|
|
|
config_lookup_int(&cfg, "shadow-offset-x", &ps->o.shadow_offset_x);
|
2018-08-22 07:58:49 -04:00
|
|
|
// -t (shadow_offset_y)
|
2018-10-23 17:12:42 -04:00
|
|
|
config_lookup_int(&cfg, "shadow-offset-y", &ps->o.shadow_offset_y);
|
2018-08-22 07:58:49 -04:00
|
|
|
// -i (inactive_opacity)
|
|
|
|
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
|
|
|
ps->o.inactive_opacity = normalize_d(dval) * OPAQUE;
|
|
|
|
// --active_opacity
|
|
|
|
if (config_lookup_float(&cfg, "active-opacity", &dval))
|
|
|
|
ps->o.active_opacity = normalize_d(dval) * OPAQUE;
|
|
|
|
// -e (frame_opacity)
|
|
|
|
config_lookup_float(&cfg, "frame-opacity", &ps->o.frame_opacity);
|
|
|
|
// -c (shadow_enable)
|
|
|
|
if (config_lookup_bool(&cfg, "shadow", &ival) && ival)
|
|
|
|
wintype_arr_enable(ps->o.wintype_shadow);
|
|
|
|
// -C (no_dock_shadow)
|
|
|
|
lcfg_lookup_bool(&cfg, "no-dock-shadow", &pcfgtmp->no_dock_shadow);
|
|
|
|
// -G (no_dnd_shadow)
|
|
|
|
lcfg_lookup_bool(&cfg, "no-dnd-shadow", &pcfgtmp->no_dnd_shadow);
|
|
|
|
// -m (menu_opacity)
|
|
|
|
config_lookup_float(&cfg, "menu-opacity", &pcfgtmp->menu_opacity);
|
|
|
|
// -f (fading_enable)
|
|
|
|
if (config_lookup_bool(&cfg, "fading", &ival) && ival)
|
|
|
|
wintype_arr_enable(ps->o.wintype_fade);
|
|
|
|
// --no-fading-open-close
|
|
|
|
lcfg_lookup_bool(&cfg, "no-fading-openclose", &ps->o.no_fading_openclose);
|
|
|
|
// --no-fading-destroyed-argb
|
|
|
|
lcfg_lookup_bool(&cfg, "no-fading-destroyed-argb",
|
|
|
|
&ps->o.no_fading_destroyed_argb);
|
|
|
|
// --shadow-red
|
|
|
|
config_lookup_float(&cfg, "shadow-red", &ps->o.shadow_red);
|
|
|
|
// --shadow-green
|
|
|
|
config_lookup_float(&cfg, "shadow-green", &ps->o.shadow_green);
|
|
|
|
// --shadow-blue
|
|
|
|
config_lookup_float(&cfg, "shadow-blue", &ps->o.shadow_blue);
|
|
|
|
// --shadow-exclude-reg
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-29 23:56:00 -04:00
|
|
|
if (config_lookup_string(&cfg, "shadow-exclude-reg", &sval))
|
|
|
|
ps->o.shadow_exclude_reg_str = strdup(sval);
|
2018-08-22 07:58:49 -04:00
|
|
|
// --inactive-opacity-override
|
|
|
|
lcfg_lookup_bool(&cfg, "inactive-opacity-override",
|
|
|
|
&ps->o.inactive_opacity_override);
|
|
|
|
// --inactive-dim
|
|
|
|
config_lookup_float(&cfg, "inactive-dim", &ps->o.inactive_dim);
|
|
|
|
// --mark-wmwin-focused
|
|
|
|
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &ps->o.mark_wmwin_focused);
|
|
|
|
// --mark-ovredir-focused
|
|
|
|
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
|
|
|
&ps->o.mark_ovredir_focused);
|
|
|
|
// --shadow-ignore-shaped
|
|
|
|
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
|
|
|
&ps->o.shadow_ignore_shaped);
|
|
|
|
// --detect-rounded-corners
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
|
|
|
&ps->o.detect_rounded_corners);
|
|
|
|
// --xinerama-shadow-crop
|
|
|
|
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop",
|
|
|
|
&ps->o.xinerama_shadow_crop);
|
|
|
|
// --detect-client-opacity
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-client-opacity",
|
|
|
|
&ps->o.detect_client_opacity);
|
|
|
|
// --refresh-rate
|
2018-10-23 17:12:42 -04:00
|
|
|
config_lookup_int(&cfg, "refresh-rate", &ps->o.refresh_rate);
|
2018-08-22 07:58:49 -04:00
|
|
|
// --vsync
|
|
|
|
if (config_lookup_string(&cfg, "vsync", &sval) && !parse_vsync(ps, sval))
|
|
|
|
exit(1);
|
|
|
|
// --backend
|
|
|
|
if (config_lookup_string(&cfg, "backend", &sval) && !parse_backend(ps, sval))
|
|
|
|
exit(1);
|
|
|
|
// --sw-opti
|
|
|
|
lcfg_lookup_bool(&cfg, "sw-opti", &ps->o.sw_opti);
|
|
|
|
// --use-ewmh-active-win
|
|
|
|
lcfg_lookup_bool(&cfg, "use-ewmh-active-win",
|
|
|
|
&ps->o.use_ewmh_active_win);
|
|
|
|
// --unredir-if-possible
|
|
|
|
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
|
|
|
&ps->o.unredir_if_possible);
|
|
|
|
// --unredir-if-possible-delay
|
2018-10-23 17:12:42 -04:00
|
|
|
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival))
|
2018-08-22 07:58:49 -04:00
|
|
|
ps->o.unredir_if_possible_delay = ival;
|
|
|
|
// --inactive-dim-fixed
|
|
|
|
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &ps->o.inactive_dim_fixed);
|
|
|
|
// --detect-transient
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-transient", &ps->o.detect_transient);
|
|
|
|
// --detect-client-leader
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-client-leader",
|
|
|
|
&ps->o.detect_client_leader);
|
|
|
|
// --shadow-exclude
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
|
|
|
// --fade-exclude
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.fade_blacklist, "fade-exclude");
|
|
|
|
// --focus-exclude
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.focus_blacklist, "focus-exclude");
|
|
|
|
// --invert-color-include
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.invert_color_list, "invert-color-include");
|
|
|
|
// --blur-background-exclude
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.blur_background_blacklist, "blur-background-exclude");
|
|
|
|
// --opacity-rule
|
|
|
|
parse_cfg_condlst_opct(ps, &cfg, "opacity-rule");
|
|
|
|
// --unredir-if-possible-exclude
|
|
|
|
parse_cfg_condlst(ps, &cfg, &ps->o.unredir_if_possible_blacklist, "unredir-if-possible-exclude");
|
|
|
|
// --blur-background
|
|
|
|
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
|
|
|
|
// --blur-background-frame
|
|
|
|
lcfg_lookup_bool(&cfg, "blur-background-frame",
|
|
|
|
&ps->o.blur_background_frame);
|
|
|
|
// --blur-background-fixed
|
|
|
|
lcfg_lookup_bool(&cfg, "blur-background-fixed",
|
|
|
|
&ps->o.blur_background_fixed);
|
|
|
|
// --blur-kern
|
|
|
|
if (config_lookup_string(&cfg, "blur-kern", &sval)
|
|
|
|
&& !parse_conv_kern_lst(ps, sval, ps->o.blur_kerns, MAX_BLUR_PASS))
|
|
|
|
exit(1);
|
|
|
|
// --resize-damage
|
2018-10-23 17:12:42 -04:00
|
|
|
config_lookup_int(&cfg, "resize-damage", &ps->o.resize_damage);
|
2018-08-22 07:58:49 -04:00
|
|
|
// --glx-no-stencil
|
|
|
|
lcfg_lookup_bool(&cfg, "glx-no-stencil", &ps->o.glx_no_stencil);
|
|
|
|
// --glx-no-rebind-pixmap
|
|
|
|
lcfg_lookup_bool(&cfg, "glx-no-rebind-pixmap", &ps->o.glx_no_rebind_pixmap);
|
|
|
|
// --glx-swap-method
|
|
|
|
if (config_lookup_string(&cfg, "glx-swap-method", &sval)
|
|
|
|
&& !parse_glx_swap_method(ps, sval))
|
|
|
|
exit(1);
|
|
|
|
// --glx-use-gpushader4
|
|
|
|
lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &ps->o.glx_use_gpushader4);
|
2018-11-08 09:53:13 -05:00
|
|
|
// --xrender-sync
|
|
|
|
lcfg_lookup_bool(&cfg, "xrender-sync", &ps->o.xrender_sync);
|
|
|
|
// --xrender-sync-fence
|
|
|
|
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &ps->o.xrender_sync_fence);
|
2018-10-23 17:12:42 -04:00
|
|
|
|
|
|
|
if (lcfg_lookup_bool(&cfg, "clear-shadow", &bval))
|
|
|
|
printf_errf("(): \"clear-shadow\" is removed as an option, and is always"
|
|
|
|
" enabled now. Consider removing it from your config file");
|
2018-11-03 10:04:18 -04:00
|
|
|
if (lcfg_lookup_bool(&cfg, "paint-on-overlay", &bval))
|
|
|
|
printf_errf("(): \"paint-on-overlay\" has been removed as an option, and "
|
|
|
|
"is enabled whenever possible");
|
2018-10-23 17:12:42 -04:00
|
|
|
|
2018-11-10 07:48:36 -05:00
|
|
|
if (config_lookup_float(&cfg, "alpha-step", &dval))
|
|
|
|
printf_errf("(): \"alpha-step\" has been removed, compton now tries to make use"
|
|
|
|
" of all alpha values");
|
|
|
|
|
2018-10-23 17:12:42 -04:00
|
|
|
const char *deprecation_message = "has been removed. If you encounter problems "
|
2018-11-10 07:48:36 -05:00
|
|
|
"without this feature, please feel free to open a bug report";
|
2018-10-23 17:12:42 -04:00
|
|
|
if (lcfg_lookup_bool(&cfg, "glx-use-copysubbuffermesa", &bval) && bval)
|
|
|
|
printf_errf("(): \"glx-use-copysubbuffermesa\" %s", deprecation_message);
|
|
|
|
if (lcfg_lookup_bool(&cfg, "glx-copy-from-front", &bval) && bval)
|
|
|
|
printf_errf("(): \"glx-copy-from-front\" %s", deprecation_message);
|
|
|
|
|
2018-08-22 07:58:49 -04:00
|
|
|
// Wintype settings
|
|
|
|
|
2018-11-09 14:56:05 -05:00
|
|
|
// XXX ! Refactor all the wintype_* arrays into a struct
|
2018-08-22 07:58:49 -04:00
|
|
|
for (wintype_t i = 0; i < NUM_WINTYPES; ++i) {
|
|
|
|
char *str = mstrjoin("wintypes.", WINTYPES[i]);
|
|
|
|
config_setting_t *setting = config_lookup(&cfg, str);
|
|
|
|
free(str);
|
|
|
|
if (setting) {
|
|
|
|
if (config_setting_lookup_bool(setting, "shadow", &ival))
|
|
|
|
ps->o.wintype_shadow[i] = (bool) ival;
|
|
|
|
if (config_setting_lookup_bool(setting, "fade", &ival))
|
|
|
|
ps->o.wintype_fade[i] = (bool) ival;
|
|
|
|
if (config_setting_lookup_bool(setting, "focus", &ival))
|
|
|
|
ps->o.wintype_focus[i] = (bool) ival;
|
2018-11-09 14:56:05 -05:00
|
|
|
if (config_setting_lookup_bool(setting, "full-shadow", &ival))
|
|
|
|
ps->o.wintype_full_shadow[i] = ival;
|
2018-08-22 07:58:49 -04:00
|
|
|
|
|
|
|
double fval;
|
|
|
|
if (config_setting_lookup_float(setting, "opacity", &fval))
|
|
|
|
ps->o.wintype_opacity[i] = normalize_d(fval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
config_destroy(&cfg);
|
|
|
|
}
|