[titlebar] Store titlebar inside client

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-04 11:50:21 +02:00
parent 321f855752
commit aecc3c0e45
9 changed files with 237 additions and 298 deletions

View File

@ -198,7 +198,7 @@ client_updatetitle(client_t *c)
luaA_client_userdata_new(c); luaA_client_userdata_new(c);
luaA_dofunction(globalconf.L, globalconf.hooks.titleupdate, 1); luaA_dofunction(globalconf.L, globalconf.hooks.titleupdate, 1);
titlebar_draw(titlebar_getbyclient(c)); titlebar_draw(c);
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
} }
@ -211,7 +211,7 @@ client_unfocus(client_t *c)
focus_client_push(NULL); focus_client_push(NULL);
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
titlebar_draw(titlebar_getbyclient(c)); titlebar_draw(c);
} }
/** Ban client and unmap it /** Ban client and unmap it
@ -220,14 +220,12 @@ client_unfocus(client_t *c)
void void
client_ban(client_t *c) client_ban(client_t *c)
{ {
titlebar_t *titlebar = titlebar_getbyclient(c);
if(globalconf.focus->client == c) if(globalconf.focus->client == c)
client_unfocus(c); client_unfocus(c);
xcb_unmap_window(globalconf.connection, c->win); xcb_unmap_window(globalconf.connection, c->win);
window_setstate(c->win, XCB_WM_ICONIC_STATE); window_setstate(c->win, XCB_WM_ICONIC_STATE);
if(titlebar && titlebar->position && titlebar->sw) if(c->titlebar && c->titlebar->position && c->titlebar->sw)
xcb_unmap_window(globalconf.connection, titlebar->sw->window); xcb_unmap_window(globalconf.connection, c->titlebar->sw->window);
} }
/** Give focus to client, or to first client if c is NULL /** Give focus to client, or to first client if c is NULL
@ -256,7 +254,7 @@ client_focus(client_t *c, int screen)
client_unban(c); client_unban(c);
/* save sel in focus history */ /* save sel in focus history */
focus_client_push(c); focus_client_push(c);
titlebar_draw(titlebar_getbyclient(c)); titlebar_draw(c);
xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT, xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT,
c->win, XCB_CURRENT_TIME); c->win, XCB_CURRENT_TIME);
/* since we're dropping EnterWindow events and sometimes the window /* since we're dropping EnterWindow events and sometimes the window
@ -297,7 +295,6 @@ client_raise(client_t *c)
uint32_t config_win_vals[2]; uint32_t config_win_vals[2];
client_node_t *node; client_node_t *node;
layer_t layer; layer_t layer;
titlebar_t *titlebar;
config_win_vals[0] = XCB_NONE; config_win_vals[0] = XCB_NONE;
config_win_vals[1] = XCB_STACK_MODE_BELOW; config_win_vals[1] = XCB_STACK_MODE_BELOW;
@ -309,15 +306,15 @@ client_raise(client_t *c)
if(node->client->layer == layer if(node->client->layer == layer
&& client_isvisible_anyscreen(node->client)) && client_isvisible_anyscreen(node->client))
{ {
if((titlebar = titlebar_getbyclient(node->client)) if(node->client->titlebar
&& titlebar->position && node->client->titlebar->sw
&& titlebar->sw) && node->client->titlebar->position)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
titlebar->sw->window, node->client->titlebar->sw->window,
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
config_win_vals); config_win_vals);
config_win_vals[0] = titlebar->sw->window; config_win_vals[0] = node->client->titlebar->sw->window;
} }
xcb_configure_window(globalconf.connection, node->client->win, xcb_configure_window(globalconf.connection, node->client->win,
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
@ -489,14 +486,11 @@ client_resize(client_t *c, area_t geometry, bool hints)
/* Values to configure a window is an array where values are /* Values to configure a window is an array where values are
* stored according to 'value_mask' */ * stored according to 'value_mask' */
uint32_t values[5]; uint32_t values[5];
titlebar_t *titlebar;
titlebar = titlebar_getbyclient(c); if(c->titlebar && !c->ismoving && !c->isfloating && layout != layout_floating)
if(titlebar && !c->ismoving && !c->isfloating && layout != layout_floating)
{ {
titlebar_update_geometry(titlebar, geometry); titlebar_update_geometry(c, geometry);
geometry = titlebar_geometry_remove(titlebar, geometry); geometry = titlebar_geometry_remove(c->titlebar, geometry);
} }
if(hints) if(hints)
@ -535,7 +529,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
if(c->ismoving || c->isfloating if(c->ismoving || c->isfloating
|| layout_get_current(new_screen) == layout_floating) || layout_get_current(new_screen) == layout_floating)
{ {
titlebar_update_geometry_floating(titlebar); titlebar_update_geometry_floating(c);
if(!c->ismax) if(!c->ismax)
c->f_geometry = geometry; c->f_geometry = geometry;
} }
@ -556,7 +550,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
/* call it again like it was floating, /* call it again like it was floating,
* we want it to be sticked to the window */ * we want it to be sticked to the window */
if(!c->ismoving && !c->isfloating && layout != layout_floating) if(!c->ismoving && !c->isfloating && layout != layout_floating)
titlebar_update_geometry_floating(titlebar); titlebar_update_geometry_floating(c);
return resized; return resized;
} }
@ -627,18 +621,16 @@ client_saveprops(client_t *c)
void void
client_unban(client_t *c) client_unban(client_t *c)
{ {
titlebar_t *titlebar = titlebar_getbyclient(c);
xcb_map_window(globalconf.connection, c->win); xcb_map_window(globalconf.connection, c->win);
window_setstate(c->win, XCB_WM_NORMAL_STATE); window_setstate(c->win, XCB_WM_NORMAL_STATE);
if(titlebar && titlebar->sw && titlebar->position != Off) if(c->titlebar && c->titlebar->sw && c->titlebar->position)
xcb_map_window(globalconf.connection, titlebar->sw->window); xcb_map_window(globalconf.connection, c->titlebar->sw->window);
} }
void void
client_unmanage(client_t *c) client_unmanage(client_t *c)
{ {
tag_t *tag; tag_t *tag;
titlebar_t *titlebar;
/* The server grab construct avoids race conditions. */ /* The server grab construct avoids race conditions. */
xcb_grab_server(globalconf.connection); xcb_grab_server(globalconf.connection);
@ -663,11 +655,10 @@ client_unmanage(client_t *c)
xcb_aux_sync(globalconf.connection); xcb_aux_sync(globalconf.connection);
xcb_ungrab_server(globalconf.connection); xcb_ungrab_server(globalconf.connection);
if((titlebar = titlebar_getbyclient(c))) if(c->titlebar)
{ {
simplewindow_delete(&titlebar->sw); simplewindow_delete(&c->titlebar->sw);
titlebar_list_detach(&globalconf.titlebar, titlebar); titlebar_unref(&c->titlebar);
titlebar_unref(&titlebar);
} }
p_delete(&c); p_delete(&c);
@ -684,7 +675,7 @@ client_updatewmhints(client_t *c)
if((c->isurgent = (wm_hints_flags & XCB_WM_X_URGENCY_HINT))) if((c->isurgent = (wm_hints_flags & XCB_WM_X_URGENCY_HINT)))
{ {
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
titlebar_draw(titlebar_getbyclient(c)); titlebar_draw(c);
/* execute hook */ /* execute hook */
luaA_client_userdata_new(c); luaA_client_userdata_new(c);
luaA_dofunction(globalconf.L, globalconf.hooks.urgent, 1); luaA_dofunction(globalconf.L, globalconf.hooks.urgent, 1);
@ -1110,6 +1101,9 @@ luaA_client_icon_set(lua_State *L)
return 0; return 0;
} }
/** Get the client name.
* \return A string with the client name.
*/
static int static int
luaA_client_name_get(lua_State *L) luaA_client_name_get(lua_State *L)
{ {
@ -1118,6 +1112,9 @@ luaA_client_name_get(lua_State *L)
return 1; return 1;
} }
/** Change the client name. It'll change it only from awesome point of view.
* \param A string with the new client name.
*/
static int static int
luaA_client_name_set(lua_State *L) luaA_client_name_set(lua_State *L)
{ {
@ -1128,6 +1125,36 @@ luaA_client_name_set(lua_State *L)
return 0; return 0;
} }
/** Set the client's titlebar.
* \param A titlebar.
*/
static int
luaA_client_titlebar_set(lua_State *L)
{
client_t *cl, **c = luaL_checkudata(L, 1, "client");
titlebar_t **t = luaL_checkudata(L, 2, "titlebar");
for(cl = globalconf.clients; cl; cl = cl->next)
if(cl->titlebar == *t)
luaL_error(L, "titlebar is already used by another client");
/* If client had a titlebar, unref it */
if((*c)->titlebar)
titlebar_unref(&(*c)->titlebar);
/* Attach titlebar to client */
(*c)->titlebar = *t;
titlebar_ref(t);
titlebar_init(*c);
if((*c)->isfloating || layout_get_current((*c)->screen) == layout_floating)
titlebar_update_geometry_floating(*c);
else
globalconf.screens[(*c)->screen].need_arrange = true;
return 0;
}
/** Stop managing a client. /** Stop managing a client.
*/ */
static int static int
@ -1156,6 +1183,7 @@ const struct luaL_reg awesome_client_methods[] =
}; };
const struct luaL_reg awesome_client_meta[] = const struct luaL_reg awesome_client_meta[] =
{ {
{ "titlebar_set", luaA_client_titlebar_set },
{ "name_get", luaA_client_name_get }, { "name_get", luaA_client_name_get },
{ "name_set", luaA_client_name_set }, { "name_set", luaA_client_name_set },
{ "screen_set", luaA_client_screen_set }, { "screen_set", luaA_client_screen_set },

28
event.c
View File

@ -81,7 +81,6 @@ event_handle_buttonpress(void *data __attribute__ ((unused)),
client_t *c; client_t *c;
widget_node_t *w; widget_node_t *w;
statusbar_t *statusbar; statusbar_t *statusbar;
titlebar_t *titlebar;
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) for(screen = 0; screen < globalconf.screens_info->nscreen; screen++)
for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next)
@ -123,30 +122,30 @@ event_handle_buttonpress(void *data __attribute__ ((unused)),
return 0; return 0;
} }
if((titlebar = titlebar_getbywin(ev->event))) if((c = client_getbytitlebarwin(ev->event)))
{ {
/* Need to transform coordinates like it was /* Need to transform coordinates like it was
* top/bottom */ * top/bottom */
switch(titlebar->position) switch(c->titlebar->position)
{ {
case Right: case Right:
tmp = ev->event_y; tmp = ev->event_y;
ev->event_y = titlebar->height - ev->event_x; ev->event_y = c->titlebar->height - ev->event_x;
ev->event_x = tmp; ev->event_x = tmp;
break; break;
case Left: case Left:
tmp = ev->event_y; tmp = ev->event_y;
ev->event_y = ev->event_x; ev->event_y = ev->event_x;
ev->event_x = titlebar->width - tmp; ev->event_x = c->titlebar->width - tmp;
break; break;
default: default:
break; break;
} }
for(w = titlebar->widgets; w; w = w->next) for(w = c->titlebar->widgets; w; w = w->next)
if(ev->event_x >= w->area.x && ev->event_x < w->area.x + w->area.width if(ev->event_x >= w->area.x && ev->event_x < w->area.x + w->area.width
&& ev->event_y >= w->area.y && ev->event_y < w->area.y + w->area.height) && ev->event_y >= w->area.y && ev->event_y < w->area.y + w->area.height)
{ {
w->widget->button_press(w, ev, titlebar->client->screen, titlebar); w->widget->button_press(w, ev, c->screen, c->titlebar);
return 0; return 0;
} }
/* return if no widget match */ /* return if no widget match */
@ -210,7 +209,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)),
} }
else else
{ {
titlebar_update_geometry_floating(titlebar_getbyclient(c)); titlebar_update_geometry_floating(c);
window_configure(c->win, geometry, c->border); window_configure(c->win, geometry, c->border);
} }
} }
@ -311,17 +310,14 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
xcb_enter_notify_event_t *ev) xcb_enter_notify_event_t *ev)
{ {
client_t *c = NULL; client_t *c = NULL;
titlebar_t *t;
if(ev->mode != XCB_NOTIFY_MODE_NORMAL if(ev->mode != XCB_NOTIFY_MODE_NORMAL
|| (ev->root_x == globalconf.pointer_x || (ev->root_x == globalconf.pointer_x
&& ev->root_y == globalconf.pointer_y)) && ev->root_y == globalconf.pointer_y))
return 0; return 0;
if((t = titlebar_getbywin(ev->event))) if((c = client_getbytitlebarwin(ev->event))
c = t->client; || (c = client_get_bywin(globalconf.clients, ev->event)))
if(c || (c = client_get_bywin(globalconf.clients, ev->event)))
{ {
window_grabbuttons(c->win, c->phys_screen); window_grabbuttons(c->win, c->phys_screen);
/* the idea behind saving pointer_x and pointer_y is Bob Marley powered /* the idea behind saving pointer_x and pointer_y is Bob Marley powered
@ -349,7 +345,7 @@ event_handle_expose(void *data __attribute__ ((unused)),
{ {
int screen; int screen;
statusbar_t *statusbar; statusbar_t *statusbar;
titlebar_t *t; client_t *c;
if(!ev->count) if(!ev->count)
{ {
@ -362,8 +358,8 @@ event_handle_expose(void *data __attribute__ ((unused)),
return 0; return 0;
} }
if((t = titlebar_getbywin(ev->window))) if((c = client_getbytitlebarwin(ev->window)))
simplewindow_refresh_drawable(t->sw); simplewindow_refresh_drawable(c->titlebar->sw);
} }
return 0; return 0;

25
ewmh.c
View File

@ -253,7 +253,6 @@ static void
ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
{ {
const uint32_t raise_window_val = XCB_STACK_MODE_ABOVE; const uint32_t raise_window_val = XCB_STACK_MODE_ABOVE;
titlebar_t *titlebar;
if(state == net_wm_state_sticky) if(state == net_wm_state_sticky)
{ {
@ -282,12 +281,8 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
/* restore geometry */ /* restore geometry */
geometry = c->m_geometry; geometry = c->m_geometry;
/* restore borders and titlebar */ /* restore borders and titlebar */
if((titlebar = titlebar_getbyclient(c)) if(c->titlebar && c->titlebar->sw && (c->titlebar->position = c->titlebar->oldposition))
&& (titlebar->position = titlebar->oldposition)) xcb_map_window(globalconf.connection, c->titlebar->sw->window);
{
titlebar->position = titlebar->oldposition;
xcb_map_window(globalconf.connection, titlebar->sw->window);
}
c->noborder = false; c->noborder = false;
c->ismax = false; c->ismax = false;
client_setborder(c, c->oldborder); client_setborder(c, c->oldborder);
@ -300,11 +295,10 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
c->m_geometry = c->geometry; c->m_geometry = c->geometry;
c->wasfloating = c->isfloating; c->wasfloating = c->isfloating;
/* disable titlebar and borders */ /* disable titlebar and borders */
if((titlebar = titlebar_getbyclient(c)) if(c->titlebar && c->titlebar->sw && (c->titlebar->oldposition = c->titlebar->position))
&& (titlebar->oldposition = titlebar->position))
{ {
xcb_unmap_window(globalconf.connection, titlebar->sw->window); xcb_unmap_window(globalconf.connection, c->titlebar->sw->window);
titlebar->position = Off; c->titlebar->position = Off;
} }
c->ismax = true; c->ismax = true;
c->oldborder = c->border; c->oldborder = c->border;
@ -346,8 +340,6 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
static void static void
ewmh_process_window_type_atom(client_t *c, xcb_atom_t state) ewmh_process_window_type_atom(client_t *c, xcb_atom_t state)
{ {
titlebar_t *titlebar;
if(state == net_wm_window_type_normal) if(state == net_wm_window_type_normal)
{ {
/* do nothing. this is REALLY IMPORTANT */ /* do nothing. this is REALLY IMPORTANT */
@ -357,11 +349,10 @@ ewmh_process_window_type_atom(client_t *c, xcb_atom_t state)
{ {
c->skip = true; c->skip = true;
c->isfixed = true; c->isfixed = true;
if((titlebar = titlebar_getbyclient(c)) if(c->titlebar && c->titlebar->position && c->titlebar->sw)
&& titlebar->position && titlebar->sw)
{ {
xcb_unmap_window(globalconf.connection, titlebar->sw->window); xcb_unmap_window(globalconf.connection, c->titlebar->sw->window);
titlebar->position = Off; c->titlebar->position = Off;
} }
client_setborder(c, 0); client_setborder(c, 0);
c->noborder = true; c->noborder = true;

13
mouse.c
View File

@ -89,22 +89,21 @@ mouse_snapclienttogeometry_inside(area_t geometry, area_t snap_geometry, int sna
} }
/** Snap a client with a futur geometry to the screen and other clients. /** Snap a client with a futur geometry to the screen and other clients.
* \param c the client * \param c The client.
* \param geometry geometry the client will get * \param geometry Geometry the client will get.
* \return geometry to set to the client * \return Geometry to set to the client.
*/ */
static area_t static area_t
mouse_snapclient(client_t *c, area_t geometry, int snap) mouse_snapclient(client_t *c, area_t geometry, int snap)
{ {
client_t *snapper; client_t *snapper;
titlebar_t *t = titlebar_getbyclient(c);
area_t snapper_geometry; area_t snapper_geometry;
area_t screen_geometry = area_t screen_geometry =
screen_get_area(c->screen, screen_get_area(c->screen,
globalconf.screens[c->screen].statusbar, globalconf.screens[c->screen].statusbar,
&globalconf.screens[c->screen].padding); &globalconf.screens[c->screen].padding);
geometry = titlebar_geometry_add(t, geometry); geometry = titlebar_geometry_add(c->titlebar, geometry);
geometry.width += 2 * c->border; geometry.width += 2 * c->border;
geometry.height += 2 * c->border; geometry.height += 2 * c->border;
@ -117,7 +116,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap)
snapper_geometry = snapper->geometry; snapper_geometry = snapper->geometry;
snapper_geometry.width += 2 * c->border; snapper_geometry.width += 2 * c->border;
snapper_geometry.height += 2 * c->border; snapper_geometry.height += 2 * c->border;
snapper_geometry = titlebar_geometry_add(t, snapper_geometry); snapper_geometry = titlebar_geometry_add(c->titlebar, snapper_geometry);
geometry = geometry =
mouse_snapclienttogeometry_outside(geometry, mouse_snapclienttogeometry_outside(geometry,
snapper_geometry, snapper_geometry,
@ -126,7 +125,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap)
geometry.width -= 2 * c->border; geometry.width -= 2 * c->border;
geometry.height -= 2 * c->border; geometry.height -= 2 * c->border;
return titlebar_geometry_remove(t, geometry); return titlebar_geometry_remove(c->titlebar, geometry);
} }
/** Redraw the resizebar. /** Redraw the resizebar.

View File

@ -73,7 +73,6 @@ placement_smart(client_t *c)
area_t *screen_geometry, *arealist = NULL, *r; area_t *screen_geometry, *arealist = NULL, *r;
bool found = false; bool found = false;
layout_t *layout; layout_t *layout;
titlebar_t *titlebar = titlebar_getbyclient(c);
screen_geometry = p_new(area_t, 1); screen_geometry = p_new(area_t, 1);
@ -92,7 +91,7 @@ placement_smart(client_t *c)
newgeometry = client->f_geometry; newgeometry = client->f_geometry;
newgeometry.width += 2 * client->border; newgeometry.width += 2 * client->border;
newgeometry.height += 2 * client->border; newgeometry.height += 2 * client->border;
newgeometry = titlebar_geometry_add(titlebar, newgeometry); newgeometry = titlebar_geometry_add(c->titlebar, newgeometry);
area_list_remove(&arealist, &newgeometry); area_list_remove(&arealist, &newgeometry);
} }
@ -120,9 +119,9 @@ placement_smart(client_t *c)
newgeometry.width = c->f_geometry.width; newgeometry.width = c->f_geometry.width;
newgeometry.height = c->f_geometry.height; newgeometry.height = c->f_geometry.height;
newgeometry = titlebar_geometry_add(titlebar, newgeometry); newgeometry = titlebar_geometry_add(c->titlebar, newgeometry);
newgeometry = placement_fix_offscreen(newgeometry, c->screen, c->border); newgeometry = placement_fix_offscreen(newgeometry, c->screen, c->border);
newgeometry = titlebar_geometry_remove(titlebar, newgeometry); newgeometry = titlebar_geometry_remove(c->titlebar, newgeometry);
area_list_wipe(&arealist); area_list_wipe(&arealist);
@ -135,7 +134,6 @@ placement_under_mouse(client_t *c)
xcb_query_pointer_cookie_t qp_c; xcb_query_pointer_cookie_t qp_c;
xcb_query_pointer_reply_t *qp_r; xcb_query_pointer_reply_t *qp_r;
area_t finalgeometry = c->f_geometry; area_t finalgeometry = c->f_geometry;
titlebar_t *titlebar = titlebar_getbyclient(c);
qp_c = xcb_query_pointer(globalconf.connection, qp_c = xcb_query_pointer(globalconf.connection,
xcb_aux_get_screen(globalconf.connection, c->phys_screen)->root); xcb_aux_get_screen(globalconf.connection, c->phys_screen)->root);
@ -147,9 +145,9 @@ placement_under_mouse(client_t *c)
p_delete(&qp_r); p_delete(&qp_r);
} }
finalgeometry = titlebar_geometry_add(titlebar, finalgeometry); finalgeometry = titlebar_geometry_add(c->titlebar, finalgeometry);
finalgeometry = placement_fix_offscreen(finalgeometry, c->screen, c->border); finalgeometry = placement_fix_offscreen(finalgeometry, c->screen, c->border);
finalgeometry = titlebar_geometry_remove(titlebar, finalgeometry); finalgeometry = titlebar_geometry_remove(c->titlebar, finalgeometry);
return finalgeometry; return finalgeometry;
} }

View File

@ -153,8 +153,6 @@ struct titlebar_t
{ {
/** Ref count */ /** Ref count */
int refcount; int refcount;
/** Attached client */
client_t *client;
/** Position */ /** Position */
position_t position, oldposition; position_t position, oldposition;
/** Alignment on window */ /** Alignment on window */
@ -170,8 +168,6 @@ struct titlebar_t
{ {
xcolor_t fg, bg; xcolor_t fg, bg;
} colors; } colors;
/** Next and previous in list */
titlebar_t *prev, *next;
}; };
/** Delete a titlebar structure. /** Delete a titlebar structure.
@ -184,7 +180,6 @@ titlebar_delete(titlebar_t **t)
p_delete(t); p_delete(t);
} }
DO_SLIST(titlebar_t, titlebar, titlebar_delete)
DO_RCNT(titlebar_t, titlebar, titlebar_delete) DO_RCNT(titlebar_t, titlebar, titlebar_delete)
/** Keys bindings */ /** Keys bindings */
@ -289,6 +284,8 @@ struct client_t
layer_t layer, oldlayer; layer_t layer, oldlayer;
/** Path to an icon */ /** Path to an icon */
char *icon_path; char *icon_path;
/** Titlebar */
titlebar_t *titlebar;
}; };
struct client_node_t struct client_node_t
@ -394,8 +391,6 @@ struct awesome_t
xcb_cursor_t cursor[CurLast]; xcb_cursor_t cursor[CurLast];
/** Clients list */ /** Clients list */
client_t *clients; client_t *clients;
/** Titlebar list */
titlebar_t *titlebar;
/** Path to config file */ /** Path to config file */
char *configpath; char *configpath;
/** Floating window placement algo */ /** Floating window placement algo */

View File

@ -32,55 +32,39 @@
extern awesome_t globalconf; extern awesome_t globalconf;
/** Get a titlebar for a client /** Get a client by its titlebar window.
* \param c The client.
* \return A titlebar.
*/
titlebar_t *
titlebar_getbyclient(client_t *c)
{
titlebar_t *t;
for(t = globalconf.titlebar; t; t = t->next)
if(t->client == c)
return t;
return NULL;
}
/** Get a titlebar which own a window.
* \param The window. * \param The window.
* \return A titlebar. * \return A client.
*/ */
titlebar_t * client_t *
titlebar_getbywin(xcb_window_t win) client_getbytitlebarwin(xcb_window_t win)
{ {
titlebar_t *t; client_t *c;
for(t = globalconf.titlebar; t; t = t->next) for(c = globalconf.clients; c; c = c->next)
if(t->sw && t->sw->window == win) if(c->titlebar && c->titlebar->sw && c->titlebar->sw->window == win)
return t; return c;
return NULL; return NULL;
} }
/** Draw the titlebar content. /** Draw the titlebar content.
* \param c the client * \param c The client.
*/ */
void void
titlebar_draw(titlebar_t *titlebar) titlebar_draw(client_t *c)
{ {
xcb_drawable_t dw = 0; xcb_drawable_t dw = 0;
draw_context_t *ctx; draw_context_t *ctx;
xcb_screen_t *s; xcb_screen_t *s;
if(!titlebar || !titlebar->sw || !titlebar->position) if(!c->titlebar || !c->titlebar->sw || !c->titlebar->position)
return; return;
s = xcb_aux_get_screen(globalconf.connection, s = xcb_aux_get_screen(globalconf.connection,
titlebar->sw->phys_screen); c->titlebar->sw->phys_screen);
switch(titlebar->position) switch(c->titlebar->position)
{ {
case Off: case Off:
return; return;
@ -90,49 +74,49 @@ titlebar_draw(titlebar_t *titlebar)
xcb_create_pixmap(globalconf.connection, s->root_depth, xcb_create_pixmap(globalconf.connection, s->root_depth,
dw, dw,
s->root, s->root,
titlebar->sw->geometry.height, c->titlebar->sw->geometry.height,
titlebar->sw->geometry.width); c->titlebar->sw->geometry.width);
ctx = draw_context_new(globalconf.connection, titlebar->sw->phys_screen, ctx = draw_context_new(globalconf.connection, c->titlebar->sw->phys_screen,
titlebar->sw->geometry.height, c->titlebar->sw->geometry.height,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
dw, dw,
titlebar->colors.fg, c->titlebar->colors.fg,
titlebar->colors.bg); c->titlebar->colors.bg);
break; break;
default: default:
ctx = draw_context_new(globalconf.connection, titlebar->sw->phys_screen, ctx = draw_context_new(globalconf.connection, c->titlebar->sw->phys_screen,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
titlebar->sw->geometry.height, c->titlebar->sw->geometry.height,
titlebar->sw->drawable, c->titlebar->sw->drawable,
titlebar->colors.fg, c->titlebar->colors.fg,
titlebar->colors.bg); c->titlebar->colors.bg);
break; break;
} }
widget_render(titlebar->widgets, ctx, titlebar->sw->gc, titlebar->sw->drawable, widget_render(c->titlebar->widgets, ctx, c->titlebar->sw->gc, c->titlebar->sw->drawable,
titlebar->client->screen, titlebar->position, c->screen, c->titlebar->position,
titlebar->sw->geometry.x, titlebar->sw->geometry.y, titlebar); c->titlebar->sw->geometry.x, c->titlebar->sw->geometry.y, c->titlebar);
switch(titlebar->position) switch(c->titlebar->position)
{ {
case Left: case Left:
draw_rotate(ctx, ctx->drawable, titlebar->sw->drawable, draw_rotate(ctx, ctx->drawable, c->titlebar->sw->drawable,
ctx->width, ctx->height, ctx->width, ctx->height,
ctx->height, ctx->width, ctx->height, ctx->width,
- M_PI_2, 0, titlebar->sw->geometry.height); - M_PI_2, 0, c->titlebar->sw->geometry.height);
xcb_free_pixmap(globalconf.connection, dw); xcb_free_pixmap(globalconf.connection, dw);
break; break;
case Right: case Right:
draw_rotate(ctx, ctx->drawable, titlebar->sw->drawable, draw_rotate(ctx, ctx->drawable, c->titlebar->sw->drawable,
ctx->width, ctx->height, ctx->width, ctx->height,
ctx->height, ctx->width, ctx->height, ctx->width,
M_PI_2, titlebar->sw->geometry.width, 0); M_PI_2, c->titlebar->sw->geometry.width, 0);
xcb_free_pixmap(globalconf.connection, dw); xcb_free_pixmap(globalconf.connection, dw);
default: default:
break; break;
} }
simplewindow_refresh_drawable(titlebar->sw); simplewindow_refresh_drawable(c->titlebar->sw);
draw_context_delete(&ctx); draw_context_delete(&ctx);
} }
@ -141,267 +125,262 @@ titlebar_draw(titlebar_t *titlebar)
* \param c the client * \param c the client
*/ */
void void
titlebar_update_geometry_floating(titlebar_t *titlebar) titlebar_update_geometry_floating(client_t *c)
{ {
int width, x_offset = 0, y_offset = 0; int width, x_offset = 0, y_offset = 0;
if(!titlebar || !titlebar->sw) if(!c->titlebar || !c->titlebar->sw)
return; return;
switch(titlebar->position) switch(c->titlebar->position)
{ {
default: default:
return; return;
case Off:
return;
case Top: case Top:
if(titlebar->width) if(c->titlebar->width)
width = MIN(titlebar->width, titlebar->client->geometry.width); width = MIN(c->titlebar->width, c->geometry.width);
else else
width = titlebar->client->geometry.width + 2 * titlebar->client->border; width = c->geometry.width + 2 * c->border;
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * titlebar->client->border + titlebar->client->geometry.width - width; x_offset = 2 * c->border + c->geometry.width - width;
break; break;
case AlignCenter: case AlignCenter:
x_offset = (titlebar->client->geometry.width - width) / 2; x_offset = (c->geometry.width - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
titlebar->client->geometry.x + x_offset, c->geometry.x + x_offset,
titlebar->client->geometry.y - titlebar->sw->geometry.height, c->geometry.y - c->titlebar->sw->geometry.height,
width, width,
titlebar->sw->geometry.height); c->titlebar->sw->geometry.height);
break; break;
case Bottom: case Bottom:
if(titlebar->width) if(c->titlebar->width)
width = MIN(titlebar->width, titlebar->client->geometry.width); width = MIN(c->titlebar->width, c->geometry.width);
else else
width = titlebar->client->geometry.width + 2 * titlebar->client->border; width = c->geometry.width + 2 * c->border;
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * titlebar->client->border + titlebar->client->geometry.width - width; x_offset = 2 * c->border + c->geometry.width - width;
break; break;
case AlignCenter: case AlignCenter:
x_offset = (titlebar->client->geometry.width - width) / 2; x_offset = (c->geometry.width - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
titlebar->client->geometry.x + x_offset, c->geometry.x + x_offset,
titlebar->client->geometry.y + titlebar->client->geometry.height + 2 * titlebar->client->border, c->geometry.y + c->geometry.height + 2 * c->border,
width, width,
titlebar->sw->geometry.height); c->titlebar->sw->geometry.height);
break; break;
case Left: case Left:
if(titlebar->width) if(c->titlebar->width)
width = MIN(titlebar->width, titlebar->client->geometry.height); width = MIN(c->titlebar->width, c->geometry.height);
else else
width = titlebar->client->geometry.height + 2 * titlebar->client->border; width = c->geometry.height + 2 * c->border;
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * titlebar->client->border + titlebar->client->geometry.height - width; y_offset = 2 * c->border + c->geometry.height - width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (titlebar->client->geometry.height - width) / 2; y_offset = (c->geometry.height - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
titlebar->client->geometry.x - titlebar->sw->geometry.width, c->geometry.x - c->titlebar->sw->geometry.width,
titlebar->client->geometry.y + y_offset, c->geometry.y + y_offset,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
width); width);
break; break;
case Right: case Right:
if(titlebar->width) if(c->titlebar->width)
width = MIN(titlebar->width, titlebar->client->geometry.height); width = MIN(c->titlebar->width, c->geometry.height);
else else
width = titlebar->client->geometry.height + 2 * titlebar->client->border; width = c->geometry.height + 2 * c->border;
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * titlebar->client->border + titlebar->client->geometry.height - width; y_offset = 2 * c->border + c->geometry.height - width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (titlebar->client->geometry.height - width) / 2; y_offset = (c->geometry.height - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
titlebar->client->geometry.x + titlebar->client->geometry.width + 2 * titlebar->client->border, c->geometry.x + c->geometry.width + 2 * c->border,
titlebar->client->geometry.y + y_offset, c->geometry.y + y_offset,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
width); width);
break; break;
} }
titlebar_draw(titlebar); titlebar_draw(c);
} }
/** Update the titlebar geometry for a tiled client. /** Update the titlebar geometry for a tiled client.
* \param c the client * \param c The client.
* \param geometry the geometry the client will receive * \param geometry The geometry the client will receive.
*/ */
void void
titlebar_update_geometry(titlebar_t *titlebar, area_t geometry) titlebar_update_geometry(client_t *c, area_t geometry)
{ {
int width, x_offset = 0 , y_offset = 0; int width, x_offset = 0 , y_offset = 0;
if(!titlebar || !titlebar->sw) if(!c->titlebar || !c->titlebar->sw)
return; return;
switch(titlebar->position) switch(c->titlebar->position)
{ {
default: default:
return; return;
case Off:
return;
case Top: case Top:
if(!titlebar->width) if(!c->titlebar->width)
width = geometry.width + 2 * titlebar->client->border; width = geometry.width + 2 * c->border;
else else
width = MIN(titlebar->width, geometry.width); width = MIN(c->titlebar->width, geometry.width);
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * titlebar->client->border + geometry.width - width; 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_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
geometry.x + x_offset, geometry.x + x_offset,
geometry.y, geometry.y,
width, width,
titlebar->sw->geometry.height); c->titlebar->sw->geometry.height);
break; break;
case Bottom: case Bottom:
if(titlebar->width) if(c->titlebar->width)
width = geometry.width + 2 * titlebar->client->border; width = geometry.width + 2 * c->border;
else else
width = MIN(titlebar->width, geometry.width); width = MIN(c->titlebar->width, geometry.width);
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
x_offset = 2 * titlebar->client->border + geometry.width - width; 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_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
geometry.x + x_offset, geometry.x + x_offset,
geometry.y + geometry.height geometry.y + geometry.height
- titlebar->sw->geometry.height + 2 * titlebar->client->border, - c->titlebar->sw->geometry.height + 2 * c->border,
width, width,
titlebar->sw->geometry.height); c->titlebar->sw->geometry.height);
break; break;
case Left: case Left:
if(!titlebar->width) if(!c->titlebar->width)
width = geometry.height + 2 * titlebar->client->border; width = geometry.height + 2 * c->border;
else else
width = MIN(titlebar->width, geometry.height); width = MIN(c->titlebar->width, geometry.height);
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * titlebar->client->border + geometry.height - width; y_offset = 2 * c->border + geometry.height - width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (geometry.height - width) / 2; y_offset = (geometry.height - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
geometry.x, geometry.x,
geometry.y + y_offset, geometry.y + y_offset,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
width); width);
break; break;
case Right: case Right:
if(titlebar->width) if(c->titlebar->width)
width = geometry.height + 2 * titlebar->client->border; width = geometry.height + 2 * c->border;
else else
width = MIN(titlebar->width, geometry.height); width = MIN(c->titlebar->width, geometry.height);
switch(titlebar->align) switch(c->titlebar->align)
{ {
default: default:
break; break;
case AlignRight: case AlignRight:
y_offset = 2 * titlebar->client->border + geometry.height - width; y_offset = 2 * c->border + geometry.height - width;
break; break;
case AlignCenter: case AlignCenter:
y_offset = (geometry.height - width) / 2; y_offset = (geometry.height - width) / 2;
break; break;
} }
simplewindow_move_resize(titlebar->sw, simplewindow_move_resize(c->titlebar->sw,
geometry.x + geometry.width geometry.x + geometry.width
- titlebar->sw->geometry.width + 2 * titlebar->client->border, - c->titlebar->sw->geometry.width + 2 * c->border,
geometry.y + y_offset, geometry.y + y_offset,
titlebar->sw->geometry.width, c->titlebar->sw->geometry.width,
width); width);
break; break;
} }
titlebar_draw(titlebar); titlebar_draw(c);
} }
/** Set client titlebar position. /** Set client titlebar position.
* \param c The client. * \param c The client.
* \param p The position.
*/ */
void void
titlebar_init(titlebar_t *titlebar) titlebar_init(client_t *c)
{ {
int width = 0, height = 0; int width = 0, height = 0;
switch(titlebar->position) switch(c->titlebar->position)
{ {
default: default:
titlebar->position = Off; c->titlebar->position = Off;
if(titlebar->sw) if(c->titlebar->sw)
xcb_unmap_window(globalconf.connection, titlebar->sw->window); xcb_unmap_window(globalconf.connection, c->titlebar->sw->window);
return; return;
case Top: case Top:
case Bottom: case Bottom:
if(titlebar->width) if(c->titlebar->width)
width = MIN(titlebar->width, titlebar->client->geometry.width); width = MIN(c->titlebar->width, c->geometry.width);
else else
width = titlebar->client->geometry.width + 2 * titlebar->client->border; width = c->geometry.width + 2 * c->border;
height = titlebar->height; height = c->titlebar->height;
break; break;
case Left: case Left:
case Right: case Right:
if(titlebar->width) if(c->titlebar->width)
height = MIN(titlebar->width, titlebar->client->geometry.height); height = MIN(c->titlebar->width, c->geometry.height);
else else
height = titlebar->client->geometry.height + 2 * titlebar->client->border; height = c->geometry.height + 2 * c->border;
width = titlebar->height; width = c->titlebar->height;
break; break;
} }
/* Delete old statusbar */ /* Delete old statusbar */
simplewindow_delete(&titlebar->sw); simplewindow_delete(&c->titlebar->sw);
titlebar->sw = simplewindow_new(globalconf.connection, c->titlebar->sw = simplewindow_new(globalconf.connection,
titlebar->client->phys_screen, 0, 0, c->phys_screen, 0, 0,
width, height, 0); width, height, 0);
titlebar_draw(titlebar); titlebar_draw(c);
xcb_map_window(globalconf.connection, titlebar->sw->window); xcb_map_window(globalconf.connection, c->titlebar->sw->window);
} }
/** Create a new titlebar. /** Create a new titlebar.
@ -451,53 +430,6 @@ luaA_titlebar_new(lua_State *L)
return luaA_settype(L, "titlebar"); return luaA_settype(L, "titlebar");
} }
/** Set the client where the titlebar belongs to.
* \param A client where to attach titlebar, or none for removing.
*/
static int
luaA_titlebar_client_set(lua_State *L)
{
titlebar_t *oldt, **t = luaL_checkudata(L, 1, "titlebar");
client_t **c = NULL;
if(lua_gettop(L) == 2)
c = luaL_checkudata(L, 2, "client");
if(!c)
{
if((*t)->client
&& (*t)->client->isfloating
&& layout_get_current((*t)->client->screen) != layout_floating)
globalconf.screens[(*t)->client->screen].need_arrange = true;
simplewindow_delete(&(*t)->sw);
titlebar_list_detach(&globalconf.titlebar, *t);
titlebar_unref(t);
}
else
{
if((oldt = titlebar_getbyclient(*c)))
{
simplewindow_delete(&oldt->sw);
titlebar_list_detach(&globalconf.titlebar, oldt);
titlebar_unref(&oldt);
}
titlebar_list_push(&globalconf.titlebar, *t);
titlebar_ref(t);
(*t)->client = *c;
titlebar_init(*t);
if((*c)->isfloating || layout_get_current((*c)->screen) == layout_floating)
titlebar_update_geometry_floating(*t);
else
globalconf.screens[(*c)->screen].need_arrange = true;
}
return 0;
}
/** Add a widget to a titlebar. /** Add a widget to a titlebar.
* \param A widget. * \param A widget.
*/ */
@ -512,7 +444,8 @@ luaA_titlebar_widget_add(lua_State *L)
widget_node_list_append(&(*tb)->widgets, w); widget_node_list_append(&(*tb)->widgets, w);
widget_ref(widget); widget_ref(widget);
titlebar_draw(*tb); /* XXX */
// titlebar_draw(*tb);
return 0; return 0;
} }
@ -549,7 +482,6 @@ const struct luaL_reg awesome_titlebar_methods[] =
}; };
const struct luaL_reg awesome_titlebar_meta[] = const struct luaL_reg awesome_titlebar_meta[] =
{ {
{ "client_set", luaA_titlebar_client_set },
{ "widget_add", luaA_titlebar_widget_add }, { "widget_add", luaA_titlebar_widget_add },
{ "__eq", luaA_titlebar_eq }, { "__eq", luaA_titlebar_eq },
{ "__gc", luaA_titlebar_gc }, { "__gc", luaA_titlebar_gc },

View File

@ -24,12 +24,11 @@
#include "structs.h" #include "structs.h"
titlebar_t * titlebar_getbyclient(client_t *); client_t * client_getbytitlebarwin(xcb_window_t);
titlebar_t * titlebar_getbywin(xcb_window_t); void titlebar_draw(client_t *);
void titlebar_draw(titlebar_t *); void titlebar_update_geometry_floating(client_t *);
void titlebar_update_geometry_floating(titlebar_t *); void titlebar_update_geometry(client_t *, area_t);
void titlebar_update_geometry(titlebar_t *, area_t); void titlebar_init(client_t *);
void titlebar_init(titlebar_t *);
/** Add the titlebar geometry to a geometry. /** Add the titlebar geometry to a geometry.
* \param t the titlebar * \param t the titlebar

View File

@ -272,7 +272,7 @@ widget_invalidate_bywidget(widget_t *widget)
int screen; int screen;
statusbar_t *statusbar; statusbar_t *statusbar;
widget_node_t *witer; widget_node_t *witer;
titlebar_t *t; client_t *c;
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) for(screen = 0; screen < globalconf.screens_info->nscreen; screen++)
for(statusbar = globalconf.screens[screen].statusbar; for(statusbar = globalconf.screens[screen].statusbar;
@ -285,10 +285,11 @@ widget_invalidate_bywidget(widget_t *widget)
break; break;
} }
for(t = globalconf.titlebar; t; t = t->next) for(c = globalconf.clients; c; c = c->next)
for(witer = t->widgets; witer; witer = witer->next) if(c->titlebar)
for(witer = c->titlebar->widgets; witer; witer = witer->next)
if(witer->widget == widget) if(witer->widget == widget)
titlebar_draw(t); titlebar_draw(c);
} }
/** Create a new widget userdata. The object is pushed on the stack. /** Create a new widget userdata. The object is pushed on the stack.