titlebar: add support for border, refactorize code
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
8753a54c65
commit
32a73f9ae6
2
client.c
2
client.c
|
@ -478,7 +478,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -185,6 +185,12 @@ struct titlebar_t
|
|||
{
|
||||
xcolor_t fg, bg;
|
||||
} colors;
|
||||
/** Border */
|
||||
struct
|
||||
{
|
||||
xcolor_t color;
|
||||
int width;
|
||||
} border;
|
||||
};
|
||||
|
||||
/** Delete a titlebar structure.
|
||||
|
|
219
titlebar.c
219
titlebar.c
|
@ -137,223 +137,100 @@ titlebar_draw(client_t *c)
|
|||
draw_context_delete(&ctx);
|
||||
}
|
||||
|
||||
/** Update the titlebar geometry for a floating client.
|
||||
* \param c the client
|
||||
*/
|
||||
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;
|
||||
|
||||
if(!c->titlebar || !c->titlebar->sw)
|
||||
return;
|
||||
|
||||
switch(c->titlebar->position)
|
||||
{
|
||||
default:
|
||||
return;
|
||||
case Top:
|
||||
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
|
||||
width = c->geometry.width + 2 * c->border;
|
||||
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
|
||||
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->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;
|
||||
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
|
||||
break;
|
||||
case AlignCenter:
|
||||
x_offset = (geometry.width - width) / 2;
|
||||
break;
|
||||
}
|
||||
simplewindow_moveresize(c->titlebar->sw,
|
||||
geometry.x + x_offset,
|
||||
geometry.y,
|
||||
width,
|
||||
c->titlebar->sw->geometry.height);
|
||||
res->x = geometry.x + x_offset;
|
||||
res->y = geometry.y - c->titlebar->height - 2 * c->titlebar->border.width;
|
||||
res->width = width;
|
||||
res->height = c->titlebar->height;
|
||||
break;
|
||||
case Bottom:
|
||||
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
|
||||
width = MIN(c->titlebar->width, geometry.width);
|
||||
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
|
||||
switch(c->titlebar->align)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case AlignRight:
|
||||
x_offset = 2 * c->border + geometry.width - width;
|
||||
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
|
||||
break;
|
||||
case AlignCenter:
|
||||
x_offset = (geometry.width - width) / 2;
|
||||
break;
|
||||
}
|
||||
simplewindow_moveresize(c->titlebar->sw,
|
||||
geometry.x + x_offset,
|
||||
geometry.y + geometry.height
|
||||
- c->titlebar->sw->geometry.height + 2 * c->border,
|
||||
width,
|
||||
c->titlebar->sw->geometry.height);
|
||||
res->x = geometry.x + x_offset;
|
||||
res->y = geometry.y + geometry.height + 2 * c->border;
|
||||
res->width = width;
|
||||
res->height = c->titlebar->height;
|
||||
break;
|
||||
case Left:
|
||||
if(!c->titlebar->width)
|
||||
width = geometry.height + 2 * c->border;
|
||||
if(c->titlebar->width)
|
||||
width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width));
|
||||
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)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case AlignRight:
|
||||
y_offset = 2 * c->border + geometry.height - width;
|
||||
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
|
||||
break;
|
||||
case AlignCenter:
|
||||
y_offset = (geometry.height - width) / 2;
|
||||
break;
|
||||
}
|
||||
simplewindow_moveresize(c->titlebar->sw,
|
||||
geometry.x,
|
||||
geometry.y + y_offset,
|
||||
c->titlebar->sw->geometry.width,
|
||||
width);
|
||||
res->x = geometry.x - c->titlebar->height;
|
||||
res->y = geometry.y + y_offset;
|
||||
res->width = c->titlebar->height;
|
||||
res->height = width;
|
||||
break;
|
||||
case Right:
|
||||
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
|
||||
width = MIN(c->titlebar->width, geometry.height);
|
||||
width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width);
|
||||
switch(c->titlebar->align)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case AlignRight:
|
||||
y_offset = 2 * c->border + geometry.height - width;
|
||||
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
|
||||
break;
|
||||
case AlignCenter:
|
||||
y_offset = (geometry.height - width) / 2;
|
||||
break;
|
||||
}
|
||||
simplewindow_moveresize(c->titlebar->sw,
|
||||
geometry.x + geometry.width
|
||||
- c->titlebar->sw->geometry.width + 2 * c->border,
|
||||
geometry.y + y_offset,
|
||||
c->titlebar->sw->geometry.width,
|
||||
width);
|
||||
res->x = geometry.x + geometry.width + 2 * c->border;
|
||||
res->y = geometry.y + y_offset;
|
||||
res->width = c->titlebar->height;
|
||||
res->height = width;
|
||||
break;
|
||||
}
|
||||
|
||||
titlebar_draw(c);
|
||||
}
|
||||
|
||||
/** Set client titlebar position.
|
||||
|
@ -363,6 +240,7 @@ void
|
|||
titlebar_init(client_t *c)
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
area_t geom;
|
||||
|
||||
switch(c->titlebar->position)
|
||||
{
|
||||
|
@ -372,26 +250,33 @@ titlebar_init(client_t *c)
|
|||
case Top:
|
||||
case Bottom:
|
||||
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
|
||||
width = c->geometry.width + 2 * c->border;
|
||||
width = c->geometry.width + 2 * c->border - 2 * c->titlebar->border.width;
|
||||
height = c->titlebar->height;
|
||||
break;
|
||||
case Left:
|
||||
case Right:
|
||||
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
|
||||
height = c->geometry.height + 2 * c->border;
|
||||
height = c->geometry.height + 2 * c->border - 2 * c->titlebar->border.width;
|
||||
width = c->titlebar->height;
|
||||
break;
|
||||
}
|
||||
|
||||
c->titlebar->sw = simplewindow_new(globalconf.connection,
|
||||
c->phys_screen, 0, 0,
|
||||
width, height, 0);
|
||||
titlebar_geometry_compute(c, c->geometry, &geom);
|
||||
|
||||
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);
|
||||
xcb_map_window(globalconf.connection, c->titlebar->sw->window);
|
||||
|
||||
if(client_isvisible(c, c->screen))
|
||||
xcb_map_window(globalconf.connection, c->titlebar->sw->window);
|
||||
}
|
||||
|
||||
/** Create a new titlebar.
|
||||
|
@ -422,20 +307,24 @@ luaA_titlebar_new(lua_State *L)
|
|||
|
||||
tb->position = position_get_from_str(luaA_getopt_string(L, 1, "position", "top"));
|
||||
|
||||
lua_getfield(L, 1, "fg");
|
||||
if((color = luaL_optstring(L, -1, NULL)))
|
||||
if((color = luaA_getopt_string(L, -1, "fg", NULL)))
|
||||
xcolor_new(globalconf.connection, globalconf.default_screen,
|
||||
color, &tb->colors.fg);
|
||||
else
|
||||
tb->colors.fg = globalconf.colors.fg;
|
||||
|
||||
lua_getfield(L, 1, "bg");
|
||||
if((color = luaL_optstring(L, -1, NULL)))
|
||||
if((color = luaA_getopt_string(L, 1, "bg", NULL)))
|
||||
xcolor_new(globalconf.connection, globalconf.default_screen,
|
||||
color, &tb->colors.bg);
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
61
titlebar.h
61
titlebar.h
|
@ -26,9 +26,8 @@
|
|||
|
||||
client_t * client_getbytitlebar(titlebar_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_update_geometry_floating(client_t *);
|
||||
void titlebar_update_geometry(client_t *, area_t);
|
||||
void titlebar_init(client_t *);
|
||||
|
||||
int luaA_titlebar_userdata_new(titlebar_t *);
|
||||
|
@ -45,18 +44,18 @@ titlebar_geometry_add(titlebar_t *t, area_t geometry)
|
|||
switch(t->position)
|
||||
{
|
||||
case Top:
|
||||
geometry.y -= t->sw->geometry.height;
|
||||
geometry.height += t->sw->geometry.height;
|
||||
geometry.y -= t->sw->geometry.height + 2 * t->border.width;
|
||||
geometry.height += t->sw->geometry.height + 2 * t->border.width;
|
||||
break;
|
||||
case Bottom:
|
||||
geometry.height += t->sw->geometry.height;
|
||||
geometry.height += t->sw->geometry.height + 2 * t->border.width;
|
||||
break;
|
||||
case Left:
|
||||
geometry.x -= t->sw->geometry.width;
|
||||
geometry.width += t->sw->geometry.width;
|
||||
geometry.x -= t->sw->geometry.width + 2 * t->border.width;
|
||||
geometry.width += t->sw->geometry.width + 2 * t->border.width;
|
||||
break;
|
||||
case Right:
|
||||
geometry.width += t->sw->geometry.width;
|
||||
geometry.width += t->sw->geometry.width + 2 * t->border.width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -77,18 +76,18 @@ titlebar_geometry_remove(titlebar_t *t, area_t geometry)
|
|||
switch(t->position)
|
||||
{
|
||||
case Top:
|
||||
geometry.y += t->sw->geometry.height;
|
||||
geometry.height -= t->sw->geometry.height;
|
||||
geometry.y += t->sw->geometry.height + 2 * t->border.width;
|
||||
geometry.height -= t->sw->geometry.height + 2 * t->border.width;
|
||||
break;
|
||||
case Bottom:
|
||||
geometry.height -= t->sw->geometry.height;
|
||||
geometry.height -= t->sw->geometry.height + 2 * t->border.width;
|
||||
break;
|
||||
case Left:
|
||||
geometry.x += t->sw->geometry.width;
|
||||
geometry.width -= t->sw->geometry.width;
|
||||
geometry.x += t->sw->geometry.width + 2 * t->border.width;
|
||||
geometry.width -= t->sw->geometry.width + 2 * t->border.width;
|
||||
break;
|
||||
case Right:
|
||||
geometry.width -= t->sw->geometry.width;
|
||||
geometry.width -= t->sw->geometry.width + 2 * t->border.width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -97,5 +96,39 @@ titlebar_geometry_remove(titlebar_t *t, area_t 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
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||
|
|
Loading…
Reference in New Issue