Improvement: Change painting sequence
- Now compton paints windows from the lowest to the highest. Warning: I'm not completely certain that the change won't introduce unexpected glitches. This commit may be revoked in the future. - Remove w->border_clip since it's no longer needed. - Correct a mistake in find_toplevel2(). (clang --analyze found it out.) - Change "func_name()" prototypes to "func_name(void)". If I remember correctly, "func_name()" means you are remaining silent about this function's parameters instead of stating it has no parameter in ANSI C. - Add timestamps to error messages. - Suppress error messages caused by free_damage().
This commit is contained in:
parent
dfde67255f
commit
cdf7db750d
107
src/compton.c
107
src/compton.c
|
@ -14,9 +14,7 @@
|
||||||
* Shared
|
* Shared
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG_EVENTS
|
|
||||||
struct timeval time_start = { 0, 0 };
|
struct timeval time_start = { 0, 0 };
|
||||||
#endif
|
|
||||||
|
|
||||||
win *list;
|
win *list;
|
||||||
fade *fades;
|
fade *fades;
|
||||||
|
@ -774,7 +772,7 @@ find_toplevel2(Display *dpy, Window wid) {
|
||||||
// just leave it alone.
|
// just leave it alone.
|
||||||
if (!XQueryTree(dpy, wid, &troot, &parent, &tchildren,
|
if (!XQueryTree(dpy, wid, &troot, &parent, &tchildren,
|
||||||
&tnchildren)) {
|
&tnchildren)) {
|
||||||
wid = 0;
|
parent = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,7 +1112,6 @@ paint_all(Display *dpy, XserverRegion region) {
|
||||||
if (clip_changed) {
|
if (clip_changed) {
|
||||||
free_region(dpy, &w->border_size);
|
free_region(dpy, &w->border_size);
|
||||||
free_region(dpy, &w->extents);
|
free_region(dpy, &w->extents);
|
||||||
free_region(dpy, &w->border_clip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!w->border_size) {
|
if (!w->border_size) {
|
||||||
|
@ -1150,43 +1147,6 @@ paint_all(Display *dpy, XserverRegion region) {
|
||||||
w->frame_opacity_cur = w->frame_opacity;
|
w->frame_opacity_cur = w->frame_opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->mode == WINDOW_SOLID && !w->frame_opacity) {
|
|
||||||
int x, y, wid, hei;
|
|
||||||
|
|
||||||
#if HAS_NAME_WINDOW_PIXMAP
|
|
||||||
x = w->a.x;
|
|
||||||
y = w->a.y;
|
|
||||||
wid = w->a.width + w->a.border_width * 2;
|
|
||||||
hei = w->a.height + w->a.border_width * 2;
|
|
||||||
#else
|
|
||||||
x = w->a.x + w->a.border_width;
|
|
||||||
y = w->a.y + w->a.border_width;
|
|
||||||
wid = w->a.width;
|
|
||||||
hei = w->a.height;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region);
|
|
||||||
set_ignore(dpy, NextRequest(dpy));
|
|
||||||
|
|
||||||
XFixesSubtractRegion(dpy, region, region, w->border_size);
|
|
||||||
set_ignore(dpy, NextRequest(dpy));
|
|
||||||
|
|
||||||
XRenderComposite(
|
|
||||||
dpy, PictOpSrc, w->picture,
|
|
||||||
None, root_buffer, 0, 0, 0, 0,
|
|
||||||
x, y, wid, hei);
|
|
||||||
|
|
||||||
if (w->dim) {
|
|
||||||
XRenderComposite(dpy, PictOpOver, dim_picture, None,
|
|
||||||
root_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!w->border_clip) {
|
|
||||||
w->border_clip = XFixesCreateRegion(dpy, 0, 0);
|
|
||||||
XFixesCopyRegion(dpy, w->border_clip, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
w->prev_trans = t;
|
w->prev_trans = t;
|
||||||
t = w;
|
t = w;
|
||||||
}
|
}
|
||||||
|
@ -1196,30 +1156,13 @@ paint_all(Display *dpy, XserverRegion region) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XFixesSetPictureClipRegion(dpy,
|
XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region);
|
||||||
root_buffer, 0, 0, region);
|
|
||||||
|
|
||||||
paint_root(dpy);
|
paint_root(dpy);
|
||||||
|
|
||||||
for (w = t; w; w = w->prev_trans) {
|
for (w = t; w; w = w->prev_trans) {
|
||||||
XFixesSetPictureClipRegion(dpy,
|
|
||||||
root_buffer, 0, 0, w->border_clip);
|
|
||||||
|
|
||||||
if (win_type_shadow[w->window_type]) {
|
|
||||||
XRenderComposite(
|
|
||||||
dpy, PictOpOver, cshadow_picture, w->shadow_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w->mode != WINDOW_SOLID || w->frame_opacity) {
|
|
||||||
int x, y, wid, hei;
|
int x, y, wid, hei;
|
||||||
|
|
||||||
// Necessary to make sure specially-shaped windows are
|
|
||||||
// painted correctly
|
|
||||||
XFixesIntersectRegion(dpy, w->border_clip, w->border_clip, w->border_size);
|
|
||||||
XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, w->border_clip);
|
|
||||||
#if HAS_NAME_WINDOW_PIXMAP
|
#if HAS_NAME_WINDOW_PIXMAP
|
||||||
x = w->a.x;
|
x = w->a.x;
|
||||||
y = w->a.y;
|
y = w->a.y;
|
||||||
|
@ -1232,15 +1175,32 @@ paint_all(Display *dpy, XserverRegion region) {
|
||||||
hei = w->a.height;
|
hei = w->a.height;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set_ignore(dpy, NextRequest(dpy));
|
// Allow shadow to be painted anywhere in the damaged region
|
||||||
|
XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region);
|
||||||
|
|
||||||
|
// Painting shadow
|
||||||
|
if (win_type_shadow[w->window_type]) {
|
||||||
|
XRenderComposite(
|
||||||
|
dpy, PictOpOver, cshadow_picture, w->shadow_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The window only could be painted in its bounding region
|
||||||
|
XserverRegion paint_reg = XFixesCreateRegion(dpy, NULL, 0);
|
||||||
|
XFixesIntersectRegion(dpy, paint_reg, region, w->border_size);
|
||||||
|
XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, paint_reg);
|
||||||
|
|
||||||
Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
|
Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
|
||||||
|
int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver);
|
||||||
|
|
||||||
|
// Painting the window
|
||||||
if (!w->frame_opacity) {
|
if (!w->frame_opacity) {
|
||||||
XRenderComposite(
|
XRenderComposite(dpy, op, w->picture, alpha_mask,
|
||||||
dpy, PictOpOver, w->picture, alpha_mask,
|
|
||||||
root_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
root_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
unsigned int t = w->top_width;
|
unsigned int t = w->top_width;
|
||||||
unsigned int l = w->left_width;
|
unsigned int l = w->left_width;
|
||||||
unsigned int b = w->bottom_width;
|
unsigned int b = w->bottom_width;
|
||||||
|
@ -1268,17 +1228,18 @@ paint_all(Display *dpy, XserverRegion region) {
|
||||||
|
|
||||||
/* body */
|
/* body */
|
||||||
XRenderComposite(
|
XRenderComposite(
|
||||||
dpy, PictOpOver, w->picture, alpha_mask, root_buffer,
|
dpy, op, w->picture, alpha_mask, root_buffer,
|
||||||
l, t, l, t, x + l, y + t, wid - l - r, hei - t - b);
|
l, t, l, t, x + l, y + t, wid - l - r, hei - t - b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dimming the window if needed
|
||||||
if (w->dim) {
|
if (w->dim) {
|
||||||
XRenderComposite(dpy, PictOpOver, dim_picture, None,
|
XRenderComposite(dpy, PictOpOver, dim_picture, None,
|
||||||
root_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
root_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free_region(dpy, &w->border_clip);
|
XFixesDestroyRegion(dpy, paint_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFixesDestroyRegion(dpy, region);
|
XFixesDestroyRegion(dpy, region);
|
||||||
|
@ -1547,7 +1508,6 @@ finish_unmap_win(Display *dpy, win *w) {
|
||||||
free_picture(dpy, &w->picture);
|
free_picture(dpy, &w->picture);
|
||||||
free_region(dpy, &w->border_size);
|
free_region(dpy, &w->border_size);
|
||||||
free_picture(dpy, &w->shadow_pict);
|
free_picture(dpy, &w->shadow_pict);
|
||||||
free_region(dpy, &w->border_clip);
|
|
||||||
|
|
||||||
clip_changed = True;
|
clip_changed = True;
|
||||||
}
|
}
|
||||||
|
@ -1567,7 +1527,8 @@ unmap_win(Display *dpy, Window id, Bool fade) {
|
||||||
|
|
||||||
w->a.map_state = IsUnmapped;
|
w->a.map_state = IsUnmapped;
|
||||||
|
|
||||||
/* don't care about properties anymore */
|
// don't care about properties anymore
|
||||||
|
// Will get BadWindow if the window is destroyed
|
||||||
set_ignore(dpy, NextRequest(dpy));
|
set_ignore(dpy, NextRequest(dpy));
|
||||||
XSelectInput(dpy, w->id, 0);
|
XSelectInput(dpy, w->id, 0);
|
||||||
|
|
||||||
|
@ -1809,7 +1770,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
||||||
new->need_configure = False;
|
new->need_configure = False;
|
||||||
new->window_type = WINTYPE_UNKNOWN;
|
new->window_type = WINTYPE_UNKNOWN;
|
||||||
|
|
||||||
new->border_clip = None;
|
|
||||||
new->prev_trans = 0;
|
new->prev_trans = 0;
|
||||||
|
|
||||||
new->left_width = 0;
|
new->left_width = 0;
|
||||||
|
@ -2178,6 +2138,7 @@ error(Display *dpy, XErrorEvent *ev) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_timestamp();
|
||||||
printf("error %d (%s) request %d minor %d serial %lu\n",
|
printf("error %d (%s) request %d minor %d serial %lu\n",
|
||||||
ev->error_code, name, ev->request_code,
|
ev->error_code, name, ev->request_code,
|
||||||
ev->minor_code, ev->serial);
|
ev->minor_code, ev->serial);
|
||||||
|
@ -2577,7 +2538,7 @@ ev_handle(XEvent *ev) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage() {
|
usage(void) {
|
||||||
fprintf(stderr, "compton v0.0.1\n");
|
fprintf(stderr, "compton v0.0.1\n");
|
||||||
fprintf(stderr, "usage: compton [options]\n");
|
fprintf(stderr, "usage: compton [options]\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -2669,7 +2630,7 @@ register_cm(int scr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fork_after() {
|
fork_after(void) {
|
||||||
if (getppid() == 1) return;
|
if (getppid() == 1) return;
|
||||||
|
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
|
@ -2689,7 +2650,7 @@ fork_after() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_atoms() {
|
get_atoms(void) {
|
||||||
extents_atom = XInternAtom(dpy,
|
extents_atom = XInternAtom(dpy,
|
||||||
"_NET_FRAME_EXTENTS", False);
|
"_NET_FRAME_EXTENTS", False);
|
||||||
opacity_atom = XInternAtom(dpy,
|
opacity_atom = XInternAtom(dpy,
|
||||||
|
@ -2758,9 +2719,7 @@ main(int argc, char **argv) {
|
||||||
double shadow_green = 0.0;
|
double shadow_green = 0.0;
|
||||||
double shadow_blue = 0.0;
|
double shadow_blue = 0.0;
|
||||||
|
|
||||||
#ifdef DEBUG_EVENTS
|
|
||||||
gettimeofday(&time_start, NULL);
|
gettimeofday(&time_start, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_WINTYPES; ++i) {
|
for (i = 0; i < NUM_WINTYPES; ++i) {
|
||||||
win_type_fade[i] = False;
|
win_type_fade[i] = False;
|
||||||
|
|
|
@ -36,11 +36,9 @@
|
||||||
// #define DEBUG_WINTYPE 1
|
// #define DEBUG_WINTYPE 1
|
||||||
// #define MONITOR_REPAINT 1
|
// #define MONITOR_REPAINT 1
|
||||||
|
|
||||||
#ifdef DEBUG_EVENTS
|
|
||||||
// For printing timestamps
|
// For printing timestamps
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
extern struct timeval time_start;
|
extern struct timeval time_start;
|
||||||
#endif
|
|
||||||
|
|
||||||
#define OPAQUE 0xffffffff
|
#define OPAQUE 0xffffffff
|
||||||
#define REGISTER_PROP "_NET_WM_CM_S"
|
#define REGISTER_PROP "_NET_WM_CM_S"
|
||||||
|
@ -135,8 +133,6 @@ typedef struct _win {
|
||||||
Bool need_configure;
|
Bool need_configure;
|
||||||
XConfigureEvent queue_configure;
|
XConfigureEvent queue_configure;
|
||||||
|
|
||||||
/* for drawing translucent windows */
|
|
||||||
XserverRegion border_clip;
|
|
||||||
struct _win *prev_trans;
|
struct _win *prev_trans;
|
||||||
} win;
|
} win;
|
||||||
|
|
||||||
|
@ -173,6 +169,15 @@ extern Atom atom_client_attr;
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
|
|
||||||
|
static void
|
||||||
|
discard_ignore(Display *dpy, unsigned long sequence);
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_ignore(Display *dpy, unsigned long sequence);
|
||||||
|
|
||||||
|
static int
|
||||||
|
should_ignore(Display *dpy, unsigned long sequence);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize an int value to a specific range.
|
* Normalize an int value to a specific range.
|
||||||
*
|
*
|
||||||
|
@ -218,7 +223,6 @@ array_wid_exists(const Window *arr, int count, Window wid) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_EVENTS
|
|
||||||
/*
|
/*
|
||||||
* Subtracting two struct timeval values.
|
* Subtracting two struct timeval values.
|
||||||
*
|
*
|
||||||
|
@ -267,7 +271,6 @@ print_timestamp(void) {
|
||||||
timeval_subtract(&diff, &tm, &time_start);
|
timeval_subtract(&diff, &tm, &time_start);
|
||||||
printf("[ %5ld.%02ld ] ", diff.tv_sec, diff.tv_usec / 10000);
|
printf("[ %5ld.%02ld ] ", diff.tv_sec, diff.tv_usec / 10000);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a <code>XserverRegion</code>.
|
* Destroy a <code>XserverRegion</code>.
|
||||||
|
@ -308,6 +311,8 @@ free_pixmap(Display *dpy, Pixmap *p) {
|
||||||
inline static void
|
inline static void
|
||||||
free_damage(Display *dpy, Damage *p) {
|
free_damage(Display *dpy, Damage *p) {
|
||||||
if (*p) {
|
if (*p) {
|
||||||
|
// BadDamage will be thrown if the window is destroyed
|
||||||
|
set_ignore(dpy, NextRequest(dpy));
|
||||||
XDamageDestroy(dpy, *p);
|
XDamageDestroy(dpy, *p);
|
||||||
*p = None;
|
*p = None;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +365,7 @@ win_get_children(Display *dpy, Window w,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_time_in_milliseconds();
|
get_time_in_milliseconds(void);
|
||||||
|
|
||||||
static fade *
|
static fade *
|
||||||
find_fade(win *w);
|
find_fade(win *w);
|
||||||
|
@ -411,15 +416,6 @@ static Picture
|
||||||
solid_picture(Display *dpy, Bool argb, double a,
|
solid_picture(Display *dpy, Bool argb, double a,
|
||||||
double r, double g, double b);
|
double r, double g, double b);
|
||||||
|
|
||||||
static void
|
|
||||||
discard_ignore(Display *dpy, unsigned long sequence);
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_ignore(Display *dpy, unsigned long sequence);
|
|
||||||
|
|
||||||
static int
|
|
||||||
should_ignore(Display *dpy, unsigned long sequence);
|
|
||||||
|
|
||||||
static long
|
static long
|
||||||
determine_evmask(Display *dpy, Window wid, win_evmode_t mode);
|
determine_evmask(Display *dpy, Window wid, win_evmode_t mode);
|
||||||
|
|
||||||
|
@ -558,7 +554,7 @@ ev_window(XEvent *ev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage();
|
usage(void);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
register_cm(int scr);
|
register_cm(int scr);
|
||||||
|
@ -645,7 +641,7 @@ inline static void
|
||||||
ev_handle(XEvent *ev);
|
ev_handle(XEvent *ev);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fork_after();
|
fork_after(void);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_atoms();
|
get_atoms(void);
|
||||||
|
|
Loading…
Reference in New Issue