From 797a2788140fae83f29d6bedc80c359a098d9c74 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 9 Mar 2008 19:33:10 -0400 Subject: [PATCH] don't fade on startup/shutdown, make fading a bit quicker --- Makefile | 13 ++- dcompmgr.c | 41 +++++-- dcompmgr.h | 8 ++ display.c | 31 +++++- fade.c | 19 +++- render.c | 314 +++++++++++++++++++++++++++++++++++++++++------------ screen.c | 2 + screen.h | 2 + window.c | 22 +++- window.h | 2 + 10 files changed, 359 insertions(+), 95 deletions(-) create mode 100644 dcompmgr.h diff --git a/Makefile b/Makefile index d3d8202..311914a 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,17 @@ sources = $(wildcard *.c) objs = $(sources:.c=.o) headers = $(wildcard *.h) -CFLAGS=$(shell pkg-config --cflags xcb-composite xcb-damage glib-2.0) -ggdb -W -Wall #-DEFENCE -LIBS=$(shell pkg-config --libs xcb-composite xcb-damage glib-2.0) #-lefence +# for profiling +PFLAGS=-pg -fno-inline +PLIBS= + +# for electric fence +EFLAGS=-DEFENCE +ELIBS=-lefence + +CFLAGS=$(shell pkg-config --cflags xcb-composite xcb-damage glib-2.0) -ggdb -W -Wall $(PFLAGS) +LDFLAGS=$(PFLAGS) +LIBS=$(shell pkg-config --libs xcb-composite xcb-damage glib-2.0) $(PLIBS) dcompmgr: $(objs) $(CC) -o $@ $^ $(LIBS) $(LDFLAGS) diff --git a/dcompmgr.c b/dcompmgr.c index 8fa0b28..8dcaa1f 100644 --- a/dcompmgr.c +++ b/dcompmgr.c @@ -26,6 +26,7 @@ typedef struct { } d_options_t; static gboolean quit = FALSE; +static gboolean running = FALSE; static void read_options(int argc, char **argv, d_options_t *opts) @@ -182,7 +183,8 @@ event(d_display_t *dpy) } } above = screen_find_window(sc, cev->above_sibling); - screen_stacking_move_above(sc, w, above); + if (window_is_mapped(w)) + sc->window_restack(w, above); screen_refresh(w->sc); break; } @@ -232,6 +234,7 @@ event(d_display_t *dpy) w = screen_find_window(sc, dev->drawable); if (w) { + sc->window_damage(w); screen_refresh(w->sc); break; } @@ -251,7 +254,7 @@ event(d_display_t *dpy) d_window_t *w; w = screen_find_window(sc, sev->affected_window); - if (w) { + if (w && window_is_mapped(w)) { sc->window_reshape(w); screen_refresh(w->sc); break; @@ -298,6 +301,8 @@ run(d_display_t *dpy) { struct timeval now, next_repaint; + running = TRUE; + gettimeofday(&now, NULL); next_repaint = now; @@ -306,6 +311,7 @@ run(d_display_t *dpy) int r, npaint, ntime; d_list_it_t *it; fd_set fds; + gboolean due; event(dpy); @@ -338,27 +344,31 @@ run(d_display_t *dpy) } } - if (!npaint && !ntime) + if (!npaint && !ntime) { /* wait forever, there is nothing that needs drawing */ wait = NULL; + due = FALSE; + } else if (time_compare(&next, &now) > 0) { /* wait until the next allowed redraw time */ time_difference(&next, &now, &next); wait = &next; + due = FALSE; } else { /* don't wait cuz a timer is due now already */ - next.tv_sec = 0; - next.tv_usec = 1; - wait = &next; + due = TRUE; } - FD_ZERO(&fds); - FD_SET(dpy->fd, &fds); - - //printf("select %d\n", npaint); + //printf("select? %d %d\n", due, npaint); - r = select(dpy->fd+1, &fds, NULL, NULL, wait); + if (!due) { + FD_ZERO(&fds); + FD_SET(dpy->fd, &fds); + r = select(dpy->fd+1, &fds, NULL, NULL, wait); + } + else + r = 0; gettimeofday(&now, NULL); if (r == 0) { @@ -375,6 +385,8 @@ run(d_display_t *dpy) if (xcb_connection_has_error(dpy->conn)) quit = TRUE; } + + running = FALSE; } static void @@ -475,6 +487,7 @@ main(int argc, char **argv) } } + printf("running\n"); run(dpy); { @@ -496,3 +509,9 @@ main(int argc, char **argv) display_unref(dpy); return 0; } + +gboolean +dcompmgr_running(void) +{ + return running; +} diff --git a/dcompmgr.h b/dcompmgr.h new file mode 100644 index 0000000..723d4e6 --- /dev/null +++ b/dcompmgr.h @@ -0,0 +1,8 @@ +#ifndef dc_dcompmgr_h +#define dc_dcompmgr_h + +#include + +gboolean dcompmgr_running(void); + +#endif diff --git a/display.c b/display.c index e331150..8fb74e7 100644 --- a/display.c +++ b/display.c @@ -261,6 +261,7 @@ display_error(d_display_t *dpy, xcb_generic_error_t *ev) case XCB_MATCH: name = "BadMatch"; break; case XCB_DRAWABLE: name = "BadDrawable"; break; case XCB_G_CONTEXT: name = "BadGC"; break; + case XCB_ID_CHOICE: name = "BadID"; break; default: break; } if (!name) @@ -376,6 +377,34 @@ display_error(d_display_t *dpy, xcb_generic_error_t *ev) case 8: req = "ShapeGetRectangles"; break; default: break; } + else if (major_opcode == dpy->xfixes.opcode) + switch (minor_opcode) + { + case 0: req = "XFixesQueryVersion"; break; + case 1: req = "XFixesChangeSaveSet"; break; + case 2: req = "XFixesSelectSelectionInput"; break; + case 3: req = "XFixesSelectCursorInput"; break; + case 4: req = "XFixesGetCursorImage"; break; + case 5: req = "XFixesCreateRegion"; break; + case 6: req = "XFixesCreateRegionFromBitmap"; break; + case 7: req = "XFixesCreateRegionFromWindow"; break; + case 8: req = "XFixesCreateRegionFromGC"; break; + case 9: req = "XFixesCreateRegionFromPicture"; break; + case 10: req = "XFixesDestroyRegion"; break; + case 11: req = "XFixesSetRegion"; break; + case 12: req = "XFixesCopyRegion"; break; + case 13: req = "XFixesUnionRegion"; break; + case 14: req = "XFixesIntersectRegion"; break; + case 15: req = "XFixesSubtractRegion"; break; + case 16: req = "XFixesInvertRegion"; break; + case 17: req = "XFixesTranslanteRegion"; break; + case 18: req = "XFixesRegionExtents"; break; + case 19: req = "XFixesFetchRegion"; break; + case 20: req = "XFixesGCClipRegion"; break; + case 21: req = "XFixesSetWindowShapeRegion"; break; + case 22: req = "XFixesSetPictureClipRegion"; break; + default: break; + } if (name && req) printf("XError: %s %s\n", @@ -384,7 +413,7 @@ display_error(d_display_t *dpy, xcb_generic_error_t *ev) printf("XError: %s major opcode %d minor opcode %d\n", name, major_opcode, minor_opcode); else - printf("XError: code %d major opcode %d minor opcode %d\n", + printf("XError: error code %d major opcode %d minor opcode %d\n", ev->error_code, major_opcode, minor_opcode); //abort(); diff --git a/fade.c b/fade.c index 3ce8ab3..74308e4 100644 --- a/fade.c +++ b/fade.c @@ -1,5 +1,6 @@ #include "efence.h" +#include "dcompmgr.h" #include "render.h" #include "screen.h" #include "window.h" @@ -13,6 +14,8 @@ static int plugin_id; +#define WINDOW_TYPE_FADE(t) (t != DC_WINDOW_TYPE_DESKTOP) + typedef struct { void (*window_show)(d_window_t *w); void (*window_hide)(d_window_t *w); @@ -53,7 +56,7 @@ fade_init(d_screen_t *sc, int id) sc->window_hide = fade_window_hide; d->fades = list_new(); - d->fade_step_time = 5000; /* 5 milliseconds */ + d->fade_step_time = 15000; /* 15 milliseconds */ d->fade_total_time = 180000; /* 0.18 seconds */ } @@ -97,8 +100,11 @@ fade_window_show(d_window_t *w) d->window_show(w); - if (!window_is_input_only(w)) - start_fade(w, 0x2000, 0xffff, TRUE); + if (!window_is_input_only(w) && dcompmgr_running()) { + d_window_type_t type = window_get_type(w); + if (WINDOW_TYPE_FADE(type)) + start_fade(w, 0x2000, 0xffff, TRUE); + } } static void @@ -106,8 +112,11 @@ fade_window_hide(d_window_t *w) { data_t *d; - if (!window_is_input_only(w)) - start_fade(w, 0xffff, 0x0002, FALSE); + if (!window_is_input_only(w) && dcompmgr_running()) { + d_window_type_t type = window_get_type(w); + if (WINDOW_TYPE_FADE(type)) + start_fade(w, 0xffff, 0x0002, FALSE); + } d = screen_find_plugin_data(w->sc, plugin_id); d->window_hide(w); diff --git a/render.c b/render.c index 113070e..0a2d479 100644 --- a/render.c +++ b/render.c @@ -17,8 +17,12 @@ typedef struct { void (*screen_root_pixmap_change)(d_screen_t *sc); void (*window_show)(d_window_t *w); void (*window_zombie_dead)(d_window_t *w); + void (*window_move)(d_window_t *w); void (*window_resize)(d_window_t *w); + void (*window_reshape)(d_window_t *w); + void (*window_restack)(d_window_t *w, d_window_t *above); void (*window_opacity_change)(d_window_t *w); + void (*window_damage)(d_window_t *w); xcb_render_pictformat_t root_format; xcb_render_pictformat_t argb32_format; @@ -29,8 +33,9 @@ typedef struct { xcb_render_picture_t solid_bg; xcb_xfixes_region_t all_region; + xcb_xfixes_region_t damaged_region; xcb_xfixes_region_t paint_region; - xcb_xfixes_region_t shadow_region; + xcb_xfixes_region_t shadow_paint_region; uint16_t shadowalpha; int xshadowoff; @@ -39,8 +44,11 @@ typedef struct { typedef struct { xcb_render_picture_t picture; + xcb_render_picture_t alpha_picture; xcb_render_picture_t shadow_picture; xcb_xfixes_region_t paint_clip; + xcb_xfixes_region_t shadow_region; + gboolean shadow_valid; } window_data_t; static void render_paint(d_screen_t *sc); @@ -51,8 +59,6 @@ static void paint_window(d_window_t *window, data_t *d, window_data_t *wd, int height, int bwidth); static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, int x, int y, int width, int height, int bwidth); -static void render_update_shadow_picture(d_window_t *w, data_t *d, - window_data_t *wd); static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd); static void render_update_root_picture(d_screen_t *sc, data_t *d); static void render_free_picture(d_window_t *w, window_data_t *wd); @@ -62,11 +68,17 @@ static xcb_render_pictformat_t find_argb32_format(data_t *d); static xcb_render_picture_t solid_picture(data_t *d, d_screen_t *sc, uint16_t a, uint16_t r, uint16_t g, uint16_t b); +static void render_update_opacity(d_window_t *w, data_t *d, window_data_t *wd); +static void render_update_shadow(d_window_t *w, data_t *d, window_data_t *wd); static void render_window_show(d_window_t *window); static void render_window_zombie_dead(d_window_t *window); +static void render_window_move(d_window_t *window); static void render_window_resize(d_window_t *window); +static void render_window_reshape(d_window_t *window); +static void render_window_restack(d_window_t *window, d_window_t *above); static void render_window_opacity_change(d_window_t *w); +static void render_window_damage(d_window_t *w); void render_init(d_screen_t *sc, int id) @@ -82,16 +94,24 @@ render_init(d_screen_t *sc, int id) d->screen_root_pixmap_change = sc->screen_root_pixmap_change; d->window_show = sc->window_show; d->window_zombie_dead = sc->window_zombie_dead; + d->window_move = sc->window_move; d->window_resize = sc->window_resize; + d->window_reshape = sc->window_reshape; + d->window_restack = sc->window_restack; d->window_opacity_change = sc->window_opacity_change; + d->window_damage = sc->window_damage; screen_add_plugin_data(sc, plugin_id, d); sc->screen_paint = render_paint; sc->screen_root_pixmap_change = render_root_pixmap_change; sc->window_show = render_window_show; sc->window_zombie_dead = render_window_zombie_dead; + sc->window_move = render_window_move; sc->window_resize = render_window_resize; + sc->window_reshape = render_window_reshape; + sc->window_restack = render_window_restack; sc->window_opacity_change = render_window_opacity_change; + sc->window_damage = render_window_damage; ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn); d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck, @@ -119,14 +139,16 @@ render_init(d_screen_t *sc, int id) d->solid_bg = solid_picture(d, sc, 0xffff, 0x6060, 02020, 0x3030); d->all_region = xcb_generate_id(sc->dpy->conn); + d->damaged_region = xcb_generate_id(sc->dpy->conn); d->paint_region = xcb_generate_id(sc->dpy->conn); - d->shadow_region = xcb_generate_id(sc->dpy->conn); + d->shadow_paint_region = xcb_generate_id(sc->dpy->conn); rect.x = rect.y = 0; rect.width = sc->super.width_in_pixels; rect.height = sc->super.height_in_pixels; xcb_xfixes_create_region(sc->dpy->conn, d->all_region, 1, &rect); + xcb_xfixes_create_region(sc->dpy->conn, d->damaged_region, 1, &rect); xcb_xfixes_create_region(sc->dpy->conn, d->paint_region, 1, &rect); - xcb_xfixes_create_region(sc->dpy->conn, d->shadow_region, 1, &rect); + xcb_xfixes_create_region(sc->dpy->conn, d->shadow_paint_region, 1, &rect); d->shadowalpha = 0x3333; /* 20% */ d->xshadowoff = 2; @@ -144,8 +166,9 @@ render_free(d_screen_t *sc) xcb_render_free_picture(sc->dpy->conn, d->overlay_picture); xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer); xcb_xfixes_destroy_region(sc->dpy->conn, d->all_region); + xcb_xfixes_destroy_region(sc->dpy->conn, d->damaged_region); xcb_xfixes_destroy_region(sc->dpy->conn, d->paint_region); - xcb_xfixes_destroy_region(sc->dpy->conn, d->shadow_region); + xcb_xfixes_destroy_region(sc->dpy->conn, d->shadow_paint_region); free(d); screen_remove_plugin_data(sc, plugin_id); } @@ -168,10 +191,10 @@ void render_window_free(d_window_t *w, window_data_t *wd) { render_free_picture(w, wd); - if (wd->shadow_picture) { - xcb_render_free_picture(w->sc->dpy->conn, wd->shadow_picture); - wd->shadow_picture = XCB_NONE; - } + xcb_render_free_picture(w->sc->dpy->conn, wd->alpha_picture); + xcb_render_free_picture(w->sc->dpy->conn, wd->shadow_picture); + xcb_xfixes_destroy_region(w->sc->dpy->conn, wd->paint_clip); + xcb_xfixes_destroy_region(w->sc->dpy->conn, wd->shadow_region); free(wd); } @@ -195,15 +218,46 @@ render_window_show(d_window_t *w) wd->picture = XCB_NONE; wd->paint_clip = xcb_generate_id(w->sc->dpy->conn); - rect.x = rect.y = 0; + wd->shadow_region = xcb_generate_id(w->sc->dpy->conn); + rect.x = rect.y = -1; rect.width = rect.height = 1; xcb_xfixes_create_region(w->sc->dpy->conn, wd->paint_clip, 1, &rect); + xcb_xfixes_create_region(w->sc->dpy->conn, wd->shadow_region, 1, &rect); - render_update_shadow_picture(w, d, wd); + wd->shadow_valid = FALSE; + + wd->alpha_picture = solid_picture(d, w->sc, 0, 0, 0, 0); + wd->shadow_picture = solid_picture(d, w->sc, 0, 0, 0, 0); + + render_update_opacity(w, d, wd); window_add_plugin_data(w, plugin_id, wd); } +static void +render_update_opacity(d_window_t *w, data_t *d, window_data_t *wd) +{ + static xcb_render_color_t c = { 0, 0, 0, 0 }; + static xcb_rectangle_t rect = {0, 0, 1, 1}; + unsigned long a; + + /* make the window's shadow and alpha-map match its current opacity */ + c.alpha = window_get_opacity(w); + xcb_render_fill_rectangles(w->sc->dpy->conn, + XCB_RENDER_PICT_OP_SRC, + wd->alpha_picture, c, 1, &rect); + a = d->shadowalpha; + a = a * window_get_opacity(w) / 0xffff; + //if (w->id == 0x1811453) + // printf("window opacity 0x%x\n", c.alpha); + c.alpha = a; + if (w->id == 0x1811453) + printf("shadow opacity 0x%04x\n", c.alpha); + xcb_render_fill_rectangles(w->sc->dpy->conn, + XCB_RENDER_PICT_OP_SRC, + wd->shadow_picture, c, 1, &rect); +} + static void render_window_zombie_dead(d_window_t *w) { @@ -213,8 +267,16 @@ render_window_zombie_dead(d_window_t *w) d = screen_find_plugin_data(w->sc, plugin_id); wd = window_find_plugin_data(w, plugin_id); if (wd) { + /* make sure the shadow region is right */ + render_update_shadow(w, d, wd); + + /* redraw the window's area, and its shadow's as well */ + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + window_get_region(w), d->damaged_region); + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + wd->shadow_region, d->damaged_region); + render_window_free(w, wd); - xcb_xfixes_destroy_region(w->sc->dpy->conn, wd->paint_clip); window_remove_plugin_data(w, plugin_id); } @@ -310,17 +372,6 @@ render_free_picture(d_window_t *w, window_data_t *wd) } } -static void -render_update_shadow_picture(d_window_t *w, data_t *d, window_data_t *wd) -{ - if (wd->shadow_picture) - xcb_render_free_picture(w->sc->dpy->conn, wd->shadow_picture); - wd->shadow_picture = solid_picture(d, w->sc, - d->shadowalpha * - window_get_opacity(w) / 0xffff, - 0, 0, 0); -} - static void render_update_root_picture(d_screen_t *sc, data_t *d) { @@ -360,6 +411,26 @@ render_update_picture(d_window_t *w, data_t *d, window_data_t *wd) } } +static void +render_window_move(d_window_t *w) +{ + data_t *d; + window_data_t *wd; + + d = screen_find_plugin_data(w->sc, plugin_id); + wd = window_find_plugin_data(w, plugin_id); + + /* pass it on */ + d->window_move(w); + + d = screen_find_plugin_data(w->sc, plugin_id); + + /* redraw the screen */ + xcb_xfixes_copy_region(w->sc->dpy->conn, d->all_region, d->damaged_region); + /* reget the shadow's shape */ + wd->shadow_valid = FALSE; +} + static void render_window_resize(d_window_t *w) { @@ -374,8 +445,71 @@ render_window_resize(d_window_t *w) assert(wd != NULL); render_free_picture(w, wd); + + /* redraw the screen */ + xcb_xfixes_copy_region(w->sc->dpy->conn, d->all_region, d->damaged_region); + /* reget the shadow's shape */ + wd->shadow_valid = FALSE; +} + +static void +render_window_reshape(d_window_t *w) +{ + data_t *d; + window_data_t *wd; + + d = screen_find_plugin_data(w->sc, plugin_id); + wd = window_find_plugin_data(w, plugin_id); + + /* pass it on */ + d->window_reshape(w); + + assert(wd != NULL); + render_free_picture(w, wd); + + /* redraw the screen */ + xcb_xfixes_copy_region(w->sc->dpy->conn, d->all_region, d->damaged_region); + /* reget the shadow's shape */ + wd->shadow_valid = FALSE; } +static void +render_window_restack(d_window_t *w, d_window_t *above) +{ + data_t *d; + window_data_t *wd; + + d = screen_find_plugin_data(w->sc, plugin_id); + wd = window_find_plugin_data(w, plugin_id); + + /* pass it on */ + d->window_restack(w, above); + + assert(wd != NULL); + + /* make sure the shadow region is right */ + render_update_shadow(w, d, wd); + + /* redraw the window's contents, and its shadow as well */ + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + window_get_region(w), d->damaged_region); + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + wd->shadow_region, d->damaged_region); +} + +static void +render_update_shadow(d_window_t *w, data_t *d, window_data_t *wd) +{ + if (!wd->shadow_valid) { + xcb_xfixes_copy_region(w->sc->dpy->conn, window_get_region(w), + wd->shadow_region); + xcb_xfixes_translate_region(w->sc->dpy->conn, wd->shadow_region, + d->xshadowoff, d->yshadowoff); + wd->shadow_valid = TRUE; + } +} + + static void render_window_opacity_change(d_window_t *w) { @@ -389,7 +523,35 @@ render_window_opacity_change(d_window_t *w) d->window_opacity_change(w); assert(wd != NULL); - render_update_shadow_picture(w, d, wd); + + /* update the window and its shadows opacities */ + render_update_opacity(w, d, wd); + + /* make sure the shadow region is right */ + render_update_shadow(w, d, wd); + + /* redraw the window's contents, and its shadow as well */ + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + window_get_region(w), d->damaged_region); + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + wd->shadow_region, d->damaged_region); + + //printf("opacity change 0x%x\n", w->id); +} + +static void +render_window_damage(d_window_t *w) +{ + data_t *d; + + d = screen_find_plugin_data(w->sc, plugin_id); + + /* pass it on */ + d->window_damage(w); + + /* redraw the window's contents */ + xcb_xfixes_union_region(w->sc->dpy->conn, d->damaged_region, + window_get_region(w), d->damaged_region); } static void @@ -405,6 +567,9 @@ render_root_pixmap_change(d_screen_t *sc) /* pass it on */ d->screen_root_pixmap_change(sc); + + /* redraw the screen */ + xcb_xfixes_copy_region(sc->dpy->conn, d->all_region, d->damaged_region); } static void @@ -413,39 +578,45 @@ render_paint(d_screen_t *sc) data_t *d = screen_find_plugin_data(sc, plugin_id); d_list_it_t *it; - xcb_xfixes_copy_region(sc->dpy->conn, d->all_region, d->paint_region); + xcb_xfixes_copy_region(sc->dpy->conn, d->damaged_region, d->paint_region); //printf("-- painting --\n"); for (it = list_top(sc->stacking); it; it = it->next) { d_window_t *w = it->data; - int x, y, width, height, bwidth; - - window_get_area(w, &x, &y, &width, &height, &bwidth); if (!window_is_input_only(w) && - (window_is_mapped(w) || window_is_zombie(w)) && - x < sc->super.width_in_pixels && - y < sc->super.height_in_pixels && - x + width > 0 && y + height > 0) + (window_is_mapped(w) || window_is_zombie(w))) { - gboolean opaque = !(window_is_argb(w) || - window_get_opacity(w) < 0xffff); + int x, y, width, height, bwidth; + gboolean opaque; window_data_t *wd; + window_get_area(w, &x, &y, &width, &height, &bwidth); + + if (!(x < sc->super.width_in_pixels && + y < sc->super.height_in_pixels && + x + width > 0 && y + height > 0)) + { + continue; + } + + opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff; + wd = window_find_plugin_data(w, plugin_id); if (opaque) { - paint_window(w, d, wd, opaque, x, y, width, height, bwidth); + xcb_xfixes_set_picture_clip_region(sc->dpy->conn, + d->overlay_buffer, + d->paint_region, + 0, 0); + paint_window(w, d, wd, opaque, + x, y, width, height, bwidth); /* remove this window from the paint region, as nothing is above it, so nothing should draw to this space again */ xcb_xfixes_subtract_region(sc->dpy->conn, d->paint_region, window_get_region(w), d->paint_region); - xcb_xfixes_set_picture_clip_region(sc->dpy->conn, - d->overlay_buffer, - d->paint_region, - 0, 0); } /* save the clip region, when drawing windows (and shadows) @@ -457,41 +628,40 @@ render_paint(d_screen_t *sc) paint_root(sc, d); - xcb_xfixes_set_picture_clip_region(sc->dpy->conn, - d->overlay_buffer, - d->paint_region, - 0, 0); - for (it = list_bottom(sc->stacking); it; it = it->prev) { d_window_t *w = it->data; - int x, y, width, height, bwidth; - - window_get_area(w, &x, &y, &width, &height, &bwidth); if (!window_is_input_only(w) && - (window_is_mapped(w) || window_is_zombie(w)) && - x < sc->super.width_in_pixels && - y < sc->super.height_in_pixels && - (x + width > 0 || x + width + d->xshadowoff > 0) && - (y + height > 0 || y + height + d->yshadowoff > 0)) + (window_is_mapped(w) || window_is_zombie(w))) { + int x, y, width, height, bwidth; + gboolean opaque; window_data_t *wd; - gboolean opaque = !(window_is_argb(w) || - window_get_opacity(w) < 0xffff); + + window_get_area(w, &x, &y, &width, &height, &bwidth); + + if (!(x < sc->super.width_in_pixels && + y < sc->super.height_in_pixels && + (x + width > 0 || x + width + d->xshadowoff > 0) && + (y + height > 0 || y + height + d->yshadowoff > 0))) + { + continue; + } + + opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff; wd = window_find_plugin_data(w, plugin_id); + if (!wd->shadow_valid) + render_update_shadow(w, d, wd); + /* shape the shadow to the window */ - xcb_xfixes_copy_region(sc->dpy->conn, window_get_region(w), - d->shadow_region); - xcb_xfixes_translate_region(sc->dpy->conn, d->shadow_region, - d->xshadowoff, d->yshadowoff); xcb_xfixes_intersect_region(sc->dpy->conn, - wd->paint_clip, d->shadow_region, - d->shadow_region); + wd->paint_clip, wd->shadow_region, + d->shadow_paint_region); xcb_xfixes_set_picture_clip_region(sc->dpy->conn, d->overlay_buffer, - d->shadow_region, + d->shadow_paint_region, 0, 0); paint_shadow(w, d, wd, x, y, width, height, bwidth); @@ -524,6 +694,10 @@ render_paint(d_screen_t *sc) sc->super.width_in_pixels, sc->super.height_in_pixels); + /* empty the damaged region */ + xcb_xfixes_subtract_region(sc->dpy->conn, d->all_region, + d->all_region, d->damaged_region); + /* call the function we replaced in the chain */ d->screen_paint(sc); } @@ -561,22 +735,22 @@ static void paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque, int x, int y, int width, int height, int bwidth) { - xcb_render_picture_t alphamap; - if (!wd->picture) render_update_picture(w, d, wd); //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture); if (wd->picture) { + xcb_render_picture_t alphamap; int op; - op = !opaque ? - XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC; - - if (opaque) + if (opaque) { + op = XCB_RENDER_PICT_OP_SRC; alphamap = XCB_NONE; - else - alphamap = solid_picture(d, w->sc, window_get_opacity(w), 0, 0, 0); + } + else { + op = XCB_RENDER_PICT_OP_OVER; + alphamap = wd->alpha_picture; + } xcb_render_composite(w->sc->dpy->conn, op, diff --git a/screen.c b/screen.c index 7a68c80..8314c00 100644 --- a/screen.c +++ b/screen.c @@ -380,6 +380,8 @@ screen_setup_default_functions(d_screen_t *sc) sc->window_resize = window_resize; sc->window_reshape = window_reshape; sc->window_opacity_change = window_opacity_change; + sc->window_damage = window_damage; + sc->window_restack = window_restack; sc->screen_root_pixmap_change = screen_update_root_pixmap; } diff --git a/screen.h b/screen.h index 15ef143..49d0ed2 100644 --- a/screen.h +++ b/screen.h @@ -42,6 +42,8 @@ typedef struct d_screen { void (*window_resize)(struct d_window *w); void (*window_reshape)(struct d_window *w); void (*window_opacity_change)(struct d_window *w); + void (*window_damage)(struct d_window *w); + void (*window_restack)(struct d_window *w, struct d_window *above); void (*screen_root_pixmap_change)(struct d_screen *sc); } d_screen_t; diff --git a/window.c b/window.c index 0662acf..39685a8 100644 --- a/window.c +++ b/window.c @@ -434,7 +434,7 @@ window_reshape(d_window_t *w) void window_opacity_change(d_window_t *w) { - (void)w; + screen_refresh(w->sc); } void @@ -642,10 +642,8 @@ window_set_opacity(d_window_t *pubw, uint16_t o) d_window_priv_t *w = (d_window_priv_t*)pubw; w->opacity = o; - if (w->mapped || w->zombie) { + if (w->mapped || w->zombie) w->sc->window_opacity_change(pubw); - screen_refresh(w->sc); - } //printf("mapped %d opacity 0x%x\n", w->mapped, w->opacity); } @@ -663,6 +661,8 @@ window_zombie_unref(d_window_t *pubw) d_window_priv_t *w = (d_window_priv_t*)pubw; if (--w->zombieref == 0) { + w->sc->window_zombie_dead(pubw); + w->zombie = FALSE; if (w->region) { @@ -677,9 +677,19 @@ window_zombie_unref(d_window_t *pubw) w->pixmap = XCB_NONE; } - w->sc->window_zombie_dead(pubw); - /* reset the opacity */ w->opacity = 0xffff; } } + +void +window_damage(d_window_t *w) +{ + (void)w; +} + +void +window_restack(d_window_t *w, d_window_t *above) +{ + screen_stacking_move_above(w->sc, w, above); +} diff --git a/window.h b/window.h index 9787f84..8d29274 100644 --- a/window.h +++ b/window.h @@ -48,6 +48,8 @@ void window_move(d_window_t *w); void window_resize(d_window_t *w); void window_reshape(d_window_t *w); void window_opacity_change(d_window_t *w); +void window_damage(d_window_t *w); +void window_restack(d_window_t *w, d_window_t *above); gboolean window_is_zombie(d_window_t *w); gboolean window_is_input_only(d_window_t *w); -- 2.34.1