all repos — tint2 @ b1c239db22285e9556df59d448e7f0abd6c1748c

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

fixed bugs with new design (first step)

git-svn-id: http://tint2.googlecode.com/svn/trunk@18 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
lorthiois@bbsoft.fr lorthiois@bbsoft.fr@121b4492-b84c-0410-8b4c-0d4edfb3f3cc
commit

b1c239db22285e9556df59d448e7f0abd6c1748c

parent

f327e045c6787f811e86144010fc8120febc187c

M ChangeLogChangeLog

@@ -1,7 +1,13 @@

+ + + +2008-11-02 +- fixed bugs with new design +- panel.area manage the tree of visible objects 2008-10-28 - fixed issue : "untitled task", "task button did not update", "window don't shade", - "error if I don't do 'make install", "Makefile error" + "error if I don't do 'make install'", "Makefile error" 2008-09-24 - change tintrc format
M src/clock/clock.csrc/clock/clock.c

@@ -27,6 +27,7 @@ #include "window.h"

#include "server.h" #include "area.h" #include "clock.h" +#include "panel.h" void init_clock(Clock *clock, int panel_height)

@@ -40,6 +41,10 @@

if (strchr(clock->time1_format, 'S') == NULL) clock->time_precision = 60; else clock->time_precision = 1; + clock->area.posy = panel.area.border.width + panel.area.paddingy; + clock->area.height = panel.area.height - (2 * clock->area.posy); + clock->area.redraw = 1; + gettimeofday(&clock->clock, 0); clock->clock.tv_sec -= clock->clock.tv_sec % clock->time_precision;

@@ -72,6 +77,8 @@ strftime(buf_time, sizeof(buf_time), clock->time1_format, localtime(&clock->clock.tv_sec));

if (clock->time2_format) strftime(buf_date, sizeof(buf_date), clock->time2_format, localtime(&clock->clock.tv_sec)); + //printf(" draw_foreground_clock : %s\n", buf_time); +redraw: layout = pango_cairo_create_layout (c); // check width

@@ -90,11 +97,14 @@ else new_width = date_width;

new_width += (2*clock->area.paddingx) + (2*clock->area.border.width); if (new_width > clock->area.width || (new_width != clock->area.width && date_width > time_width)) { - printf("clock_width %d, new_width %d\n", clock->area.width, new_width); + //printf("clock_width %d, new_width %d\n", clock->area.width, new_width); + // resize clock clock->area.width = new_width; + panel.clock.area.posx = panel.area.width - panel.clock.area.width - panel.area.paddingx - panel.area.border.width; g_object_unref (layout); - return 1; + resize_taskbar(); + goto redraw; } // draw layout
M src/clock/clock.hsrc/clock/clock.h

@@ -13,7 +13,6 @@ #include "area.h"

typedef struct Clock { - // -------------------------------------------------- // always start with area Area area;
M src/config.csrc/config.c

@@ -45,21 +45,24 @@ #include "window.h"

void cleanup_taskbar() -{ - Task *tsk; - Taskbar *tskbar; - GSList *l0; - for (l0 = panel.area.list; l0 ; l0 = l0->next) { - tskbar = l0->data; - GSList *l1; - for (l1 = tskbar->area.list; l1 ; l1 = l1->next) { - tsk = l1->data; +{ + free_area(&panel.area); + + int i, nb; + Task *tsk, *next; + + nb = panel.nb_desktop * panel.nb_monitor; + for (i=0 ; i < nb ; i++) { +/* TODO: voir ce code !! + for (tsk = panel.taskbar[i].tasklist; tsk ; tsk = next) { + next = tsk->next; remove_task (tsk); } - g_slist_free(tskbar->area.list); +*/ } - g_slist_free(panel.area.list); - panel.area.list = 0; + + free(panel.taskbar); + panel.taskbar = 0; }

@@ -69,7 +72,7 @@ if (panel.old_task_font) free(panel.old_task_font);

if (g_task.font_desc) pango_font_description_free(g_task.font_desc); if (panel.clock.time1_font_desc) pango_font_description_free(panel.clock.time1_font_desc); if (panel.clock.time2_font_desc) pango_font_description_free(panel.clock.time2_font_desc); - cleanup_taskbar(); + if (panel.taskbar) cleanup_taskbar(); if (panel.clock.time1_format) g_free(panel.clock.time1_format); if (panel.clock.time2_format) g_free(panel.clock.time2_format); if (server.monitor) free(server.monitor);

@@ -473,37 +476,31 @@ server.nb_desktop = 1;

fprintf(stderr, "tint2 warning : cannot found number of desktop.\n"); } - cleanup_taskbar(); + if (panel.taskbar) cleanup_taskbar(); panel.nb_desktop = server.nb_desktop; if (panel.mode == MULTI_MONITOR) panel.nb_monitor = server.nb_monitor; else panel.nb_monitor = 1; - - // TODO: mémoriser le pointeur sur la première - // malgré l'apparant désordre, les taskbars sont ordonnées - Taskbar *new_tskbar; + panel.taskbar = calloc(panel.nb_desktop * panel.nb_monitor, sizeof(Taskbar)); + g_slist_free(panel.area.list); + panel.area.list = 0; + + Taskbar *tskbar; for (i=0 ; i < panel.nb_desktop ; i++) { for (j=0 ; j < panel.nb_monitor ; j++) { - new_tskbar = calloc(1, sizeof(Taskbar)); - memcpy(&new_tskbar->area, &g_taskbar, sizeof(Area)); - new_tskbar->desktop = i; - new_tskbar->monitor = j; + tskbar = &panel.taskbar[index(i,j)]; + memcpy(&tskbar->area, &g_taskbar, sizeof(Area)); + tskbar->desktop = i; + tskbar->monitor = j; - panel.area.list = g_slist_append(panel.area.list, new_tskbar); + // TODO: redefinir panel.area.list en fonction des objets visibles + panel.area.list = g_slist_append(panel.area.list, tskbar); } } - /* - comment faire pour parcourir les barres de taches ? on ne peut pas se baser sur l'ordre des éléments !! - a t'on besoin de parcourir les barres de taches ?? OUI !! bof ?? - => resize_taskbar() dans panel.c => - => task_refresh_tasklist () dans taskbar.c - => Task *task_get_task (Window win) dans taskbar.c - => event_button_press (int x, int y) dans tint.c => area->event_button_press() est conseillé !! - cela enlève aussi l'organisation des barres de taches en tableau à 2 dimensions - il est possible de mémoriser un pointeur sur la première barre de taches -*/ + if (panel.clock.time1_format) + panel.area.list = g_slist_append(panel.area.list, &panel.clock); - //printf("tasbar (desktop x monitor) : (%d x %d)\n", panel.nb_desktop, panel.nb_monitor); + //printf("taskbar (desktop x monitor) : (%d x %d)\n", panel.nb_desktop, panel.nb_monitor); resize_taskbar(); task_refresh_tasklist (); panel.refresh = 1;

@@ -529,7 +526,7 @@ //printf("tint2 wake up on monitor %d\n", panel.monitor+1);

if (!server.monitor[panel.monitor].width || !server.monitor[panel.monitor].height) fprintf(stderr, "tint2 error : invalid monitor size.\n"); } - + if (!panel.area.width) panel.area.width = server.monitor[panel.monitor].width; // taskbar

@@ -551,9 +548,6 @@ if (panel.area.border.rounded > panel.area.height/2)

panel.area.border.rounded = panel.area.height/2; // clock - panel.clock.area.posy = panel.area.border.width + panel.area.paddingy; - panel.clock.area.height = panel.area.height - (2 * panel.clock.area.posy); - panel.clock.area.redraw = 1; init_clock(&panel.clock, panel.area.height); // compute vertical position : text and icon

@@ -569,7 +563,8 @@ g_task.icon_posy = (g_task.area.height - g_task.icon_size1) / 2;

} config_taskbar(); - + visible_object(); + // cleanup background list GSList *l0; for (l0 = list_back; l0 ; l0 = l0->next) {
M src/panel.csrc/panel.c

@@ -31,43 +31,22 @@

void visual_refresh () { - server_refresh_root_pixmap (); + if (!server.root_pmap) { + Pixmap wall = get_root_pixmap(); + + server.root_pmap = server_create_pixmap (panel.area.width, panel.area.height); + + XCopyArea (server.dsp, wall, server.root_pmap, server.gc, server.posx, server.posy, panel.area.width, panel.area.height, 0, 0); - draw (&panel.area); - refresh (&panel.area); + redraw (&panel.area); + } - if (panel.clock.time1_format) { - if (panel.clock.area.redraw) - panel.refresh = 1; - if (draw (&panel.clock.area)) { - panel.clock.area.redraw = 1; - draw (&panel.clock.area); - resize_clock(); - resize_taskbar(); - redraw(&panel.area); - } - refresh (&panel.clock.area); - } + if (server.pmap) XFreePixmap (server.dsp, server.pmap); + server.pmap = server_create_pixmap (panel.area.width, panel.area.height); - // TODO: ne pas afficher les taskbar invisibles - //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue; - Task *tsk; - Taskbar *tskbar; - GSList *l0; - for (l0 = panel.area.list; l0 ; l0 = l0->next) { - tskbar = l0->data; - draw (&tskbar->area); - refresh (&tskbar->area); - - GSList *l1; - for (l1 = tskbar->area.list; l1 ; l1 = l1->next) { - tsk = l1->data; - draw(&tsk->area); + XCopyArea (server.dsp, server.root_pmap, server.pmap, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0); - if (tsk == panel.task_active) refresh (&tsk->area_active); - else refresh (&tsk->area); - } - } + draw (&panel.area); XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0); XFlush(server.dsp);

@@ -103,9 +82,9 @@ struts[3] = panel.area.height + panel.marginy;

struts[10] = server.posx; struts[11] = server.posx + panel.area.width; } - XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12); - // Old specification + // Old specification : fluxbox need _NET_WM_STRUT. XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4); + XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12); // Sticky and below other window val = 0xFFFFFFFF;

@@ -163,50 +142,29 @@ XFlush (server.dsp);

} -void resize_clock() -{ - panel.clock.area.posx = panel.area.width - panel.clock.area.width - panel.area.paddingx - panel.area.border.width; -} - - -// initialise taskbar posx and width -void resize_taskbar() +void visible_object() { - int taskbar_width, modulo_width, taskbar_on_screen; + if (panel.area.list) { + g_slist_free(panel.area.list); + panel.area.list = 0; + } - if (panel.mode == MULTI_DESKTOP) taskbar_on_screen = panel.nb_desktop; - else taskbar_on_screen = panel.nb_monitor; - - taskbar_width = panel.area.width - (2 * panel.area.paddingx) - (2 * panel.area.border.width); - if (panel.clock.time1_format) - taskbar_width -= (panel.clock.area.width + panel.area.paddingx); - taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) / taskbar_on_screen; + // list of visible objects + // start with clock because draw(clock) can resize others object + if (panel.clock.time1_format) + panel.area.list = g_slist_append(panel.area.list, &panel.clock); - if (taskbar_on_screen > 1) - modulo_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) % taskbar_on_screen; - else - modulo_width = 0; - - int posx, modulo, i; - Taskbar *tskbar; - GSList *l0; - for (i = 0, l0 = panel.area.list; l0 ; i++, l0 = l0->next) { - if ((i % taskbar_on_screen) == 0) { - posx = panel.area.border.width + panel.area.paddingx; - modulo = modulo_width; - } - else posx += taskbar_width + panel.area.paddingx; - - tskbar = l0->data; - tskbar->area.posx = posx; - tskbar->area.width = taskbar_width; - if (modulo) { - tskbar->area.width++; - modulo--; + int i, j; + Taskbar *taskbar; + for (i=0 ; i < panel.nb_desktop ; i++) { + for (j=0 ; j < panel.nb_monitor ; j++) { + taskbar = &panel.taskbar[index(i,j)]; + if (panel.mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) continue; + + panel.area.list = g_slist_append(panel.area.list, taskbar); } - - resize_tasks(tskbar); } + panel.refresh = 1; }
M src/panel.hsrc/panel.h

@@ -26,7 +26,6 @@ enum { LEFT=0x01, RIGHT=0x02, CENTER=0X04, TOP=0X08, BOTTOM=0x10 };

typedef struct { - // -------------------------------------------------- // always start with area Area area;

@@ -49,7 +48,7 @@ int marginx, marginy;

// -------------------------------------------------- // taskbar point to the first taskbar in panel.area.list. number of tasbar == nb_desktop x nb_monitor. - //Taskbar *taskbar; + Taskbar *taskbar; int mode; int nb_desktop; int nb_monitor;

@@ -78,8 +77,7 @@

void visual_refresh (); void set_panel_properties (Window win); void window_draw_panel (); -void resize_clock(); -void resize_taskbar(); +void visible_object(); #endif
M src/server.csrc/server.c

@@ -191,24 +191,6 @@ return 0;

} */ -void server_refresh_root_pixmap () -{ - if (!server.root_pmap) { - Pixmap wall = get_root_pixmap(); - - server.root_pmap = server_create_pixmap (panel.area.width, panel.area.height); - - XCopyArea (server.dsp, wall, server.root_pmap, server.gc, server.posx, server.posy, panel.area.width, panel.area.height, 0, 0); - - panel.area.redraw = 1; - } - - if (server.pmap) XFreePixmap (server.dsp, server.pmap); - server.pmap = server_create_pixmap (panel.area.width, panel.area.height); - - XCopyArea (server.dsp, server.root_pmap, server.pmap, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0); -} - void get_monitors() {
M src/taskbar/task.csrc/taskbar/task.c

@@ -68,11 +68,11 @@ return;

} Taskbar *tskbar; - tskbar = g_slist_nth_data(panel.area.list, index(desktop, monitor)); + tskbar = &panel.taskbar[index(desktop, monitor)]; new_tsk->area.parent = tskbar; tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk); - if (resize_tasks (tskbar)) + if (resize_tasks (tskbar)) redraw (&tskbar->area); }

@@ -263,7 +263,8 @@ {

Task *tsk = obj; cairo_surface_t *cs; cairo_t *ca; - + //printf(" draw_foreground_task\n"); + draw_task_title (c, tsk, 0); // draw active pmap
M src/taskbar/task.hsrc/taskbar/task.h

@@ -17,6 +17,7 @@ // global task parameter

typedef struct { Area area; Area area_active; + Area area_inactive; int text; int icon;

@@ -38,10 +39,10 @@

// -------------------------------------------------- // task parameter typedef struct { - // -------------------------------------------------- // always start with area Area area; Area area_active; + Area area_inactive; // TODO: group task with list of windows here Window win;
M src/taskbar/taskbar.csrc/taskbar/taskbar.c

@@ -35,21 +35,17 @@

Task *task_get_task (Window win) { - Taskbar *tskbar; Task *tsk; GSList *l0; + int i, nb; - for (l0 = panel.area.list; l0 ; l0 = l0->next) { - tskbar = l0->data; - GSList *l1; - for (l1 = tskbar->area.list; l1 ; l1 = l1->next) { - tsk = l1->data; + nb = panel.nb_desktop * panel.nb_monitor; + for (i=0 ; i < nb ; i++) { + for (l0 = panel.taskbar[i].area.list; l0 ; l0 = l0->next) { + tsk = l0->data; if (win == tsk->win) return tsk; } } - - // nb = panel.nb_desktop * panel.nb_monitor; - //printf("task_get_task return 0\n"); return 0; }

@@ -57,24 +53,22 @@

void task_refresh_tasklist () { Window *win, active_win; - int num_results, i, j; + int num_results, i, j, nb; + GSList *l0; + Task *tsk; win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results); if (!win) return; - /* Remove any old and set active win */ + // Remove any old and set active win active_win = window_get_active (); - Task *tsk; - Taskbar *tskbar; - GSList *l0; - for (l0 = panel.area.list; l0 ; l0 = l0->next) { - tskbar = l0->data; - GSList *l1; - for (l1 = tskbar->area.list; l1 ; l1 = l1->next) { - tsk = l1->data; - + nb = panel.nb_desktop * panel.nb_monitor; + for (i=0 ; i < nb ; i++) { + for (l0 = panel.taskbar[i].area.list; l0 ; l0 = l0->next) { + tsk = l0->data; + if (tsk->win == active_win) panel.task_active = tsk; for (j = 0; j < num_results; j++) {

@@ -83,11 +77,11 @@ }

if (tsk->win != win[j]) remove_task (tsk); } } - - /* Add any new */ - for (i = 0; i < num_results; i++) { - if (!task_get_task (win[i])) add_task (win[i]); - } + + // Add any new + for (i = 0; i < num_results; i++) + if (!task_get_task (win[i])) + add_task (win[i]); XFree (win); }

@@ -141,3 +135,42 @@ return ret;

} +// initialise taskbar posx and width +void resize_taskbar() +{ + int taskbar_width, modulo_width, taskbar_on_screen; + + if (panel.mode == MULTI_DESKTOP) taskbar_on_screen = panel.nb_desktop; + else taskbar_on_screen = panel.nb_monitor; + + taskbar_width = panel.area.width - (2 * panel.area.paddingx) - (2 * panel.area.border.width); + if (panel.clock.time1_format) + taskbar_width -= (panel.clock.area.width + panel.area.paddingx); + taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) / taskbar_on_screen; + + if (taskbar_on_screen > 1) + modulo_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) % taskbar_on_screen; + else + modulo_width = 0; + + int posx, modulo, i, nb; + nb = panel.nb_desktop * panel.nb_monitor; + for (i=0 ; i < nb ; i++) { + if ((i % taskbar_on_screen) == 0) { + posx = panel.area.border.width + panel.area.paddingx; + modulo = modulo_width; + } + else posx += taskbar_width + panel.area.paddingx; + + panel.taskbar[i].area.posx = posx; + panel.taskbar[i].area.width = taskbar_width; + if (modulo) { + panel.taskbar[i].area.width++; + modulo--; + } + + resize_tasks(&panel.taskbar[i]); + } +} + +
M src/taskbar/taskbar.hsrc/taskbar/taskbar.h

@@ -8,7 +8,6 @@

// -------------------------------------------------- // taskbar parameter typedef struct { - // -------------------------------------------------- // always start with area Area area;

@@ -32,6 +31,8 @@ void task_refresh_tasklist ();

// return 1 if task_width changed int resize_tasks (Taskbar *tskbar); + +void resize_taskbar(); //void add_taskbar(Area *a);
M src/tint.csrc/tint.c

@@ -158,6 +158,8 @@

void event_button_release (int button, int x, int y) { int action = TOGGLE_ICONIFY; + // TODO: convert event_button_press(int x, int y) to area->event_button_press() + // if systray is ok switch (button) { case 2:

@@ -173,9 +175,6 @@ case 5:

action = panel.mouse_scroll_down; break; } - - // TODO: ne pas afficher les taskbar invisibles - //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue; // search taskbar Taskbar *tskbar;

@@ -237,13 +236,15 @@

/* Change number of desktops */ else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) { config_taskbar(); + visible_object(); redraw(&panel.area); - panel.refresh = 1; } /* Change desktop */ else if (at == server.atom._NET_CURRENT_DESKTOP) { server.desktop = server_get_current_desktop (); - if (panel.mode != MULTI_DESKTOP) panel.refresh = 1; + if (panel.mode != MULTI_DESKTOP) { + visible_object(); + } } /* Window list */ else if (at == server.atom._NET_CLIENT_LIST) {

@@ -313,20 +314,14 @@ Task *tsk;

tsk = task_get_task (win); if (!tsk) return; - -/* TODO ??? voir ancien code !! - Taskbar *tskbar; - tskbar = tsk->area.parent; - int new_monitor = window_get_monitor (win); - int desktop = tskbar->desktop; - // task on the same monitor - if (tsk->id_taskbar == index(desktop, new_monitor)) return; - - add_task (tsk->win); - remove_task (tsk); - panel.refresh = 1; - */ + Taskbar *tskbar = tsk->area.parent; + if (tskbar->monitor != window_get_monitor (win)) { + // task on another monitor + add_task (tsk->win); + remove_task (tsk); + panel.refresh = 1; + } }

@@ -375,6 +370,9 @@ }

config_finish (); window_draw_panel (); + + // BUG: draw(clock) is needed here, but 'on the paper' it's not necessary. + draw(&panel.clock.area); x11_fd = ConnectionNumber (server.dsp); XSync (server.dsp, False);
M src/util/area.csrc/util/area.c

@@ -30,7 +30,6 @@ #include "server.h"

#include "area.h" - void redraw (Area *a) { a->redraw = 1;

@@ -43,34 +42,41 @@

int draw (Area *a) { - if (!a->redraw) return 0; - cairo_surface_t *cs; cairo_t *c; int ret = 0; - if (a->pmap) XFreePixmap (server.dsp, a->pmap); - a->pmap = server_create_pixmap (a->width, a->height); + if (a->redraw) { + //printf("begin draw area\n"); + if (a->pmap) XFreePixmap (server.dsp, a->pmap); + a->pmap = server_create_pixmap (a->width, a->height); - // add layer of root pixmap - XCopyArea (server.dsp, server.pmap, a->pmap, server.gc, a->posx, a->posy, a->width, a->height, 0, 0); + // add layer of root pixmap + XCopyArea (server.dsp, server.pmap, a->pmap, server.gc, a->posx, a->posy, a->width, a->height, 0, 0); - cs = cairo_xlib_surface_create (server.dsp, a->pmap, server.visual, a->width, a->height); - c = cairo_create (cs); + cs = cairo_xlib_surface_create (server.dsp, a->pmap, server.visual, a->width, a->height); + c = cairo_create (cs); - draw_background (a, c); - - if (a->draw_foreground) { - ret = a->draw_foreground(a, c); + draw_background (a, c); + + if (a->draw_foreground) + ret = a->draw_foreground(a, c); + + cairo_destroy (c); + cairo_surface_destroy (cs); + a->redraw = 0; } - else { - // parcours de la liste des sous objets + + XCopyArea (server.dsp, a->pmap, server.pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy); + + GSList *l = a->list; + if (l) { + // draw child object + for (; l ; l = l->next) + draw(l->data); } - cairo_destroy (c); - cairo_surface_destroy (cs); - a->redraw = 0; - + //printf("end draw area\n"); return ret; }

@@ -153,12 +159,6 @@ }

} -void refresh (Area *a) -{ - XCopyArea (server.dsp, a->pmap, server.pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy); -} - - void remove_area (Area *a) { Area *parent;

@@ -180,3 +180,16 @@ redraw (parent);

} + +void free_area (Area *a) +{ + GSList *l0; + for (l0 = a->list; l0 ; l0 = l0->next) + free_area (l0->data); + + if (a->list) { + g_slist_free(a->list); + a->list = 0; + } +} +
M src/util/area.hsrc/util/area.h

@@ -7,8 +7,8 @@ *

* Area manage the background and border drawing, size and padding. * Area manage also the tree of visible objects * panel -> taskbars -> tasks -* -> clock * -> systray -> icons +* -> clock * * un objet comprend les actions: * 1) redraw(obj)

@@ -110,7 +110,7 @@ int (*draw_foreground)(void *obj, cairo_t *c);

void (*add_child)(void *obj); int (*remove_child)(void *obj); - // list of child + // list of child : Area object GSList *list; } Area;

@@ -123,9 +123,9 @@ // return 1 if width changed, return O otherwise

int draw (Area *a); void draw_background (Area *a, cairo_t *c); -void refresh (Area *a); void remove_area (Area *a); void add_area (Area *a); +void free_area (Area *a); #endif