+wmhints.icon_pixmap=icon->xid;
+wmhints.icon_mask=icon->shape;
+XGetWMHints(...);
+XGetWMNormalHints
+
+- fixed bug : detect X11 icons
+- fixed bug : desktop background detection
+- fixed bug : border with compiz ? with xfce composite ? with xcompmanager ?
+- fixed bug : task active/inactive
+- multi_monitor : taskbar follow monitor's order (left to right, top to bottom)
+- WM background with panel padding_x and panel padding_y
+ => task (x, y) just on taskbar height
+ => draw background just when needed
+
+
+2008-12-30
+- fixed bug : segfault on ConfigureNotify event
2008-11-12
-- fixed segfault with icon
+- fixed bug : segfault with icon
- panel's left and right padding feel like WM background
(right click open window managers's menu, ...)
DEPENDENCIES:
-cairo, pango, glib, imlib2
+cairo, pango, glib, imlib2, xrandr, xinerama
---------------------------------------------------------
INSTALL:
$(PROGNAME): $(FILES) $(SYSTRAYOBJ)
$(CC) $(CFLAGS) -I. -Iutil -Iclock -Itaskbar -Isystray -o $(PROGNAME) $(FILES) $(FLAGS)
- #strip $(PROGNAME)
+ strip $(PROGNAME)
install:
mkdir -p $(BINDIR)
}
-int draw_foreground_clock (void *obj, cairo_t *c)
+void draw_foreground_clock (void *obj, cairo_t *c)
{
Clock *clock = obj;
PangoLayout *layout;
}
g_object_unref (layout);
- return 0;
}
// initialize clock : y position, precision, ...
void init_clock(Clock *clock, int panel_height);
-int draw_foreground_clock (void *obj, cairo_t *c);
+void draw_foreground_clock (void *obj, cairo_t *c);
#endif
free(l0->data);
}
g_slist_free(list_back);
+ list_back = NULL;
}
#ifndef CONFIG_H
#define CONFIG_H
-
+// list of background
GSList *list_back;
// draw child object
GSList *l = panel.area.list;
for (; l ; l = l->next)
- draw (l->data);
+ refresh (l->data);
// main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, panel.area.paddingx, 0, panel.area.width-(2*panel.area.paddingx), panel.area.height, 0, 0);
wmhints.flags = InputHint;
wmhints.input = False;
XChangeProperty (server.dsp, win, XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, (unsigned char *) &wmhints, sizeof (XWMHints) / 4);
+
+ // Undecorated
+ long prop[5] = { 2, 0, 0, 0, 0 };
+ XChangeProperty(server.dsp, win, server.atom._MOTIF_WM_HINTS, server.atom._MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *) prop, 5);
}
panel.area.list = g_slist_append(panel.area.list, taskbar);
}
}
- redraw(&panel.area);
+ set_redraw(&panel.area);
panel.refresh = 1;
}
// copy background panel on desktop window
XCopyArea (server.dsp, panel.area.pmap, server.root_win, server.gc_root, 0, 0, panel.area.width, panel.area.height, server.posx, server.posy);
- redraw (&panel.area);
+ set_redraw (&panel.area);
}
server.atom._NET_WM_STRUT_PARTIAL = XInternAtom (server.dsp, "_NET_WM_STRUT_PARTIAL", False);
server.atom.WM_NAME = XInternAtom(server.dsp, "WM_NAME", False);
server.atom.__SWM_VROOT = XInternAtom(server.dsp, "__SWM_VROOT", False);
+ server.atom._MOTIF_WM_HINTS = XInternAtom(server.dsp, "_MOTIF_WM_HINTS", False);
}
Atom _NET_WM_STRUT_PARTIAL;
Atom WM_NAME;
Atom __SWM_VROOT;
+ Atom _MOTIF_WM_HINTS;
} Global_atom;
tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk);
if (resize_tasks (tskbar))
- redraw (&tskbar->area);
+ set_redraw (&tskbar->area);
}
tskbar = (Taskbar*)tsk->area.parent;
tskbar->area.list = g_slist_remove(tskbar->area.list, tsk);
resize_tasks (tskbar);
- redraw (&tskbar->area);
+ set_redraw (&tskbar->area);
//printf("remove_task %d %s\n", index(tskbar->desktop, tskbar->monitor), tsk->title);
if (tsk->title) {
int num;
data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &num);
- if (!data) return;
-
- int w, h;
- long *tmp_data;
- tmp_data = get_best_icon (data, get_icon_count (data, num), num, &w, &h, g_task.icon_size1);
-
- tsk->icon_width = w;
- tsk->icon_height = h;
- tsk->icon_data = malloc (w * h * sizeof (long));
- memcpy (tsk->icon_data, tmp_data, w * h * sizeof (long));
-
- XFree (data);
+ if (data) {
+ printf("get_icon plein\n");
+ // ARGB
+ int w, h;
+ long *tmp_data;
+ tmp_data = get_best_icon (data, get_icon_count (data, num), num, &w, &h, g_task.icon_size1);
+
+ tsk->icon_width = w;
+ tsk->icon_height = h;
+ tsk->icon_data = malloc (w * h * sizeof (long));
+ memcpy (tsk->icon_data, tmp_data, w * h * sizeof (long));
+
+ XFree (data);
+ }
+ else {
+ //XWMHints *hints;
+ //hints = XGetWMHints(server.dsp, tkwin);
+ //if (hints != NULL) {
+ // XFree(hints);
+ //}
+ printf("get_icon vide\n");
+ // XChangeProperty (display, windowH, XInternAtom (display, "_NET_WM_ICON", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char*) data, dataSize);
+ return;
+ }
}
}
-int draw_foreground_task (void *obj, cairo_t *c)
+void draw_background_task (void *obj, cairo_t *c)
+{
+ Task *tsk = obj;
+
+ draw_background (&tsk->area_active, c);
+ draw_background (&tsk->area_inactive, c);
+}
+
+
+void draw_foreground_task (void *obj, cairo_t *c)
{
Task *tsk = obj;
cairo_surface_t *cs;
ca = cairo_create (cs);
// redraw task
- draw_background (&tsk->area_active, ca);
draw_task_title (ca, tsk, 1);
cairo_destroy (ca);
cairo_surface_destroy (cs);
- return 0;
}
void add_task (Window win);
void remove_task (Task *tsk);
-int draw_foreground_task (void *obj, cairo_t *c);
+void draw_foreground_task (void *obj, cairo_t *c);
void get_icon (Task *tsk);
void get_title(Task *tsk);
taskbar->task_modulo = modulo_width;
taskbar->text_width = pixel_width - g_task.text_posx - g_task.area.border.width - g_task.area.paddingx;
}
-
+
// change pos_x and width for all tasks
x = taskbar->area.posx + taskbar->area.border.width + taskbar->area.paddingx;
for (l = taskbar->area.list; l ; l = l->next) {
panel.clock.area.draw_foreground = draw_foreground_clock;
g_task.area.draw_foreground = draw_foreground_task;
window.main_win = 0;
-
- // append full transparency background
- //Area *back = calloc(1, sizeof(Area));
- list_back = g_slist_append(0, calloc(1, sizeof(Area)));
-
+
server.dsp = XOpenDisplay (NULL);
if (!server.dsp) {
fprintf(stderr, "Could not open display.\n");
load_config:
if (panel.area.pmap) XFreePixmap (server.dsp, panel.area.pmap);
panel.area.pmap = 0;
+ // append full transparency background
+ list_back = g_slist_append(0, calloc(1, sizeof(Area)));
+
// read tint2rc config
i = 0;
if (c != -1)
window_draw_panel ();
- // BUG: draw(clock) is needed here, but 'on the paper' it's not necessary.
- draw(&panel.clock.area);
+ // BUG: refresh(clock) is needed here, but 'on the paper' it's not necessary.
+ refresh(&panel.clock.area);
x11_fd = ConnectionNumber (server.dsp);
XSync (server.dsp, False);
#include "area.h"
-void redraw (Area *a)
+void refresh (Area *a)
+{
+ if (a->redraw) {
+ if (a->draw)
+ a->draw(a);
+ else
+ draw(a);
+ }
+
+ XCopyArea (server.dsp, a->pmap, server.pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
+
+ GSList *l = a->list;
+ // refresh child object (after refreshing parent)
+ for (; l ; l = l->next)
+ refresh(l->data);
+
+ //printf("end refresh area\n");
+}
+
+
+void set_redraw (Area *a)
{
a->redraw = 1;
GSList *l;
for (l = a->list ; l ; l = l->next)
- redraw(l->data);
+ set_redraw(l->data);
}
-int draw (Area *a)
+void draw (Area *a)
{
cairo_surface_t *cs;
cairo_t *c;
- int ret = 0;
-
- 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);
+
+ //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);
+ draw_background (a, c);
- if (a->draw_foreground)
- ret = a->draw_foreground(a, c);
+ if (a->draw_foreground)
+ a->draw_foreground(a, c);
- cairo_destroy (c);
- cairo_surface_destroy (cs);
- a->redraw = 0;
- }
-
- XCopyArea (server.dsp, a->pmap, server.pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
-
- GSList *l = a->list;
- // draw child object
- for (; l ; l = l->next)
- draw(l->data);
-
- //printf("end draw area\n");
- return ret;
+ cairo_destroy (c);
+ cairo_surface_destroy (cs);
+ a->redraw = 0;
}
if (a->back.alpha > 0.0) {
//printf(" draw_background %d %d\n", a->width, a->height);
draw_rect(c, a->border.width, a->border.width, a->width-(2.0 * a->border.width), a->height-(2.0*a->border.width), a->border.rounded - a->border.width/1.571);
- /*
- double x0, y0, x1, y1;
- x0 = 0;
- y0 = 100;
- x1 = 100;
- y1 = 0;
-
- cairo_pattern_t *linpat;
- cairo_matrix_t matrix;
- linpat = cairo_pattern_create_linear (x0, y0, x1, y1);
-
- cairo_pattern_add_color_stop_rgba (linpat, 0, a->back.color[0], a->back.color[1], a->back.color[2], a->back.alpha);
- cairo_pattern_add_color_stop_rgba (linpat, 1, a->back.color[0], a->back.color[1], a->back.color[2], 0);
- //cairo_matrix_init_scale (&matrix, a->height, a->width);
- //cairo_pattern_set_matrix (linpat, &matrix);
- cairo_set_source (c, linpat);
- */
cairo_set_source_rgba(c, a->back.color[0], a->back.color[1], a->back.color[2], a->back.alpha);
cairo_fill(c);
- //cairo_pattern_destroy (linpat);
}
if (a->border.width > 0 && a->border.alpha > 0.0) {
parent = (Area*)a->parent;
parent->list = g_slist_remove(parent->list, a);
- redraw (parent);
+ set_redraw (parent);
}
parent = (Area*)a->parent;
parent->list = g_slist_remove(parent->list, a);
- redraw (parent);
+ set_redraw (parent);
}
* Area is at the begining of each graphical object so &object == &area.
*
* Area manage the background and border drawing, size and padding.
-* Area manage also the tree of visible objects
+* Area also manage the tree of visible objects
* panel -> taskbars -> tasks
* -> systray -> icons
* -> clock
*
-* un objet comprend les actions:
-* 1) redraw(obj)
-* force l'indicateur 'redraw' sur l'objet
-* parcoure la liste des sous objets => redraw(obj)
-* 2) draw(obj)
-* dessine le background, dessine le contenu dans pmap
-* parcoure la liste des sous objets => draw(obj)
-* le pmap de l'objet se base sur le pmap de l'objet parent (cumul des couches)
-* 3) draw_background(obj)
-* dessine le fond dans pmap
-* 4) draw_foreground(obj) = 0 : fonction virtuelle à redéfinir
-* dessine le contenu dans pmap
-* si l'objet n'a pas de contenu, la fonction est nulle
-* 5) resize_width(obj, width) = 0 : fonction virtuelle à redéfinir
+* draw_foreground(obj) and draw(obj) are virtual function.
+*
+* resize_width(obj, width) = 0 : fonction virtuelle à redéfinir
* recalcule la largeur de l'objet (car la hauteur est fixe)
* - taille systray calculée à partir de la liste des icones
* - taille clock calculée à partir de l'heure
* - taille d'une tache calculée à partir de la taskbar (ajout, suppression, taille)
* - taille d'une taskbar calculée à partir de la taille du panel et des autres objets
-* 6) voir refresh(obj)
-*
-* Implémentation :
-* - l'objet est en fait une zone (area).
-* l'imbrication des sous objet doit permettre de gérer le layout.
-* - les taches ont 2 objets : l'un pour la tache inactive et l'autre pour la tache active
-* draw(obj) est appellé sur le premier objet automatiquement
-* et draw_foreground(obj) lance l'affichage du 2 ieme objet
-* ainsi la taskbar gère bien une liste d'objets mais draw(obj) dessine les 2 objets
-* - les fonctions de refresh et de draw sont totalement dissociées
-*
-* ----------------------------------------------------
-* A évaluer :
-* 1. voir comment définir et gérer le panel_layout avec les objets
-* => peut on s'affranchir des données spécifiques à chaque objet ?
-* => comment gérer l'affichage du layout ?
-* => comment configurer le layout ?
-* => voir le cumul des couches et l'imbrication entre objet et parent ?
-* 2. voir la fonction de refresh des objets ??
-* surtout le refresh des taches qui est différent pour la tache active
-*
-* 3. tester l'implémentation et évaluer les autres abstractions possibles ?
-*
-* 4. comment gérer le groupage des taches
*
* voir resize_taskbar(), resize_clock() et resize_tasks()
-* voir les taches actives et inactives ?? une seule tache est active !
* variable widthChanged ou bien emission d'un signal ???
-*
-* 6) config(obj) configure un objet (définie les positions verticales)
+* voir config(obj) configure un objet (définie les positions verticales)
*
**************************************************************************/
typedef struct {
- // need redraw Pixmap
- int redraw;
-
- int paddingx, paddingy;
+ // TODO: isoler 'draw' de 'refresh'
+ // TODO: isoler les données locales des données communes aux freres
+ // absolute coordinate in panel
+ int posx, posy;
int width, height;
Pixmap pmap;
+
+ // list of child : Area object
+ GSList *list;
+
+ // need redraw Pixmap
+ int redraw;
+ int paddingx, paddingy;
+ // parent Area
+ void *parent;
Color back;
Border border;
- // absolute coordinate in panel
- int posx, posy;
- // parent Area
- void *parent;
-
- // pointer to function
- // draw_foreground : return 1 if width changed, return O otherwise
- int (*draw_foreground)(void *obj, cairo_t *c);
+ // each object can overwrite following function
+ void (*draw)(void *obj);
+ void (*draw_foreground)(void *obj, cairo_t *c);
void (*add_child)(void *obj);
- int (*remove_child)(void *obj);
-
- // list of child : Area object
- GSList *list;
+ int (*remove_child)(void *obj);
} Area;
-// redraw an area and childs
-void redraw (Area *a);
// draw background and foreground
-// return 1 if width changed, return O otherwise
-int draw (Area *a);
+void refresh (Area *a);
+
+// set 'redraw' on an area and childs
+void set_redraw (Area *a);
+void draw (Area *a);
void draw_background (Area *a, cairo_t *c);
void remove_area (Area *a);
// taskbar table : convert 2 dimension in 1 dimension
#define index(i, j) ((i * panel.nb_monitor) + j)
+/*
+void fxfree(void** ptr){
+ if(*ptr){
+ free(*ptr);
+ *ptr=NULL;
+ }
+ }
+FXint fxmalloc(void** ptr,unsigned long size){
+ *ptr=NULL;
+ if(size!=0){
+ if((*ptr=malloc(size))==NULL) return FALSE;
+ }
+ return TRUE;
+ }
+*/
+
// mouse actions
enum { NONE=0, CLOSE, TOGGLE, ICONIFY, SHADE, TOGGLE_ICONIFY };
panel_monitor = 1
panel_position = bottom right
panel_size = 0 27
-panel_margin = 0 0
+panel_margin = 0 20
panel_padding = 4 2
font_shadow = 0
panel_background_id = 1