mirror of
https://github.com/yshui/picom.git
synced 2024-11-25 14:06:08 -05:00
Merge branch 'richardgv-dev'
This commit is contained in:
commit
c7ca3454ee
4 changed files with 326 additions and 129 deletions
6
Makefile
6
Makefile
|
@ -12,6 +12,12 @@ INCS += $(shell pcre-config --cflags)
|
|||
CFLAGS += -Wall -std=c99
|
||||
OBJS = compton.o
|
||||
|
||||
CFG ?= -DCONFIG_LIBCONFIG -DCONFIG_REGEX_PCRE -DCONFIG_REGEX_PCRE_JIT
|
||||
# libconfig-1.3* does not define LIBCONFIG_VER* macros, so we use pkg-config
|
||||
# to determine its version here
|
||||
CFG += $(shell pkg-config --atleast-version=1.4 libconfig || echo '-DCONFIG_LIBCONFIG_LEGACY')
|
||||
CFLAGS += $(CFG)
|
||||
|
||||
%.o: src/%.c src/%.h
|
||||
$(CC) $(CFLAGS) $(INCS) -c src/$*.c
|
||||
|
||||
|
|
|
@ -3,15 +3,16 @@ shadow = true;
|
|||
no-dnd-shadow = true;
|
||||
no-dock-shadow = true;
|
||||
clear-shadow = true;
|
||||
shadow-radius = 7
|
||||
shadow-offset-x = -7
|
||||
shadow-offset-y = -7
|
||||
# shadow-opacity = 0.7
|
||||
# shadow-red = 0.0
|
||||
# shadow-green = 0.0
|
||||
# shadow-blue = 0.0
|
||||
shadow-radius = 7;
|
||||
shadow-offset-x = -7;
|
||||
shadow-offset-y = -7;
|
||||
# shadow-opacity = 0.7;
|
||||
# shadow-red = 0.0;
|
||||
# shadow-green = 0.0;
|
||||
# shadow-blue = 0.0;
|
||||
shadow-exclude = [ "n:e:Notification" ];
|
||||
# shadow-exclude = "n:e:Notification";
|
||||
shadow-ignore-shaped = true;
|
||||
|
||||
# Opacity
|
||||
menu-opacity = 0.8;
|
||||
|
@ -21,17 +22,18 @@ inactive-opacity-override = true;
|
|||
|
||||
# Fading
|
||||
fading = true;
|
||||
# fade-delta = 30
|
||||
fade-in-step = 0.03
|
||||
fade-out-step = 0.03
|
||||
# fade-delta = 30;
|
||||
fade-in-step = 0.03;
|
||||
fade-out-step = 0.03;
|
||||
# no-fading-openclose = true;
|
||||
|
||||
# Other
|
||||
mark-wmwin-focused = true;
|
||||
mark-ovredir-focused = true;
|
||||
detect-rounded-corners = true;
|
||||
|
||||
# Window type settings
|
||||
wintypes:
|
||||
{
|
||||
tooltip = { fade = true; shadow = false; opacity = 0.75; };
|
||||
}
|
||||
};
|
||||
|
|
262
src/compton.c
262
src/compton.c
|
@ -51,6 +51,9 @@ XserverRegion all_damage;
|
|||
Bool has_name_pixmap;
|
||||
#endif
|
||||
int root_height, root_width;
|
||||
/// Whether the program is idling. I.e. no fading, no potential window
|
||||
/// changes.
|
||||
Bool idling;
|
||||
|
||||
/* errors */
|
||||
ignore *ignore_head = NULL, **ignore_tail = &ignore_head;
|
||||
|
@ -109,31 +112,37 @@ Atom win_type[NUM_WINTYPES];
|
|||
|
||||
static options_t opts = {
|
||||
.display = NULL,
|
||||
.mark_wmwin_focused = False,
|
||||
.mark_ovredir_focused = False,
|
||||
.fork_after_register = False,
|
||||
.synchronize = False,
|
||||
.detect_rounded_corners = False,
|
||||
|
||||
.wintype_shadow = { False },
|
||||
.shadow_red = 0.0,
|
||||
.shadow_green = 0.0,
|
||||
.shadow_blue = 0.0,
|
||||
.shadow_radius = 12,
|
||||
.shadow_offset_x = -15,
|
||||
.shadow_offset_y = -15,
|
||||
.shadow_opacity = .75,
|
||||
.clear_shadow = False,
|
||||
.shadow_blacklist = NULL,
|
||||
.shadow_ignore_shaped = False,
|
||||
|
||||
.wintype_fade = { False },
|
||||
.fade_in_step = 0.028 * OPAQUE,
|
||||
.fade_out_step = 0.03 * OPAQUE,
|
||||
.fade_delta = 10,
|
||||
.no_fading_openclose = False,
|
||||
.clear_shadow = False,
|
||||
.fade_blacklist = NULL,
|
||||
|
||||
.wintype_opacity = { 0.0 },
|
||||
.inactive_opacity = 0,
|
||||
.inactive_opacity_override = False,
|
||||
.frame_opacity = 0.0,
|
||||
.inactive_dim = 0.0,
|
||||
.mark_wmwin_focused = False,
|
||||
.mark_ovredir_focused = False,
|
||||
.shadow_blacklist = NULL,
|
||||
.fade_blacklist = NULL,
|
||||
.fork_after_register = False,
|
||||
.shadow_red = 0.0,
|
||||
.shadow_green = 0.0,
|
||||
.shadow_blue = 0.0,
|
||||
.wintype_opacity = { 0.0 },
|
||||
.wintype_shadow = { False },
|
||||
.wintype_fade = { False },
|
||||
.synchronize = False,
|
||||
|
||||
.track_focus = False,
|
||||
.track_wdata = False,
|
||||
};
|
||||
|
@ -207,6 +216,9 @@ run_fade(Display *dpy, win *w, unsigned steps) {
|
|||
w->fade_fin = True;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
idling = False;
|
||||
}
|
||||
|
||||
w->fade_fin = False;
|
||||
}
|
||||
|
@ -224,8 +236,12 @@ set_fade_callback(Display *dpy, win *w,
|
|||
|
||||
w->fade_callback = callback;
|
||||
// Must be the last line as the callback could destroy w!
|
||||
if (exec_callback && old_callback)
|
||||
if (exec_callback && old_callback) {
|
||||
old_callback(dpy, w);
|
||||
// Although currently no callback function affects window state on
|
||||
// next paint, it could, in the future
|
||||
idling = False;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -384,11 +400,10 @@ make_shadow(Display *dpy, double opacity,
|
|||
int width, int height) {
|
||||
XImage *ximage;
|
||||
unsigned char *data;
|
||||
int gsize = gaussian_map->size;
|
||||
int ylimit, xlimit;
|
||||
int swidth = width + gsize;
|
||||
int sheight = height + gsize;
|
||||
int center = gsize / 2;
|
||||
int swidth = width + cgsize;
|
||||
int sheight = height + cgsize;
|
||||
int center = cgsize / 2;
|
||||
int x, y;
|
||||
unsigned char d;
|
||||
int x_diff;
|
||||
|
@ -434,10 +449,10 @@ make_shadow(Display *dpy, double opacity,
|
|||
* corners
|
||||
*/
|
||||
|
||||
ylimit = gsize;
|
||||
ylimit = cgsize;
|
||||
if (ylimit > sheight / 2) ylimit = (sheight + 1) / 2;
|
||||
|
||||
xlimit = gsize;
|
||||
xlimit = cgsize;
|
||||
if (xlimit > swidth / 2) xlimit = (swidth + 1) / 2;
|
||||
|
||||
for (y = 0; y < ylimit; y++) {
|
||||
|
@ -460,7 +475,7 @@ make_shadow(Display *dpy, double opacity,
|
|||
* top/bottom
|
||||
*/
|
||||
|
||||
x_diff = swidth - (gsize * 2);
|
||||
x_diff = swidth - (cgsize * 2);
|
||||
if (x_diff > 0 && ylimit > 0) {
|
||||
for (y = 0; y < ylimit; y++) {
|
||||
if (ylimit == cgsize) {
|
||||
|
@ -469,8 +484,8 @@ make_shadow(Display *dpy, double opacity,
|
|||
d = sum_gaussian(gaussian_map,
|
||||
opacity, center, y - center, width, height);
|
||||
}
|
||||
memset(&data[y * swidth + gsize], d, x_diff);
|
||||
memset(&data[(sheight - y - 1) * swidth + gsize], d, x_diff);
|
||||
memset(&data[y * swidth + cgsize], d, x_diff);
|
||||
memset(&data[(sheight - y - 1) * swidth + cgsize], d, x_diff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,7 +500,7 @@ make_shadow(Display *dpy, double opacity,
|
|||
d = sum_gaussian(gaussian_map,
|
||||
opacity, x - center, center, width, height);
|
||||
}
|
||||
for (y = gsize; y < sheight - gsize; y++) {
|
||||
for (y = cgsize; y < sheight - cgsize; y++) {
|
||||
data[y * swidth + x] = d;
|
||||
data[y * swidth + (swidth - x - 1)] = d;
|
||||
}
|
||||
|
@ -512,48 +527,62 @@ make_shadow(Display *dpy, double opacity,
|
|||
|
||||
static Picture
|
||||
shadow_picture(Display *dpy, double opacity, int width, int height) {
|
||||
XImage *shadow_image;
|
||||
Pixmap shadow_pixmap;
|
||||
Picture shadow_picture;
|
||||
GC gc;
|
||||
XImage *shadow_image = NULL;
|
||||
Pixmap shadow_pixmap = None, shadow_pixmap_argb = None;
|
||||
Picture shadow_picture = None, shadow_picture_argb = None;
|
||||
GC gc = None;
|
||||
|
||||
shadow_image = make_shadow(dpy, opacity, width, height);
|
||||
if (!shadow_image) return None;
|
||||
if (!shadow_image)
|
||||
return None;
|
||||
|
||||
shadow_pixmap = XCreatePixmap(dpy, root,
|
||||
shadow_image->width, shadow_image->height, 8);
|
||||
shadow_pixmap_argb = XCreatePixmap(dpy, root,
|
||||
shadow_image->width, shadow_image->height, 32);
|
||||
|
||||
if (!shadow_pixmap) {
|
||||
XDestroyImage(shadow_image);
|
||||
return None;
|
||||
}
|
||||
if (!shadow_pixmap || !shadow_pixmap_argb)
|
||||
goto shadow_picture_err;
|
||||
|
||||
shadow_picture = XRenderCreatePicture(dpy, shadow_pixmap,
|
||||
XRenderFindStandardFormat(dpy, PictStandardA8), 0, 0);
|
||||
|
||||
if (!shadow_picture) {
|
||||
XDestroyImage(shadow_image);
|
||||
XFreePixmap(dpy, shadow_pixmap);
|
||||
return None;
|
||||
}
|
||||
shadow_picture_argb = XRenderCreatePicture(dpy, shadow_pixmap_argb,
|
||||
XRenderFindStandardFormat(dpy, PictStandardARGB32), 0, 0);
|
||||
if (!shadow_picture || !shadow_picture_argb)
|
||||
goto shadow_picture_err;
|
||||
|
||||
gc = XCreateGC(dpy, shadow_pixmap, 0, 0);
|
||||
if (!gc) {
|
||||
XDestroyImage(shadow_image);
|
||||
XFreePixmap(dpy, shadow_pixmap);
|
||||
XRenderFreePicture(dpy, shadow_picture);
|
||||
return None;
|
||||
}
|
||||
if (!gc)
|
||||
goto shadow_picture_err;
|
||||
|
||||
XPutImage(
|
||||
dpy, shadow_pixmap, gc, shadow_image, 0, 0, 0, 0,
|
||||
XPutImage(dpy, shadow_pixmap, gc, shadow_image, 0, 0, 0, 0,
|
||||
shadow_image->width, shadow_image->height);
|
||||
XRenderComposite(dpy, PictOpSrc, cshadow_picture, shadow_picture,
|
||||
shadow_picture_argb, 0, 0, 0, 0, 0, 0,
|
||||
shadow_image->width, shadow_image->height);
|
||||
|
||||
XFreeGC(dpy, gc);
|
||||
XDestroyImage(shadow_image);
|
||||
XFreePixmap(dpy, shadow_pixmap);
|
||||
XFreePixmap(dpy, shadow_pixmap_argb);
|
||||
XRenderFreePicture(dpy, shadow_picture);
|
||||
|
||||
return shadow_picture;
|
||||
return shadow_picture_argb;
|
||||
|
||||
shadow_picture_err:
|
||||
if (shadow_image)
|
||||
XDestroyImage(shadow_image);
|
||||
if (shadow_pixmap)
|
||||
XFreePixmap(dpy, shadow_pixmap);
|
||||
if (shadow_pixmap_argb)
|
||||
XFreePixmap(dpy, shadow_pixmap_argb);
|
||||
if (shadow_picture)
|
||||
XRenderFreePicture(dpy, shadow_picture);
|
||||
if (shadow_picture_argb)
|
||||
XRenderFreePicture(dpy, shadow_picture_argb);
|
||||
if (gc)
|
||||
XFreeGC(dpy, gc);
|
||||
return None;
|
||||
}
|
||||
|
||||
static Picture
|
||||
|
@ -632,6 +661,48 @@ should_ignore(Display *dpy, unsigned long sequence) {
|
|||
* Windows
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if a window has rounded corners.
|
||||
*/
|
||||
static void
|
||||
win_rounded_corners(Display *dpy, win *w) {
|
||||
if (!w->bounding_shaped)
|
||||
return;
|
||||
|
||||
// Fetch its bounding region
|
||||
if (!w->border_size)
|
||||
w->border_size = border_size(dpy, w);
|
||||
|
||||
// Quit if border_size() returns None
|
||||
if (!w->border_size)
|
||||
return;
|
||||
|
||||
// Determine the minimum width/height of a rectangle that could mark
|
||||
// a window as having rounded corners
|
||||
unsigned short minwidth = max_i(w->widthb * (1 - ROUNDED_PERCENT),
|
||||
w->widthb - ROUNDED_PIXELS);
|
||||
unsigned short minheight = max_i(w->heightb * (1 - ROUNDED_PERCENT),
|
||||
w->heightb - ROUNDED_PIXELS);
|
||||
|
||||
// Get the rectangles in the bounding region
|
||||
int nrects = 0, i;
|
||||
XRectangle *rects = XFixesFetchRegion(dpy, w->border_size, &nrects);
|
||||
if (!rects)
|
||||
return;
|
||||
|
||||
// Look for a rectangle large enough for this window be considered
|
||||
// having rounded corners
|
||||
for (i = 0; i < nrects; ++i)
|
||||
if (rects[i].width >= minwidth && rects[i].height >= minheight) {
|
||||
w->rounded_corners = True;
|
||||
XFree(rects);
|
||||
return;
|
||||
}
|
||||
|
||||
w->rounded_corners = False;
|
||||
XFree(rects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a window against a single window condition.
|
||||
*
|
||||
|
@ -1110,7 +1181,7 @@ border_size(Display *dpy, win *w) {
|
|||
|
||||
static Window
|
||||
find_client_win(Display *dpy, Window w) {
|
||||
if (win_has_attr(dpy, w, client_atom)) {
|
||||
if (wid_has_attr(dpy, w, client_atom)) {
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -1119,7 +1190,7 @@ find_client_win(Display *dpy, Window w) {
|
|||
unsigned int i;
|
||||
Window ret = 0;
|
||||
|
||||
if (!win_get_children(dpy, w, &children, &nchildren)) {
|
||||
if (!wid_get_children(dpy, w, &children, &nchildren)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1276,12 +1347,18 @@ paint_preprocess(Display *dpy, win *list) {
|
|||
if (w->flags & WFLAG_SIZE_CHANGE)
|
||||
free_picture(dpy, &w->shadow_pict);
|
||||
|
||||
if (w->shadow
|
||||
&& (!w->shadow_pict
|
||||
|| w->shadow_opacity != w->shadow_opacity_cur)) {
|
||||
free_picture(dpy, &w->shadow_pict);
|
||||
w->shadow_pict = shadow_picture(dpy, w->shadow_opacity,
|
||||
if (w->shadow && !w->shadow_pict) {
|
||||
w->shadow_pict = shadow_picture(dpy, 1,
|
||||
w->widthb, w->heightb);
|
||||
}
|
||||
|
||||
// Rebuild shadow_alpha_pict if necessary
|
||||
if (w->shadow
|
||||
&& (!w->shadow_alpha_pict
|
||||
|| w->shadow_opacity != w->shadow_opacity_cur)) {
|
||||
free_picture(dpy, &w->shadow_alpha_pict);
|
||||
w->shadow_alpha_pict = solid_picture(
|
||||
dpy, False, w->shadow_opacity, 0, 0, 0);
|
||||
w->shadow_opacity_cur = w->shadow_opacity;
|
||||
}
|
||||
|
||||
|
@ -1359,7 +1436,7 @@ paint_all(Display *dpy, XserverRegion region, win *t) {
|
|||
// Painting shadow
|
||||
if (w->shadow) {
|
||||
XRenderComposite(
|
||||
dpy, PictOpOver, cshadow_picture, w->shadow_pict,
|
||||
dpy, PictOpOver, w->shadow_pict, w->shadow_alpha_pict,
|
||||
root_buffer, 0, 0, 0, 0,
|
||||
w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
|
||||
w->shadow_width, w->shadow_height);
|
||||
|
@ -1510,7 +1587,7 @@ determine_wintype(Display *dpy, Window w) {
|
|||
type = get_wintype_prop(dpy, w);
|
||||
if (type != WINTYPE_UNKNOWN) return type;
|
||||
|
||||
if (!win_get_children(dpy, w, &children, &nchildren))
|
||||
if (!wid_get_children(dpy, w, &children, &nchildren))
|
||||
return WINTYPE_UNKNOWN;
|
||||
|
||||
for (i = 0; i < nchildren; i++) {
|
||||
|
@ -1570,6 +1647,13 @@ map_win(Display *dpy, Window id,
|
|||
w->id, WINTYPES[w->window_type]);
|
||||
#endif
|
||||
|
||||
// Detect if the window is shaped or has rounded corners
|
||||
if (opts.shadow_ignore_shaped) {
|
||||
w->bounding_shaped = wid_bounding_shaped(dpy, w->id);
|
||||
if (w->bounding_shaped && opts.detect_rounded_corners)
|
||||
win_rounded_corners(dpy, w);
|
||||
}
|
||||
|
||||
// Get window name and class if we are tracking them
|
||||
if (opts.track_wdata) {
|
||||
win_get_name(dpy, w);
|
||||
|
@ -1592,7 +1676,8 @@ map_win(Display *dpy, Window id,
|
|||
w->focused = True;
|
||||
}
|
||||
|
||||
// Window type change could affect shadow and fade
|
||||
// Window type change and bounding shape state change could affect
|
||||
// shadow
|
||||
determine_shadow(dpy, w);
|
||||
|
||||
// Determine mode here just in case the colormap changes
|
||||
|
@ -1601,6 +1686,7 @@ map_win(Display *dpy, Window id,
|
|||
// Fading in
|
||||
calc_opacity(dpy, w, True);
|
||||
|
||||
// Set fading state
|
||||
if (opts.no_fading_openclose) {
|
||||
set_fade_callback(dpy, w, finish_map_win, True);
|
||||
// Must be set after we execute the old fade callback, in case we
|
||||
|
@ -1820,7 +1906,9 @@ determine_shadow(Display *dpy, win *w) {
|
|||
Bool shadow_old = w->shadow;
|
||||
|
||||
w->shadow = (opts.wintype_shadow[w->window_type]
|
||||
&& !win_match(w, opts.shadow_blacklist, &w->cache_sblst));
|
||||
&& !win_match(w, opts.shadow_blacklist, &w->cache_sblst)
|
||||
&& !(opts.shadow_ignore_shaped && w->bounding_shaped
|
||||
&& !w->rounded_corners));
|
||||
|
||||
// Window extents need update on shadow state change
|
||||
if (w->shadow != shadow_old) {
|
||||
|
@ -1935,6 +2023,8 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
|||
new->class_general = NULL;
|
||||
new->cache_sblst = NULL;
|
||||
new->cache_fblst = NULL;
|
||||
new->bounding_shaped = False;
|
||||
new->rounded_corners = False;
|
||||
|
||||
new->border_size = None;
|
||||
new->extents = None;
|
||||
|
@ -1942,6 +2032,7 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
|||
new->shadow_opacity = 0.0;
|
||||
new->shadow_opacity_cur = 0.0;
|
||||
new->shadow_pict = None;
|
||||
new->shadow_alpha_pict = None;
|
||||
new->shadow_dx = 0;
|
||||
new->shadow_dy = 0;
|
||||
new->shadow_width = 0;
|
||||
|
@ -2752,6 +2843,16 @@ ev_shape_notify(XShapeEvent *ev) {
|
|||
// Mark the new border_size as damaged
|
||||
add_damage(dpy, copy_region(dpy, w->border_size));
|
||||
}
|
||||
|
||||
// Redo bounding shape detection and rounded corner detection
|
||||
if (opts.shadow_ignore_shaped) {
|
||||
w->bounding_shaped = wid_bounding_shaped(dpy, w->id);
|
||||
if (w->bounding_shaped && opts.detect_rounded_corners)
|
||||
win_rounded_corners(dpy, w);
|
||||
|
||||
// Shadow state could be changed
|
||||
determine_shadow(dpy, w);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void
|
||||
|
@ -2905,6 +3006,11 @@ usage(void) {
|
|||
" Mark over-redirect windows as active.\n"
|
||||
"--no-fading-openclose\n"
|
||||
" Do not fade on window open/close.\n"
|
||||
"--shadow-ignore-shaped\n"
|
||||
" Do not paint shadows on shaped windows.\n"
|
||||
"--detect-rounded-corners\n"
|
||||
" Try to detect windows with rounded corners and don't consider\n"
|
||||
" them shaped windows.\n"
|
||||
"\n"
|
||||
"Format of a condition:\n"
|
||||
"\n"
|
||||
|
@ -3071,7 +3177,7 @@ open_config_file(char *cpath, char **ppath) {
|
|||
*/
|
||||
static void
|
||||
parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
||||
char *path = NULL, *parent = NULL;
|
||||
char *path = NULL;
|
||||
FILE *f;
|
||||
config_t cfg;
|
||||
int ival = 0;
|
||||
|
@ -3085,9 +3191,11 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
|||
}
|
||||
|
||||
config_init(&cfg);
|
||||
parent = dirname(path);
|
||||
#ifndef CONFIG_LIBCONFIG_LEGACY
|
||||
char *parent = dirname(path);
|
||||
if (parent)
|
||||
config_set_include_dir(&cfg, parent);
|
||||
#endif
|
||||
|
||||
if (CONFIG_FALSE == config_read(&cfg, f)) {
|
||||
printf("Error when reading configuration file \"%s\", line %d: %s\n",
|
||||
|
@ -3104,7 +3212,7 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
|||
// right now. It will be done later
|
||||
|
||||
// -D (fade_delta)
|
||||
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
||||
if (lcfg_lookup_int(&cfg, "fade-delta", &ival))
|
||||
opts.fade_delta = ival;
|
||||
// -I (fade_in_step)
|
||||
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
||||
|
@ -3113,13 +3221,13 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
|||
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
||||
opts.fade_out_step = normalize_d(dval) * OPAQUE;
|
||||
// -r (shadow_radius)
|
||||
config_lookup_int(&cfg, "shadow-radius", &opts.shadow_radius);
|
||||
lcfg_lookup_int(&cfg, "shadow-radius", &opts.shadow_radius);
|
||||
// -o (shadow_opacity)
|
||||
config_lookup_float(&cfg, "shadow-opacity", &opts.shadow_opacity);
|
||||
// -l (shadow_offset_x)
|
||||
config_lookup_int(&cfg, "shadow-offset-x", &opts.shadow_offset_x);
|
||||
lcfg_lookup_int(&cfg, "shadow-offset-x", &opts.shadow_offset_x);
|
||||
// -t (shadow_offset_y)
|
||||
config_lookup_int(&cfg, "shadow-offset-y", &opts.shadow_offset_y);
|
||||
lcfg_lookup_int(&cfg, "shadow-offset-y", &opts.shadow_offset_y);
|
||||
// -i (inactive_opacity)
|
||||
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
||||
opts.inactive_opacity = normalize_d(dval) * OPAQUE;
|
||||
|
@ -3157,6 +3265,12 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
|||
// --mark-ovredir-focused
|
||||
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
||||
&opts.mark_ovredir_focused);
|
||||
// --shadow-ignore-shaped
|
||||
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
||||
&opts.shadow_ignore_shaped);
|
||||
// --detect-rounded-corners
|
||||
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
||||
&opts.detect_rounded_corners);
|
||||
// --shadow-exclude
|
||||
{
|
||||
config_setting_t *setting =
|
||||
|
@ -3217,6 +3331,8 @@ get_cfg(int argc, char *const *argv) {
|
|||
{ "shadow-exclude", required_argument, NULL, 263 },
|
||||
{ "mark-ovredir-focused", no_argument, NULL, 264 },
|
||||
{ "no-fading-openclose", no_argument, NULL, 265 },
|
||||
{ "shadow-ignore-shaped", no_argument, NULL, 266 },
|
||||
{ "detect-rounded-corners", no_argument, NULL, 267 },
|
||||
// Must terminate with a NULL entry
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
@ -3363,6 +3479,14 @@ get_cfg(int argc, char *const *argv) {
|
|||
// --no-fading-openclose
|
||||
opts.no_fading_openclose = True;
|
||||
break;
|
||||
case 266:
|
||||
// --shadow-ignore-shaped
|
||||
opts.shadow_ignore_shaped = True;
|
||||
break;
|
||||
case 267:
|
||||
// --detect-rounded-corners
|
||||
opts.detect_rounded_corners = True;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
@ -3591,10 +3715,13 @@ main(int argc, char **argv) {
|
|||
t = paint_preprocess(dpy, list);
|
||||
paint_all(dpy, None, t);
|
||||
|
||||
// Initialize idling
|
||||
idling = False;
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
if (!QLength(dpy)) {
|
||||
if (poll(&ufd, 1, fade_timeout()) == 0) {
|
||||
if (poll(&ufd, 1, (idling ? -1: fade_timeout())) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3603,6 +3730,9 @@ main(int argc, char **argv) {
|
|||
ev_handle((XEvent *)&ev);
|
||||
} while (QLength(dpy));
|
||||
|
||||
// idling will be turned off during paint_preprocess() if needed
|
||||
idling = True;
|
||||
|
||||
t = paint_preprocess(dpy, list);
|
||||
if (all_damage) {
|
||||
static int paint;
|
||||
|
|
163
src/compton.h
163
src/compton.h
|
@ -20,12 +20,12 @@
|
|||
|
||||
// Whether to enable PCRE regular expression support in blacklists, enabled
|
||||
// by default
|
||||
#define CONFIG_REGEX_PCRE 1
|
||||
// #define CONFIG_REGEX_PCRE 1
|
||||
// Whether to enable JIT support of libpcre. This may cause problems on PaX
|
||||
// kernels.
|
||||
#define CONFIG_REGEX_PCRE_JIT 1
|
||||
// #define CONFIG_REGEX_PCRE_JIT 1
|
||||
// Whether to enable parsing of configuration files using libconfig
|
||||
#define CONFIG_LIBCONFIG 1
|
||||
// #define CONFIG_LIBCONFIG 1
|
||||
|
||||
// === Includes ===
|
||||
|
||||
|
@ -49,6 +49,12 @@
|
|||
|
||||
#ifdef CONFIG_REGEX_PCRE
|
||||
#include <pcre.h>
|
||||
|
||||
// For compatiblity with <libpcre-8.20
|
||||
#ifndef PCRE_STUDY_JIT_COMPILE
|
||||
#define PCRE_STUDY_JIT_COMPILE 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
|
@ -69,6 +75,9 @@
|
|||
#define HAS_NAME_WINDOW_PIXMAP 1
|
||||
#endif
|
||||
|
||||
#define ROUNDED_PERCENT 0.05
|
||||
#define ROUNDED_PIXELS 10
|
||||
|
||||
// For printing timestamps
|
||||
#include <time.h>
|
||||
extern struct timeval time_start;
|
||||
|
@ -168,6 +177,10 @@ typedef struct _win {
|
|||
Bool destroyed;
|
||||
/// Cached width/height of the window including border.
|
||||
int widthb, heightb;
|
||||
/// Whether the window is bounding-shaped.
|
||||
Bool bounding_shaped;
|
||||
/// Whether the window just have rounded corners.
|
||||
Bool rounded_corners;
|
||||
|
||||
// Blacklist related members
|
||||
char *name;
|
||||
|
@ -222,9 +235,10 @@ typedef struct _win {
|
|||
int shadow_width;
|
||||
/// Height of shadow. Affected by window size and commandline argument.
|
||||
int shadow_height;
|
||||
/// Alpha mask Picture to render shadow. Affected by window size and
|
||||
/// shadow opacity.
|
||||
/// Picture to render shadow. Affected by window size.
|
||||
Picture shadow_pict;
|
||||
/// Alpha mask Picture to render shadow. Affected by shadow opacity.
|
||||
Picture shadow_alpha_pict;
|
||||
|
||||
// Dim-related members
|
||||
/// Whether the window is to be dimmed.
|
||||
|
@ -250,6 +264,9 @@ typedef struct _options {
|
|||
Bool mark_ovredir_focused;
|
||||
/// Whether to fork to background.
|
||||
Bool fork_after_register;
|
||||
/// Whether to detect rounded corners.
|
||||
Bool detect_rounded_corners;
|
||||
/// Whether to work under synchronized mode for debugging.
|
||||
Bool synchronize;
|
||||
|
||||
// Shadow
|
||||
|
@ -262,6 +279,8 @@ typedef struct _options {
|
|||
Bool clear_shadow;
|
||||
/// Shadow blacklist. A linked list of conditions.
|
||||
wincond *shadow_blacklist;
|
||||
/// Whether bounding-shaped window should be ignored.
|
||||
Bool shadow_ignore_shaped;
|
||||
|
||||
// Fading
|
||||
Bool wintype_fade[NUM_WINTYPES];
|
||||
|
@ -314,6 +333,8 @@ typedef enum {
|
|||
|
||||
extern int root_height, root_width;
|
||||
extern Atom atom_client_attr;
|
||||
extern Bool idling;
|
||||
extern Bool shape_exists;
|
||||
|
||||
/**
|
||||
* Functions
|
||||
|
@ -555,52 +576,6 @@ free_damage(Display *dpy, Damage *p) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a window has a specific attribute.
|
||||
*
|
||||
* @param dpy Display to use
|
||||
* @param w window to check
|
||||
* @param atom atom of attribute to check
|
||||
* @return 1 if it has the attribute, 0 otherwise
|
||||
*/
|
||||
static inline Bool
|
||||
win_has_attr(Display *dpy, Window w, Atom atom) {
|
||||
Atom type = None;
|
||||
int format;
|
||||
unsigned long nitems, after;
|
||||
unsigned char *data;
|
||||
|
||||
if (Success == XGetWindowProperty(dpy, w, atom, 0, 0, False,
|
||||
AnyPropertyType, &type, &format, &nitems, &after, &data)) {
|
||||
XFree(data);
|
||||
if (type) return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the children of a window.
|
||||
*
|
||||
* @param dpy Display to use
|
||||
* @param w window to check
|
||||
* @param children [out] an array of child window IDs
|
||||
* @param nchildren [out] number of children
|
||||
* @return 1 if successful, 0 otherwise
|
||||
*/
|
||||
static inline Bool
|
||||
win_get_children(Display *dpy, Window w,
|
||||
Window **children, unsigned *nchildren) {
|
||||
Window troot, tparent;
|
||||
|
||||
if (!XQueryTree(dpy, w, &troot, &tparent, children, nchildren)) {
|
||||
*nchildren = 0;
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
get_time_in_milliseconds(void);
|
||||
|
||||
|
@ -660,6 +635,75 @@ static inline bool is_normal_win(const win *w) {
|
|||
|| WINTYPE_UNKNOWN == w->window_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a window has a specific attribute.
|
||||
*
|
||||
* @param dpy Display to use
|
||||
* @param w window to check
|
||||
* @param atom atom of attribute to check
|
||||
* @return 1 if it has the attribute, 0 otherwise
|
||||
*/
|
||||
static inline Bool
|
||||
wid_has_attr(Display *dpy, Window w, Atom atom) {
|
||||
Atom type = None;
|
||||
int format;
|
||||
unsigned long nitems, after;
|
||||
unsigned char *data;
|
||||
|
||||
if (Success == XGetWindowProperty(dpy, w, atom, 0, 0, False,
|
||||
AnyPropertyType, &type, &format, &nitems, &after, &data)) {
|
||||
XFree(data);
|
||||
if (type) return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the children of a window.
|
||||
*
|
||||
* @param dpy Display to use
|
||||
* @param w window to check
|
||||
* @param children [out] an array of child window IDs
|
||||
* @param nchildren [out] number of children
|
||||
* @return 1 if successful, 0 otherwise
|
||||
*/
|
||||
static inline Bool
|
||||
wid_get_children(Display *dpy, Window w,
|
||||
Window **children, unsigned *nchildren) {
|
||||
Window troot, tparent;
|
||||
|
||||
if (!XQueryTree(dpy, w, &troot, &tparent, children, nchildren)) {
|
||||
*nchildren = 0;
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a window is bounding-shaped.
|
||||
*/
|
||||
static inline Bool
|
||||
wid_bounding_shaped(Display *dpy, Window wid) {
|
||||
if (shape_exists) {
|
||||
Bool bounding_shaped = False;
|
||||
Bool clip_shaped;
|
||||
int x_bounding, y_bounding, x_clip, y_clip;
|
||||
unsigned int w_bounding, h_bounding, w_clip, h_clip;
|
||||
|
||||
XShapeQueryExtents(dpy, wid, &bounding_shaped,
|
||||
&x_bounding, &y_bounding, &w_bounding, &h_bounding,
|
||||
&clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip);
|
||||
return bounding_shaped;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
win_rounded_corners(Display *dpy, win *w);
|
||||
|
||||
static bool
|
||||
win_match_once(win *w, const wincond *cond);
|
||||
|
||||
|
@ -923,7 +967,7 @@ static void
|
|||
fork_after(void);
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
static void
|
||||
static inline void
|
||||
lcfg_lookup_bool(const config_t *config, const char *path, Bool *value) {
|
||||
int ival;
|
||||
|
||||
|
@ -931,6 +975,21 @@ lcfg_lookup_bool(const config_t *config, const char *path, Bool *value) {
|
|||
*value = ival;
|
||||
}
|
||||
|
||||
static inline int
|
||||
lcfg_lookup_int(const config_t *config, const char *path, int *value) {
|
||||
#ifndef CONFIG_LIBCONFIG_LEGACY
|
||||
return config_lookup_int(config, path, value);
|
||||
#else
|
||||
long lval;
|
||||
int ret;
|
||||
|
||||
if ((ret = config_lookup_int(config, path, &lval)))
|
||||
*value = lval;
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static FILE *
|
||||
open_config_file(char *cpath, char **path);
|
||||
|
||||
|
|
Loading…
Reference in a new issue