titlebar: add support for border, refactorize code

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-18 11:22:54 +02:00
parent 8753a54c65
commit 32a73f9ae6
4 changed files with 108 additions and 180 deletions

View File

@ -478,7 +478,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
if(c->titlebar && !c->ismoving && !c->isfloating && layout != layout_floating) if(c->titlebar && !c->ismoving && !c->isfloating && layout != layout_floating)
{ {
titlebar_update_geometry(c, geometry); titlebar_update_geometry_tiled(c, geometry);
geometry = titlebar_geometry_remove(c->titlebar, geometry); geometry = titlebar_geometry_remove(c->titlebar, geometry);
} }

View File

@ -185,6 +185,12 @@ struct titlebar_t
{ {
xcolor_t fg, bg; xcolor_t fg, bg;
} colors; } colors;
/** Border */
struct
{
xcolor_t color;
int width;
} border;
}; };
/** Delete a titlebar structure. /** Delete a titlebar structure.

View File

@ -137,223 +137,100 @@ titlebar_draw(client_t *c)
draw_context_delete(&ctx); draw_context_delete(&ctx);
} }
/** Update the titlebar geometry for a floating client.
* \param c the client
*/
void void
titlebar_update_geometry_floating(client_t *c) titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
{ {
int width, x_offset = 0, y_offset = 0; int width, x_offset = 0, y_offset = 0;
if(!c->titlebar || !c->titlebar->sw)
return;
switch(c->titlebar->position) switch(c->titlebar->position)
{ {
default: default:
return; return;
case Top: case Top:
if(c->titlebar->width) if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width); width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width));
else else
width = c->geometry.width + 2 * c->border; width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * c->border + c->geometry.width - width; x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
break;
case AlignCenter:
x_offset = (c->geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + x_offset,
c->geometry.y - c->titlebar->sw->geometry.height,
width,
c->titlebar->sw->geometry.height);
break;
case Bottom:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width);
else
width = c->geometry.width + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + c->geometry.width - width;
break;
case AlignCenter:
x_offset = (c->geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + x_offset,
c->geometry.y + c->geometry.height + 2 * c->border,
width,
c->titlebar->sw->geometry.height);
break;
case Left:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.height);
else
width = c->geometry.height + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + c->geometry.height - width;
break;
case AlignCenter:
y_offset = (c->geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x - c->titlebar->sw->geometry.width,
c->geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
break;
case Right:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.height);
else
width = c->geometry.height + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + c->geometry.height - width;
break;
case AlignCenter:
y_offset = (c->geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + c->geometry.width + 2 * c->border,
c->geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
break;
}
titlebar_draw(c);
}
/** Update the titlebar geometry for a tiled client.
* \param c The client.
* \param geometry The geometry the client will receive.
*/
void
titlebar_update_geometry(client_t *c, area_t geometry)
{
int width, x_offset = 0 , y_offset = 0;
if(!c->titlebar || !c->titlebar->sw)
return;
switch(c->titlebar->position)
{
default:
return;
case Top:
if(!c->titlebar->width)
width = geometry.width + 2 * c->border;
else
width = MIN(c->titlebar->width, geometry.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + geometry.width - width;
break; break;
case AlignCenter: case AlignCenter:
x_offset = (geometry.width - width) / 2; x_offset = (geometry.width - width) / 2;
break; break;
} }
simplewindow_moveresize(c->titlebar->sw, res->x = geometry.x + x_offset;
geometry.x + x_offset, res->y = geometry.y - c->titlebar->height - 2 * c->titlebar->border.width;
geometry.y, res->width = width;
width, res->height = c->titlebar->height;
c->titlebar->sw->geometry.height);
break; break;
case Bottom: case Bottom:
if(c->titlebar->width) if(c->titlebar->width)
width = geometry.width + 2 * c->border; width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width));
else else
width = MIN(c->titlebar->width, geometry.width); width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * c->border + geometry.width - width; x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
break; break;
case AlignCenter: case AlignCenter:
x_offset = (geometry.width - width) / 2; x_offset = (geometry.width - width) / 2;
break; break;
} }
simplewindow_moveresize(c->titlebar->sw, res->x = geometry.x + x_offset;
geometry.x + x_offset, res->y = geometry.y + geometry.height + 2 * c->border;
geometry.y + geometry.height res->width = width;
- c->titlebar->sw->geometry.height + 2 * c->border, res->height = c->titlebar->height;
width,
c->titlebar->sw->geometry.height);
break; break;
case Left: case Left:
if(!c->titlebar->width) if(c->titlebar->width)
width = geometry.height + 2 * c->border; width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width));
else else
width = MIN(c->titlebar->width, geometry.height); width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * c->border + geometry.height - width; y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (geometry.height - width) / 2; y_offset = (geometry.height - width) / 2;
break; break;
} }
simplewindow_moveresize(c->titlebar->sw, res->x = geometry.x - c->titlebar->height;
geometry.x, res->y = geometry.y + y_offset;
geometry.y + y_offset, res->width = c->titlebar->height;
c->titlebar->sw->geometry.width, res->height = width;
width);
break; break;
case Right: case Right:
if(c->titlebar->width) if(c->titlebar->width)
width = geometry.height + 2 * c->border; width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width));
else else
width = MIN(c->titlebar->width, geometry.height); width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * c->border + geometry.height - width; y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (geometry.height - width) / 2; y_offset = (geometry.height - width) / 2;
break; break;
} }
simplewindow_moveresize(c->titlebar->sw, res->x = geometry.x + geometry.width + 2 * c->border;
geometry.x + geometry.width res->y = geometry.y + y_offset;
- c->titlebar->sw->geometry.width + 2 * c->border, res->width = c->titlebar->height;
geometry.y + y_offset, res->height = width;
c->titlebar->sw->geometry.width,
width);
break; break;
} }
titlebar_draw(c);
} }
/** Set client titlebar position. /** Set client titlebar position.
@ -363,6 +240,7 @@ void
titlebar_init(client_t *c) titlebar_init(client_t *c)
{ {
int width = 0, height = 0; int width = 0, height = 0;
area_t geom;
switch(c->titlebar->position) switch(c->titlebar->position)
{ {
@ -372,25 +250,32 @@ titlebar_init(client_t *c)
case Top: case Top:
case Bottom: case Bottom:
if(c->titlebar->width) if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width); width = MIN(c->titlebar->width, c->geometry.width - 2 * c->titlebar->border.width);
else else
width = c->geometry.width + 2 * c->border; width = c->geometry.width + 2 * c->border - 2 * c->titlebar->border.width;
height = c->titlebar->height; height = c->titlebar->height;
break; break;
case Left: case Left:
case Right: case Right:
if(c->titlebar->width) if(c->titlebar->width)
height = MIN(c->titlebar->width, c->geometry.height); height = MIN(c->titlebar->width, c->geometry.height - 2 * c->titlebar->border.width);
else else
height = c->geometry.height + 2 * c->border; height = c->geometry.height + 2 * c->border - 2 * c->titlebar->border.width;
width = c->titlebar->height; width = c->titlebar->height;
break; break;
} }
c->titlebar->sw = simplewindow_new(globalconf.connection, titlebar_geometry_compute(c, c->geometry, &geom);
c->phys_screen, 0, 0,
width, height, 0); c->titlebar->sw = simplewindow_new(globalconf.connection, c->phys_screen, geom.x, geom.y,
geom.width, geom.height, c->titlebar->border.width);
if(c->titlebar->border.width)
xcb_change_window_attributes(globalconf.connection, c->titlebar->sw->window,
XCB_CW_BORDER_PIXEL, &c->titlebar->border.color.pixel);
titlebar_draw(c); titlebar_draw(c);
if(client_isvisible(c, c->screen))
xcb_map_window(globalconf.connection, c->titlebar->sw->window); xcb_map_window(globalconf.connection, c->titlebar->sw->window);
} }
@ -422,20 +307,24 @@ luaA_titlebar_new(lua_State *L)
tb->position = position_get_from_str(luaA_getopt_string(L, 1, "position", "top")); tb->position = position_get_from_str(luaA_getopt_string(L, 1, "position", "top"));
lua_getfield(L, 1, "fg"); if((color = luaA_getopt_string(L, -1, "fg", NULL)))
if((color = luaL_optstring(L, -1, NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen, xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->colors.fg); color, &tb->colors.fg);
else else
tb->colors.fg = globalconf.colors.fg; tb->colors.fg = globalconf.colors.fg;
lua_getfield(L, 1, "bg"); if((color = luaA_getopt_string(L, 1, "bg", NULL)))
if((color = luaL_optstring(L, -1, NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen, xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->colors.bg); color, &tb->colors.bg);
else else
tb->colors.bg = globalconf.colors.bg; tb->colors.bg = globalconf.colors.bg;
if((color = luaA_getopt_string(L, 1, "border_color", NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->border.color);
tb->border.width = luaA_getopt_number(L, 1, "border_width", 0);
return luaA_titlebar_userdata_new(tb); return luaA_titlebar_userdata_new(tb);
} }

View File

@ -26,9 +26,8 @@
client_t * client_getbytitlebar(titlebar_t *); client_t * client_getbytitlebar(titlebar_t *);
client_t * client_getbytitlebarwin(xcb_window_t); client_t * client_getbytitlebarwin(xcb_window_t);
void titlebar_geometry_compute(client_t *, area_t, area_t *);
void titlebar_draw(client_t *); void titlebar_draw(client_t *);
void titlebar_update_geometry_floating(client_t *);
void titlebar_update_geometry(client_t *, area_t);
void titlebar_init(client_t *); void titlebar_init(client_t *);
int luaA_titlebar_userdata_new(titlebar_t *); int luaA_titlebar_userdata_new(titlebar_t *);
@ -45,18 +44,18 @@ titlebar_geometry_add(titlebar_t *t, area_t geometry)
switch(t->position) switch(t->position)
{ {
case Top: case Top:
geometry.y -= t->sw->geometry.height; geometry.y -= t->sw->geometry.height + 2 * t->border.width;
geometry.height += t->sw->geometry.height; geometry.height += t->sw->geometry.height + 2 * t->border.width;
break; break;
case Bottom: case Bottom:
geometry.height += t->sw->geometry.height; geometry.height += t->sw->geometry.height + 2 * t->border.width;
break; break;
case Left: case Left:
geometry.x -= t->sw->geometry.width; geometry.x -= t->sw->geometry.width + 2 * t->border.width;
geometry.width += t->sw->geometry.width; geometry.width += t->sw->geometry.width + 2 * t->border.width;
break; break;
case Right: case Right:
geometry.width += t->sw->geometry.width; geometry.width += t->sw->geometry.width + 2 * t->border.width;
break; break;
default: default:
break; break;
@ -77,18 +76,18 @@ titlebar_geometry_remove(titlebar_t *t, area_t geometry)
switch(t->position) switch(t->position)
{ {
case Top: case Top:
geometry.y += t->sw->geometry.height; geometry.y += t->sw->geometry.height + 2 * t->border.width;
geometry.height -= t->sw->geometry.height; geometry.height -= t->sw->geometry.height + 2 * t->border.width;
break; break;
case Bottom: case Bottom:
geometry.height -= t->sw->geometry.height; geometry.height -= t->sw->geometry.height + 2 * t->border.width;
break; break;
case Left: case Left:
geometry.x += t->sw->geometry.width; geometry.x += t->sw->geometry.width + 2 * t->border.width;
geometry.width -= t->sw->geometry.width; geometry.width -= t->sw->geometry.width + 2 * t->border.width;
break; break;
case Right: case Right:
geometry.width -= t->sw->geometry.width; geometry.width -= t->sw->geometry.width + 2 * t->border.width;
break; break;
default: default:
break; break;
@ -97,5 +96,39 @@ titlebar_geometry_remove(titlebar_t *t, area_t geometry)
return geometry; return geometry;
} }
/** Update the titlebar geometry for a floating client.
* \param c the client
*/
static inline void
titlebar_update_geometry_floating(client_t *c)
{
area_t geom;
if(!c->titlebar || !c->titlebar->sw)
return;
titlebar_geometry_compute(c, c->geometry, &geom);
simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height);
titlebar_draw(c);
}
/** Update the titlebar geometry for a tiled client.
* \param c The client.
* \param geometry The geometry the client will receive.
*/
static inline void
titlebar_update_geometry_tiled(client_t *c, area_t geometry)
{
area_t geom;
if(!c->titlebar || !c->titlebar->sw)
return;
titlebar_geometry_compute(c, geometry, &geom);
simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height);
titlebar_draw(c);
}
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80