+2009-02-27
+- fixed issue 49 : better Makefile
+- some systray code (doesn't work)
+- cleanup code
+
+2009-02-25
+- fixed issue 48 : tint2 does't create config file on first start
+
+2009-02-14
+- fxed issue 45 : segfault without clock
+
2009-02-13
- improved object oriented layout
- tint2 looks good for me. if you see bugs, report it.
$(PROGNAME): $(FILES) $(SYSTRAYOBJ)
$(CC) $(CFLAGS) -I. -Iutil -Iclock -Itaskbar -Isystray -o $(PROGNAME) $(FILES) $(FLAGS)
+
+install: install-strip
+
+install-strip:
+ mkdir -p $(BINDIR)
+ mkdir -p $(XDG_CONFIG_DIR)/tint2
+ mkdir -p $(MANDIR)
+ mkdir -p $(MANDIR)/man1
strip $(PROGNAME)
+ install $(PROGNAME) $(BINDIR)
+ cp -f ../tintrc01 $(XDG_CONFIG_DIR)/tint2/tint2rc
+ cp -f ../doc/man/tint2.1 $(MANDIR)/man1
-install:
+install-nostrip:
mkdir -p $(BINDIR)
mkdir -p $(XDG_CONFIG_DIR)/tint2
mkdir -p $(MANDIR)
clean:
rm -f $(PROGNAME)
-.PHONY: clean uninstall install
+.PHONY: clean uninstall install install-strip install-nostrip
/* Systray */
else if (strcmp (key, "systray_padding") == 0) {
extract_values(value, &value1, &value2, &value3);
- panel_config->systray.area.paddingxlr = panel_config->systray.area.paddingx = atoi (value1);
- if (value2) panel_config->systray.area.paddingy = atoi (value2);
- if (value3) panel_config->systray.area.paddingx = atoi (value3);
- panel_config->systray.area.visible = 1;
+ systray.area.paddingxlr = systray.area.paddingx = atoi (value1);
+ if (value2) systray.area.paddingy = atoi (value2);
+ if (value3) systray.area.paddingx = atoi (value3);
+ systray.area.visible = 1;
}
else if (strcmp (key, "systray_background_id") == 0) {
int id = atoi (value);
Area *a = g_slist_nth_data(list_back, id);
- memcpy(&panel_config->systray.area.pix.back, &a->pix.back, sizeof(Color));
- memcpy(&panel_config->systray.area.pix.border, &a->pix.border, sizeof(Border));
+ memcpy(&systray.area.pix.back, &a->pix.back, sizeof(Color));
+ memcpy(&systray.area.pix.border, &a->pix.border, sizeof(Border));
}
/* Mouse actions */
// alloc panels
int i;
if (panel_config->monitor >= 0) {
- // just one monitor
+ // one monitor
nb_panel = 1;
panel1 = calloc(nb_panel, sizeof(Panel));
memcpy(panel1, panel_config, sizeof(Panel));
}
// TODO: user can configure layout => ordered objects in panel.area.list
- // clock and systray before taskbar because resize(clock) can resize others object
+ // clock and systray before taskbar because resize(clock) can resize others object ??
init_panel();
init_clock();
- // force the resize
- for (i=0 ; i < nb_panel ; i++) {
- panel1[i].area.resize = 1;
- if (panel1[i].clock.area.visible)
- resize_clock(&panel1[i].clock);
- }
-
init_systray();
init_taskbar();
visible_object();
{
int i;
Panel *p;
+
for (i=0 ; i < nb_panel ; i++) {
p = &panel1[i];
p->area.parent = p;
p->area.panel = p;
p->area.visible = 1;
+ p->area.resize = 1;
p->area._resize = resize_panel;
p->g_taskbar.parent = p;
p->g_taskbar.panel = p;
// add childs
if (p->clock.area.visible)
p->area.list = g_slist_append(p->area.list, &p->clock);
- if (p->systray.area.visible)
- p->area.list = g_slist_append(p->area.list, &p->systray);
+ if (systray.area.visible && i == 0) {
+ // systray only on first panel
+ p->area.list = g_slist_append(p->area.list, &systray);
+ }
// detect panel size
if (p->pourcentx)
else taskbar_on_screen = 1;
taskbar_width = panel->area.width - (2 * panel->area.paddingxlr) - (2 * panel->area.pix.border.width);
- if (panel->clock.area.visible)
+ if (panel->clock.area.visible && panel->clock.area.width)
taskbar_width -= (panel->clock.area.width + panel->area.paddingx);
- if (panel->systray.area.visible)
- taskbar_width -= (panel->systray.area.width + panel->area.paddingx);
+ if (systray.area.visible && systray.area.width)
+ taskbar_width -= (systray.area.width + panel->area.paddingx);
taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel->area.paddingx)) / taskbar_on_screen;
// clock
Clock clock;
- // --------------------------------------------------
- // systray
- Systraybar systray;
-
- // global taskbar parameter
- //Area g_systraybar;
} Panel;
// selection window
Window net_sel_win = None;
+// freedesktop specification doesn't allow multi systray
+Systraybar systray;
+
void init_systray()
{
- Panel *panel;
- Systraybar *sysbar;
- int i, run_systray;
-
cleanup_systray();
- run_systray = 0;
- for (i=0 ; i < nb_panel ; i++) {
- if (panel1[i].systray.area.visible) {
- run_systray = 1;
- break;
- }
- }
- if (run_systray) {
+ Panel *panel = &panel1[0];
+ systray.area.parent = panel;
+ systray.area.panel = panel;
+ systray.area._resize = resize_systray;
+
+ if (systray.area.visible) {
if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != None) {
fprintf(stderr, "tint2 : another systray is running\n");
- run_systray = 0;
+ systray.area.visible = 0;
}
}
- if (run_systray)
- run_systray = net_init();
-
- // configure sysbar on all panels
- for (i=0 ; i < nb_panel ; i++) {
- panel = &panel1[i];
- sysbar = &panel->systray;
-
- if (!run_systray) {
- sysbar->area.visible = 0;
- continue;
- }
- if (!sysbar->area.visible)
- continue;
+ if (systray.area.visible)
+ systray.area.visible = net_init();
- sysbar->area.parent = panel;
- sysbar->area.panel = panel;
+ if (!systray.area.visible)
+ return;
- sysbar->area.posy = panel->area.pix.border.width + panel->area.paddingy;
- sysbar->area.height = panel->area.height - (2 * sysbar->area.posy);
- sysbar->area.width = 100;
+ // configure systray
+ // draw only one systray (even with multi panel)
+ systray.area.posy = panel->area.pix.border.width + panel->area.paddingy;
+ systray.area.height = panel->area.height - (2 * systray.area.posy);
+ systray.area.width = 0;
- sysbar->area.posx = panel->area.width - panel->area.paddingxlr - panel->area.pix.border.width - sysbar->area.width;
- if (panel->clock.area.visible)
- sysbar->area.posx -= (panel->clock.area.width + panel->area.paddingx);
+ systray.area.posx = panel->area.width - panel->area.paddingxlr - panel->area.pix.border.width - systray.area.width;
+ if (panel->clock.area.visible)
+ systray.area.posx -= (panel->clock.area.width + panel->area.paddingx);
- sysbar->area.redraw = 1;
- }
+ systray.area.redraw = 1;
}
void cleanup_systray()
{
- Panel *panel;
- int i;
-
- for (i=0 ; i < nb_panel ; i++) {
- panel = &panel1[i];
- if (!panel->systray.area.visible) continue;
-
- free_area(&panel->systray.area);
- }
+ free_area(&systray.area);
if (net_sel_win != None) {
XDestroyWindow(server.dsp, net_sel_win);
net_sel_win = None;
}
+ if (systray.list_icons) {
+ g_slist_free(systray.list_icons);
+ systray.list_icons = 0;
+ }
}
ev.data.l[2] = net_sel_win;
ev.data.l[3] = 0;
ev.data.l[4] = 0;
- XSendEvent(server.dsp, server.root_win, False, StructureNotifyMask, &ev);
+ XSendEvent(server.dsp, server.root_win, False, StructureNotifyMask, (XEvent*)&ev);
return 1;
}
-int resize_systray (Systraybar *sysbar)
+void resize_systray (void *obj)
{
- return 0;
+ Systraybar *sysbar = obj;
+ Panel *panel = sysbar->area.panel;
+ int count = g_slist_length(systray.list_icons);
+
+ if (!count) systray.area.width = 0;
+ else systray.area.width = 30 * count;
+
+ systray.area.posx = panel->area.width - panel->area.paddingxlr - panel->area.pix.border.width - systray.area.width;
+ if (panel->clock.area.visible)
+ systray.area.posx -= (panel->clock.area.width + panel->area.paddingx);
+
+ systray.area.redraw = 1;
+
+ // resize other objects on panel
+ printf("resize_systray %d %d\n", systray.area.posx, systray.area.width);
}
traywin = g_new0(TrayWindow, 1);
traywin->id = id;
+ systray.list_icons = g_slist_append(systray.list_icons, traywin);
+ printf("ajout d'un icone %d (%lx)\n", g_slist_length(systray.list_icons), id);
+ systray.area.resize = 1;
+
+ // changed in systray force resize on panel
+ Panel *panel = systray.area.panel;
+ panel->area.resize = 1;
+ panel_refresh = 1;
+ return TRUE;
+
if (!icon_swallow(traywin)) {
printf("not icon_swallow\n");
g_free(traywin);
icons = g_slist_append(icons, traywin);
// watch for the icon trying to resize itself!
- XSelectInput(server.dsp, traywin->id, StructureNotifyMask);
+ //XSelectInput(server.dsp, traywin->id, StructureNotifyMask);
// position and size the icon window
XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, icon_size, icon_size);
}
+void icon_remove(TrayWindow *traywin)
+{
+ XErrorHandler old;
+ Window win_id = traywin->id;
+
+ XSelectInput(server.dsp, traywin->id, NoEventMask);
+
+ // remove it from our list
+ systray.list_icons = g_slist_remove(systray.list_icons, traywin);
+ g_free(traywin);
+ printf("suppression d'un icone %d\n", g_slist_length(systray.list_icons));
+ systray.area.resize = 1;
+
+ // changed in systray force resize on panel
+ Panel *panel = systray.area.panel;
+ panel->area.resize = 1;
+ panel_refresh = 1;
+ return;
+
+/*
+ // reparent it to root
+ error = FALSE;
+ old = XSetErrorHandler(window_error_handler);
+ XReparentWindow(server.dsp, win_id, root, 0, 0);
+ XSync(server.dsp, False);
+ XSetErrorHandler(old);
+
+ reposition_icons();
+ fix_geometry();
+ */
+}
+
+
void net_message(XClientMessageEvent *e)
{
unsigned long opcode;
case SYSTEM_TRAY_REQUEST_DOCK:
panel_refresh = 1;
id = e->data.l[2];
- printf("add dockapp\n");
if (id && icon_add(id)) {
XSelectInput(server.dsp, id, StructureNotifyMask);
}
extern Window net_sel_win;
+extern Systraybar systray;
void init_systray();
void cleanup_systray();
int net_init();
void net_message(XClientMessageEvent *e);
+void icon_remove(TrayWindow *traywin);
-// return 1 if task_width changed
-int resize_systray (Systraybar *sysbar);
-
+void resize_systray (void *obj);
#endif
// set global data
memset(&server, 0, sizeof(Server_global));
+ memset(&systray, 0, sizeof(Systraybar));
server.dsp = XOpenDisplay (NULL);
if (!server.dsp) {
void cleanup()
{
cleanup_panel();
+ cleanup_systray();
if (time1_font_desc) pango_font_description_free(time1_font_desc);
if (time2_font_desc) pango_font_description_free(time2_font_desc);
int x11_fd, i, c;
struct timeval tv;
Panel *panel;
+ GSList *it;
c = getopt (argc, argv, "c:");
init ();
case UnmapNotify:
case DestroyNotify:
-// printf("destroy client\n");
- /*
- GSList *it;
- for (it = icons; it; it = g_slist_next(it)) {
+ for (it = systray.list_icons; it; it = g_slist_next(it)) {
if (((TrayWindow*)it->data)->id == e.xany.window) {
- icon_remove(it);
+ icon_remove((TrayWindow*)it->data);
break;
}
- }*/
+ }
break;
case ClientMessage:
if (panel->temp_pmap) XFreePixmap(server.dsp, panel->temp_pmap);
panel->temp_pmap = XCreatePixmap(server.dsp, server.root_win, panel->area.width, panel->area.height, server.depth);
- refresh(panel);
+ refresh(&panel->area);
XCopyArea(server.dsp, panel->temp_pmap, panel->main_win, server.gc, 0, 0, panel->area.width, panel->area.height, 0, 0);
}
XFlush (server.dsp);
#include "server.h"
#include "panel.h"
-
+// 1) resize child
+// 2) resize parent
+// 3) redraw parent
+// 4) redraw child
void refresh (Area *a)
{
if (!a->visible) return;
- if (a->resize) {
- // resize can generate a redraw
- if (a->_resize) {
- //printf("resize area posx %d, width %d\n", a->posx, a->width);
- a->_resize(a);
- }
- a->resize = 0;
- }
+
+ size(a);
if (a->redraw) {
+ a->redraw = 0;
//printf("draw area posx %d, width %d\n", a->posx, a->width);
draw(a, 0);
if (a->use_active)
draw(a, 1);
- a->redraw = 0;
}
// draw current Area
XCopyArea (server.dsp, *pmap, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
// and then refresh child object
- GSList *l = a->list;
- for (; l ; l = l->next)
+ GSList *l;
+ for (l = a->list; l ; l = l->next)
refresh(l->data);
}
+void size (Area *a)
+{
+ GSList *l;
+
+ if (a->resize) {
+ a->resize = 0;
+ for (l = a->list; l ; l = l->next)
+ size(l->data);
+
+ // resize can generate a redraw
+ if (a->_resize) {
+ a->_resize(a);
+ }
+ }
+}
+
+
void set_redraw (Area *a)
{
a->redraw = 1;
typedef struct {
// absolute coordinate in panel
int posx, posy;
+ // width and height including border
int width, height;
Pmap pix;
Pmap pix_active;
// draw background and foreground
void refresh (Area *a);
+void size (Area *a);
+
// set 'redraw' on an area and childs
void set_redraw (Area *a);