summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Grenville <pyxlcy@gmail.com>2012-09-17 16:04:04 +0800
committerRichard Grenville <pyxlcy@gmail.com>2012-09-17 16:04:04 +0800
commite7ba091cccc4eba365302f79eee9ab0abe1ec253 (patch)
tree1c0c6c1a0cd67490751f07f59b8b1a0a57b5085d
parent65e8e56c1ef0e1d02f3008e2af243e1b170414f3 (diff)
downloadtdebase-e7ba091cccc4eba365302f79eee9ab0abe1ec253.tar.gz
tdebase-e7ba091cccc4eba365302f79eee9ab0abe1ec253.zip
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().
-rw-r--r--compton.c183
-rw-r--r--compton.h34
2 files changed, 86 insertions, 131 deletions
diff --git a/compton.c b/compton.c
index a6a99a887..544121ea9 100644
--- a/compton.c
+++ b/compton.c
@@ -14,9 +14,7 @@
* Shared
*/
-#ifdef DEBUG_EVENTS
struct timeval time_start = { 0, 0 };
-#endif
win *list;
fade *fades;
@@ -774,7 +772,7 @@ find_toplevel2(Display *dpy, Window wid) {
// just leave it alone.
if (!XQueryTree(dpy, wid, &troot, &parent, &tchildren,
&tnchildren)) {
- wid = 0;
+ parent = 0;
break;
}
@@ -1114,7 +1112,6 @@ paint_all(Display *dpy, XserverRegion region) {
if (clip_changed) {
free_region(dpy, &w->border_size);
free_region(dpy, &w->extents);
- free_region(dpy, &w->border_clip);
}
if (!w->border_size) {
@@ -1150,43 +1147,6 @@ paint_all(Display *dpy, XserverRegion region) {
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;
t = w;
}
@@ -1196,15 +1156,29 @@ paint_all(Display *dpy, XserverRegion region) {
fflush(stdout);
#endif
- XFixesSetPictureClipRegion(dpy,
- root_buffer, 0, 0, region);
+ XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region);
paint_root(dpy);
for (w = t; w; w = w->prev_trans) {
- XFixesSetPictureClipRegion(dpy,
- root_buffer, 0, 0, w->border_clip);
+ 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
+
+ // 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,
@@ -1213,72 +1187,59 @@ paint_all(Display *dpy, XserverRegion region) {
w->shadow_width, w->shadow_height);
}
- if (w->mode != WINDOW_SOLID || w->frame_opacity) {
- int x, y, wid, hei;
+ // 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);
- // 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
- 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
+ Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
+ int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver);
- set_ignore(dpy, NextRequest(dpy));
+ // Painting the window
+ if (!w->frame_opacity) {
+ XRenderComposite(dpy, op, w->picture, alpha_mask,
+ root_buffer, 0, 0, 0, 0, x, y, wid, hei);
+ }
+ else {
+ unsigned int t = w->top_width;
+ unsigned int l = w->left_width;
+ unsigned int b = w->bottom_width;
+ unsigned int r = w->right_width;
- Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
+ /* top */
+ XRenderComposite(
+ dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
+ 0, 0, 0, 0, x, y, wid, t);
- if (!w->frame_opacity) {
- XRenderComposite(
- dpy, PictOpOver, w->picture, alpha_mask,
- root_buffer, 0, 0, 0, 0, x, y, wid, hei);
- } else {
- unsigned int t = w->top_width;
- unsigned int l = w->left_width;
- unsigned int b = w->bottom_width;
- unsigned int r = w->right_width;
-
- /* top */
- XRenderComposite(
- dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
- 0, 0, 0, 0, x, y, wid, t);
-
- /* left */
- XRenderComposite(
- dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
- 0, t, 0, t, x, y + t, l, hei - t);
-
- /* bottom */
- XRenderComposite(
- dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
- l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b);
-
- /* right */
- XRenderComposite(
- dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
- wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t);
-
- /* body */
- XRenderComposite(
- dpy, PictOpOver, w->picture, alpha_mask, root_buffer,
- l, t, l, t, x + l, y + t, wid - l - r, hei - t - b);
- }
+ /* left */
+ XRenderComposite(
+ dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
+ 0, t, 0, t, x, y + t, l, hei - t);
+
+ /* bottom */
+ XRenderComposite(
+ dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
+ l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b);
+
+ /* right */
+ XRenderComposite(
+ dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer,
+ wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t);
+
+ /* body */
+ XRenderComposite(
+ dpy, op, w->picture, alpha_mask, root_buffer,
+ l, t, l, t, x + l, y + t, wid - l - r, hei - t - b);
- if (w->dim) {
- XRenderComposite(dpy, PictOpOver, dim_picture, None,
- root_buffer, 0, 0, 0, 0, x, y, wid, hei);
- }
}
- free_region(dpy, &w->border_clip);
+ // Dimming the window if needed
+ if (w->dim) {
+ XRenderComposite(dpy, PictOpOver, dim_picture, None,
+ root_buffer, 0, 0, 0, 0, x, y, wid, hei);
+ }
+
+ XFixesDestroyRegion(dpy, paint_reg);
}
XFixesDestroyRegion(dpy, region);
@@ -1547,7 +1508,6 @@ finish_unmap_win(Display *dpy, win *w) {
free_picture(dpy, &w->picture);
free_region(dpy, &w->border_size);
free_picture(dpy, &w->shadow_pict);
- free_region(dpy, &w->border_clip);
clip_changed = True;
}
@@ -1567,7 +1527,8 @@ unmap_win(Display *dpy, Window id, Bool fade) {
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));
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->window_type = WINTYPE_UNKNOWN;
- new->border_clip = None;
new->prev_trans = 0;
new->left_width = 0;
@@ -2178,6 +2138,7 @@ error(Display *dpy, XErrorEvent *ev) {
break;
}
+ print_timestamp();
printf("error %d (%s) request %d minor %d serial %lu\n",
ev->error_code, name, ev->request_code,
ev->minor_code, ev->serial);
@@ -2577,7 +2538,7 @@ ev_handle(XEvent *ev) {
*/
static void
-usage() {
+usage(void) {
fprintf(stderr, "compton v0.0.1\n");
fprintf(stderr, "usage: compton [options]\n");
fprintf(stderr,
@@ -2669,7 +2630,7 @@ register_cm(int scr) {
}
static void
-fork_after() {
+fork_after(void) {
if (getppid() == 1) return;
int pid = fork();
@@ -2689,7 +2650,7 @@ fork_after() {
}
static void
-get_atoms() {
+get_atoms(void) {
extents_atom = XInternAtom(dpy,
"_NET_FRAME_EXTENTS", False);
opacity_atom = XInternAtom(dpy,
@@ -2758,9 +2719,7 @@ main(int argc, char **argv) {
double shadow_green = 0.0;
double shadow_blue = 0.0;
-#ifdef DEBUG_EVENTS
gettimeofday(&time_start, NULL);
-#endif
for (i = 0; i < NUM_WINTYPES; ++i) {
win_type_fade[i] = False;
diff --git a/compton.h b/compton.h
index ef49acb50..3ca318fe8 100644
--- a/compton.h
+++ b/compton.h
@@ -36,11 +36,9 @@
// #define DEBUG_WINTYPE 1
// #define MONITOR_REPAINT 1
-#ifdef DEBUG_EVENTS
// For printing timestamps
#include <time.h>
extern struct timeval time_start;
-#endif
#define OPAQUE 0xffffffff
#define REGISTER_PROP "_NET_WM_CM_S"
@@ -135,8 +133,6 @@ typedef struct _win {
Bool need_configure;
XConfigureEvent queue_configure;
- /* for drawing translucent windows */
- XserverRegion border_clip;
struct _win *prev_trans;
} win;
@@ -173,6 +169,15 @@ extern Atom atom_client_attr;
// 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.
*
@@ -218,7 +223,6 @@ array_wid_exists(const Window *arr, int count, Window wid) {
return False;
}
-#ifdef DEBUG_EVENTS
/*
* Subtracting two struct timeval values.
*
@@ -267,7 +271,6 @@ print_timestamp(void) {
timeval_subtract(&diff, &tm, &time_start);
printf("[ %5ld.%02ld ] ", diff.tv_sec, diff.tv_usec / 10000);
}
-#endif
/**
* Destroy a <code>XserverRegion</code>.
@@ -308,6 +311,8 @@ free_pixmap(Display *dpy, Pixmap *p) {
inline static void
free_damage(Display *dpy, Damage *p) {
if (*p) {
+ // BadDamage will be thrown if the window is destroyed
+ set_ignore(dpy, NextRequest(dpy));
XDamageDestroy(dpy, *p);
*p = None;
}
@@ -360,7 +365,7 @@ win_get_children(Display *dpy, Window w,
}
static int
-get_time_in_milliseconds();
+get_time_in_milliseconds(void);
static fade *
find_fade(win *w);
@@ -411,15 +416,6 @@ static Picture
solid_picture(Display *dpy, Bool argb, double a,
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
determine_evmask(Display *dpy, Window wid, win_evmode_t mode);
@@ -558,7 +554,7 @@ ev_window(XEvent *ev);
#endif
static void
-usage();
+usage(void);
static void
register_cm(int scr);
@@ -645,7 +641,7 @@ inline static void
ev_handle(XEvent *ev);
static void
-fork_after();
+fork_after(void);
static void
-get_atoms();
+get_atoms(void);