mirror of
https://github.com/yshui/picom.git
synced 2024-10-27 05:24:17 -04:00
Merge pull request #72 from yshui/clean-opt2
Option/config parsing clean up
This commit is contained in:
commit
4dce20fab4
12 changed files with 730 additions and 609 deletions
58
src/c2.c
58
src/c2.c
|
@ -34,6 +34,8 @@
|
|||
#include "utils.h"
|
||||
#include "log.h"
|
||||
|
||||
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||
|
||||
#define C2_MAX_LEVELS 10
|
||||
|
||||
typedef struct _c2_b c2_b_t;
|
||||
|
@ -301,22 +303,19 @@ c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
|||
}
|
||||
|
||||
static int
|
||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||
c2_parse_grp(const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||
|
||||
static int
|
||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static bool
|
||||
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
||||
c2_parse_legacy(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static void
|
||||
c2_free(c2_ptr_t p);
|
||||
|
@ -351,7 +350,7 @@ c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
|||
* Parse a condition string.
|
||||
*/
|
||||
c2_lptr_t *
|
||||
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||
c2_parse(c2_lptr_t **pcondlst, const char *pattern,
|
||||
void *data) {
|
||||
if (!pattern)
|
||||
return NULL;
|
||||
|
@ -361,9 +360,9 @@ c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
|||
int offset = -1;
|
||||
|
||||
if (strlen(pattern) >= 2 && ':' == pattern[1])
|
||||
offset = c2_parse_legacy(ps, pattern, 0, &result);
|
||||
offset = c2_parse_legacy(pattern, 0, &result);
|
||||
else
|
||||
offset = c2_parse_grp(ps, pattern, 0, &result, 0);
|
||||
offset = c2_parse_grp(pattern, 0, &result, 0);
|
||||
|
||||
if (offset < 0) {
|
||||
c2_freep(&result);
|
||||
|
@ -405,7 +404,7 @@ c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
|||
* @return offset of next character in string
|
||||
*/
|
||||
static int
|
||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level) {
|
||||
c2_parse_grp(const char *pattern, int offset, c2_ptr_t *presult, int level) {
|
||||
// Check for recursion levels
|
||||
if (level > C2_MAX_LEVELS)
|
||||
c2_error("Exceeded maximum recursion levels.");
|
||||
|
@ -505,12 +504,12 @@ c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult,
|
|||
|
||||
// It's a subgroup if it starts with '('
|
||||
if ('(' == pattern[offset]) {
|
||||
if ((offset = c2_parse_grp(ps, pattern, offset + 1, pele, level + 1)) < 0)
|
||||
if ((offset = c2_parse_grp(pattern, offset + 1, pele, level + 1)) < 0)
|
||||
goto fail;
|
||||
}
|
||||
// Otherwise it's a leaf
|
||||
else {
|
||||
if ((offset = c2_parse_target(ps, pattern, offset, pele)) < 0)
|
||||
if ((offset = c2_parse_target(pattern, offset, pele)) < 0)
|
||||
goto fail;
|
||||
|
||||
assert(!pele->isbranch && !c2_ptr_isempty(*pele));
|
||||
|
@ -518,10 +517,7 @@ c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult,
|
|||
if ((offset = c2_parse_op(pattern, offset, pele)) < 0)
|
||||
goto fail;
|
||||
|
||||
if ((offset = c2_parse_pattern(ps, pattern, offset, pele)) < 0)
|
||||
goto fail;
|
||||
|
||||
if (!c2_l_postprocess(ps, pele->l))
|
||||
if ((offset = c2_parse_pattern(pattern, offset, pele)) < 0)
|
||||
goto fail;
|
||||
}
|
||||
// Decrement offset -- we will increment it in loop update
|
||||
|
@ -579,7 +575,7 @@ fail:
|
|||
* Parse the target part of a rule.
|
||||
*/
|
||||
static int
|
||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
// Initialize leaf
|
||||
presult->isbranch = false;
|
||||
presult->l = cmalloc(c2_l_t);
|
||||
|
@ -838,7 +834,7 @@ fail:
|
|||
* Parse the pattern part of a leaf.
|
||||
*/
|
||||
static int
|
||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
c2_l_t * const pleaf = presult->l;
|
||||
|
||||
// Exists operator cannot have pattern
|
||||
|
@ -977,7 +973,7 @@ fail:
|
|||
* Parse a condition with legacy syntax.
|
||||
*/
|
||||
static int
|
||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
c2_parse_legacy(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||
unsigned plen = strlen(pattern + offset);
|
||||
|
||||
if (plen < 4 || ':' != pattern[offset + 1]
|
||||
|
@ -1033,9 +1029,6 @@ c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presul
|
|||
// Copy the pattern
|
||||
pleaf->ptnstr = strdup(pattern + offset);
|
||||
|
||||
if (!c2_l_postprocess(ps, pleaf))
|
||||
return -1;
|
||||
|
||||
return offset;
|
||||
|
||||
fail:
|
||||
|
@ -1145,6 +1138,25 @@ c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool c2_tree_postprocess(session_t *ps, c2_ptr_t node) {
|
||||
if (!node.isbranch) {
|
||||
return c2_l_postprocess(ps, node.l);
|
||||
}
|
||||
if (!c2_tree_postprocess(ps, node.b->opr1))
|
||||
return false;
|
||||
return c2_tree_postprocess(ps, node.b->opr2);
|
||||
}
|
||||
|
||||
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list) {
|
||||
c2_lptr_t *head = list;
|
||||
while (head) {
|
||||
if (!c2_tree_postprocess(ps, head->ptr))
|
||||
return false;
|
||||
head = head->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Free a condition tree.
|
||||
*/
|
||||
|
|
14
src/c2.h
14
src/c2.h
|
@ -17,13 +17,11 @@ typedef struct _c2_lptr c2_lptr_t;
|
|||
typedef struct session session_t;
|
||||
typedef struct win win;
|
||||
|
||||
c2_lptr_t *
|
||||
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||
void *data);
|
||||
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
|
||||
|
||||
c2_lptr_t *
|
||||
c2_free_lptr(c2_lptr_t *lp);
|
||||
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp);
|
||||
|
||||
bool
|
||||
c2_match(session_t *ps, win *w, const c2_lptr_t *condlst,
|
||||
const c2_lptr_t **cache, void **pdata);
|
||||
bool c2_match(session_t *ps, win *w, const c2_lptr_t *condlst, const c2_lptr_t **cache,
|
||||
void **pdata);
|
||||
|
||||
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list);
|
||||
|
|
323
src/common.h
323
src/common.h
|
@ -122,6 +122,7 @@
|
|||
#include "utils.h"
|
||||
#include "compiler.h"
|
||||
#include "kernel.h"
|
||||
#include "options.h"
|
||||
|
||||
// === Constants ===
|
||||
|
||||
|
@ -155,9 +156,6 @@
|
|||
/// @brief Maximum OpenGL buffer age.
|
||||
#define CGLX_MAX_BUFFER_AGE 5
|
||||
|
||||
/// @brief Maximum passes for blur.
|
||||
#define MAX_BLUR_PASS 5
|
||||
|
||||
// Window flags
|
||||
|
||||
// Window size is changed
|
||||
|
@ -173,9 +171,6 @@
|
|||
|
||||
// === Types ===
|
||||
|
||||
typedef long time_ms_t;
|
||||
typedef struct _c2_lptr c2_lptr_t;
|
||||
|
||||
/// Structure representing needed window updates.
|
||||
typedef struct {
|
||||
bool shadow : 1;
|
||||
|
@ -206,25 +201,6 @@ enum wincond_type {
|
|||
|
||||
#define CONDF_IGNORECASE 0x0001
|
||||
|
||||
/// VSync modes.
|
||||
typedef enum {
|
||||
VSYNC_NONE,
|
||||
VSYNC_DRM,
|
||||
VSYNC_OPENGL,
|
||||
VSYNC_OPENGL_OML,
|
||||
VSYNC_OPENGL_SWC,
|
||||
VSYNC_OPENGL_MSWC,
|
||||
NUM_VSYNC,
|
||||
} vsync_t;
|
||||
|
||||
/// @brief Possible backends of compton.
|
||||
enum backend {
|
||||
BKEND_XRENDER,
|
||||
BKEND_GLX,
|
||||
BKEND_XR_GLX_HYBRID,
|
||||
NUM_BKEND,
|
||||
};
|
||||
|
||||
/// @brief Possible swap methods.
|
||||
enum {
|
||||
SWAPM_BUFFER_AGE = -1,
|
||||
|
@ -371,202 +347,6 @@ typedef struct _latom {
|
|||
|
||||
#define REG_DATA_INIT { NULL, 0 }
|
||||
|
||||
typedef struct win_option_mask {
|
||||
bool shadow: 1;
|
||||
bool fade: 1;
|
||||
bool focus: 1;
|
||||
bool full_shadow: 1;
|
||||
bool redir_ignore: 1;
|
||||
bool opacity: 1;
|
||||
} win_option_mask_t;
|
||||
|
||||
typedef struct win_option {
|
||||
bool shadow;
|
||||
bool fade;
|
||||
bool focus;
|
||||
bool full_shadow;
|
||||
bool redir_ignore;
|
||||
double opacity;
|
||||
} win_option_t;
|
||||
|
||||
/// Structure representing all options.
|
||||
typedef struct options_t {
|
||||
// === Debugging ===
|
||||
bool monitor_repaint;
|
||||
bool print_diagnostics;
|
||||
// === General ===
|
||||
/// The configuration file we used.
|
||||
char *config_file;
|
||||
/// Path to write PID to.
|
||||
char *write_pid_path;
|
||||
/// The backend in use.
|
||||
enum backend backend;
|
||||
/// Whether to sync X drawing to avoid certain delay issues with
|
||||
/// GLX backend.
|
||||
bool xrender_sync;
|
||||
/// Whether to sync X drawing with X Sync fence.
|
||||
bool xrender_sync_fence;
|
||||
/// Whether to avoid using stencil buffer under GLX backend. Might be
|
||||
/// unsafe.
|
||||
bool glx_no_stencil;
|
||||
/// Whether to avoid rebinding pixmap on window damage.
|
||||
bool glx_no_rebind_pixmap;
|
||||
/// GLX swap method we assume OpenGL uses.
|
||||
int glx_swap_method;
|
||||
/// Whether to use GL_EXT_gpu_shader4 to (hopefully) accelerates blurring.
|
||||
bool glx_use_gpushader4;
|
||||
/// Custom fragment shader for painting windows, as a string.
|
||||
char *glx_fshader_win_str;
|
||||
/// Custom GLX program used for painting window.
|
||||
glx_prog_main_t glx_prog_win;
|
||||
/// Whether to fork to background.
|
||||
bool fork_after_register;
|
||||
/// Whether to detect rounded corners.
|
||||
bool detect_rounded_corners;
|
||||
/// Force painting of window content with blending.
|
||||
bool force_win_blend;
|
||||
/// Resize damage for a specific number of pixels.
|
||||
int resize_damage;
|
||||
/// Whether to unredirect all windows if a full-screen opaque window
|
||||
/// is detected.
|
||||
bool unredir_if_possible;
|
||||
/// List of conditions of windows to ignore as a full-screen window
|
||||
/// when determining if a window could be unredirected.
|
||||
c2_lptr_t *unredir_if_possible_blacklist;
|
||||
/// Delay before unredirecting screen.
|
||||
time_ms_t unredir_if_possible_delay;
|
||||
/// Forced redirection setting through D-Bus.
|
||||
switch_t redirected_force;
|
||||
/// Whether to stop painting. Controlled through D-Bus.
|
||||
switch_t stoppaint_force;
|
||||
/// Whether to re-redirect screen on root size change.
|
||||
bool reredir_on_root_change;
|
||||
/// Whether to reinitialize GLX on root size change.
|
||||
bool glx_reinit_on_root_change;
|
||||
/// Whether to enable D-Bus support.
|
||||
bool dbus;
|
||||
/// Path to log file.
|
||||
char *logpath;
|
||||
/// Number of cycles to paint in benchmark mode. 0 for disabled.
|
||||
int benchmark;
|
||||
/// Window to constantly repaint in benchmark mode. 0 for full-screen.
|
||||
Window benchmark_wid;
|
||||
/// A list of conditions of windows not to paint.
|
||||
c2_lptr_t *paint_blacklist;
|
||||
/// Whether to show all X errors.
|
||||
bool show_all_xerrors;
|
||||
/// Whether to avoid acquiring X Selection.
|
||||
bool no_x_selection;
|
||||
/// Window type option override.
|
||||
win_option_t wintype_option[NUM_WINTYPES];
|
||||
|
||||
// === VSync & software optimization ===
|
||||
/// User-specified refresh rate.
|
||||
int refresh_rate;
|
||||
/// Whether to enable refresh-rate-based software optimization.
|
||||
bool sw_opti;
|
||||
/// VSync method to use;
|
||||
vsync_t vsync;
|
||||
/// Whether to do VSync aggressively.
|
||||
bool vsync_aggressive;
|
||||
/// Whether to use glFinish() instead of glFlush() for (possibly) better
|
||||
/// VSync yet probably higher CPU usage.
|
||||
bool vsync_use_glfinish;
|
||||
|
||||
// === Shadow ===
|
||||
/// Red, green and blue tone of the shadow.
|
||||
double shadow_red, shadow_green, shadow_blue;
|
||||
int shadow_radius;
|
||||
int shadow_offset_x, shadow_offset_y;
|
||||
double shadow_opacity;
|
||||
/// argument string to shadow-exclude-reg option
|
||||
char *shadow_exclude_reg_str;
|
||||
/// Shadow blacklist. A linked list of conditions.
|
||||
c2_lptr_t *shadow_blacklist;
|
||||
/// Whether bounding-shaped window should be ignored.
|
||||
bool shadow_ignore_shaped;
|
||||
/// Whether to respect _COMPTON_SHADOW.
|
||||
bool respect_prop_shadow;
|
||||
/// Whether to crop shadow to the very Xinerama screen.
|
||||
bool xinerama_shadow_crop;
|
||||
|
||||
// === Fading ===
|
||||
/// How much to fade in in a single fading step.
|
||||
opacity_t fade_in_step;
|
||||
/// How much to fade out in a single fading step.
|
||||
opacity_t fade_out_step;
|
||||
/// Fading time delta. In milliseconds.
|
||||
time_ms_t fade_delta;
|
||||
/// Whether to disable fading on window open/close.
|
||||
bool no_fading_openclose;
|
||||
/// Whether to disable fading on ARGB managed destroyed windows.
|
||||
bool no_fading_destroyed_argb;
|
||||
/// Fading blacklist. A linked list of conditions.
|
||||
c2_lptr_t *fade_blacklist;
|
||||
|
||||
// === Opacity ===
|
||||
/// Default opacity for inactive windows.
|
||||
/// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for
|
||||
/// not enabled, default.
|
||||
opacity_t inactive_opacity;
|
||||
/// Default opacity for inactive windows.
|
||||
opacity_t active_opacity;
|
||||
/// Whether inactive_opacity overrides the opacity set by window
|
||||
/// attributes.
|
||||
bool inactive_opacity_override;
|
||||
/// Frame opacity. Relative to window opacity, also affects shadow
|
||||
/// opacity.
|
||||
double frame_opacity;
|
||||
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
||||
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
||||
bool detect_client_opacity;
|
||||
|
||||
// === Other window processing ===
|
||||
/// Whether to blur background of semi-transparent / ARGB windows.
|
||||
bool blur_background;
|
||||
/// Whether to blur background when the window frame is not opaque.
|
||||
/// Implies blur_background.
|
||||
bool blur_background_frame;
|
||||
/// Whether to use fixed blur strength instead of adjusting according
|
||||
/// to window opacity.
|
||||
bool blur_background_fixed;
|
||||
/// Background blur blacklist. A linked list of conditions.
|
||||
c2_lptr_t *blur_background_blacklist;
|
||||
/// Blur convolution kernel.
|
||||
xcb_render_fixed_t *blur_kerns[MAX_BLUR_PASS];
|
||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||
double inactive_dim;
|
||||
/// Whether to use fixed inactive dim opacity, instead of deciding
|
||||
/// based on window opacity.
|
||||
bool inactive_dim_fixed;
|
||||
/// Conditions of windows to have inverted colors.
|
||||
c2_lptr_t *invert_color_list;
|
||||
/// Rules to change window opacity.
|
||||
c2_lptr_t *opacity_rules;
|
||||
|
||||
// === Focus related ===
|
||||
/// Whether to try to detect WM windows and mark them as focused.
|
||||
bool mark_wmwin_focused;
|
||||
/// Whether to mark override-redirect windows as focused.
|
||||
bool mark_ovredir_focused;
|
||||
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
||||
bool use_ewmh_active_win;
|
||||
/// A list of windows always to be considered focused.
|
||||
c2_lptr_t *focus_blacklist;
|
||||
/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
|
||||
bool detect_transient;
|
||||
/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
|
||||
bool detect_client_leader;
|
||||
|
||||
// === Calculated ===
|
||||
/// Whether compton needs to track focus changes.
|
||||
bool track_focus;
|
||||
/// Whether compton needs to track window name and class.
|
||||
bool track_wdata;
|
||||
/// Whether compton needs to track window leaders.
|
||||
bool track_leader;
|
||||
} options_t;
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
/// Structure containing GLX-dependent data for a compton session.
|
||||
typedef struct {
|
||||
|
@ -687,6 +467,9 @@ typedef struct session {
|
|||
#ifdef CONFIG_OPENGL
|
||||
/// Pointer to GLX data.
|
||||
glx_session_t *psglx;
|
||||
/// Custom GLX program used for painting window.
|
||||
// XXX should be in glx_session_t
|
||||
glx_prog_main_t glx_prog_win;
|
||||
#endif
|
||||
|
||||
// === Operation related ===
|
||||
|
@ -710,7 +493,7 @@ typedef struct session {
|
|||
/// Pre-generated alpha pictures.
|
||||
xcb_render_picture_t *alpha_picts;
|
||||
/// Time of last fading. In milliseconds.
|
||||
time_ms_t fade_time;
|
||||
unsigned long fade_time;
|
||||
/// Head pointer of the error ignore linked list.
|
||||
ignore_t *ignore_head;
|
||||
/// Pointer to the <code>next</code> member of tail element of the error
|
||||
|
@ -894,8 +677,6 @@ typedef enum {
|
|||
} win_evmode_t;
|
||||
|
||||
extern const char * const WINTYPES[NUM_WINTYPES];
|
||||
extern const char * const VSYNC_STRS[NUM_VSYNC + 1];
|
||||
extern const char * const BACKEND_STRS[NUM_BKEND + 1];
|
||||
extern session_t *ps_g;
|
||||
|
||||
// == Debugging code ==
|
||||
|
@ -924,7 +705,7 @@ timeval_isempty(struct timeval *ptv) {
|
|||
* @return > 0 if ptv > ms, 0 if ptv == 0, -1 if ptv < ms
|
||||
*/
|
||||
static inline int
|
||||
timeval_ms_cmp(struct timeval *ptv, time_ms_t ms) {
|
||||
timeval_ms_cmp(struct timeval *ptv, unsigned long ms) {
|
||||
assert(ptv);
|
||||
|
||||
// We use those if statement instead of a - expression because of possible
|
||||
|
@ -1067,97 +848,6 @@ print_timestamp(session_t *ps) {
|
|||
fprintf(stderr, "[ %5ld.%06ld ] ", diff.tv_sec, diff.tv_usec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a VSync option argument.
|
||||
*/
|
||||
static inline bool
|
||||
parse_vsync(session_t *ps, const char *str) {
|
||||
for (vsync_t i = 0; VSYNC_STRS[i]; ++i)
|
||||
if (!strcasecmp(str, VSYNC_STRS[i])) {
|
||||
ps->o.vsync = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
log_error("Invalid vsync argument: %s", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a backend option argument.
|
||||
*/
|
||||
static inline bool
|
||||
parse_backend(session_t *ps, const char *str) {
|
||||
for (enum backend i = 0; BACKEND_STRS[i]; ++i)
|
||||
if (!strcasecmp(str, BACKEND_STRS[i])) {
|
||||
ps->o.backend = i;
|
||||
return true;
|
||||
}
|
||||
// Keep compatibility with an old revision containing a spelling mistake...
|
||||
if (!strcasecmp(str, "xr_glx_hybird")) {
|
||||
ps->o.backend = BKEND_XR_GLX_HYBRID;
|
||||
return true;
|
||||
}
|
||||
// cju wants to use dashes
|
||||
if (!strcasecmp(str, "xr-glx-hybrid")) {
|
||||
ps->o.backend = BKEND_XR_GLX_HYBRID;
|
||||
return true;
|
||||
}
|
||||
log_error("Invalid backend argument: %s", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a glx_swap_method option argument.
|
||||
*/
|
||||
static inline bool
|
||||
parse_glx_swap_method(session_t *ps, const char *str) {
|
||||
// Parse alias
|
||||
if (!strcmp("undefined", str)) {
|
||||
ps->o.glx_swap_method = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp("copy", str)) {
|
||||
ps->o.glx_swap_method = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp("exchange", str)) {
|
||||
ps->o.glx_swap_method = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp("buffer-age", str)) {
|
||||
ps->o.glx_swap_method = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parse number
|
||||
{
|
||||
char *pc = NULL;
|
||||
int age = strtol(str, &pc, 0);
|
||||
if (!pc || str == pc) {
|
||||
log_error("glx-swap-method is an invalid number: %s", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; *pc; ++pc)
|
||||
if (!isspace(*pc)) {
|
||||
log_error("Trailing characters in glx-swap-method option: %s", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (age > CGLX_MAX_BUFFER_AGE + 1 || age < -1) {
|
||||
log_error("Number for glx-swap-method is too large / too small: %s", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
ps->o.glx_swap_method = age;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper of XFree() for convenience.
|
||||
*
|
||||
|
@ -1187,6 +877,7 @@ get_atom(session_t *ps, const char *atom_name) {
|
|||
|
||||
xcb_atom_t atom = XCB_NONE;
|
||||
if (reply) {
|
||||
log_debug("Atom %s is %d", atom_name, reply->atom);
|
||||
atom = reply->atom;
|
||||
free(reply);
|
||||
} else
|
||||
|
|
|
@ -190,7 +190,7 @@ free_win_res(session_t *ps, win *w) {
|
|||
/**
|
||||
* Get current system clock in milliseconds.
|
||||
*/
|
||||
static inline time_ms_t
|
||||
static inline unsigned long
|
||||
get_time_ms(void) {
|
||||
struct timeval tv;
|
||||
|
||||
|
@ -350,7 +350,11 @@ void add_damage(session_t *ps, const region_t *damage) {
|
|||
*/
|
||||
static double
|
||||
fade_timeout(session_t *ps) {
|
||||
int diff = ps->o.fade_delta - get_time_ms() + ps->fade_time;
|
||||
auto now = get_time_ms();
|
||||
if (ps->o.fade_delta + ps->fade_time < now)
|
||||
return 0;
|
||||
|
||||
int diff = ps->o.fade_delta + ps->fade_time - now;
|
||||
|
||||
diff = normalize_i_range(diff, 0, ps->o.fade_delta * 2);
|
||||
|
||||
|
@ -547,13 +551,13 @@ paint_preprocess(session_t *ps, win *list) {
|
|||
win *t = NULL, *next = NULL;
|
||||
|
||||
// Fading step calculation
|
||||
time_ms_t steps = 0L;
|
||||
if (ps->fade_time)
|
||||
steps = (get_time_ms() - ps->fade_time +
|
||||
FADE_DELTA_TOLERANCE*ps->o.fade_delta) /
|
||||
ps->o.fade_delta;
|
||||
unsigned long steps = 0L;
|
||||
auto now = get_time_ms();
|
||||
auto tolerance = FADE_DELTA_TOLERANCE*ps->o.fade_delta;
|
||||
if (ps->fade_time && now+tolerance >= ps->fade_time) {
|
||||
steps = (now - ps->fade_time + tolerance) / ps->o.fade_delta;
|
||||
} else {
|
||||
// Reset fade_time if unset, or there appears to be a time disorder
|
||||
if (!ps->fade_time || steps < 0L) {
|
||||
ps->fade_time = get_time_ms();
|
||||
steps = 0L;
|
||||
}
|
||||
|
@ -2567,13 +2571,13 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
|||
.tgt_picture = None,
|
||||
.tgt_buffer = PAINT_INIT,
|
||||
.reg_win = None,
|
||||
#ifdef CONFIG_OPENGL
|
||||
.glx_prog_win = GLX_PROG_MAIN_INIT,
|
||||
#endif
|
||||
.o = {
|
||||
.config_file = NULL,
|
||||
.backend = BKEND_XRENDER,
|
||||
.glx_no_stencil = false,
|
||||
#ifdef CONFIG_OPENGL
|
||||
.glx_prog_win = GLX_PROG_MAIN_INIT,
|
||||
#endif
|
||||
.mark_wmwin_focused = false,
|
||||
.mark_ovredir_focused = false,
|
||||
.fork_after_register = false,
|
||||
|
@ -2830,8 +2834,28 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
|||
xcb_discard_reply(ps->c,
|
||||
xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence);
|
||||
|
||||
// Second pass
|
||||
get_cfg(ps, argc, argv);
|
||||
// Parse configuration file
|
||||
win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}};
|
||||
bool shadow_enabled = false, fading_enable = false, hasneg = false;
|
||||
char *config_file = parse_config(&ps->o, ps->o.config_file, &shadow_enabled,
|
||||
&fading_enable, &hasneg, winopt_mask);
|
||||
free(ps->o.config_file);
|
||||
ps->o.config_file = config_file;
|
||||
|
||||
// Parse all of the rest command line options
|
||||
get_cfg(&ps->o, argc, argv, shadow_enabled, fading_enable, hasneg, winopt_mask);
|
||||
|
||||
// Get needed atoms for c2 condition lists
|
||||
if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.paint_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.shadow_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.fade_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.blur_background_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.invert_color_list) &&
|
||||
c2_list_postprocess(ps, ps->o.opacity_rules) &&
|
||||
c2_list_postprocess(ps, ps->o.focus_blacklist))) {
|
||||
log_error("Post-processing of conditionals failed, some of your rules might not work");
|
||||
}
|
||||
|
||||
rebuild_shadow_exclude_reg(ps);
|
||||
|
||||
|
|
59
src/config.c
59
src/config.c
|
@ -59,8 +59,10 @@ parse_matrix_readnum(const char *src, double *dest) {
|
|||
* Parse a matrix.
|
||||
*/
|
||||
xcb_render_fixed_t *
|
||||
parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||
parse_matrix(const char *src, const char **endptr, bool *hasneg) {
|
||||
int wid = 0, hei = 0;
|
||||
*hasneg = false;
|
||||
|
||||
const char *pc = NULL;
|
||||
|
||||
// Get matrix width and height
|
||||
|
@ -95,7 +97,6 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
|||
// Read elements
|
||||
{
|
||||
int skip = hei / 2 * wid + wid / 2;
|
||||
bool hasneg = false;
|
||||
for (int i = 0; i < wid * hei; ++i) {
|
||||
// Ignore the center element
|
||||
if (i == skip) {
|
||||
|
@ -106,12 +107,9 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
|||
if (src == (pc = parse_matrix_readnum(src, &val)))
|
||||
goto err2;
|
||||
src = pc;
|
||||
if (val < 0) hasneg = true;
|
||||
if (val < 0) *hasneg = true;
|
||||
matrix[2 + i] = DOUBLE_TO_XFIXED(val);
|
||||
}
|
||||
if (BKEND_XRENDER == ps->o.backend && hasneg)
|
||||
log_warn("A convolution kernel with negative values may not work properly under X "
|
||||
"Render backend.");
|
||||
}
|
||||
|
||||
// Detect trailing characters
|
||||
|
@ -151,17 +149,23 @@ err1:
|
|||
|
||||
/**
|
||||
* Parse a convolution kernel.
|
||||
*
|
||||
* Output:
|
||||
* hasneg: whether the convolution kernel has negative values
|
||||
*/
|
||||
xcb_render_fixed_t *
|
||||
parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
||||
return parse_matrix(ps, src, endptr);
|
||||
parse_conv_kern(const char *src, const char **endptr, bool *hasneg) {
|
||||
return parse_matrix(src, endptr, hasneg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of convolution kernels.
|
||||
*
|
||||
* Output:
|
||||
* hasneg: whether any of the convolution kernel has negative values
|
||||
*/
|
||||
bool
|
||||
parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, int max) {
|
||||
parse_conv_kern_lst(const char *src, xcb_render_fixed_t **dest, int max, bool *hasneg) {
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *kern_str;
|
||||
|
@ -175,10 +179,13 @@ parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, i
|
|||
{ "9x9gaussian", "9,9,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000," },
|
||||
{ "11x11gaussian", "11,11,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000," },
|
||||
};
|
||||
|
||||
*hasneg = false;
|
||||
|
||||
for (unsigned int i = 0;
|
||||
i < sizeof(CONV_KERN_PREDEF) / sizeof(CONV_KERN_PREDEF[0]); ++i)
|
||||
if (!strcmp(CONV_KERN_PREDEF[i].name, src))
|
||||
return parse_conv_kern_lst(ps, CONV_KERN_PREDEF[i].kern_str, dest, max);
|
||||
return parse_conv_kern_lst(CONV_KERN_PREDEF[i].kern_str, dest, max, hasneg);
|
||||
|
||||
int i = 0;
|
||||
const char *pc = src;
|
||||
|
@ -192,8 +199,10 @@ parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, i
|
|||
// Continue parsing until the end of source string
|
||||
i = 0;
|
||||
while (pc && *pc && i < max - 1) {
|
||||
if (!(dest[i++] = parse_conv_kern(ps, pc, &pc)))
|
||||
bool tmp_hasneg;
|
||||
if (!(dest[i++] = parse_conv_kern(pc, &pc, &tmp_hasneg)))
|
||||
return false;
|
||||
*hasneg |= tmp_hasneg;
|
||||
}
|
||||
|
||||
if (i > 1) {
|
||||
|
@ -300,7 +309,7 @@ parse_geometry_end:
|
|||
/**
|
||||
* Parse a list of opacity rules.
|
||||
*/
|
||||
bool parse_rule_opacity(session_t *ps, const char *src) {
|
||||
bool parse_rule_opacity(c2_lptr_t **res, const char *src) {
|
||||
// Find opacity value
|
||||
char *endptr = NULL;
|
||||
long val = strtol(src, &endptr, 0);
|
||||
|
@ -324,27 +333,30 @@ bool parse_rule_opacity(session_t *ps, const char *src) {
|
|||
|
||||
// Parse pattern
|
||||
// I hope 1-100 is acceptable for (void *)
|
||||
return c2_parse(ps, &ps->o.opacity_rules, endptr, (void *) val);
|
||||
return c2_parse(res, endptr, (void *) val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pattern to a condition linked list.
|
||||
*/
|
||||
bool
|
||||
condlst_add(session_t *ps, c2_lptr_t **pcondlst, const char *pattern) {
|
||||
condlst_add(c2_lptr_t **pcondlst, const char *pattern) {
|
||||
if (!pattern)
|
||||
return false;
|
||||
|
||||
if (!c2_parse(ps, pcondlst, pattern, NULL))
|
||||
if (!c2_parse(pcondlst, pattern, NULL))
|
||||
exit(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
||||
char *parse_config(options_t *opt, const char *config_file,
|
||||
bool *shadow_enable, bool *fading_enable, bool *hasneg,
|
||||
win_option_mask_t *winopt_mask) {
|
||||
char *ret = NULL;
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
parse_config_libconfig(ps, shadow_enable, fading_enable, winopt_mask);
|
||||
ret = parse_config_libconfig(opt, config_file, shadow_enable, fading_enable,
|
||||
hasneg, winopt_mask);
|
||||
#endif
|
||||
|
||||
// Apply default wintype options that does not depends on global options.
|
||||
|
@ -354,7 +366,7 @@ void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
|||
// Except desktop windows are always drawn without shadow.
|
||||
if (!winopt_mask[WINTYPE_DESKTOP].shadow) {
|
||||
winopt_mask[WINTYPE_DESKTOP].shadow = true;
|
||||
ps->o.wintype_option[WINTYPE_DESKTOP].shadow = false;
|
||||
opt->wintype_option[WINTYPE_DESKTOP].shadow = false;
|
||||
}
|
||||
|
||||
// Focused/unfocused state only apply to a few window types, all other windows
|
||||
|
@ -364,27 +376,28 @@ void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
|||
for (unsigned long i = 0; i < ARR_SIZE(nofocus_type); i++) {
|
||||
if (!winopt_mask[nofocus_type[i]].focus) {
|
||||
winopt_mask[nofocus_type[i]].focus = true;
|
||||
ps->o.wintype_option[nofocus_type[i]].focus = false;
|
||||
opt->wintype_option[nofocus_type[i]].focus = false;
|
||||
}
|
||||
}
|
||||
for (unsigned long i = 0; i < NUM_WINTYPES; i++) {
|
||||
if (!winopt_mask[i].focus) {
|
||||
winopt_mask[i].focus = true;
|
||||
ps->o.wintype_option[i].focus = true;
|
||||
opt->wintype_option[i].focus = true;
|
||||
}
|
||||
if (!winopt_mask[i].full_shadow) {
|
||||
winopt_mask[i].full_shadow = true;
|
||||
ps->o.wintype_option[i].full_shadow = false;
|
||||
opt->wintype_option[i].full_shadow = false;
|
||||
}
|
||||
if (!winopt_mask[i].redir_ignore) {
|
||||
winopt_mask[i].redir_ignore = true;
|
||||
ps->o.wintype_option[i].redir_ignore = false;
|
||||
opt->wintype_option[i].redir_ignore = false;
|
||||
}
|
||||
if (!winopt_mask[i].opacity) {
|
||||
winopt_mask[i].opacity = true;
|
||||
// Opacity is not set to a concrete number here because the opacity logic
|
||||
// is complicated, and needs an "unset" state
|
||||
ps->o.wintype_option[i].opacity = NAN;
|
||||
opt->wintype_option[i].opacity = NAN;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
357
src/config.h
357
src/config.h
|
@ -1,7 +1,11 @@
|
|||
#pragma once
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2011-2013, Christopher Jeffrey
|
||||
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
|
||||
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
||||
#pragma once
|
||||
|
||||
/// Common functions and definitions for configuration parsing
|
||||
/// Used for command line arguments and config files
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -11,25 +15,348 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
bool parse_long(const char *, long *);
|
||||
const char *parse_matrix_readnum(const char *, double *);
|
||||
xcb_render_fixed_t *parse_matrix(session_t *, const char *, const char **);
|
||||
xcb_render_fixed_t *parse_conv_kern(session_t *, const char *, const char **);
|
||||
bool parse_conv_kern_lst(session_t *, const char *, xcb_render_fixed_t **, int);
|
||||
bool parse_geometry(session_t *, const char *, region_t *);
|
||||
bool parse_rule_opacity(session_t *, const char *);
|
||||
/// VSync modes.
|
||||
typedef enum {
|
||||
VSYNC_NONE,
|
||||
VSYNC_DRM,
|
||||
VSYNC_OPENGL,
|
||||
VSYNC_OPENGL_OML,
|
||||
VSYNC_OPENGL_SWC,
|
||||
VSYNC_OPENGL_MSWC,
|
||||
NUM_VSYNC,
|
||||
} vsync_t;
|
||||
|
||||
/// @brief Possible backends of compton.
|
||||
enum backend {
|
||||
BKEND_XRENDER,
|
||||
BKEND_GLX,
|
||||
BKEND_XR_GLX_HYBRID,
|
||||
NUM_BKEND,
|
||||
};
|
||||
|
||||
typedef struct win_option_mask {
|
||||
bool shadow : 1;
|
||||
bool fade : 1;
|
||||
bool focus : 1;
|
||||
bool full_shadow : 1;
|
||||
bool redir_ignore : 1;
|
||||
bool opacity : 1;
|
||||
} win_option_mask_t;
|
||||
|
||||
typedef struct win_option {
|
||||
bool shadow;
|
||||
bool fade;
|
||||
bool focus;
|
||||
bool full_shadow;
|
||||
bool redir_ignore;
|
||||
double opacity;
|
||||
} win_option_t;
|
||||
|
||||
typedef struct _c2_lptr c2_lptr_t;
|
||||
|
||||
// This macro is here because this is the maximum number
|
||||
// of blur passes options_t can hold, not a limitation of
|
||||
// rendering.
|
||||
/// @brief Maximum passes for blur.
|
||||
#define MAX_BLUR_PASS 5
|
||||
|
||||
/// Structure representing all options.
|
||||
typedef struct options_t {
|
||||
// === Debugging ===
|
||||
bool monitor_repaint;
|
||||
bool print_diagnostics;
|
||||
// === General ===
|
||||
/// The configuration file we used.
|
||||
char *config_file;
|
||||
/// Path to write PID to.
|
||||
char *write_pid_path;
|
||||
/// The backend in use.
|
||||
enum backend backend;
|
||||
/// Whether to sync X drawing to avoid certain delay issues with
|
||||
/// GLX backend.
|
||||
bool xrender_sync;
|
||||
/// Whether to sync X drawing with X Sync fence.
|
||||
bool xrender_sync_fence;
|
||||
/// Whether to avoid using stencil buffer under GLX backend. Might be
|
||||
/// unsafe.
|
||||
bool glx_no_stencil;
|
||||
/// Whether to avoid rebinding pixmap on window damage.
|
||||
bool glx_no_rebind_pixmap;
|
||||
/// GLX swap method we assume OpenGL uses.
|
||||
int glx_swap_method;
|
||||
/// Whether to use GL_EXT_gpu_shader4 to (hopefully) accelerates blurring.
|
||||
bool glx_use_gpushader4;
|
||||
/// Custom fragment shader for painting windows, as a string.
|
||||
char *glx_fshader_win_str;
|
||||
/// Whether to fork to background.
|
||||
bool fork_after_register;
|
||||
/// Whether to detect rounded corners.
|
||||
bool detect_rounded_corners;
|
||||
/// Force painting of window content with blending.
|
||||
bool force_win_blend;
|
||||
/// Resize damage for a specific number of pixels.
|
||||
int resize_damage;
|
||||
/// Whether to unredirect all windows if a full-screen opaque window
|
||||
/// is detected.
|
||||
bool unredir_if_possible;
|
||||
/// List of conditions of windows to ignore as a full-screen window
|
||||
/// when determining if a window could be unredirected.
|
||||
c2_lptr_t *unredir_if_possible_blacklist;
|
||||
/// Delay before unredirecting screen, in milliseconds.
|
||||
unsigned long unredir_if_possible_delay;
|
||||
/// Forced redirection setting through D-Bus.
|
||||
switch_t redirected_force;
|
||||
/// Whether to stop painting. Controlled through D-Bus.
|
||||
switch_t stoppaint_force;
|
||||
/// Whether to re-redirect screen on root size change.
|
||||
bool reredir_on_root_change;
|
||||
/// Whether to reinitialize GLX on root size change.
|
||||
bool glx_reinit_on_root_change;
|
||||
/// Whether to enable D-Bus support.
|
||||
bool dbus;
|
||||
/// Path to log file.
|
||||
char *logpath;
|
||||
/// Number of cycles to paint in benchmark mode. 0 for disabled.
|
||||
int benchmark;
|
||||
/// Window to constantly repaint in benchmark mode. 0 for full-screen.
|
||||
Window benchmark_wid;
|
||||
/// A list of conditions of windows not to paint.
|
||||
c2_lptr_t *paint_blacklist;
|
||||
/// Whether to show all X errors.
|
||||
bool show_all_xerrors;
|
||||
/// Whether to avoid acquiring X Selection.
|
||||
bool no_x_selection;
|
||||
/// Window type option override.
|
||||
win_option_t wintype_option[NUM_WINTYPES];
|
||||
|
||||
// === VSync & software optimization ===
|
||||
/// User-specified refresh rate.
|
||||
int refresh_rate;
|
||||
/// Whether to enable refresh-rate-based software optimization.
|
||||
bool sw_opti;
|
||||
/// VSync method to use;
|
||||
vsync_t vsync;
|
||||
/// Whether to do VSync aggressively.
|
||||
bool vsync_aggressive;
|
||||
/// Whether to use glFinish() instead of glFlush() for (possibly) better
|
||||
/// VSync yet probably higher CPU usage.
|
||||
bool vsync_use_glfinish;
|
||||
|
||||
// === Shadow ===
|
||||
/// Red, green and blue tone of the shadow.
|
||||
double shadow_red, shadow_green, shadow_blue;
|
||||
int shadow_radius;
|
||||
int shadow_offset_x, shadow_offset_y;
|
||||
double shadow_opacity;
|
||||
/// argument string to shadow-exclude-reg option
|
||||
char *shadow_exclude_reg_str;
|
||||
/// Shadow blacklist. A linked list of conditions.
|
||||
c2_lptr_t *shadow_blacklist;
|
||||
/// Whether bounding-shaped window should be ignored.
|
||||
bool shadow_ignore_shaped;
|
||||
/// Whether to respect _COMPTON_SHADOW.
|
||||
bool respect_prop_shadow;
|
||||
/// Whether to crop shadow to the very Xinerama screen.
|
||||
bool xinerama_shadow_crop;
|
||||
|
||||
// === Fading ===
|
||||
/// How much to fade in in a single fading step.
|
||||
opacity_t fade_in_step;
|
||||
/// How much to fade out in a single fading step.
|
||||
opacity_t fade_out_step;
|
||||
/// Fading time delta. In milliseconds.
|
||||
unsigned long fade_delta;
|
||||
/// Whether to disable fading on window open/close.
|
||||
bool no_fading_openclose;
|
||||
/// Whether to disable fading on ARGB managed destroyed windows.
|
||||
bool no_fading_destroyed_argb;
|
||||
/// Fading blacklist. A linked list of conditions.
|
||||
c2_lptr_t *fade_blacklist;
|
||||
|
||||
// === Opacity ===
|
||||
/// Default opacity for inactive windows.
|
||||
/// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for
|
||||
/// not enabled, default.
|
||||
opacity_t inactive_opacity;
|
||||
/// Default opacity for inactive windows.
|
||||
opacity_t active_opacity;
|
||||
/// Whether inactive_opacity overrides the opacity set by window
|
||||
/// attributes.
|
||||
bool inactive_opacity_override;
|
||||
/// Frame opacity. Relative to window opacity, also affects shadow
|
||||
/// opacity.
|
||||
double frame_opacity;
|
||||
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
||||
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
||||
bool detect_client_opacity;
|
||||
|
||||
// === Other window processing ===
|
||||
/// Whether to blur background of semi-transparent / ARGB windows.
|
||||
bool blur_background;
|
||||
/// Whether to blur background when the window frame is not opaque.
|
||||
/// Implies blur_background.
|
||||
bool blur_background_frame;
|
||||
/// Whether to use fixed blur strength instead of adjusting according
|
||||
/// to window opacity.
|
||||
bool blur_background_fixed;
|
||||
/// Background blur blacklist. A linked list of conditions.
|
||||
c2_lptr_t *blur_background_blacklist;
|
||||
/// Blur convolution kernel.
|
||||
xcb_render_fixed_t *blur_kerns[MAX_BLUR_PASS];
|
||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||
double inactive_dim;
|
||||
/// Whether to use fixed inactive dim opacity, instead of deciding
|
||||
/// based on window opacity.
|
||||
bool inactive_dim_fixed;
|
||||
/// Conditions of windows to have inverted colors.
|
||||
c2_lptr_t *invert_color_list;
|
||||
/// Rules to change window opacity.
|
||||
c2_lptr_t *opacity_rules;
|
||||
|
||||
// === Focus related ===
|
||||
/// Whether to try to detect WM windows and mark them as focused.
|
||||
bool mark_wmwin_focused;
|
||||
/// Whether to mark override-redirect windows as focused.
|
||||
bool mark_ovredir_focused;
|
||||
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
||||
bool use_ewmh_active_win;
|
||||
/// A list of windows always to be considered focused.
|
||||
c2_lptr_t *focus_blacklist;
|
||||
/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
|
||||
bool detect_transient;
|
||||
/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
|
||||
bool detect_client_leader;
|
||||
|
||||
// === Calculated ===
|
||||
/// Whether compton needs to track focus changes.
|
||||
bool track_focus;
|
||||
/// Whether compton needs to track window name and class.
|
||||
bool track_wdata;
|
||||
/// Whether compton needs to track window leaders.
|
||||
bool track_leader;
|
||||
} options_t;
|
||||
|
||||
extern const char *const VSYNC_STRS[NUM_VSYNC + 1];
|
||||
extern const char *const BACKEND_STRS[NUM_BKEND + 1];
|
||||
|
||||
attr_warn_unused_result bool parse_long(const char *, long *);
|
||||
attr_warn_unused_result const char *parse_matrix_readnum(const char *, double *);
|
||||
attr_warn_unused_result xcb_render_fixed_t *
|
||||
parse_matrix(const char *, const char **, bool *hasneg);
|
||||
attr_warn_unused_result xcb_render_fixed_t *
|
||||
parse_conv_kern(const char *, const char **, bool *hasneg);
|
||||
attr_warn_unused_result bool
|
||||
parse_conv_kern_lst(const char *, xcb_render_fixed_t **, int, bool *hasneg);
|
||||
attr_warn_unused_result bool parse_geometry(session_t *, const char *, region_t *);
|
||||
attr_warn_unused_result bool parse_rule_opacity(c2_lptr_t **, const char *);
|
||||
|
||||
/**
|
||||
* Add a pattern to a condition linked list.
|
||||
*/
|
||||
bool condlst_add(session_t *, c2_lptr_t **, const char *);
|
||||
bool condlst_add(c2_lptr_t **, const char *);
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
void
|
||||
parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||
bool *fading_enable, win_option_mask_t *winopt_mask);
|
||||
/// Parse a configuration file
|
||||
/// Returns the actually config_file name used, allocated on heap
|
||||
/// Outputs:
|
||||
/// shadow_enable = whether shaodw is enabled globally
|
||||
/// fading_enable = whether fading is enabled globally
|
||||
/// win_option_mask = whether option overrides for specific window type is set for given
|
||||
/// options
|
||||
/// hasneg = whether the convolution kernel has negative values
|
||||
char *
|
||||
parse_config_libconfig(options_t *, const char *config_file, bool *shadow_enable,
|
||||
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||
#endif
|
||||
|
||||
void
|
||||
parse_config(session_t *ps, bool *shadow_enable,
|
||||
bool *fading_enable, win_option_mask_t *winopt_mask);
|
||||
/// Parse a configuration file is that is enabled, also initialize the winopt_mask with
|
||||
/// default values
|
||||
/// Outputs and returns:
|
||||
/// same as parse_config_libconfig
|
||||
char *parse_config(options_t *, const char *config_file, bool *shadow_enable,
|
||||
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||
|
||||
/**
|
||||
* Parse a backend option argument.
|
||||
*/
|
||||
static inline attr_const enum backend parse_backend(const char *str) {
|
||||
for (enum backend i = 0; BACKEND_STRS[i]; ++i) {
|
||||
if (!strcasecmp(str, BACKEND_STRS[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// Keep compatibility with an old revision containing a spelling mistake...
|
||||
if (!strcasecmp(str, "xr_glx_hybird")) {
|
||||
log_warn("backend xr_glx_hybird should be xr_glx_hybrid, the misspelt"
|
||||
"version will be removed soon.");
|
||||
return BKEND_XR_GLX_HYBRID;
|
||||
}
|
||||
// cju wants to use dashes
|
||||
if (!strcasecmp(str, "xr-glx-hybrid")) {
|
||||
log_warn("backend xr-glx-hybrid should be xr_glx_hybrid, the alternative"
|
||||
"version will be removed soon.");
|
||||
return BKEND_XR_GLX_HYBRID;
|
||||
}
|
||||
log_error("Invalid backend argument: %s", str);
|
||||
return NUM_BKEND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a glx_swap_method option argument.
|
||||
*
|
||||
* Returns -2 on failure
|
||||
*/
|
||||
static inline attr_const int parse_glx_swap_method(const char *str) {
|
||||
// Parse alias
|
||||
if (!strcmp("undefined", str)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp("copy", str)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp("exchange", str)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!strcmp("buffer-age", str)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parse number
|
||||
char *pc = NULL;
|
||||
int age = strtol(str, &pc, 0);
|
||||
if (!pc || str == pc) {
|
||||
log_error("glx-swap-method is an invalid number: %s", str);
|
||||
return -2;
|
||||
}
|
||||
|
||||
for (; *pc; ++pc)
|
||||
if (!isspace(*pc)) {
|
||||
log_error("Trailing characters in glx-swap-method option: %s", str);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (age < -1) {
|
||||
log_error("Number for glx-swap-method is too small: %s", str);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return age;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a VSync option argument.
|
||||
*/
|
||||
static inline vsync_t parse_vsync(const char *str) {
|
||||
for (vsync_t i = 0; VSYNC_STRS[i]; ++i)
|
||||
if (!strcasecmp(str, VSYNC_STRS[i])) {
|
||||
return i;
|
||||
}
|
||||
|
||||
log_error("Invalid vsync argument: %s", str);
|
||||
return NUM_VSYNC;
|
||||
}
|
||||
|
||||
// vim: set noet sw=8 ts=8 :
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "string_utils.h"
|
||||
#include "options.h"
|
||||
#include "log.h"
|
||||
|
||||
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||
|
||||
/**
|
||||
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
||||
*
|
||||
|
@ -36,7 +39,7 @@ lcfg_lookup_bool(const config_t *config, const char *path, bool *value) {
|
|||
* Follows the XDG specification to search for the configuration file.
|
||||
*/
|
||||
FILE *
|
||||
open_config_file(char *cpath, char **ppath) {
|
||||
open_config_file(const char *cpath, char **ppath) {
|
||||
static const char *config_paths[] = {
|
||||
"/compton.conf",
|
||||
"/compton/compton.conf"
|
||||
|
@ -46,7 +49,7 @@ open_config_file(char *cpath, char **ppath) {
|
|||
if (cpath) {
|
||||
FILE *ret = fopen(cpath, "r");
|
||||
if (ret && ppath)
|
||||
*ppath = cpath;
|
||||
*ppath = strdup(cpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -82,7 +85,7 @@ open_config_file(char *cpath, char **ppath) {
|
|||
* Parse a condition list in configuration file.
|
||||
*/
|
||||
void
|
||||
parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
||||
parse_cfg_condlst(const config_t *pcfg, c2_lptr_t **pcondlst,
|
||||
const char *name) {
|
||||
config_setting_t *setting = config_lookup(pcfg, name);
|
||||
if (setting) {
|
||||
|
@ -90,11 +93,11 @@ parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
|||
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));
|
||||
condlst_add(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));
|
||||
condlst_add(pcondlst, config_setting_get_string(setting));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,29 +106,32 @@ parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
|||
* 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) {
|
||||
parse_cfg_condlst_opct(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);
|
||||
while (i--)
|
||||
if (!parse_rule_opacity(ps, config_setting_get_string_elem(setting,
|
||||
i)))
|
||||
if (!parse_rule_opacity(&opt->opacity_rules,
|
||||
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));
|
||||
else if (config_setting_type(setting) == CONFIG_TYPE_STRING) {
|
||||
if (!parse_rule_opacity(&opt->opacity_rules, config_setting_get_string(setting)))
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a configuration file from default location.
|
||||
*
|
||||
* Returns the actually config_file name
|
||||
*/
|
||||
void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||
bool *fading_enable, win_option_mask_t *winopt_mask)
|
||||
char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shadow_enable,
|
||||
bool *fading_enable, bool *conv_kern_hasneg, win_option_mask_t *winopt_mask)
|
||||
{
|
||||
char *path = NULL;
|
||||
FILE *f;
|
||||
|
@ -137,16 +143,14 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
// anything
|
||||
const char *sval = NULL;
|
||||
|
||||
f = open_config_file(ps->o.config_file, &path);
|
||||
f = open_config_file(config_file, &path);
|
||||
if (!f) {
|
||||
if (ps->o.config_file) {
|
||||
free(ps->o.config_file);
|
||||
ps->o.config_file = NULL;
|
||||
|
||||
log_fatal("Failed to read configuration file \"%s\".", ps->o.config_file);
|
||||
if (config_file) {
|
||||
log_fatal("Failed to read configuration file \"%s\".", config_file);
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config_init(&cfg);
|
||||
|
@ -171,44 +175,39 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
path, config_error_line(&cfg), config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
free(path);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
config_set_auto_convert(&cfg, 1);
|
||||
|
||||
if (path != ps->o.config_file) {
|
||||
assert(ps->o.config_file == NULL);
|
||||
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)
|
||||
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
||||
ps->o.fade_delta = ival;
|
||||
opt->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;
|
||||
opt->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;
|
||||
opt->fade_out_step = normalize_d(dval) * OPAQUE;
|
||||
// -r (shadow_radius)
|
||||
config_lookup_int(&cfg, "shadow-radius", &ps->o.shadow_radius);
|
||||
config_lookup_int(&cfg, "shadow-radius", &opt->shadow_radius);
|
||||
// -o (shadow_opacity)
|
||||
config_lookup_float(&cfg, "shadow-opacity", &ps->o.shadow_opacity);
|
||||
config_lookup_float(&cfg, "shadow-opacity", &opt->shadow_opacity);
|
||||
// -l (shadow_offset_x)
|
||||
config_lookup_int(&cfg, "shadow-offset-x", &ps->o.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", &ps->o.shadow_offset_y);
|
||||
config_lookup_int(&cfg, "shadow-offset-y", &opt->shadow_offset_y);
|
||||
// -i (inactive_opacity)
|
||||
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
||||
ps->o.inactive_opacity = normalize_d(dval) * OPAQUE;
|
||||
opt->inactive_opacity = normalize_d(dval) * OPAQUE;
|
||||
// --active_opacity
|
||||
if (config_lookup_float(&cfg, "active-opacity", &dval))
|
||||
ps->o.active_opacity = normalize_d(dval) * OPAQUE;
|
||||
opt->active_opacity = normalize_d(dval) * OPAQUE;
|
||||
// -e (frame_opacity)
|
||||
config_lookup_float(&cfg, "frame-opacity", &ps->o.frame_opacity);
|
||||
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
||||
// -c (shadow_enable)
|
||||
if (config_lookup_bool(&cfg, "shadow", &ival))
|
||||
*shadow_enable = ival;
|
||||
|
@ -216,22 +215,22 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
if (config_lookup_bool(&cfg, "no-dock-shadow", &ival)) {
|
||||
log_warn("Option `no-dock-shadow` is deprecated, and will be removed."
|
||||
" Please use the wintype option `shadow` of `dock` instead.");
|
||||
ps->o.wintype_option[WINTYPE_DOCK].shadow = false;
|
||||
opt->wintype_option[WINTYPE_DOCK].shadow = false;
|
||||
winopt_mask[WINTYPE_DOCK].shadow = true;
|
||||
}
|
||||
// -G (no_dnd_shadow)
|
||||
if (config_lookup_bool(&cfg, "no-dnd-shadow", &ival)) {
|
||||
log_warn("Option `no-dnd-shadow` is deprecated, and will be removed."
|
||||
" Please use the wintype option `shadow` of `dnd` instead.");
|
||||
ps->o.wintype_option[WINTYPE_DND].shadow = false;
|
||||
opt->wintype_option[WINTYPE_DND].shadow = false;
|
||||
winopt_mask[WINTYPE_DND].shadow = true;
|
||||
};
|
||||
// -m (menu_opacity)
|
||||
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
||||
log_warn("Option `menu-opacity` is deprecated, and will be removed.Please use the "
|
||||
"wintype option `opacity` of `popup_menu` and `dropdown_menu` instead.");
|
||||
ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = dval;
|
||||
ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = dval;
|
||||
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;
|
||||
}
|
||||
|
@ -239,53 +238,59 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
if (config_lookup_bool(&cfg, "fading", &ival))
|
||||
*fading_enable = ival;
|
||||
// --no-fading-open-close
|
||||
lcfg_lookup_bool(&cfg, "no-fading-openclose", &ps->o.no_fading_openclose);
|
||||
lcfg_lookup_bool(&cfg, "no-fading-openclose", &opt->no_fading_openclose);
|
||||
// --no-fading-destroyed-argb
|
||||
lcfg_lookup_bool(&cfg, "no-fading-destroyed-argb",
|
||||
&ps->o.no_fading_destroyed_argb);
|
||||
&opt->no_fading_destroyed_argb);
|
||||
// --shadow-red
|
||||
config_lookup_float(&cfg, "shadow-red", &ps->o.shadow_red);
|
||||
config_lookup_float(&cfg, "shadow-red", &opt->shadow_red);
|
||||
// --shadow-green
|
||||
config_lookup_float(&cfg, "shadow-green", &ps->o.shadow_green);
|
||||
config_lookup_float(&cfg, "shadow-green", &opt->shadow_green);
|
||||
// --shadow-blue
|
||||
config_lookup_float(&cfg, "shadow-blue", &ps->o.shadow_blue);
|
||||
config_lookup_float(&cfg, "shadow-blue", &opt->shadow_blue);
|
||||
// --shadow-exclude-reg
|
||||
if (config_lookup_string(&cfg, "shadow-exclude-reg", &sval))
|
||||
ps->o.shadow_exclude_reg_str = strdup(sval);
|
||||
opt->shadow_exclude_reg_str = strdup(sval);
|
||||
// --inactive-opacity-override
|
||||
lcfg_lookup_bool(&cfg, "inactive-opacity-override",
|
||||
&ps->o.inactive_opacity_override);
|
||||
&opt->inactive_opacity_override);
|
||||
// --inactive-dim
|
||||
config_lookup_float(&cfg, "inactive-dim", &ps->o.inactive_dim);
|
||||
config_lookup_float(&cfg, "inactive-dim", &opt->inactive_dim);
|
||||
// --mark-wmwin-focused
|
||||
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &ps->o.mark_wmwin_focused);
|
||||
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &opt->mark_wmwin_focused);
|
||||
// --mark-ovredir-focused
|
||||
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
||||
&ps->o.mark_ovredir_focused);
|
||||
&opt->mark_ovredir_focused);
|
||||
// --shadow-ignore-shaped
|
||||
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
||||
&ps->o.shadow_ignore_shaped);
|
||||
&opt->shadow_ignore_shaped);
|
||||
// --detect-rounded-corners
|
||||
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
||||
&ps->o.detect_rounded_corners);
|
||||
&opt->detect_rounded_corners);
|
||||
// --xinerama-shadow-crop
|
||||
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop",
|
||||
&ps->o.xinerama_shadow_crop);
|
||||
&opt->xinerama_shadow_crop);
|
||||
// --detect-client-opacity
|
||||
lcfg_lookup_bool(&cfg, "detect-client-opacity",
|
||||
&ps->o.detect_client_opacity);
|
||||
&opt->detect_client_opacity);
|
||||
// --refresh-rate
|
||||
config_lookup_int(&cfg, "refresh-rate", &ps->o.refresh_rate);
|
||||
config_lookup_int(&cfg, "refresh-rate", &opt->refresh_rate);
|
||||
// --vsync
|
||||
if (config_lookup_string(&cfg, "vsync", &sval) && !parse_vsync(ps, sval)) {
|
||||
if (config_lookup_string(&cfg, "vsync", &sval)) {
|
||||
opt->vsync = parse_vsync(sval);
|
||||
if (opt->vsync >= NUM_VSYNC) {
|
||||
log_fatal("Cannot parse vsync");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// --backend
|
||||
if (config_lookup_string(&cfg, "backend", &sval) && !parse_backend(ps, sval)) {
|
||||
if (config_lookup_string(&cfg, "backend", &sval)) {
|
||||
opt->backend = parse_backend(sval);
|
||||
if (opt->backend >= NUM_BKEND) {
|
||||
log_fatal("Cannot parse backend");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// --log-level
|
||||
if (config_lookup_string(&cfg, "log-level", &sval)) {
|
||||
auto level = string_to_log_level(sval);
|
||||
|
@ -296,69 +301,71 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
}
|
||||
}
|
||||
// --sw-opti
|
||||
lcfg_lookup_bool(&cfg, "sw-opti", &ps->o.sw_opti);
|
||||
lcfg_lookup_bool(&cfg, "sw-opti", &opt->sw_opti);
|
||||
// --use-ewmh-active-win
|
||||
lcfg_lookup_bool(&cfg, "use-ewmh-active-win",
|
||||
&ps->o.use_ewmh_active_win);
|
||||
&opt->use_ewmh_active_win);
|
||||
// --unredir-if-possible
|
||||
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
||||
&ps->o.unredir_if_possible);
|
||||
&opt->unredir_if_possible);
|
||||
// --unredir-if-possible-delay
|
||||
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival))
|
||||
ps->o.unredir_if_possible_delay = ival;
|
||||
opt->unredir_if_possible_delay = ival;
|
||||
// --inactive-dim-fixed
|
||||
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &ps->o.inactive_dim_fixed);
|
||||
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &opt->inactive_dim_fixed);
|
||||
// --detect-transient
|
||||
lcfg_lookup_bool(&cfg, "detect-transient", &ps->o.detect_transient);
|
||||
lcfg_lookup_bool(&cfg, "detect-transient", &opt->detect_transient);
|
||||
// --detect-client-leader
|
||||
lcfg_lookup_bool(&cfg, "detect-client-leader",
|
||||
&ps->o.detect_client_leader);
|
||||
&opt->detect_client_leader);
|
||||
// --shadow-exclude
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
||||
parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude");
|
||||
// --fade-exclude
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.fade_blacklist, "fade-exclude");
|
||||
parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude");
|
||||
// --focus-exclude
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.focus_blacklist, "focus-exclude");
|
||||
parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude");
|
||||
// --invert-color-include
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.invert_color_list, "invert-color-include");
|
||||
parse_cfg_condlst(&cfg, &opt->invert_color_list, "invert-color-include");
|
||||
// --blur-background-exclude
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.blur_background_blacklist, "blur-background-exclude");
|
||||
parse_cfg_condlst(&cfg, &opt->blur_background_blacklist, "blur-background-exclude");
|
||||
// --opacity-rule
|
||||
parse_cfg_condlst_opct(ps, &cfg, "opacity-rule");
|
||||
parse_cfg_condlst_opct(opt, &cfg, "opacity-rule");
|
||||
// --unredir-if-possible-exclude
|
||||
parse_cfg_condlst(ps, &cfg, &ps->o.unredir_if_possible_blacklist, "unredir-if-possible-exclude");
|
||||
parse_cfg_condlst(&cfg, &opt->unredir_if_possible_blacklist, "unredir-if-possible-exclude");
|
||||
// --blur-background
|
||||
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
|
||||
lcfg_lookup_bool(&cfg, "blur-background", &opt->blur_background);
|
||||
// --blur-background-frame
|
||||
lcfg_lookup_bool(&cfg, "blur-background-frame",
|
||||
&ps->o.blur_background_frame);
|
||||
&opt->blur_background_frame);
|
||||
// --blur-background-fixed
|
||||
lcfg_lookup_bool(&cfg, "blur-background-fixed",
|
||||
&ps->o.blur_background_fixed);
|
||||
&opt->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)) {
|
||||
if (config_lookup_string(&cfg, "blur-kern", &sval) &&
|
||||
!parse_conv_kern_lst(sval, opt->blur_kerns, MAX_BLUR_PASS, conv_kern_hasneg)) {
|
||||
log_fatal("Cannot parse \"blur-kern\"");
|
||||
exit(1);
|
||||
}
|
||||
// --resize-damage
|
||||
config_lookup_int(&cfg, "resize-damage", &ps->o.resize_damage);
|
||||
config_lookup_int(&cfg, "resize-damage", &opt->resize_damage);
|
||||
// --glx-no-stencil
|
||||
lcfg_lookup_bool(&cfg, "glx-no-stencil", &ps->o.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", &ps->o.glx_no_rebind_pixmap);
|
||||
lcfg_lookup_bool(&cfg, "glx-no-rebind-pixmap", &opt->glx_no_rebind_pixmap);
|
||||
// --glx-swap-method
|
||||
if (config_lookup_string(&cfg, "glx-swap-method", &sval) &&
|
||||
!parse_glx_swap_method(ps, sval)) {
|
||||
if (config_lookup_string(&cfg, "glx-swap-method", &sval)) {
|
||||
opt->glx_swap_method = parse_glx_swap_method(sval);
|
||||
if (opt->glx_swap_method == -2) {
|
||||
log_fatal("Cannot parse \"glx-swap-method\"");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// --glx-use-gpushader4
|
||||
lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &ps->o.glx_use_gpushader4);
|
||||
lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &opt->glx_use_gpushader4);
|
||||
// --xrender-sync
|
||||
lcfg_lookup_bool(&cfg, "xrender-sync", &ps->o.xrender_sync);
|
||||
lcfg_lookup_bool(&cfg, "xrender-sync", &opt->xrender_sync);
|
||||
// --xrender-sync-fence
|
||||
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &ps->o.xrender_sync_fence);
|
||||
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &opt->xrender_sync_fence);
|
||||
|
||||
if (lcfg_lookup_bool(&cfg, "clear-shadow", &bval))
|
||||
log_warn("\"clear-shadow\" is removed as an option, and is always"
|
||||
|
@ -386,7 +393,7 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
config_setting_t *setting = config_lookup(&cfg, str);
|
||||
free(str);
|
||||
|
||||
win_option_t *o = &ps->o.wintype_option[i];
|
||||
win_option_t *o = &opt->wintype_option[i];
|
||||
win_option_mask_t *mask = &winopt_mask[i];
|
||||
if (setting) {
|
||||
if (config_setting_lookup_bool(setting, "shadow", &ival)) {
|
||||
|
@ -419,4 +426,5 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
|||
}
|
||||
|
||||
config_destroy(&cfg);
|
||||
return path;
|
||||
}
|
||||
|
|
26
src/dbus.c
26
src/dbus.c
|
@ -1183,15 +1183,27 @@ cdbus_process_opts_set(session_t *ps, DBusMessage *msg) {
|
|||
if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_STRING, &val))
|
||||
return false;
|
||||
vsync_deinit(ps);
|
||||
if (!parse_vsync(ps, val)) {
|
||||
log_error(CDBUS_ERROR_BADARG_S, 1, "Value invalid.");
|
||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADARG, CDBUS_ERROR_BADARG_S, 1, "Value invalid.");
|
||||
auto tmp_vsync = parse_vsync(val);
|
||||
if (tmp_vsync >= NUM_VSYNC) {
|
||||
log_error("Failed to parse vsync: invalid value %s.", val);
|
||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADARG, CDBUS_ERROR_BADARG_S, 1,
|
||||
"Value invalid.");
|
||||
return true;
|
||||
}
|
||||
else if (!vsync_init(ps)) {
|
||||
log_error(CDBUS_ERROR_CUSTOM_S, "Failed to initialize specified VSync method.");
|
||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_CUSTOM, CDBUS_ERROR_CUSTOM_S, "Failed to initialize specified VSync method.");
|
||||
|
||||
auto old_vsync = ps->o.vsync;
|
||||
ps->o.vsync = tmp_vsync;
|
||||
if (!vsync_init(ps)) {
|
||||
// Trying to revert back to original vsync values
|
||||
log_error("Failed to initialize specified VSync method.");
|
||||
ps->o.vsync = old_vsync;
|
||||
if (!vsync_init(ps)) {
|
||||
log_error("Failed to revert back to original VSync method.");
|
||||
ps->o.vsync = VSYNC_NONE;
|
||||
}
|
||||
else
|
||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_CUSTOM, CDBUS_ERROR_CUSTOM_S,
|
||||
"Failed to initialize specified VSync method.");
|
||||
} else
|
||||
goto cdbus_process_opts_set_success;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -230,6 +230,11 @@ glx_init(session_t *ps, bool need_render) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ps->o.glx_swap_method > CGLX_MAX_BUFFER_AGE) {
|
||||
log_error("glx-swap-method is too big");
|
||||
goto glx_init_end;
|
||||
}
|
||||
|
||||
// Get XVisualInfo
|
||||
pvis = get_visualinfo_from_visual(ps, ps->vis);
|
||||
if (!pvis) {
|
||||
|
@ -436,7 +441,7 @@ glx_destroy(session_t *ps) {
|
|||
glDeleteProgram(ppass->prog);
|
||||
}
|
||||
|
||||
glx_free_prog_main(ps, &ps->o.glx_prog_win);
|
||||
glx_free_prog_main(ps, &ps->glx_prog_win);
|
||||
|
||||
glx_check_err(ps);
|
||||
|
||||
|
|
143
src/options.c
143
src/options.c
|
@ -6,9 +6,11 @@
|
|||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "options.h"
|
||||
|
||||
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||
|
||||
/**
|
||||
* Print usage text and exit.
|
||||
|
@ -502,21 +504,18 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all
|
|||
/**
|
||||
* Process arguments and configuration files.
|
||||
*/
|
||||
void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||
void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||
bool fading_enable, bool conv_kern_hasneg,
|
||||
win_option_mask_t *winopt_mask) {
|
||||
|
||||
int o = 0, longopt_idx = -1;
|
||||
|
||||
bool shadow_enable = false, fading_enable = false;
|
||||
char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL));
|
||||
|
||||
win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}};
|
||||
|
||||
// Enforce LC_NUMERIC locale "C" here to make sure dots are recognized
|
||||
// instead of commas in atof().
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
parse_config(ps, &shadow_enable, &fading_enable, winopt_mask);
|
||||
|
||||
// Parse commandline arguments. Range checking will be done later.
|
||||
|
||||
const char *deprecation_message = "has been removed. If you encounter problems "
|
||||
|
@ -528,40 +527,42 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
switch (o) {
|
||||
#define P_CASEBOOL(idx, option) \
|
||||
case idx: \
|
||||
ps->o.option = true; \
|
||||
opt->option = true; \
|
||||
break
|
||||
#define P_CASELONG(idx, option) \
|
||||
case idx: \
|
||||
if (!parse_long(optarg, &val)) \
|
||||
exit(1); \
|
||||
ps->o.option = val; \
|
||||
opt->option = val; \
|
||||
break
|
||||
|
||||
// clang-format off
|
||||
// Short options
|
||||
case 'h': usage(0); break;
|
||||
case 'd':
|
||||
case 'S':
|
||||
case 314:
|
||||
case 318:
|
||||
case 320: break; P_CASELONG('D', fade_delta);
|
||||
case 'I': ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||
case 'O': ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||
case 320: break;
|
||||
P_CASELONG('D', fade_delta);
|
||||
case 'I': opt->fade_in_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||
case 'O': opt->fade_out_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||
case 'c': shadow_enable = true; break;
|
||||
case 'C':
|
||||
winopt_mask[WINTYPE_DOCK].shadow = true;
|
||||
ps->o.wintype_option[WINTYPE_DOCK].shadow = true;
|
||||
opt->wintype_option[WINTYPE_DOCK].shadow = true;
|
||||
break;
|
||||
case 'G':
|
||||
winopt_mask[WINTYPE_DND].shadow = true;
|
||||
ps->o.wintype_option[WINTYPE_DND].shadow = true;
|
||||
opt->wintype_option[WINTYPE_DND].shadow = true;
|
||||
break;
|
||||
case 'm':;
|
||||
double tmp;
|
||||
tmp = normalize_d(atof(optarg));
|
||||
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
||||
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
||||
ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = tmp;
|
||||
ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp;
|
||||
opt->wintype_option[WINTYPE_POPUP_MENU].opacity = tmp;
|
||||
opt->wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
|
@ -569,14 +570,14 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
break;
|
||||
P_CASELONG('r', shadow_radius);
|
||||
case 'o':
|
||||
ps->o.shadow_opacity = atof(optarg);
|
||||
opt->shadow_opacity = atof(optarg);
|
||||
break;
|
||||
P_CASELONG('l', shadow_offset_x);
|
||||
P_CASELONG('t', shadow_offset_y);
|
||||
case 'i':
|
||||
ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||
opt->inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||
break;
|
||||
case 'e': ps->o.frame_opacity = atof(optarg); break;
|
||||
case 'e': opt->frame_opacity = atof(optarg); break;
|
||||
case 'z':
|
||||
log_warn("clear-shadow is removed, shadows are automatically "
|
||||
"cleared now. If you want to prevent shadow from been "
|
||||
|
@ -595,25 +596,25 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
break;
|
||||
case 257:
|
||||
// --shadow-red
|
||||
ps->o.shadow_red = atof(optarg);
|
||||
opt->shadow_red = atof(optarg);
|
||||
break;
|
||||
case 258:
|
||||
// --shadow-green
|
||||
ps->o.shadow_green = atof(optarg);
|
||||
opt->shadow_green = atof(optarg);
|
||||
break;
|
||||
case 259:
|
||||
// --shadow-blue
|
||||
ps->o.shadow_blue = atof(optarg);
|
||||
opt->shadow_blue = atof(optarg);
|
||||
break;
|
||||
P_CASEBOOL(260, inactive_opacity_override);
|
||||
case 261:
|
||||
// --inactive-dim
|
||||
ps->o.inactive_dim = atof(optarg);
|
||||
opt->inactive_dim = atof(optarg);
|
||||
break;
|
||||
P_CASEBOOL(262, mark_wmwin_focused);
|
||||
case 263:
|
||||
// --shadow-exclude
|
||||
condlst_add(ps, &ps->o.shadow_blacklist, optarg);
|
||||
condlst_add(&opt->shadow_blacklist, optarg);
|
||||
break;
|
||||
P_CASEBOOL(264, mark_ovredir_focused);
|
||||
P_CASEBOOL(265, no_fading_openclose);
|
||||
|
@ -623,7 +624,8 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASELONG(269, refresh_rate);
|
||||
case 270:
|
||||
// --vsync
|
||||
if (!parse_vsync(ps, optarg))
|
||||
opt->vsync = parse_vsync(optarg);
|
||||
if (opt->vsync >= NUM_VSYNC)
|
||||
exit(1);
|
||||
break;
|
||||
case 271:
|
||||
|
@ -643,7 +645,7 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASEBOOL(278, unredir_if_possible);
|
||||
case 279:
|
||||
// --focus-exclude
|
||||
condlst_add(ps, &ps->o.focus_blacklist, optarg);
|
||||
condlst_add(&opt->focus_blacklist, optarg);
|
||||
break;
|
||||
P_CASEBOOL(280, inactive_dim_fixed);
|
||||
P_CASEBOOL(281, detect_transient);
|
||||
|
@ -654,19 +656,20 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASEBOOL(286, dbus);
|
||||
case 287:
|
||||
// --logpath
|
||||
ps->o.logpath = strdup(optarg);
|
||||
opt->logpath = strdup(optarg);
|
||||
break;
|
||||
case 288:
|
||||
// --invert-color-include
|
||||
condlst_add(ps, &ps->o.invert_color_list, optarg);
|
||||
condlst_add(&opt->invert_color_list, optarg);
|
||||
break;
|
||||
case 289:
|
||||
// --opengl
|
||||
ps->o.backend = BKEND_GLX;
|
||||
opt->backend = BKEND_GLX;
|
||||
break;
|
||||
case 290:
|
||||
// --backend
|
||||
if (!parse_backend(ps, optarg))
|
||||
opt->backend = parse_backend(optarg);
|
||||
if (opt->backend >= NUM_BKEND)
|
||||
exit(1);
|
||||
break;
|
||||
P_CASEBOOL(291, glx_no_stencil);
|
||||
|
@ -676,61 +679,62 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASELONG(293, benchmark);
|
||||
case 294:
|
||||
// --benchmark-wid
|
||||
ps->o.benchmark_wid = strtol(optarg, NULL, 0);
|
||||
opt->benchmark_wid = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 295:
|
||||
log_warn("--glx-use-copysubbuffermesa %s", deprecation_message);
|
||||
break;
|
||||
case 296:
|
||||
// --blur-background-exclude
|
||||
condlst_add(ps, &ps->o.blur_background_blacklist, optarg);
|
||||
condlst_add(&opt->blur_background_blacklist, optarg);
|
||||
break;
|
||||
case 297:
|
||||
// --active-opacity
|
||||
ps->o.active_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||
opt->active_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||
break;
|
||||
P_CASEBOOL(298, glx_no_rebind_pixmap);
|
||||
case 299:
|
||||
// --glx-swap-method
|
||||
if (!parse_glx_swap_method(ps, optarg))
|
||||
opt->glx_swap_method = parse_glx_swap_method(optarg);
|
||||
if (opt->glx_swap_method == -2)
|
||||
exit(1);
|
||||
break;
|
||||
case 300:
|
||||
// --fade-exclude
|
||||
condlst_add(ps, &ps->o.fade_blacklist, optarg);
|
||||
condlst_add(&opt->fade_blacklist, optarg);
|
||||
break;
|
||||
case 301:
|
||||
// --blur-kern
|
||||
if (!parse_conv_kern_lst(ps, optarg, ps->o.blur_kerns,
|
||||
MAX_BLUR_PASS))
|
||||
if (!parse_conv_kern_lst(optarg, opt->blur_kerns,
|
||||
MAX_BLUR_PASS, &conv_kern_hasneg))
|
||||
exit(1);
|
||||
break;
|
||||
P_CASELONG(302, resize_damage);
|
||||
P_CASEBOOL(303, glx_use_gpushader4);
|
||||
case 304:
|
||||
// --opacity-rule
|
||||
if (!parse_rule_opacity(ps, optarg))
|
||||
if (!parse_rule_opacity(&opt->opacity_rules, optarg))
|
||||
exit(1);
|
||||
break;
|
||||
case 305:
|
||||
// --shadow-exclude-reg
|
||||
ps->o.shadow_exclude_reg_str = strdup(optarg);
|
||||
opt->shadow_exclude_reg_str = strdup(optarg);
|
||||
log_warn("--shadow-exclude-reg is deprecated. You are likely "
|
||||
"better off using --shadow-exclude anyway");
|
||||
break;
|
||||
case 306:
|
||||
// --paint-exclude
|
||||
condlst_add(ps, &ps->o.paint_blacklist, optarg);
|
||||
condlst_add(&opt->paint_blacklist, optarg);
|
||||
break;
|
||||
P_CASEBOOL(307, xinerama_shadow_crop);
|
||||
case 308:
|
||||
// --unredir-if-possible-exclude
|
||||
condlst_add(ps, &ps->o.unredir_if_possible_blacklist, optarg);
|
||||
condlst_add(&opt->unredir_if_possible_blacklist, optarg);
|
||||
break;
|
||||
P_CASELONG(309, unredir_if_possible_delay);
|
||||
case 310:
|
||||
// --write-pid-path
|
||||
ps->o.write_pid_path = strdup(optarg);
|
||||
opt->write_pid_path = strdup(optarg);
|
||||
break;
|
||||
P_CASEBOOL(311, vsync_use_glfinish);
|
||||
P_CASEBOOL(312, xrender_sync);
|
||||
|
@ -738,7 +742,7 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASEBOOL(315, no_fading_destroyed_argb);
|
||||
P_CASEBOOL(316, force_win_blend);
|
||||
case 317:
|
||||
ps->o.glx_fshader_win_str = strdup(optarg);
|
||||
opt->glx_fshader_win_str = strdup(optarg);
|
||||
log_warn("--glx-fshader-win is being deprecated, and might be "
|
||||
"removed in the future. If you really need this "
|
||||
"feature, please report an issue to let us know");
|
||||
|
@ -756,34 +760,35 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
P_CASEBOOL(731, reredir_on_root_change);
|
||||
P_CASEBOOL(732, glx_reinit_on_root_change);
|
||||
P_CASEBOOL(800, monitor_repaint);
|
||||
case 801: ps->o.print_diagnostics = true; break;
|
||||
case 801: opt->print_diagnostics = true; break;
|
||||
default: usage(1); break;
|
||||
#undef P_CASEBOOL
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Restore LC_NUMERIC
|
||||
setlocale(LC_NUMERIC, lc_numeric_old);
|
||||
free(lc_numeric_old);
|
||||
|
||||
if (ps->o.monitor_repaint && ps->o.backend != BKEND_XRENDER) {
|
||||
if (opt->monitor_repaint && opt->backend != BKEND_XRENDER) {
|
||||
log_warn("--monitor-repaint has no effect when backend is not xrender");
|
||||
}
|
||||
|
||||
// Range checking and option assignments
|
||||
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
||||
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0);
|
||||
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
||||
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
||||
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
||||
ps->o.inactive_dim = normalize_d(ps->o.inactive_dim);
|
||||
ps->o.frame_opacity = normalize_d(ps->o.frame_opacity);
|
||||
ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity);
|
||||
ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300);
|
||||
opt->fade_delta = max_i(opt->fade_delta, 1);
|
||||
opt->shadow_radius = max_i(opt->shadow_radius, 0);
|
||||
opt->shadow_red = normalize_d(opt->shadow_red);
|
||||
opt->shadow_green = normalize_d(opt->shadow_green);
|
||||
opt->shadow_blue = normalize_d(opt->shadow_blue);
|
||||
opt->inactive_dim = normalize_d(opt->inactive_dim);
|
||||
opt->frame_opacity = normalize_d(opt->frame_opacity);
|
||||
opt->shadow_opacity = normalize_d(opt->shadow_opacity);
|
||||
opt->refresh_rate = normalize_i_range(opt->refresh_rate, 0, 300);
|
||||
|
||||
// Apply default wintype options that are dependent on global options
|
||||
for (int i = 0; i < NUM_WINTYPES; i++) {
|
||||
auto wo = &ps->o.wintype_option[i];
|
||||
auto wo = &opt->wintype_option[i];
|
||||
auto mask = &winopt_mask[i];
|
||||
if (!mask->shadow) {
|
||||
wo->shadow = shadow_enable;
|
||||
|
@ -796,26 +801,26 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
}
|
||||
|
||||
// --blur-background-frame implies --blur-background
|
||||
if (ps->o.blur_background_frame)
|
||||
ps->o.blur_background = true;
|
||||
if (opt->blur_background_frame)
|
||||
opt->blur_background = true;
|
||||
|
||||
if (ps->o.xrender_sync_fence)
|
||||
ps->o.xrender_sync = true;
|
||||
if (opt->xrender_sync_fence)
|
||||
opt->xrender_sync = true;
|
||||
|
||||
// Other variables determined by options
|
||||
|
||||
// Determine whether we need to track focus changes
|
||||
if (ps->o.inactive_opacity != ps->o.active_opacity || ps->o.inactive_dim) {
|
||||
ps->o.track_focus = true;
|
||||
if (opt->inactive_opacity != opt->active_opacity || opt->inactive_dim) {
|
||||
opt->track_focus = true;
|
||||
}
|
||||
|
||||
// Determine whether we track window grouping
|
||||
if (ps->o.detect_transient || ps->o.detect_client_leader) {
|
||||
ps->o.track_leader = true;
|
||||
if (opt->detect_transient || opt->detect_client_leader) {
|
||||
opt->track_leader = true;
|
||||
}
|
||||
|
||||
// Fill default blur kernel
|
||||
if (ps->o.blur_background && !ps->o.blur_kerns[0]) {
|
||||
if (opt->blur_background && !opt->blur_kerns[0]) {
|
||||
// Convolution filter parameter (box blur)
|
||||
// gaussian or binomial filters are definitely superior, yet looks
|
||||
// like they aren't supported as of xorg-server-1.13.0
|
||||
|
@ -835,13 +840,17 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
|||
DOUBLE_TO_XFIXED(1),
|
||||
DOUBLE_TO_XFIXED(1),
|
||||
};
|
||||
ps->o.blur_kerns[0] =
|
||||
opt->blur_kerns[0] =
|
||||
ccalloc(ARR_SIZE(convolution_blur), xcb_render_fixed_t);
|
||||
memcpy(ps->o.blur_kerns[0], convolution_blur, sizeof(convolution_blur));
|
||||
memcpy(opt->blur_kerns[0], convolution_blur, sizeof(convolution_blur));
|
||||
}
|
||||
|
||||
if (ps->o.resize_damage < 0)
|
||||
if (opt->resize_damage < 0)
|
||||
log_warn("Negative --resize-damage will not work correctly.");
|
||||
|
||||
if (opt->backend == BKEND_XRENDER && conv_kern_hasneg)
|
||||
log_warn("A convolution kernel with negative values may not work "
|
||||
"properly under X Render backend.");
|
||||
}
|
||||
|
||||
// vim: set noet sw=8 ts=8 :
|
||||
|
|
|
@ -2,9 +2,15 @@
|
|||
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
|
||||
#pragma once
|
||||
|
||||
/// Parse command line options
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <xcb/render.h> // for xcb_render_fixed_t
|
||||
|
||||
#include "compiler.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "win.h" // for wintype_t
|
||||
|
||||
typedef struct session session_t;
|
||||
|
||||
|
@ -15,5 +21,15 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all
|
|||
|
||||
/**
|
||||
* Process arguments and configuration files.
|
||||
*
|
||||
* Parameters:
|
||||
* shadow_enable = Carry overs from parse_config
|
||||
* fading_enable
|
||||
* conv_kern_hasneg
|
||||
* winopt_mask
|
||||
*/
|
||||
void get_cfg(session_t *ps, int argc, char *const *argv);
|
||||
void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||
bool fading_enable, bool conv_kern_hasneg,
|
||||
win_option_mask_t *winopt_mask);
|
||||
|
||||
// vim: set noet sw=8 ts=8:
|
||||
|
|
10
src/render.c
10
src/render.c
|
@ -4,6 +4,7 @@
|
|||
#include <xcb/xcb_image.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "options.h"
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
#include "opengl.h"
|
||||
|
@ -125,7 +126,12 @@ paint_region(session_t *ps, win *w, int x, int y, int wid, int hei, double opaci
|
|||
|
||||
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict,
|
||||
(w ? w->paint.ptex : ps->root_tile_paint.ptex), reg_paint,
|
||||
(w ? &ps->o.glx_prog_win : NULL));
|
||||
#ifdef CONFIG_OPENGL
|
||||
w ? &ps->glx_prog_win : NULL
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1223,7 +1229,7 @@ bool init_render(session_t *ps) {
|
|||
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
||||
#ifdef CONFIG_OPENGL
|
||||
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str,
|
||||
&ps->o.glx_prog_win))
|
||||
&ps->glx_prog_win))
|
||||
return false;
|
||||
#else
|
||||
log_error("GLSL supported not compiled in, can't load "
|
||||
|
|
Loading…
Reference in a new issue