tint2 is developped by :
-- 2008 Thierry Lorthiois <lorthiois@bbsoft.fr>, project maintainer
+- 2008-2009 Thierry Lorthiois <lorthiois@bbsoft.fr>, project maintainer
tint2 is based on ttm source code (http://code.google.com/p/ttm/)
-- 2007 Pål Staurland <staura@gmail.com>
+- 2007-2008 Pål Staurland <staura@gmail.com>
Contributors:
+ Kwaku Yeboah <kwakuyeboah@gmail.com> : wiki page
Daniel Moerner <dmoerner@gmail.com> : man page and debian package
Doug Barton : freebsd package
James Buren <ryuo@frugalware.org> : Frugalware package
Pierre-Emmanuel Andre <pea@raveland.org> : openbsd port
Redroar : arch package
-
-
+
+
else new_width = date_width;
new_width += (2*clock->area.paddingxlr) + (2*clock->area.pix.border.width);
- if (new_width > clock->area.width || new_width < (clock->area.width-3)) {
+ if (new_width > clock->area.width || new_width < (clock->area.width-6)) {
int i;
Panel *panel = ((Area*)obj)->panel;
- //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;
+ // we try to limit the number of resize
+ clock->area.width = new_width + 1;
clock->area.posx = panel->area.width - clock->area.width - panel->area.paddingxlr - panel->area.pix.border.width;
// resize other objects on panel
}
else
- fprintf(stderr, "Invalid option: \"%s\", correct your config file\n", key);
+ fprintf(stderr, "tint2 : invalid option \"%s\", correct your config file\n", key);
if (value1) free (value1);
if (value2) free (value2);
int config_read ()
{
const gchar * const * system_dirs;
- char *path1, *path2, *dir;
+ char *path1;
gint i;
save_file_config = 0;
+ // follow XDG specification
deb:
- // check tint2rc file according to XDG specification
+ // check tint2rc in user directory
path1 = g_build_filename (g_get_user_config_dir(), "tint2", "tint2rc", NULL);
- if (!g_file_test (path1, G_FILE_TEST_EXISTS)) {
+ if (g_file_test (path1, G_FILE_TEST_EXISTS)) {
+ i = config_read_file (path1);
+ g_free(path1);
+ return i;
+ }
- if (save_file_config) {
- fprintf(stderr, "tint2 error : enable to write $HOME/.config/tint2/tint2rc\n");
- exit(0);
- }
- // check old tintrc config file
- path1 = g_build_filename (g_get_user_config_dir(), "tint", "tintrc", NULL);
- if (g_file_test (path1, G_FILE_TEST_EXISTS)) {
- save_file_config = 1;
- old_task_font = 0;
- old_time1_font = 0;
- old_time2_font = 0;
- config_read_file (path1);
- save_config();
- if (old_task_font) g_free(old_task_font);
- if (old_time1_font) g_free(old_time1_font);
- if (old_time2_font) g_free(old_time2_font);
- goto deb;
- }
- else {
- path2 = 0;
- system_dirs = g_get_system_config_dirs();
- for (i = 0; system_dirs[i]; i++) {
- path2 = g_build_filename(system_dirs[i], "tint2", "tint2rc", NULL);
-
- if (g_file_test(path2, G_FILE_TEST_EXISTS)) break;
- g_free (path2);
- path2 = 0;
- }
+ g_free(path1);
+ if (save_file_config) {
+ fprintf(stderr, "tint2 exit : enable to write $HOME/.config/tint2/tint2rc\n");
+ exit(0);
+ }
+
+ // check old tintrc config file
+ path1 = g_build_filename (g_get_user_config_dir(), "tint", "tintrc", NULL);
+ if (g_file_test (path1, G_FILE_TEST_EXISTS)) {
+ save_file_config = 1;
+ old_task_font = 0;
+ old_time1_font = 0;
+ old_time2_font = 0;
+ config_read_file (path1);
+ save_config();
+ if (old_task_font) g_free(old_task_font);
+ if (old_time1_font) g_free(old_time1_font);
+ if (old_time2_font) g_free(old_time2_font);
+ g_free(path1);
+ goto deb;
+ }
- if (path2) {
- // copy file in user directory (path1)
- dir = g_build_filename (g_get_user_config_dir(), "tint2", NULL);
- if (!g_file_test (dir, G_FILE_TEST_IS_DIR)) g_mkdir(dir, 0777);
- g_free(dir);
+ // copy tint2rc from system directory to user directory
+ g_free(path1);
+ char *path2 = 0;
+ system_dirs = g_get_system_config_dirs();
+ for (i = 0; system_dirs[i]; i++) {
+ path2 = g_build_filename(system_dirs[i], "tint2", "tint2rc", NULL);
- copy_file(path2, path1);
- g_free(path2);
- }
- }
- }
+ if (g_file_test(path2, G_FILE_TEST_EXISTS)) break;
+ g_free (path2);
+ path2 = 0;
+ }
+
+ if (path2) {
+ // copy file in user directory (path1)
+ char *dir = g_build_filename (g_get_user_config_dir(), "tint2", NULL);
+ if (!g_file_test (dir, G_FILE_TEST_IS_DIR)) g_mkdir(dir, 0777);
+ g_free(dir);
- i = config_read_file (path1);
- g_free(path1);
+ path1 = g_build_filename (g_get_user_config_dir(), "tint2", "tint2rc", NULL);
+ copy_file(path2, path1);
+ g_free(path2);
- return i;
+ i = config_read_file (path1);
+ g_free(path1);
+ return i;
+ }
+ return 0;
}
void save_config ()
{
- fprintf(stderr, "tint2 warning : convert user's config file tintrc to tint2rc\n");
+ fprintf(stderr, "tint2 : convert user's config file tintrc to tint2rc\n");
char *path, *dir;
FILE *fp;
server.atom._NET_WM_STATE_SKIP_PAGER = XInternAtom (server.dsp, "_NET_WM_STATE_SKIP_PAGER", False);
server.atom._NET_WM_STATE_SKIP_TASKBAR = XInternAtom (server.dsp, "_NET_WM_STATE_SKIP_TASKBAR", False);
server.atom._NET_WM_STATE_STICKY = XInternAtom (server.dsp, "_NET_WM_STATE_STICKY", False);
+ server.atom._NET_WM_STATE_DEMANDS_ATTENTION = XInternAtom (server.dsp, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
server.atom._NET_WM_WINDOW_TYPE_DOCK = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_DOCK", False);
server.atom._NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
server.atom._NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
server.atom._NET_SYSTEM_TRAY_OPCODE = XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_OPCODE", False);
server.atom.MANAGER = XInternAtom(server.dsp, "MANAGER", False);
server.atom._NET_SYSTEM_TRAY_MESSAGE_DATA = XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
+ server.atom._NET_SYSTEM_TRAY_ORIENTATION = XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_ORIENTATION", False);
}
server.root_pmap = ret;
if (server.root_pmap == None)
- fprintf(stderr, "pixmap background detection failed\n");
+ fprintf(stderr, "tint2 : pixmap background detection failed\n");
else {
XGCValues gcv;
gcv.ts_x_origin = 0;
}
if (server.nb_desktop == 0) {
server.nb_desktop = 1;
- fprintf(stderr, "tint2 warning : cannot found number of desktop.\n");
+ fprintf(stderr, "tint2 : cannot found number of desktop.\n");
}
- fprintf(stderr, "nb monitor %d, nb desktop %d\n", server.nb_monitor, server.nb_desktop);
+ fprintf(stderr, "tint2 : nb monitor %d, nb desktop %d\n", server.nb_monitor, server.nb_desktop);
}
Atom _NET_WM_STATE_SKIP_PAGER;
Atom _NET_WM_STATE_SKIP_TASKBAR;
Atom _NET_WM_STATE_STICKY;
+ Atom _NET_WM_STATE_DEMANDS_ATTENTION;
Atom _NET_WM_WINDOW_TYPE_DOCK;
Atom _NET_WM_WINDOW_TYPE_DESKTOP;
Atom _NET_WM_WINDOW_TYPE_TOOLBAR;
Atom _NET_SYSTEM_TRAY_OPCODE;
Atom MANAGER;
Atom _NET_SYSTEM_TRAY_MESSAGE_DATA;
+ Atom _NET_SYSTEM_TRAY_ORIENTATION;
} Global_atom;
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+// selection window
Window net_sel_win = None;
}
if (run_systray) {
if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != None) {
- fprintf(stderr, "tint2 warning : another systray is running\n");
+ fprintf(stderr, "tint2 : another systray is running\n");
run_systray = 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;
}
+int net_init()
+{
+ // init systray protocol
+ net_sel_win = XCreateSimpleWindow(server.dsp, server.root_win, -1, -1, 1, 1, 0, 0, 0);
+
+ // v0.2 trayer specification. tint2 always orizontal.
+ int orient = 0;
+ XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ORIENTATION, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &orient, 1);
+
+ XSetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN, net_sel_win, CurrentTime);
+ if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != net_sel_win) {
+ fprintf(stderr, "tint2 : can't get systray manager\n");
+ return 0;
+ }
+
+ XClientMessageEvent ev;
+ ev.type = ClientMessage;
+ ev.window = server.root_win;
+ ev.message_type = server.atom.MANAGER;
+ ev.format = 32;
+ ev.data.l[0] = CurrentTime;
+ ev.data.l[1] = server.atom._NET_SYSTEM_TRAY_SCREEN;
+ 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);
+
+ return 1;
+}
+
+
int resize_systray (Systraybar *sysbar)
{
return 0;
{
GSList *it;
- //* find the proper width and height
+ // find the proper width and height
width = 0;
height = icon_size;
for (it = icons; it != NULL; it = g_slist_next(it)) {
// The traywin must have its id and type set.
gboolean icon_add(Window id)
{
- TrayWindow *traywin;
+ TrayWindow *traywin;
- traywin = g_new0(TrayWindow, 1);
- traywin->id = id;
+ traywin = g_new0(TrayWindow, 1);
+ traywin->id = id;
- if (!icon_swallow(traywin)) {
- g_free(traywin);
- return FALSE;
- }
+ if (!icon_swallow(traywin)) {
+ printf("not icon_swallow\n");
+ g_free(traywin);
+ return FALSE;
+ }
- // find the positon for the systray app window
+ // find the positon for the systray app window
int count = g_slist_length(icons);
traywin->x = border + ((width % icon_size) / 2) +
(count % (width / icon_size)) * icon_size;
traywin->y = border + ((height % icon_size) / 2) +
(count / (height / icon_size)) * icon_size;
- // add the new icon to the list
- icons = g_slist_append(icons, traywin);
-
- // watch for the icon trying to resize itself!
- XSelectInput(server.dsp, traywin->id, StructureNotifyMask);
+ // add the new icon to the list
+ icons = g_slist_append(icons, traywin);
- // position and size the icon window
- XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, icon_size, icon_size);
+ // watch for the icon trying to resize itself!
+ XSelectInput(server.dsp, traywin->id, StructureNotifyMask);
- // resize our window so that the new window can fit in it
- fix_geometry();
+ // position and size the icon window
+ XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, icon_size, icon_size);
- // flush before clearing, otherwise the clear isn't effective.
- XFlush(server.dsp);
- // make sure the new child will get the right stuff in its background
- // for ParentRelative.
- XClearWindow(server.dsp, win);
+ // resize our window so that the new window can fit in it
+ fix_geometry();
- // show the window
- XMapRaised(server.dsp, traywin->id);
+ // flush before clearing, otherwise the clear isn't effective.
+ XFlush(server.dsp);
+ // make sure the new child will get the right stuff in its background
+ // for ParentRelative.
+ XClearWindow(server.dsp, win);
- return TRUE;
-}
-
-
-int net_init()
-{
- // init systray protocol
- net_sel_win = XCreateSimpleWindow(server.dsp, server.root_win, -1, -1, 1, 1, 0, 0, 0);
+ // show the window
+ XMapRaised(server.dsp, traywin->id);
- XSetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN, net_sel_win, CurrentTime);
- if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != net_sel_win) {
- fprintf(stderr, "tint2 warning : can't get systray manager\n");
- return 0;
- }
-
- XEvent m;
- m.type = ClientMessage;
- m.xclient.message_type = server.atom.MANAGER;
- m.xclient.format = 32;
- m.xclient.data.l[0] = CurrentTime;
- m.xclient.data.l[1] = server.atom._NET_SYSTEM_TRAY_SCREEN;
- m.xclient.data.l[2] = net_sel_win;
- m.xclient.data.l[3] = 0;
- m.xclient.data.l[4] = 0;
- XSendEvent(server.dsp, server.root_win, False, StructureNotifyMask, &m);
- return 1;
+ return TRUE;
}
void net_message(XClientMessageEvent *e)
{
- unsigned long opcode;
- Window id;
-
- opcode = e->data.l[1];
-
- switch (opcode)
- {
- case SYSTEM_TRAY_REQUEST_DOCK: /* dock a new icon */
- id = e->data.l[2];
- if (id && icon_add(id))
- XSelectInput(server.dsp, id, StructureNotifyMask);
- break;
-
- case SYSTEM_TRAY_BEGIN_MESSAGE:
- //g_printerr("Message From Dockapp\n");
- id = e->window;
- break;
-
- case SYSTEM_TRAY_CANCEL_MESSAGE:
- //g_printerr("Message Cancelled\n");
- id = e->window;
- break;
-
- default:
- if (opcode == server.atom._NET_SYSTEM_TRAY_MESSAGE_DATA) {
- //g_printerr("Text For Message From Dockapp:\n%s\n", e->data.b);
- id = e->window;
- break;
- }
-
- /* unknown message type. not in the spec. */
- //g_printerr("Warning: Received unknown client message to System Tray selection window.\n");
- break;
- }
+ unsigned long opcode;
+ Window id;
+
+ opcode = e->data.l[1];
+
+ switch (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);
+ }
+ break;
+
+ case SYSTEM_TRAY_BEGIN_MESSAGE:
+ //g_printerr("Message From Dockapp\n");
+ id = e->window;
+ break;
+
+ case SYSTEM_TRAY_CANCEL_MESSAGE:
+ //g_printerr("Message Cancelled\n");
+ id = e->window;
+ break;
+
+ default:
+ if (opcode == server.atom._NET_SYSTEM_TRAY_MESSAGE_DATA) {
+ printf("message from dockapp:\n %s\n", e->data.b);
+ id = e->window;
+ }
+ // unknown message type. not in the spec
+ break;
+ }
}
* Copyright (C) 2009 thierry lorthiois (lorthiois@bbsoft.fr)
*
* systraybar
+* based on 'docker-1.5' from Ben Jansens
*
**************************************************************************/
#ifndef SYSTRAYBAR_H
#define SYSTRAYBAR_H
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
#include "area.h"
// always start with area
Area area;
+ GSList *list_icons;
} Systraybar;
{
Window id;
int x, y;
+ int width, height;
- Window win;
long *icon_data;
- int icon_width;
- int icon_height;
} TrayWindow;
+extern Window net_sel_win;
+
+
void init_systray();
void cleanup_systray();
-int net_init();
+int net_init();
+void net_message(XClientMessageEvent *e);
// return 1 if task_width changed
int resize_systray (Systraybar *sysbar);
pango_layout_set_text (layout, tsk->title, -1);
/* Drawing width and Cut text */
+ // pango use U+22EF or U+2026
pango_layout_set_width (layout, ((Taskbar*)tsk->area.parent)->text_width * PANGO_SCALE);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
server.dsp = XOpenDisplay (NULL);
if (!server.dsp) {
- fprintf(stderr, "Could not open display.\n");
+ fprintf(stderr, "tint2 exit : could not open display.\n");
exit(0);
}
server_init_atoms ();
}
-void event_property_notify (Window win, Atom at)
+void event_property_notify (XEvent *e)
{
int i, j;
Task *tsk;
+ Window win = e->xproperty.window;
+ Atom at = e->xproperty.atom;
if (win == server.root_win) {
if (!server.got_root_win) {
server.got_root_win = 1;
}
- /* Change number of desktops */
+ // Change number of desktops
else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) {
server.nb_desktop = server_get_number_of_desktop ();
cleanup_taskbar();
task_refresh_tasklist();
panel_refresh = 1;
}
- /* Change desktop */
+ // Change desktop
else if (at == server.atom._NET_CURRENT_DESKTOP) {
server.desktop = server_get_current_desktop ();
if (panel_mode != MULTI_DESKTOP) {
visible_object();
}
}
- /* Window list */
+ // Window list
else if (at == server.atom._NET_CLIENT_LIST) {
task_refresh_tasklist();
panel_refresh = 1;
}
- /* Change active */
+ // Change active
else if (at == server.atom._NET_ACTIVE_WINDOW) {
GSList *l0;
if (task_active) {
}
panel_refresh = 1;
}
- /* Wallpaper changed */
+ // Wallpaper changed
else if (at == server.atom._XROOTPMAP_ID) {
for (i=0 ; i < nb_panel ; i++) {
set_panel_background(&panel1[i]);
if (!tsk) return;
//printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
- /* Window title changed */
+ // Window title changed
if (at == server.atom._NET_WM_VISIBLE_NAME || at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) {
Task *tsk2;
GSList *l0;
}
panel_refresh = 1;
}
- /* Iconic state */
+ // Demand attention
+ else if (at == server.atom._NET_WM_STATE) {
+ if (window_is_urgent (win)) {
+ printf(" event_property_notify _NET_WM_STATE_DEMANDS_ATTENTION\n");
+ }
+ else {
+ }
+ }
else if (at == server.atom.WM_STATE) {
- if (window_is_iconified (win))
+ // Iconic state
+ // TODO : try to delete following code
+ if (window_is_iconified (win)) {
if (task_active) {
if (task_active->win == tsk->win) {
Task *tsk2;
task_active = 0;
}
}
- }
- /* Window icon changed */
+ }
+ }
+ // Window icon changed
else if (at == server.atom._NET_WM_ICON) {
get_icon(tsk);
Task *tsk2;
}
panel_refresh = 1;
}
- /* Window desktop changed */
+ // Window desktop changed
else if (at == server.atom._NET_WM_DESKTOP) {
remove_task (tsk);
add_task (win);
break;
case PropertyNotify:
- event_property_notify (e.xproperty.window, e.xproperty.atom);
+ event_property_notify (&e);
break;
case ConfigureNotify:
case UnmapNotify:
case DestroyNotify:
+// printf("destroy client\n");
/*
GSList *it;
for (it = icons; it; it = g_slist_next(it)) {
break;
case ClientMessage:
- break;
- if (e.xclient.message_type == server.atom._NET_SYSTEM_TRAY_OPCODE && e.xclient.format == 32)
- // && e.xclient.window == net_sel_win)
+ //printf("ClientMessage\n");
+ if (e.xclient.message_type == server.atom._NET_SYSTEM_TRAY_OPCODE && e.xclient.format == 32 && e.xclient.window == net_sel_win) {
net_message(&e.xclient);
+ }
break;
}
}
}
+int window_is_urgent (Window win)
+{
+ Atom *at;
+ int count, i;
+
+ at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
+ for (i = 0; i < count; i++) {
+ if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
+ XFree(at);
+ return 1;
+ }
+ }
+ XFree(at);
+ return 0;
+}
+
+
int server_get_number_of_desktop ()
{
return get_property32(server.root_win, server.atom._NET_NUMBER_OF_DESKTOPS, XA_CARDINAL);
int server_get_current_desktop ();
int server_get_number_of_desktop ();
int window_is_iconified (Window win);
+int window_is_urgent (Window win);
int window_is_hidden (Window win);
int window_is_active (Window win);
int get_icon_count (long *data, int num);
#---------------------------------------------
panel_monitor = all
panel_position = bottom center
-panel_size = 88% 28
+panel_size = 90% 28
panel_margin = 0 0
panel_padding = 7 0
font_shadow = 0
panel_position = bottom center
panel_size = 92% 30
panel_margin = 0 0
-panel_padding = 7 3
+panel_padding = 7 3 7
font_shadow = 0
panel_background_id = 1
#---------------------------------------------
# TASKBAR
#---------------------------------------------
+#taskbar_mode = single_desktop
+#taskbar_mode = single_monitor
taskbar_mode = multi_desktop
taskbar_padding = 0 0 0
taskbar_background_id = 2
task_background_id = 0
task_active_background_id = 3
+#---------------------------------------------
+# SYSTRAYBAR
+#---------------------------------------------
+systray_padding = 4 2 2
+systray_background_id = 2
+
#---------------------------------------------
# CLOCK
#---------------------------------------------