Drawable: Ignore exposes when we have nothing to draw

The X11 server tells us about things that need to be redrawn via expose events.
When we get such an expose event before lua drew the drawable, we just fill the
exposed area with old data (which is black for newly-created drawables).

Fix this by tracking if we have any usable data in a drawable's double buffering
pixmap. This flag is unset whenever we throw away the old content (e.g. due to a
resize) and is set when lua gave us some new content to display.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2014-03-17 16:27:10 +01:00
parent 3e1f4ff02f
commit e2a6d72611
4 changed files with 12 additions and 3 deletions

View File

@ -1524,14 +1524,18 @@ client_get_drawable(client_t *c, int x, int y)
static void
client_refresh_titlebar_partial(client_t *c, client_titlebar_t bar, int16_t x, int16_t y, uint16_t width, uint16_t height)
{
if(c->titlebar[bar].drawable == NULL || c->titlebar[bar].drawable->pixmap == XCB_NONE)
if(c->titlebar[bar].drawable == NULL
|| c->titlebar[bar].drawable->pixmap == XCB_NONE
|| !c->titlebar[bar].drawable->refreshed)
return;
area_t area = titlebar_get_area(c, bar);
/* Is the titlebar part of the area that should get redrawn? */
area_t area = titlebar_get_area(c, bar);
if (AREA_LEFT(area) >= x + width || AREA_RIGHT(area) <= x)
return;
if (AREA_TOP(area) >= y + height || AREA_BOTTOM(area) <= y)
return;
/* Redraw the affected parts */
cairo_surface_flush(c->titlebar[bar].drawable->surface);
xcb_copy_area(globalconf.connection, c->titlebar[bar].drawable->pixmap, c->frame_window,

View File

@ -34,6 +34,7 @@ drawable_allocator(lua_State *L, drawable_refresh_callback *callback, void *data
drawable_t *d = drawable_new(L);
d->refresh_callback = callback;
d->refresh_data = data;
d->refreshed = false;
d->surface = NULL;
d->pixmap = XCB_NONE;
return d;
@ -46,6 +47,7 @@ drawable_unset_surface(drawable_t *d)
cairo_surface_destroy(d->surface);
if (d->pixmap)
xcb_free_pixmap(globalconf.connection, d->pixmap);
d->refreshed = false;
d->surface = NULL;
d->pixmap = XCB_NONE;
}
@ -108,6 +110,7 @@ static int
luaA_drawable_refresh(lua_State *L)
{
drawable_t *drawable = luaA_checkudata(L, 1, &drawable_class);
drawable->refreshed = true;
(*drawable->refresh_callback)(drawable->refresh_data);
return 0;

View File

@ -38,6 +38,8 @@ struct drawable_t
cairo_surface_t *surface;
/** The geometry of the drawable (in root window coordinates). */
area_t geometry;
/** Surface contents are undefined if this is false. */
bool refreshed;
/** Callback for refreshing. */
drawable_refresh_callback *refresh_callback;
/** Data for refresh callback. */

View File

@ -177,7 +177,7 @@ drawin_refresh_pixmap_partial(drawin_t *drawin,
int16_t x, int16_t y,
uint16_t w, uint16_t h)
{
if (!drawin->drawable || !drawin->drawable->pixmap)
if (!drawin->drawable || !drawin->drawable->pixmap || !drawin->drawable->refreshed)
return;
/* Make cairo do all pending drawing */