all repos — tint2 @ e0a80ef5a2bc204d0809fec2003a135ed2c4b0ff

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

fixed decorated window with compiz

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

e0a80ef5a2bc204d0809fec2003a135ed2c4b0ff

parent

89bcccb4680c5838ceecc993285111d3f9ecd78a

M ChangeLogChangeLog

@@ -1,6 +1,23 @@

+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, ...)
M READMEREADME

@@ -1,5 +1,5 @@

DEPENDENCIES: -cairo, pango, glib, imlib2 +cairo, pango, glib, imlib2, xrandr, xinerama --------------------------------------------------------- INSTALL:
M src/Makefilesrc/Makefile

@@ -22,7 +22,7 @@

$(PROGNAME): $(FILES) $(SYSTRAYOBJ) $(CC) $(CFLAGS) -I. -Iutil -Iclock -Itaskbar -Isystray -o $(PROGNAME) $(FILES) $(FLAGS) - #strip $(PROGNAME) + strip $(PROGNAME) install: mkdir -p $(BINDIR)
M src/clock/clock.csrc/clock/clock.c

@@ -64,7 +64,7 @@ }

} -int draw_foreground_clock (void *obj, cairo_t *c) +void draw_foreground_clock (void *obj, cairo_t *c) { Clock *clock = obj; PangoLayout *layout;

@@ -131,6 +131,5 @@ pango_cairo_show_layout (c, layout);

} g_object_unref (layout); - return 0; }
M src/clock/clock.hsrc/clock/clock.h

@@ -32,7 +32,7 @@

// 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
M src/config.csrc/config.c

@@ -575,6 +575,7 @@ for (l0 = list_back; l0 ; l0 = l0->next) {

free(l0->data); } g_slist_free(list_back); + list_back = NULL; }
M src/config.hsrc/config.h

@@ -9,7 +9,7 @@

#ifndef CONFIG_H #define CONFIG_H - +// list of background GSList *list_back;
M src/panel.csrc/panel.c

@@ -41,7 +41,7 @@

// 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);

@@ -102,6 +102,10 @@ XWMHints wmhints;

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); }

@@ -163,7 +167,7 @@

panel.area.list = g_slist_append(panel.area.list, taskbar); } } - redraw(&panel.area); + set_redraw(&panel.area); panel.refresh = 1; }

@@ -191,7 +195,7 @@

// 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); }
M src/server.csrc/server.c

@@ -67,6 +67,7 @@ server.atom._WIN_LAYER = XInternAtom (server.dsp, "_WIN_LAYER", False);

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); }
M src/server.hsrc/server.h

@@ -52,6 +52,7 @@ Atom _WIN_LAYER;

Atom _NET_WM_STRUT_PARTIAL; Atom WM_NAME; Atom __SWM_VROOT; + Atom _MOTIF_WM_HINTS; } Global_atom;
M src/taskbar/task.csrc/taskbar/task.c

@@ -80,7 +80,7 @@ new_tsk->area.parent = tskbar;

tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk); if (resize_tasks (tskbar)) - redraw (&tskbar->area); + set_redraw (&tskbar->area); }

@@ -92,7 +92,7 @@ Taskbar *tskbar;

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) {

@@ -148,18 +148,30 @@ long *data;

int num; data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &num); - if (!data) return; + 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); - 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); + 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; + } }

@@ -272,7 +284,16 @@ }

} -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;

@@ -292,11 +313,9 @@ cs = cairo_xlib_surface_create (server.dsp, tsk->area_active.pmap, server.visual, tsk->area.width, tsk->area.height);

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; }
M src/taskbar/task.hsrc/taskbar/task.h

@@ -59,7 +59,7 @@

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);
M src/taskbar/taskbar.csrc/taskbar/taskbar.c

@@ -117,7 +117,7 @@ taskbar->task_width = pixel_width;

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) {
M src/tint.csrc/tint.c

@@ -63,11 +63,7 @@ memset(&g_taskbar, 0, sizeof(Area));

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");

@@ -355,6 +351,9 @@

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)

@@ -370,8 +369,8 @@ config_finish ();

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);
M src/util/area.csrc/util/area.c

@@ -30,52 +30,59 @@ #include "server.h"

#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); - - 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); + if (a->draw_foreground) + a->draw_foreground(a, c); - //printf("end draw area\n"); - return ret; + cairo_destroy (c); + cairo_surface_destroy (cs); + a->redraw = 0; }

@@ -84,27 +91,9 @@ {

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) {

@@ -163,7 +152,7 @@ Area *parent;

parent = (Area*)a->parent; parent->list = g_slist_remove(parent->list, a); - redraw (parent); + set_redraw (parent); }

@@ -174,7 +163,7 @@ Area *parent;

parent = (Area*)a->parent; parent->list = g_slist_remove(parent->list, a); - redraw (parent); + set_redraw (parent); }
M src/util/area.hsrc/util/area.h

@@ -5,60 +5,23 @@ * base class for all graphical objects (panel, taskbar, task, systray, clock, ...).

* 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) * **************************************************************************/

@@ -89,38 +52,40 @@ } Color;

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);
M src/util/common.hsrc/util/common.h

@@ -14,6 +14,22 @@

// 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 };
M tintrc02tintrc02

@@ -22,7 +22,7 @@ #---------------------------------------------

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