+
+
+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
#include "server.h"
#include "area.h"
#include "clock.h"
+#include "panel.h"
void init_clock(Clock *clock, int panel_height)
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;
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
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
typedef struct Clock {
- // --------------------------------------------------
// always start with area
Area area;
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;
}
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);
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;
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
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
}
config_taskbar();
-
+ visible_object();
+
// cleanup background list
GSList *l0;
for (l0 = list_back; l0 ; l0 = l0->next) {
void visual_refresh ()
{
- server_refresh_root_pixmap ();
-
- draw (&panel.area);
- refresh (&panel.area);
+ 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);
- 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);
+ redraw (&panel.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);
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;
}
-void resize_clock()
+void visible_object()
{
- 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()
-{
- 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;
-
- 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--;
+ // 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);
+
+ 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;
}
typedef struct {
- // --------------------------------------------------
// always start with area
Area area;
// --------------------------------------------------
// 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;
void visual_refresh ();
void set_panel_properties (Window win);
void window_draw_panel ();
-void resize_clock();
-void resize_taskbar();
+void visible_object();
#endif
}
*/
-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()
{
}
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);
}
Task *tsk = obj;
cairo_surface_t *cs;
cairo_t *ca;
-
+ //printf(" draw_foreground_task\n");
+
draw_task_title (c, tsk, 0);
// draw active pmap
typedef struct {
Area area;
Area area_active;
+ Area area_inactive;
int text;
int icon;
// --------------------------------------------------
// 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;
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;
}
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++) {
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);
}
}
+// 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]);
+ }
+}
+
+
// --------------------------------------------------
// taskbar parameter
typedef struct {
- // --------------------------------------------------
// always start with area
Area area;
// return 1 if task_width changed
int resize_tasks (Taskbar *tskbar);
+void resize_taskbar();
+
//void add_taskbar(Area *a);
#endif
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:
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;
/* 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) {
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;
+ }
}
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);
#include "area.h"
-
void redraw (Area *a)
{
a->redraw = 1;
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;
}
}
-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;
}
+
+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;
+ }
+}
+
* 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)
void (*add_child)(void *obj);
int (*remove_child)(void *obj);
- // list of child
+ // list of child : Area object
GSList *list;
} Area;
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