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:
parent
3e1f4ff02f
commit
e2a6d72611
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue