statusbar: only rebuild when necessary

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-09-04 15:22:42 +02:00
parent b4d89eec6c
commit 85c85976c0
1 changed files with 118 additions and 86 deletions

View File

@ -257,6 +257,18 @@ statusbar_refresh(void)
statusbar_draw(statusbar); statusbar_draw(statusbar);
} }
static void
statusbar_clean(statusbar_t *statusbar)
{
/* Who! Check that we're not deleting a statusbar with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
statusbar_systray_kickout(statusbar->phys_screen);
simplewindow_delete(&statusbar->sw);
draw_context_delete(&statusbar->ctx);
}
/** Update the statusbar position. It deletes every statusbar resources and /** Update the statusbar position. It deletes every statusbar resources and
* create them back. * create them back.
* \param statusbar The statusbar. * \param statusbar The statusbar.
@ -265,23 +277,13 @@ void
statusbar_position_update(statusbar_t *statusbar) statusbar_position_update(statusbar_t *statusbar)
{ {
statusbar_t *sb; statusbar_t *sb;
area_t area; area_t area, wingeometry;
xcb_pixmap_t dw; xcb_pixmap_t dw;
xcb_screen_t *s = NULL; xcb_screen_t *s = NULL;
bool ignore = false; bool ignore = false;
globalconf.screens[statusbar->screen].need_arrange = true;
/* Who! Check that we're not deleting a statusbar with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
statusbar_systray_kickout(statusbar->phys_screen);
simplewindow_delete(&statusbar->sw);
draw_context_delete(&statusbar->ctx);
if(statusbar->position == Off) if(statusbar->position == Off)
return; return statusbar_clean(statusbar);
area = screen_area_get(statusbar->screen, NULL, area = screen_area_get(statusbar->screen, NULL,
&globalconf.screens[statusbar->screen].padding, true); &globalconf.screens[statusbar->screen].padding, true);
@ -356,12 +358,110 @@ statusbar_position_update(statusbar_t *statusbar)
switch(statusbar->position) switch(statusbar->position)
{ {
case Right: case Right:
if(statusbar->width_user)
wingeometry.height = statusbar->width;
else
wingeometry.height = area.height;
wingeometry.width = statusbar->height;
switch(statusbar->align)
{
default:
wingeometry.x = area.x + area.width - wingeometry.width;
wingeometry.y = area.y;
break;
case AlignRight:
wingeometry.x = area.x + area.width - wingeometry.width;
wingeometry.y = area.y + area.height - wingeometry.height;
break;
case AlignCenter:
wingeometry.x = area.x + area.width - wingeometry.width;
wingeometry.y = (area.y + area.height - wingeometry.height) / 2;
break;
}
break;
case Left: case Left:
if(!statusbar->width_user) if(statusbar->width_user)
statusbar->width = area.height; wingeometry.height = statusbar->width;
else
wingeometry.height = area.height;
wingeometry.width = statusbar->height;
switch(statusbar->align)
{
default:
wingeometry.x = area.x;
wingeometry.y = (area.y + area.height) - wingeometry.height;
break;
case AlignRight:
wingeometry.x = area.x;
wingeometry.y = area.y;
break;
case AlignCenter:
wingeometry.x = area.x;
wingeometry.y = (area.y + area.height - wingeometry.height) / 2;
}
break;
case Bottom:
if(statusbar->width_user)
wingeometry.width = statusbar->width;
else
wingeometry.width = area.width;
wingeometry.height = statusbar->height;
switch(statusbar->align)
{
default:
wingeometry.x = area.x;
wingeometry.y = (area.y + area.height) - wingeometry.height;
break;
case AlignRight:
wingeometry.x = area.x + area.width - wingeometry.width;
wingeometry.y = (area.y + area.height) - wingeometry.height;
break;
case AlignCenter:
wingeometry.x = area.x + (area.width - wingeometry.width) / 2;
wingeometry.y = (area.y + area.height) - wingeometry.height;
break;
}
break;
default:
if(statusbar->width_user)
wingeometry.width = statusbar->width;
else
wingeometry.width = area.width;
wingeometry.height = statusbar->height;
switch(statusbar->align)
{
default:
wingeometry.x = area.x;
wingeometry.y = area.y;
break;
case AlignRight:
wingeometry.x = area.x + area.width - wingeometry.width;
wingeometry.y = area.y;
break;
case AlignCenter:
wingeometry.x = area.x + (area.width - wingeometry.width) / 2;
wingeometry.y = area.y;
break;
}
break;
}
/* same window size and position ? */
if(!statusbar->sw
|| wingeometry.width != statusbar->sw->geometry.width
|| wingeometry.height != statusbar->sw->geometry.height)
{
statusbar_clean(statusbar);
statusbar->sw = statusbar->sw =
simplewindow_new(globalconf.connection, statusbar->phys_screen, 0, 0, simplewindow_new(globalconf.connection, statusbar->phys_screen, 0, 0,
statusbar->height, statusbar->width, 0); wingeometry.width, wingeometry.height, 0);
switch(statusbar->position)
{
case Right:
case Left:
statusbar->width = wingeometry.height;
s = xutil_screen_get(globalconf.connection, statusbar->phys_screen); s = xutil_screen_get(globalconf.connection, statusbar->phys_screen);
/* we need a new pixmap this way [ ] to render */ /* we need a new pixmap this way [ ] to render */
dw = xcb_generate_id(globalconf.connection); dw = xcb_generate_id(globalconf.connection);
@ -377,11 +477,7 @@ statusbar_position_update(statusbar_t *statusbar)
&statusbar->colors.bg); &statusbar->colors.bg);
break; break;
default: default:
if(!statusbar->width_user) statusbar->width = wingeometry.width;
statusbar->width = area.width;
statusbar->sw =
simplewindow_new(globalconf.connection, statusbar->phys_screen, 0, 0,
statusbar->width, statusbar->height, 0);
statusbar->ctx = draw_context_new(globalconf.connection, statusbar->ctx = draw_context_new(globalconf.connection,
statusbar->phys_screen, statusbar->phys_screen,
statusbar->width, statusbar->width,
@ -391,80 +487,16 @@ statusbar_position_update(statusbar_t *statusbar)
&statusbar->colors.bg); &statusbar->colors.bg);
break; break;
} }
simplewindow_move(statusbar->sw, wingeometry.x, wingeometry.y);
switch(statusbar->position)
{
default:
switch(statusbar->align)
{
default:
simplewindow_move(statusbar->sw, area.x, area.y);
break;
case AlignRight:
simplewindow_move(statusbar->sw,
area.x + area.width - statusbar->width, area.y);
break;
case AlignCenter:
simplewindow_move(statusbar->sw,
area.x + (area.width - statusbar->width) / 2, area.y);
break;
}
break;
case Bottom:
switch(statusbar->align)
{
default:
simplewindow_move(statusbar->sw,
area.x, (area.y + area.height) - statusbar->height);
break;
case AlignRight:
simplewindow_move(statusbar->sw,
area.x + area.width - statusbar->width,
(area.y + area.height) - statusbar->height);
break;
case AlignCenter:
simplewindow_move(statusbar->sw,
area.x + (area.width - statusbar->width) / 2,
(area.y + area.height) - statusbar->height);
break;
}
break;
case Left:
switch(statusbar->align)
{
default:
simplewindow_move(statusbar->sw, area.x,
(area.y + area.height) - statusbar->sw->geometry.height);
break;
case AlignRight:
simplewindow_move(statusbar->sw, area.x, area.y);
break;
case AlignCenter:
simplewindow_move(statusbar->sw, area.x, (area.y + area.height - statusbar->width) / 2);
}
break;
case Right:
switch(statusbar->align)
{
default:
simplewindow_move(statusbar->sw, area.x + area.width - statusbar->height, area.y);
break;
case AlignRight:
simplewindow_move(statusbar->sw, area.x + area.width - statusbar->height,
area.y + area.height - statusbar->width);
break;
case AlignCenter:
simplewindow_move(statusbar->sw, area.x + area.width - statusbar->height,
(area.y + area.height - statusbar->width) / 2);
break;
}
break;
}
xcb_map_window(globalconf.connection, statusbar->sw->window); xcb_map_window(globalconf.connection, statusbar->sw->window);
statusbar->need_update = true;
}
else if(wingeometry.x != statusbar->sw->geometry.x
|| wingeometry.y != statusbar->sw->geometry.y)
simplewindow_move(statusbar->sw, wingeometry.x, wingeometry.y);
/* Set need update */ /* Set need update */
statusbar->need_update = true; globalconf.screens[statusbar->screen].need_arrange = true;
} }
/** Convert a statusbar to a printable string. /** Convert a statusbar to a printable string.