From: Thierry Lorthiois Date: Mon, 5 Jan 2009 21:01:05 +0000 (+0000) Subject: fixed decorated window with compiz X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=2930680396e47d66f7690e7ff92d5bcccbbf996c;p=chaz%2Ftint2 fixed decorated window with compiz --- diff --git a/ChangeLog b/ChangeLog index d06bbdf..a7b0af6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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, ...) diff --git a/README b/README index 1835446..b482d51 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ DEPENDENCIES: -cairo, pango, glib, imlib2 +cairo, pango, glib, imlib2, xrandr, xinerama --------------------------------------------------------- INSTALL: diff --git a/doc/tint2-0.7.odt b/doc/tint2-0.7.odt index 6a99fbb..03af50a 100644 Binary files a/doc/tint2-0.7.odt and b/doc/tint2-0.7.odt differ diff --git a/src/Makefile b/src/Makefile index 5b8b2b7..31fe027 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,7 +22,7 @@ endif $(PROGNAME): $(FILES) $(SYSTRAYOBJ) $(CC) $(CFLAGS) -I. -Iutil -Iclock -Itaskbar -Isystray -o $(PROGNAME) $(FILES) $(FLAGS) - #strip $(PROGNAME) + strip $(PROGNAME) install: mkdir -p $(BINDIR) diff --git a/src/clock/clock.c b/src/clock/clock.c index fb5969b..1b76ec3 100644 --- a/src/clock/clock.c +++ b/src/clock/clock.c @@ -64,7 +64,7 @@ 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) { Clock *clock = obj; PangoLayout *layout; @@ -131,6 +131,5 @@ redraw: } g_object_unref (layout); - return 0; } diff --git a/src/clock/clock.h b/src/clock/clock.h index 53c4969..742a224 100644 --- a/src/clock/clock.h +++ b/src/clock/clock.h @@ -32,7 +32,7 @@ typedef struct Clock { // 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 diff --git a/src/config.c b/src/config.c index e4b6c2d..9bcc84c 100644 --- a/src/config.c +++ b/src/config.c @@ -575,6 +575,7 @@ void config_finish () free(l0->data); } g_slist_free(list_back); + list_back = NULL; } diff --git a/src/config.h b/src/config.h index 1fcd1ed..c87925f 100644 --- a/src/config.h +++ b/src/config.h @@ -9,7 +9,7 @@ #ifndef CONFIG_H #define CONFIG_H - +// list of background GSList *list_back; diff --git a/src/panel.c b/src/panel.c index b9cbcf2..6dc2c8c 100644 --- a/src/panel.c +++ b/src/panel.c @@ -41,7 +41,7 @@ void visual_refresh () // 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 @@ void set_panel_properties (Window win) 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 @@ void visible_object() panel.area.list = g_slist_append(panel.area.list, taskbar); } } - redraw(&panel.area); + set_redraw(&panel.area); panel.refresh = 1; } @@ -191,7 +195,7 @@ void set_panel_background() // 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); } diff --git a/src/server.c b/src/server.c index 2c34415..82f51b8 100644 --- a/src/server.c +++ b/src/server.c @@ -67,6 +67,7 @@ void server_init_atoms () 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); } diff --git a/src/server.h b/src/server.h index e6e230e..435aefd 100644 --- a/src/server.h +++ b/src/server.h @@ -52,6 +52,7 @@ typedef struct Global_atom Atom _NET_WM_STRUT_PARTIAL; Atom WM_NAME; Atom __SWM_VROOT; + Atom _MOTIF_WM_HINTS; } Global_atom; diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 960b53b..1bac2f6 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -80,7 +80,7 @@ void add_task (Window win) 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 @@ void remove_task (Task *tsk) 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 @@ void get_icon (Task *tsk) 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; + } } @@ -272,7 +284,16 @@ void draw_task_title (cairo_t *c, Task *tsk, int active) } -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 @@ int draw_foreground_task (void *obj, cairo_t *c) 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; } diff --git a/src/taskbar/task.h b/src/taskbar/task.h index b0c445a..054eb80 100644 --- a/src/taskbar/task.h +++ b/src/taskbar/task.h @@ -59,7 +59,7 @@ Global_task g_task; 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); diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 99e6a17..9367ddc 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -117,7 +117,7 @@ int resize_tasks (Taskbar *taskbar) 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) { diff --git a/src/tint.c b/src/tint.c index 821048b..8bf2127 100644 --- a/src/tint.c +++ b/src/tint.c @@ -63,11 +63,7 @@ void init () 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 @@ int main (int argc, char *argv[]) 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 @@ load_config: 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); diff --git a/src/tint2 b/src/tint2 index 2eafd70..4384d34 100755 Binary files a/src/tint2 and b/src/tint2 differ diff --git a/src/util/area.c b/src/util/area.c index 6585c3e..ae84d1d 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -30,52 +30,59 @@ #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; } @@ -84,27 +91,9 @@ void draw_background (Area *a, cairo_t *c) 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 @@ void remove_area (Area *a) parent = (Area*)a->parent; parent->list = g_slist_remove(parent->list, a); - redraw (parent); + set_redraw (parent); } @@ -174,7 +163,7 @@ void add_area (Area *a) parent = (Area*)a->parent; parent->list = g_slist_remove(parent->list, a); - redraw (parent); + set_redraw (parent); } diff --git a/src/util/area.h b/src/util/area.h index 5be636f..0499e1a 100644 --- a/src/util/area.h +++ b/src/util/area.h @@ -5,60 +5,23 @@ * 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 @@ typedef struct 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); diff --git a/src/util/common.h b/src/util/common.h index 313a3b7..09a95a8 100644 --- a/src/util/common.h +++ b/src/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 }; diff --git a/tintrc02 b/tintrc02 index 4a2c72d..538c7f0 100644 --- a/tintrc02 +++ b/tintrc02 @@ -22,7 +22,7 @@ border_color = #cccccc 100 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