Redraw titlebars more intelligently
Whenever a titlebar of a client needed to be refreshed, all (possibly) four titlebars would get completely refreshed. So if someone actually added more than one titlebar to a client, awesome would copy each titlebar's content to the window four times. Fix this by introducing more fine-grined functions for uploads. This also makes awesome only update the affected area when it gets an expose event for a titlebar instead of all four titlebars completely. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
1924ee9e6e
commit
6b8bd49c0b
2
event.c
2
event.c
|
@ -547,7 +547,7 @@ event_handle_expose(xcb_expose_event_t *ev)
|
||||||
ev->x, ev->y,
|
ev->x, ev->y,
|
||||||
ev->width, ev->height);
|
ev->width, ev->height);
|
||||||
if ((client = client_getbyframewin(ev->window)))
|
if ((client = client_getbyframewin(ev->window)))
|
||||||
client_refresh(client);
|
client_refresh_partial(client, ev->x, ev->y, ev->width, ev->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The key press event handler.
|
/** The key press event handler.
|
||||||
|
|
|
@ -1551,17 +1551,43 @@ client_get_drawable(client_t *c, int x, int y)
|
||||||
return client_get_drawable_offset(c, &x, &y);
|
return client_get_drawable_offset(c, &x, &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->surface == NULL)
|
||||||
|
return;
|
||||||
|
area_t area = titlebar_get_area(c, bar);
|
||||||
|
/* Is the titlebar part of the area that should get redrawn? */
|
||||||
|
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].pixmap, c->frame_window,
|
||||||
|
globalconf.gc, x - area.x, y - area.y, x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HANDLE_TITLEBAR_REFRESH(name, index) \
|
||||||
|
static void \
|
||||||
|
client_refresh_titlebar_ ## name(client_t *c) \
|
||||||
|
{ \
|
||||||
|
area_t area = titlebar_get_area(c, index); \
|
||||||
|
client_refresh_titlebar_partial(c, index, area.x, area.y, area.width, area.height); \
|
||||||
|
}
|
||||||
|
HANDLE_TITLEBAR_REFRESH(top, CLIENT_TITLEBAR_TOP)
|
||||||
|
HANDLE_TITLEBAR_REFRESH(right, CLIENT_TITLEBAR_RIGHT)
|
||||||
|
HANDLE_TITLEBAR_REFRESH(bottom, CLIENT_TITLEBAR_BOTTOM)
|
||||||
|
HANDLE_TITLEBAR_REFRESH(left, CLIENT_TITLEBAR_LEFT)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh all titlebars that are in the specified rectangle
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
client_refresh(client_t *c)
|
client_refresh_partial(client_t *c, int16_t x, int16_t y, uint16_t width, uint16_t height)
|
||||||
{
|
{
|
||||||
for (client_titlebar_t bar = CLIENT_TITLEBAR_TOP; bar < CLIENT_TITLEBAR_COUNT; bar++) {
|
for (client_titlebar_t bar = CLIENT_TITLEBAR_TOP; bar < CLIENT_TITLEBAR_COUNT; bar++) {
|
||||||
if (c->titlebar[bar].drawable == NULL || c->titlebar[bar].drawable->surface == NULL)
|
client_refresh_titlebar_partial(c, bar, x, y, width, height);
|
||||||
continue;
|
|
||||||
|
|
||||||
area_t area = titlebar_get_area(c, bar);
|
|
||||||
cairo_surface_flush(c->titlebar[bar].drawable->surface);
|
|
||||||
xcb_copy_area(globalconf.connection, c->titlebar[bar].pixmap, c->frame_window,
|
|
||||||
globalconf.gc, 0, 0, area.x, area.y, area.width, area.height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1571,7 +1597,22 @@ titlebar_get_drawable(lua_State *L, client_t *c, int cl_idx, client_titlebar_t b
|
||||||
if (c->titlebar[bar].drawable == NULL)
|
if (c->titlebar[bar].drawable == NULL)
|
||||||
{
|
{
|
||||||
cl_idx = luaA_absindex(L, cl_idx);
|
cl_idx = luaA_absindex(L, cl_idx);
|
||||||
drawable_allocator(L, (drawable_refresh_callback *) client_refresh, c);
|
switch (bar) {
|
||||||
|
case CLIENT_TITLEBAR_TOP:
|
||||||
|
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_top, c);
|
||||||
|
break;
|
||||||
|
case CLIENT_TITLEBAR_BOTTOM:
|
||||||
|
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_bottom, c);
|
||||||
|
break;
|
||||||
|
case CLIENT_TITLEBAR_RIGHT:
|
||||||
|
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_right, c);
|
||||||
|
break;
|
||||||
|
case CLIENT_TITLEBAR_LEFT:
|
||||||
|
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_left, c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatal("Unknown titlebar kind %d\n", (int) bar);
|
||||||
|
}
|
||||||
c->titlebar[bar].drawable = luaA_object_ref_item(L, cl_idx, -1);
|
c->titlebar[bar].drawable = luaA_object_ref_item(L, cl_idx, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ void client_focus_refresh(void);
|
||||||
bool client_hasproto(client_t *, xcb_atom_t);
|
bool client_hasproto(client_t *, xcb_atom_t);
|
||||||
void client_ignore_enterleave_events(void);
|
void client_ignore_enterleave_events(void);
|
||||||
void client_restore_enterleave_events(void);
|
void client_restore_enterleave_events(void);
|
||||||
void client_refresh(client_t *);
|
void client_refresh_partial(client_t *, int16_t, int16_t, uint16_t, uint16_t);
|
||||||
void client_class_setup(lua_State *);
|
void client_class_setup(lua_State *);
|
||||||
void client_send_configure(client_t *);
|
void client_send_configure(client_t *);
|
||||||
drawable_t *client_get_drawable(client_t *, int, int);
|
drawable_t *client_get_drawable(client_t *, int, int);
|
||||||
|
|
Loading…
Reference in New Issue