Drawable: Improve signal behavior
When property::surface is emitted, the drawable didn't know its geometry yet, which had weird side effects. Fix this by changing the C API a little. The function drawable_set_surface() now no longer allows a NULL surface as its argument. The required changes for the titlebar code also means that we no longer throw away the double-buffering surface when a client is moved. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
470142acc3
commit
983001613a
|
@ -668,33 +668,38 @@ client_resize_do(client_t *c, area_t geometry, bool force_notice)
|
|||
|
||||
luaA_object_push(globalconf.L, c);
|
||||
drawable_t *drawable = titlebar_get_drawable(globalconf.L, c, -1, bar);
|
||||
|
||||
/* Get rid of the old state */
|
||||
luaA_object_push_item(globalconf.L, -1, drawable);
|
||||
drawable_set_surface(drawable, -1, NULL);
|
||||
if (c->titlebar[bar].pixmap != XCB_NONE)
|
||||
xcb_free_pixmap(globalconf.connection, c->titlebar[bar].pixmap);
|
||||
c->titlebar[bar].pixmap = XCB_NONE;
|
||||
|
||||
/* And get us some new state */
|
||||
area_t area = titlebar_get_area(c, bar);
|
||||
if (c->titlebar[bar].size != 0 && !hide_titlebars)
|
||||
{
|
||||
c->titlebar[bar].pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, c->titlebar[bar].pixmap,
|
||||
globalconf.screen->root, area.width, area.height);
|
||||
cairo_surface_t *surface = cairo_xcb_surface_create(globalconf.connection,
|
||||
c->titlebar[bar].pixmap, globalconf.visual,
|
||||
area.width, area.height);
|
||||
drawable_set_surface(drawable, -1, surface);
|
||||
}
|
||||
|
||||
/* Convert to global coordinates */
|
||||
area.x += geometry.x;
|
||||
area.y += geometry.y;
|
||||
if (hide_titlebars)
|
||||
area.width = area.height = 0;
|
||||
drawable_set_geometry(drawable, -1, area);
|
||||
|
||||
if (old_geometry.width != geometry.width || old_geometry.height != geometry.height ||
|
||||
drawable->geometry.width == 0 || drawable->geometry.height == 0) {
|
||||
/* Get rid of the old state */
|
||||
drawable_unset_surface(drawable);
|
||||
if (c->titlebar[bar].pixmap != XCB_NONE)
|
||||
xcb_free_pixmap(globalconf.connection, c->titlebar[bar].pixmap);
|
||||
c->titlebar[bar].pixmap = XCB_NONE;
|
||||
|
||||
/* And get us some new state */
|
||||
if (c->titlebar[bar].size != 0 && !hide_titlebars)
|
||||
{
|
||||
c->titlebar[bar].pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, c->titlebar[bar].pixmap,
|
||||
globalconf.screen->root, area.width, area.height);
|
||||
cairo_surface_t *surface = cairo_xcb_surface_create(globalconf.connection,
|
||||
c->titlebar[bar].pixmap, globalconf.visual,
|
||||
area.width, area.height);
|
||||
drawable_set_surface(drawable, -1, surface, area);
|
||||
} else
|
||||
drawable_set_geometry(drawable, -1, area);
|
||||
} else
|
||||
drawable_set_geometry(drawable, -1, area);
|
||||
|
||||
/* Pop the client and the drawable */
|
||||
lua_pop(globalconf.L, 2);
|
||||
|
@ -1028,7 +1033,7 @@ client_unmanage(client_t *c, bool window_valid)
|
|||
luaA_object_push_item(globalconf.L, -1, c->titlebar[bar].drawable);
|
||||
|
||||
/* Make the drawable unusable */
|
||||
drawable_set_surface(c->titlebar[bar].drawable, -1, NULL);
|
||||
drawable_unset_surface(c->titlebar[bar].drawable);
|
||||
if (c->titlebar[bar].pixmap != XCB_NONE)
|
||||
xcb_free_pixmap(globalconf.connection, c->titlebar[bar].pixmap);
|
||||
|
||||
|
|
|
@ -48,24 +48,27 @@ drawable_wipe(drawable_t *d)
|
|||
}
|
||||
|
||||
void
|
||||
drawable_set_surface(drawable_t *d, int didx, cairo_surface_t *surface)
|
||||
drawable_unset_surface(drawable_t *d)
|
||||
{
|
||||
if (d->surface) {
|
||||
cairo_surface_finish(d->surface);
|
||||
cairo_surface_destroy(d->surface);
|
||||
}
|
||||
if (!d->surface)
|
||||
return;
|
||||
cairo_surface_finish(d->surface);
|
||||
cairo_surface_destroy(d->surface);
|
||||
d->surface = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
drawable_set_surface(drawable_t *d, int didx, cairo_surface_t *surface, area_t geom)
|
||||
{
|
||||
drawable_unset_surface(d);
|
||||
d->surface = cairo_surface_reference(surface);
|
||||
|
||||
if (d->surface)
|
||||
{
|
||||
/* Make sure the surface doesn't contain garbage by filling it with black */
|
||||
cairo_t *cr = cairo_create(surface);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(cr);
|
||||
cairo_destroy(cr);
|
||||
luaA_object_emit_signal(globalconf.L, didx, "property::surface", 0);
|
||||
}
|
||||
/* Make sure the surface doesn't contain garbage by filling it with black */
|
||||
cairo_t *cr = cairo_create(surface);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(cr);
|
||||
cairo_destroy(cr);
|
||||
drawable_set_geometry(d, didx, geom);
|
||||
luaA_object_emit_signal(globalconf.L, didx, "property::surface", 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -43,7 +43,8 @@ struct drawable_t
|
|||
};
|
||||
|
||||
drawable_t *drawable_allocator(lua_State *, drawable_refresh_callback *, void *);
|
||||
void drawable_set_surface(drawable_t *, int, cairo_surface_t *);
|
||||
void drawable_unset_surface(drawable_t *);
|
||||
void drawable_set_surface(drawable_t *, int, cairo_surface_t *, area_t);
|
||||
void drawable_set_geometry(drawable_t *, int, area_t);
|
||||
void drawable_class_setup(lua_State *);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ drawin_wipe(drawin_t *w)
|
|||
/* The drawin must already be unmapped, else it
|
||||
* couldn't be garbage collected -> no unmap needed */
|
||||
p_delete(&w->cursor);
|
||||
cairo_surface_finish(w->drawable->surface);
|
||||
drawable_unset_surface(w->drawable);
|
||||
if(w->window)
|
||||
{
|
||||
/* Activate BMA */
|
||||
|
@ -98,7 +98,7 @@ drawin_update_drawing(drawin_t *w, int widx)
|
|||
return;
|
||||
/* Clean up old stuff */
|
||||
luaA_object_push_item(globalconf.L, widx, w->drawable);
|
||||
drawable_set_surface(w->drawable, -1, NULL);
|
||||
drawable_unset_surface(w->drawable);
|
||||
if(w->pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, w->pixmap);
|
||||
|
||||
|
@ -111,8 +111,7 @@ drawin_update_drawing(drawin_t *w, int widx)
|
|||
cairo_surface_t *surface = cairo_xcb_surface_create(globalconf.connection,
|
||||
w->pixmap, globalconf.visual,
|
||||
w->geometry.width, w->geometry.height);
|
||||
drawable_set_surface(w->drawable, -1, surface);
|
||||
drawable_set_geometry(w->drawable, -1, w->geometry);
|
||||
drawable_set_surface(w->drawable, -1, surface, w->geometry);
|
||||
lua_pop(globalconf.L, 1);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue