systray: removed dead code, renamed some variables, added more comments
This commit is contained in:
@@ -45,9 +45,9 @@ GSList *icons;
|
|||||||
Window net_sel_win = None;
|
Window net_sel_win = None;
|
||||||
|
|
||||||
// freedesktop specification doesn't allow multi systray
|
// freedesktop specification doesn't allow multi systray
|
||||||
Systraybar systray;
|
Systray systray;
|
||||||
int refresh_systray;
|
gboolean refresh_systray;
|
||||||
int systray_enabled;
|
gboolean systray_enabled;
|
||||||
int systray_max_icon_size;
|
int systray_max_icon_size;
|
||||||
int systray_monitor;
|
int systray_monitor;
|
||||||
int chrono;
|
int chrono;
|
||||||
@@ -67,7 +67,7 @@ const int max_bad_resize_events = 10;
|
|||||||
void default_systray()
|
void default_systray()
|
||||||
{
|
{
|
||||||
systray_enabled = 0;
|
systray_enabled = 0;
|
||||||
memset(&systray, 0, sizeof(Systraybar));
|
memset(&systray, 0, sizeof(systray));
|
||||||
render_background = 0;
|
render_background = 0;
|
||||||
chrono = 0;
|
chrono = 0;
|
||||||
systray.alpha = 100;
|
systray.alpha = 100;
|
||||||
@@ -116,26 +116,22 @@ void init_systray_panel(void *p)
|
|||||||
if (!systray.area.bg)
|
if (!systray.area.bg)
|
||||||
systray.area.bg = &g_array_index(backgrounds, Background, 0);
|
systray.area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
show(&systray.area);
|
show(&systray.area);
|
||||||
systray.area.resize_needed = 1;
|
|
||||||
panel->area.resize_needed = 1;
|
|
||||||
schedule_redraw(&systray.area);
|
schedule_redraw(&systray.area);
|
||||||
panel_refresh = TRUE;
|
refresh_systray = TRUE;
|
||||||
refresh_systray = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_systray(void *obj)
|
gboolean resize_systray(void *obj)
|
||||||
{
|
{
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
||||||
Systraybar *sysbar = obj;
|
|
||||||
|
|
||||||
if (panel_horizontal)
|
if (panel_horizontal)
|
||||||
sysbar->icon_size = sysbar->area.height;
|
systray.icon_size = systray.area.height;
|
||||||
else
|
else
|
||||||
sysbar->icon_size = sysbar->area.width;
|
systray.icon_size = systray.area.width;
|
||||||
sysbar->icon_size = sysbar->icon_size - (2 * sysbar->area.bg->border.width) - (2 * sysbar->area.paddingy);
|
systray.icon_size -= (2 * systray.area.bg->border.width) + (2 * systray.area.paddingy);
|
||||||
if (systray_max_icon_size > 0 && sysbar->icon_size > systray_max_icon_size)
|
if (systray_max_icon_size > 0)
|
||||||
sysbar->icon_size = systray_max_icon_size;
|
systray.icon_size = MIN(systray.icon_size, systray_max_icon_size);
|
||||||
|
|
||||||
if (systray.icon_size > 0) {
|
if (systray.icon_size > 0) {
|
||||||
long icon_size = systray.icon_size;
|
long icon_size = systray.icon_size;
|
||||||
@@ -151,33 +147,31 @@ gboolean resize_systray(void *obj)
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (GSList *l = systray.list_icons; l; l = l->next) {
|
for (GSList *l = systray.list_icons; l; l = l->next) {
|
||||||
if (((TrayWindow *)l->data)->hide)
|
|
||||||
continue;
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, BLUE "%s:%d number of icons = %d" RESET "\n", __FUNCTION__, __LINE__, count);
|
fprintf(stderr, BLUE "%s:%d number of icons = %d" RESET "\n", __FUNCTION__, __LINE__, count);
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
int height = sysbar->area.height - 2 * sysbar->area.bg->border.width - 2 * sysbar->area.paddingy;
|
int height = systray.area.height - 2 * systray.area.bg->border.width - 2 * systray.area.paddingy;
|
||||||
// here icons_per_column always higher than 0
|
// here icons_per_column always higher than 0
|
||||||
sysbar->icons_per_column = (height + sysbar->area.paddingx) / (sysbar->icon_size + sysbar->area.paddingx);
|
systray.icons_per_column = (height + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx);
|
||||||
sysbar->margin =
|
systray.margin =
|
||||||
height - (sysbar->icons_per_column - 1) * (sysbar->icon_size + sysbar->area.paddingx) - sysbar->icon_size;
|
height - (systray.icons_per_column - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size;
|
||||||
sysbar->icons_per_row = count / sysbar->icons_per_column + (count % sysbar->icons_per_column != 0);
|
systray.icons_per_row = count / systray.icons_per_column + (count % systray.icons_per_column != 0);
|
||||||
systray.area.width = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) +
|
systray.area.width = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) +
|
||||||
(sysbar->icon_size * sysbar->icons_per_row) +
|
(systray.icon_size * systray.icons_per_row) +
|
||||||
((sysbar->icons_per_row - 1) * systray.area.paddingx);
|
((systray.icons_per_row - 1) * systray.area.paddingx);
|
||||||
} else {
|
} else {
|
||||||
int width = sysbar->area.width - 2 * sysbar->area.bg->border.width - 2 * sysbar->area.paddingy;
|
int width = systray.area.width - 2 * systray.area.bg->border.width - 2 * systray.area.paddingy;
|
||||||
// here icons_per_row always higher than 0
|
// here icons_per_row always higher than 0
|
||||||
sysbar->icons_per_row = (width + sysbar->area.paddingx) / (sysbar->icon_size + sysbar->area.paddingx);
|
systray.icons_per_row = (width + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx);
|
||||||
sysbar->margin =
|
systray.margin =
|
||||||
width - (sysbar->icons_per_row - 1) * (sysbar->icon_size + sysbar->area.paddingx) - sysbar->icon_size;
|
width - (systray.icons_per_row - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size;
|
||||||
sysbar->icons_per_column = count / sysbar->icons_per_row + (count % sysbar->icons_per_row != 0);
|
systray.icons_per_column = count / systray.icons_per_row + (count % systray.icons_per_row != 0);
|
||||||
systray.area.height = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) +
|
systray.area.height = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) +
|
||||||
(sysbar->icon_size * sysbar->icons_per_column) +
|
(systray.icon_size * systray.icons_per_column) +
|
||||||
((sysbar->icons_per_column - 1) * systray.area.paddingx);
|
((systray.icons_per_column - 1) * systray.area.paddingx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_sel_win == None) {
|
if (net_sel_win == None) {
|
||||||
@@ -215,15 +209,15 @@ void on_change_systray(void *obj)
|
|||||||
{
|
{
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
||||||
// here, systray.area.posx/posy are defined by rendering engine. so we can calculate position of tray icon.
|
if (systray.icons_per_column == 0 || systray.icons_per_row == 0)
|
||||||
Systraybar *sysbar = obj;
|
|
||||||
if (sysbar->icons_per_column == 0 || sysbar->icons_per_row == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Panel *panel = sysbar->area.panel;
|
// systray.area.posx/posy are computed by rendering engine.
|
||||||
|
// Based on this we calculate the positions of the tray icons.
|
||||||
|
Panel *panel = systray.area.panel;
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
int start = panel->area.bg->border.width + panel->area.paddingy + systray.area.bg->border.width +
|
int start = panel->area.bg->border.width + panel->area.paddingy + systray.area.bg->border.width +
|
||||||
systray.area.paddingy + sysbar->margin / 2;
|
systray.area.paddingy + systray.margin / 2;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
posy = start;
|
posy = start;
|
||||||
posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr;
|
posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr;
|
||||||
@@ -237,8 +231,6 @@ void on_change_systray(void *obj)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 1, l = systray.list_icons; l; i++, l = l->next) {
|
for (i = 1, l = systray.list_icons; l; i++, l = l->next) {
|
||||||
traywin = (TrayWindow *)l->data;
|
traywin = (TrayWindow *)l->data;
|
||||||
if (traywin->hide)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
traywin->y = posy;
|
traywin->y = posy;
|
||||||
traywin->x = posx;
|
traywin->x = posx;
|
||||||
@@ -252,21 +244,21 @@ void on_change_systray(void *obj)
|
|||||||
traywin->parent,
|
traywin->parent,
|
||||||
posx,
|
posx,
|
||||||
posy);
|
posy);
|
||||||
traywin->width = sysbar->icon_size;
|
traywin->width = systray.icon_size;
|
||||||
traywin->height = sysbar->icon_size;
|
traywin->height = systray.icon_size;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (i % sysbar->icons_per_column) {
|
if (i % systray.icons_per_column) {
|
||||||
posy += sysbar->icon_size + sysbar->area.paddingx;
|
posy += systray.icon_size + systray.area.paddingx;
|
||||||
} else {
|
} else {
|
||||||
posy = start;
|
posy = start;
|
||||||
posx += (sysbar->icon_size + systray.area.paddingx);
|
posx += (systray.icon_size + systray.area.paddingx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i % sysbar->icons_per_row) {
|
if (i % systray.icons_per_row) {
|
||||||
posx += sysbar->icon_size + systray.area.paddingx;
|
posx += systray.icon_size + systray.area.paddingx;
|
||||||
} else {
|
} else {
|
||||||
posx = start;
|
posx = start;
|
||||||
posy += (sysbar->icon_size + systray.area.paddingx);
|
posy += (systray.icon_size + systray.area.paddingx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,13 +511,21 @@ void print_icons()
|
|||||||
TrayWindow *t = l->data;
|
TrayWindow *t = l->data;
|
||||||
TrayWindow *u = l->next->data;
|
TrayWindow *u = l->next->data;
|
||||||
int cmp = compare_traywindows(t, u);
|
int cmp = compare_traywindows(t, u);
|
||||||
fprintf(stderr, "%s %s %s\n", t->name, cmp < 0 ? "<" : cmp == 0 ? "=" : ">" , u->name);
|
fprintf(stderr, "%s %s %s\n", t->name, cmp < 0 ? "<" : cmp == 0 ? "=" : ">", u->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean add_icon(Window win)
|
gboolean add_icon(Window win)
|
||||||
{
|
{
|
||||||
|
// Avoid duplicates
|
||||||
|
for (GSList *l = systray.list_icons; l; l = l->next) {
|
||||||
|
TrayWindow *other = (TrayWindow *)l->data;
|
||||||
|
if (other->win == win) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
XTextProperty xname;
|
XTextProperty xname;
|
||||||
char *name;
|
char *name;
|
||||||
if (XGetWMName(server.display, win, &xname)) {
|
if (XGetWMName(server.display, win, &xname)) {
|
||||||
@@ -538,7 +538,6 @@ gboolean add_icon(Window win)
|
|||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, win, name);
|
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, win, name);
|
||||||
Panel *panel = systray.area.panel;
|
Panel *panel = systray.area.panel;
|
||||||
int hide = 0;
|
|
||||||
|
|
||||||
// Get the process ID of the application that created the window
|
// Get the process ID of the application that created the window
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
@@ -566,94 +565,6 @@ gboolean add_icon(Window win)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GSList *l = systray.list_icons; l; l = l->next) {
|
|
||||||
TrayWindow *other = (TrayWindow *)l->data;
|
|
||||||
if (other->win == win) {
|
|
||||||
free(name);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the application leaves behind empty icons
|
|
||||||
int num_empty_same_pid = 0;
|
|
||||||
#if 0
|
|
||||||
for (GSList *l = systray.list_icons; l; l = l->next) {
|
|
||||||
TrayWindow *other = (TrayWindow *)l->data;
|
|
||||||
if (!systray_composited) {
|
|
||||||
// Empty icon detection: we compare the contents of the icon with the contents of the panel pixmap.
|
|
||||||
// If any pixel is different, the icon is not empty.
|
|
||||||
imlib_context_set_visual(server.visual);
|
|
||||||
imlib_context_set_colormap(server.colormap);
|
|
||||||
imlib_context_set_drawable(other->win);
|
|
||||||
Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, other->width, other->height, 1);
|
|
||||||
if (image) {
|
|
||||||
imlib_context_set_drawable(panel->temp_pmap);
|
|
||||||
Imlib_Image bg =
|
|
||||||
imlib_create_image_from_drawable(0, other->x, other->y, other->width, other->height, 1);
|
|
||||||
imlib_context_set_image(bg);
|
|
||||||
DATA32 *data_bg = imlib_image_get_data_for_reading_only();
|
|
||||||
imlib_context_set_image(image);
|
|
||||||
imlib_image_set_has_alpha(other->depth > 24);
|
|
||||||
DATA32 *data = imlib_image_get_data_for_reading_only();
|
|
||||||
int x, y;
|
|
||||||
gboolean empty = TRUE;
|
|
||||||
for (x = 0; x < other->width && empty; x++) {
|
|
||||||
for (y = 0; y < other->height && empty; y++) {
|
|
||||||
DATA32 pixel = data[y * other->width + x];
|
|
||||||
DATA32 a = (pixel >> 24) & 0xff;
|
|
||||||
if (a == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DATA32 rgb = pixel & 0xffFFff;
|
|
||||||
DATA32 pixel_bg = data_bg[y * other->width + x];
|
|
||||||
DATA32 rgb_bg = pixel_bg & 0xffFFff;
|
|
||||||
if (rgb != rgb_bg) {
|
|
||||||
if (systray_profile)
|
|
||||||
fprintf(stderr, "Pixel: %x different from bg %x at pos %d %d\n", pixel, pixel_bg, x, y);
|
|
||||||
empty = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
other->empty = empty;
|
|
||||||
imlib_free_image_and_decache();
|
|
||||||
imlib_context_set_image(bg);
|
|
||||||
imlib_free_image_and_decache();
|
|
||||||
if (systray_profile)
|
|
||||||
fprintf(stderr,
|
|
||||||
"[%f] %s:%d win = %lu (%s) empty = %d\n",
|
|
||||||
profiling_get_time(),
|
|
||||||
__FUNCTION__,
|
|
||||||
__LINE__,
|
|
||||||
other->win,
|
|
||||||
other->name,
|
|
||||||
other->empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pid && other->pid == pid) {
|
|
||||||
if (other->empty)
|
|
||||||
num_empty_same_pid++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove empty icons if the application leaves behind more than 1
|
|
||||||
const int max_num_empty_same_pid = 0;
|
|
||||||
if (num_empty_same_pid > max_num_empty_same_pid) {
|
|
||||||
for (GSList *l = systray.list_icons; l; l = l->next) {
|
|
||||||
if (pid && ((TrayWindow *)l->data)->pid == pid && ((TrayWindow *)l->data)->empty) {
|
|
||||||
num_empty_same_pid++;
|
|
||||||
fprintf(stderr,
|
|
||||||
RED
|
|
||||||
"Removing tray icon %lu (%s) from misbehaving application with pid=%d (too many icons)" RESET "\n",
|
|
||||||
((TrayWindow *)l->data)->win,
|
|
||||||
((TrayWindow *)l->data)->name,
|
|
||||||
pid);
|
|
||||||
remove_icon((TrayWindow *)l->data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Create the parent window that will embed the icon
|
// Create the parent window that will embed the icon
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
@@ -666,11 +577,10 @@ gboolean add_icon(Window win)
|
|||||||
XSetWindowAttributes set_attr;
|
XSetWindowAttributes set_attr;
|
||||||
Visual *visual = server.visual;
|
Visual *visual = server.visual;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
GREEN "add_icon: %lu (%s), pid %d, %d, visual %p, colormap %lu, depth %d, width %d, height %d" RESET "\n",
|
GREEN "add_icon: %lu (%s), pid %d, visual %p, colormap %lu, depth %d, width %d, height %d" RESET "\n",
|
||||||
win,
|
win,
|
||||||
name,
|
name,
|
||||||
pid,
|
pid,
|
||||||
num_empty_same_pid,
|
|
||||||
attr.visual,
|
attr.visual,
|
||||||
attr.colormap,
|
attr.colormap,
|
||||||
attr.depth,
|
attr.depth,
|
||||||
@@ -715,7 +625,6 @@ gboolean add_icon(Window win)
|
|||||||
TrayWindow *traywin = g_new0(TrayWindow, 1);
|
TrayWindow *traywin = g_new0(TrayWindow, 1);
|
||||||
traywin->parent = parent;
|
traywin->parent = parent;
|
||||||
traywin->win = win;
|
traywin->win = win;
|
||||||
traywin->hide = hide;
|
|
||||||
traywin->depth = attr.depth;
|
traywin->depth = attr.depth;
|
||||||
// Reparenting is done at the first paint event when the window is positioned correctly over its empty background,
|
// Reparenting is done at the first paint event when the window is positioned correctly over its empty background,
|
||||||
// to prevent graphical corruptions in icons with fake transparency
|
// to prevent graphical corruptions in icons with fake transparency
|
||||||
@@ -724,7 +633,7 @@ gboolean add_icon(Window win)
|
|||||||
traywin->chrono = chrono;
|
traywin->chrono = chrono;
|
||||||
chrono++;
|
chrono++;
|
||||||
|
|
||||||
if (systray.area.on_screen == 0)
|
if (!systray.area.on_screen)
|
||||||
show(&systray.area);
|
show(&systray.area);
|
||||||
|
|
||||||
if (systray.sort == SYSTRAY_SORT_RIGHT2LEFT)
|
if (systray.sort == SYSTRAY_SORT_RIGHT2LEFT)
|
||||||
@@ -734,7 +643,7 @@ gboolean add_icon(Window win)
|
|||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||||
// print_icons();
|
// print_icons();
|
||||||
|
|
||||||
if (!traywin->hide && !panel->is_hidden) {
|
if (!panel->is_hidden) {
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "XMapRaised(server.display, traywin->parent)\n");
|
fprintf(stderr, "XMapRaised(server.display, traywin->parent)\n");
|
||||||
XMapRaised(server.display, traywin->parent);
|
XMapRaised(server.display, traywin->parent);
|
||||||
@@ -745,11 +654,14 @@ gboolean add_icon(Window win)
|
|||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr,
|
||||||
|
BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
|
||||||
|
profiling_get_time(),
|
||||||
|
__FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
systray.area.resize_needed = TRUE;
|
systray.area.resize_needed = TRUE;
|
||||||
schedule_redraw(&systray.area);
|
|
||||||
panel->area.resize_needed = TRUE;
|
panel->area.resize_needed = TRUE;
|
||||||
panel_refresh = TRUE;
|
schedule_redraw(&systray.area);
|
||||||
refresh_systray = TRUE;
|
refresh_systray = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -779,7 +691,8 @@ gboolean reparent_icon(TrayWindow *traywin)
|
|||||||
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"XMoveResizeWindow(server.display, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = %d)\n",
|
"XMoveResizeWindow(server.display, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = "
|
||||||
|
"%d)\n",
|
||||||
traywin->win,
|
traywin->win,
|
||||||
traywin->width,
|
traywin->width,
|
||||||
traywin->height);
|
traywin->height);
|
||||||
@@ -881,12 +794,10 @@ gboolean embed_icon(TrayWindow *traywin)
|
|||||||
if (hide) {
|
if (hide) {
|
||||||
// In theory we have to check the embedding with this and remove icons that refuse embedding.
|
// In theory we have to check the embedding with this and remove icons that refuse embedding.
|
||||||
// In practice we have no idea when the other application processes the event and accepts the
|
// In practice we have no idea when the other application processes the event and accepts the
|
||||||
// embed
|
// embed so we cannot check now without a race.
|
||||||
// so we cannot check now without a race.
|
|
||||||
// Race can be triggered with PyGtk(2) apps.
|
// Race can be triggered with PyGtk(2) apps.
|
||||||
// We could defer this for later (if we set PropertyChangeMask in XSelectInput we get notified)
|
// We could defer this for later (if we set PropertyChangeMask in XSelectInput we get notified)
|
||||||
// but
|
// but for some reason it breaks transparency for Qt icons. So we don't.
|
||||||
// for some reason it breaks transparency for Qt icons. So we don't.
|
|
||||||
// fprintf(stderr, RED "tint2: window refused embedding" RESET "\n");
|
// fprintf(stderr, RED "tint2: window refused embedding" RESET "\n");
|
||||||
// remove_icon(traywin);
|
// remove_icon(traywin);
|
||||||
// XFree(data);
|
// XFree(data);
|
||||||
@@ -915,12 +826,10 @@ gboolean embed_icon(TrayWindow *traywin)
|
|||||||
XRaiseWindow(server.display, traywin->win);
|
XRaiseWindow(server.display, traywin->win);
|
||||||
|
|
||||||
// Make the icon visible
|
// Make the icon visible
|
||||||
if (!traywin->hide) {
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "XMapWindow(server.display, traywin->win)\n");
|
fprintf(stderr, "XMapWindow(server.display, traywin->win)\n");
|
||||||
XMapWindow(server.display, traywin->win);
|
XMapWindow(server.display, traywin->win);
|
||||||
}
|
if (!panel->is_hidden) {
|
||||||
if (!traywin->hide && !panel->is_hidden) {
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, "XMapRaised(server.display, traywin->parent)\n");
|
fprintf(stderr, "XMapRaised(server.display, traywin->parent)\n");
|
||||||
XMapRaised(server.display, traywin->parent);
|
XMapRaised(server.display, traywin->parent);
|
||||||
@@ -958,8 +867,6 @@ gboolean embed_icon(TrayWindow *traywin)
|
|||||||
|
|
||||||
void remove_icon(TrayWindow *traywin)
|
void remove_icon(TrayWindow *traywin)
|
||||||
{
|
{
|
||||||
// This code causes an X11 I/O error
|
|
||||||
// close(((_XPrivDisplay)server.display)->fd);
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"[%f] %s:%d win = %lu (%s)\n",
|
"[%f] %s:%d win = %lu (%s)\n",
|
||||||
@@ -982,7 +889,6 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
XSync(server.display, False);
|
XSync(server.display, False);
|
||||||
error = FALSE;
|
error = FALSE;
|
||||||
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
||||||
if (!traywin->hide)
|
|
||||||
XUnmapWindow(server.display, traywin->win);
|
XUnmapWindow(server.display, traywin->win);
|
||||||
XReparentWindow(server.display, traywin->win, server.root_win, 0, 0);
|
XReparentWindow(server.display, traywin->win, server.root_win, 0, 0);
|
||||||
XDestroyWindow(server.display, traywin->parent);
|
XDestroyWindow(server.display, traywin->parent);
|
||||||
@@ -1001,8 +907,6 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
for (l = systray.list_icons; l; l = l->next) {
|
||||||
if (((TrayWindow *)l->data)->hide)
|
|
||||||
continue;
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
@@ -1010,18 +914,19 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr,
|
||||||
|
BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
|
||||||
|
profiling_get_time(),
|
||||||
|
__FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
systray.area.resize_needed = TRUE;
|
systray.area.resize_needed = TRUE;
|
||||||
schedule_redraw(&systray.area);
|
|
||||||
panel->area.resize_needed = TRUE;
|
panel->area.resize_needed = TRUE;
|
||||||
panel_refresh = TRUE;
|
schedule_redraw(&systray.area);
|
||||||
refresh_systray = TRUE;
|
refresh_systray = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void systray_resize_icon(void *t)
|
void systray_resize_icon(void *t)
|
||||||
{
|
{
|
||||||
// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
|
|
||||||
// we made also sure, that we always have a 32 bit visual, i.e. we can safely create 32 bit pixmaps here
|
|
||||||
TrayWindow *traywin = t;
|
TrayWindow *traywin = t;
|
||||||
|
|
||||||
unsigned int border_width;
|
unsigned int border_width;
|
||||||
@@ -1031,17 +936,17 @@ void systray_resize_icon(void *t)
|
|||||||
if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (1 || xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"XMoveResizeWindow(server.display, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height "
|
"systray_resize_icon win = %ld, w = %d, h = %d\n",
|
||||||
"= %d)\n",
|
|
||||||
traywin->win,
|
traywin->win,
|
||||||
traywin->width,
|
traywin->width,
|
||||||
traywin->height);
|
traywin->height);
|
||||||
|
// This is the obvious thing to do but GTK tray icons do not respect the new size
|
||||||
if (0) {
|
if (0) {
|
||||||
XMoveResizeWindow(server.display, traywin->win, 0, 0, traywin->width, traywin->height);
|
XMoveResizeWindow(server.display, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
}
|
}
|
||||||
|
// This is similar but GTK tray icons still do not respect the new size
|
||||||
if (0) {
|
if (0) {
|
||||||
XWindowChanges changes;
|
XWindowChanges changes;
|
||||||
changes.x = changes.y = 0;
|
changes.x = changes.y = 0;
|
||||||
@@ -1049,6 +954,8 @@ void systray_resize_icon(void *t)
|
|||||||
changes.height = traywin->height;
|
changes.height = traywin->height;
|
||||||
XConfigureWindow(server.display, traywin->win, CWX | CWY | CWWidth | CWHeight, &changes);
|
XConfigureWindow(server.display, traywin->win, CWX | CWY | CWWidth | CWHeight, &changes);
|
||||||
}
|
}
|
||||||
|
// This is what WMs send to windows to resize them, the new size must not be ignored.
|
||||||
|
// A bit brutal but works with GTK and everything else.
|
||||||
if (1) {
|
if (1) {
|
||||||
XConfigureEvent ev;
|
XConfigureEvent ev;
|
||||||
ev.type = ConfigureNotify;
|
ev.type = ConfigureNotify;
|
||||||
@@ -1067,7 +974,6 @@ void systray_resize_icon(void *t)
|
|||||||
}
|
}
|
||||||
XSync(server.display, False);
|
XSync(server.display, False);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
||||||
@@ -1131,9 +1037,13 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
|||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr,
|
||||||
|
BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
|
||||||
|
profiling_get_time(),
|
||||||
|
__FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
refresh_systray = 1;
|
refresh_systray = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void systray_property_notify(TrayWindow *traywin, XEvent *e)
|
void systray_property_notify(TrayWindow *traywin, XEvent *e)
|
||||||
@@ -1150,8 +1060,7 @@ void systray_property_notify(TrayWindow *traywin, XEvent *e)
|
|||||||
traywin->name = strdup("");
|
traywin->name = strdup("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
|
if (systray.sort == SYSTRAY_SORT_ASCENDING || systray.sort == SYSTRAY_SORT_DESCENDING) {
|
||||||
systray.sort == SYSTRAY_SORT_DESCENDING) {
|
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||||
// print_icons();
|
// print_icons();
|
||||||
}
|
}
|
||||||
@@ -1201,9 +1110,8 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
|||||||
traywin->name);
|
traywin->name);
|
||||||
}
|
}
|
||||||
// Delayed resize
|
// Delayed resize
|
||||||
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
|
// FIXME Normally we should force the icon to resize to the size we resized it to when we embedded it.
|
||||||
// embedded it.
|
// However this triggers a resize loop in some versions of GTK, which we must avoid.
|
||||||
// However this triggers a resize loop in new versions of GTK, which we must avoid.
|
|
||||||
if (!traywin->resize_timeout)
|
if (!traywin->resize_timeout)
|
||||||
traywin->resize_timeout =
|
traywin->resize_timeout =
|
||||||
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||||
@@ -1216,9 +1124,13 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
|||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
fprintf(stderr,
|
||||||
|
BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
|
||||||
|
profiling_get_time(),
|
||||||
|
__FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
refresh_systray = 1;
|
refresh_systray = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void systray_destroy_event(TrayWindow *traywin)
|
void systray_destroy_event(TrayWindow *traywin)
|
||||||
@@ -1315,7 +1227,6 @@ void systray_render_icon_composited(void *t)
|
|||||||
// good systray icons support 32 bit depth, but some icons are still 24 bit.
|
// good systray icons support 32 bit depth, but some icons are still 24 bit.
|
||||||
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
|
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
|
||||||
// mask out all pixel with the same rgb value
|
// mask out all pixel with the same rgb value
|
||||||
Panel *panel = systray.area.panel;
|
|
||||||
|
|
||||||
// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself,
|
// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself,
|
||||||
// so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as
|
// so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as
|
||||||
@@ -1407,7 +1318,6 @@ void systray_render_icon_composited(void *t)
|
|||||||
create_heuristic_mask(data, traywin->width, traywin->height);
|
create_heuristic_mask(data, traywin->width, traywin->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean empty = FALSE; //image_empty(data, traywin->width, traywin->height);
|
|
||||||
if (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)
|
if (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)
|
||||||
adjust_asb(data,
|
adjust_asb(data,
|
||||||
traywin->width,
|
traywin->width,
|
||||||
@@ -1427,23 +1337,6 @@ void systray_render_icon_composited(void *t)
|
|||||||
if (error)
|
if (error)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
if (traywin->empty != empty) {
|
|
||||||
traywin->empty = empty;
|
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
|
||||||
// print_icons();
|
|
||||||
// Resize and redraw the systray
|
|
||||||
if (systray_profile)
|
|
||||||
fprintf(stderr,
|
|
||||||
BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
|
|
||||||
profiling_get_time(),
|
|
||||||
__FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
systray.area.resize_needed = 1;
|
|
||||||
schedule_redraw(&systray.area);
|
|
||||||
panel->area.resize_needed = 1;
|
|
||||||
panel_refresh = TRUE;
|
|
||||||
refresh_systray = 1;
|
|
||||||
}
|
|
||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
@@ -1573,16 +1466,14 @@ void refresh_systray_icons()
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
for (l = systray.list_icons; l; l = l->next) {
|
||||||
traywin = (TrayWindow *)l->data;
|
traywin = (TrayWindow *)l->data;
|
||||||
if (traywin->hide)
|
|
||||||
continue;
|
|
||||||
systray_render_icon(traywin);
|
systray_render_icon(traywin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean systray_on_monitor(int i_monitor, int num_panelss)
|
gboolean systray_on_monitor(int i_monitor, int num_panels)
|
||||||
{
|
{
|
||||||
return (i_monitor == systray_monitor) ||
|
return (i_monitor == systray_monitor) ||
|
||||||
(i_monitor == 0 && (systray_monitor >= num_panelss || systray_monitor < 0));
|
(i_monitor == 0 && (systray_monitor >= num_panels || systray_monitor < 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrayWindow *systray_find_icon(Window win)
|
TrayWindow *systray_find_icon(Window win)
|
||||||
|
|||||||
@@ -35,35 +35,41 @@ typedef struct {
|
|||||||
SystraySortMethod sort;
|
SystraySortMethod sort;
|
||||||
int alpha, saturation, brightness;
|
int alpha, saturation, brightness;
|
||||||
int icon_size, icons_per_column, icons_per_row, margin;
|
int icon_size, icons_per_column, icons_per_row, margin;
|
||||||
} Systraybar;
|
} Systray;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Window parent;
|
// The actual tray icon window (created by the application)
|
||||||
Window win;
|
Window win;
|
||||||
|
// The parent window created by tint2 to embed the icon
|
||||||
|
Window parent;
|
||||||
int x, y;
|
int x, y;
|
||||||
int width, height;
|
int width, height;
|
||||||
// TODO: manage icon's show/hide
|
|
||||||
gboolean hide;
|
|
||||||
int depth;
|
int depth;
|
||||||
Damage damage;
|
|
||||||
timeout *render_timeout;
|
|
||||||
gboolean empty;
|
|
||||||
int pid;
|
|
||||||
int chrono;
|
|
||||||
struct timespec time_last_render;
|
|
||||||
int num_fast_renders;
|
|
||||||
gboolean reparented;
|
gboolean reparented;
|
||||||
gboolean embedded;
|
gboolean embedded;
|
||||||
int bad_size_counter;
|
// Process PID or zero.
|
||||||
timeout *resize_timeout;
|
int pid;
|
||||||
struct timespec time_last_resize;
|
// A number that is incremented for each new icon, used to sort them by the order in which they were created.
|
||||||
|
int chrono;
|
||||||
|
// Name of the tray icon window.
|
||||||
char *name;
|
char *name;
|
||||||
|
// Members used for rendering
|
||||||
|
struct timespec time_last_render;
|
||||||
|
int num_fast_renders;
|
||||||
|
timeout *render_timeout;
|
||||||
|
// Members used for resizing
|
||||||
|
int bad_size_counter;
|
||||||
|
struct timespec time_last_resize;
|
||||||
|
timeout *resize_timeout;
|
||||||
|
// Icon contents if we are compositing the icon, otherwise null
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
|
// XDamage
|
||||||
|
Damage damage;
|
||||||
} TrayWindow;
|
} TrayWindow;
|
||||||
|
|
||||||
// net_sel_win != None when protocol started
|
// net_sel_win != None when protocol started
|
||||||
extern Window net_sel_win;
|
extern Window net_sel_win;
|
||||||
extern Systraybar systray;
|
extern Systray systray;
|
||||||
extern gboolean refresh_systray;
|
extern gboolean refresh_systray;
|
||||||
extern gboolean systray_enabled;
|
extern gboolean systray_enabled;
|
||||||
extern int systray_max_icon_size;
|
extern int systray_max_icon_size;
|
||||||
@@ -83,7 +89,7 @@ void init_systray_panel(void *p);
|
|||||||
void draw_systray(void *obj, cairo_t *c);
|
void draw_systray(void *obj, cairo_t *c);
|
||||||
gboolean resize_systray(void *obj);
|
gboolean resize_systray(void *obj);
|
||||||
void on_change_systray(void *obj);
|
void on_change_systray(void *obj);
|
||||||
gboolean systray_on_monitor(int i_monitor, int num_panelss);
|
gboolean systray_on_monitor(int i_monitor, int num_panels);
|
||||||
|
|
||||||
// systray protocol
|
// systray protocol
|
||||||
// many tray icon doesn't manage stop/restart of the systray manager
|
// many tray icon doesn't manage stop/restart of the systray manager
|
||||||
|
|||||||
Reference in New Issue
Block a user