systray: reorder operations to prevent the long icon first show delay that occurs sometimes
This commit is contained in:
parent
1ba023fc83
commit
f5b2de62b6
3 changed files with 75 additions and 64 deletions
|
@ -466,6 +466,10 @@ 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);
|
||||||
// printf("add_icon win %lx, %d\n", win, g_slist_length(systray.list_icons));
|
// printf("add_icon win %lx, %d\n", win, g_slist_length(systray.list_icons));
|
||||||
|
|
||||||
|
if (!traywin->hide && !panel->is_hidden)
|
||||||
|
XMapRaised(server.dsp, traywin->parent);
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
systray.area.resize = 1;
|
systray.area.resize = 1;
|
||||||
systray.area.redraw = 1;
|
systray.area.redraw = 1;
|
||||||
|
@ -548,8 +552,13 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||||
if (ret == Success) {
|
if (ret == Success) {
|
||||||
if (data) {
|
if (data) {
|
||||||
if (nbitem == 2) {
|
if (nbitem == 2) {
|
||||||
//hide = ((data[1] & XEMBED_MAPPED) == 0);
|
int hide = ((data[1] & XEMBED_MAPPED) == 0);
|
||||||
//printf("hide %d\n", hide);
|
if (hide) {
|
||||||
|
//fprintf(stderr, "tint2: window refused embedding\n");
|
||||||
|
//remove_icon(traywin);
|
||||||
|
//XFree(data);
|
||||||
|
//return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
|
@ -575,7 +584,7 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||||
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||||
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
|
|
||||||
XFlush(server.dsp);
|
XSync(server.dsp, False);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -647,28 +656,6 @@ void net_message(XClientMessageEvent *e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Display *display = NULL;
|
|
||||||
XImage *tintXGetImage(Window win)
|
|
||||||
{
|
|
||||||
char *display_name = XDisplayName(NULL);
|
|
||||||
if (!display_name)
|
|
||||||
return NULL;
|
|
||||||
if (!display)
|
|
||||||
display = XOpenDisplay(display_name);
|
|
||||||
if (!display)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
unsigned int border_width;
|
|
||||||
int xpos, ypos;
|
|
||||||
unsigned int width, height, depth;
|
|
||||||
Window root;
|
|
||||||
if (!XGetGeometry(display, win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
|
||||||
fprintf(stderr, "Couldn't get geometry of window!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return XGetImage(display, win, 0, 0, width, height, AllPlanes, XYPixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void systray_render_icon_composited(void* t)
|
void systray_render_icon_composited(void* t)
|
||||||
{
|
{
|
||||||
// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
|
// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
|
||||||
|
@ -686,7 +673,7 @@ void systray_render_icon_composited(void* t)
|
||||||
traywin->time_last_render.tv_sec = now.tv_sec;
|
traywin->time_last_render.tv_sec = now.tv_sec;
|
||||||
traywin->time_last_render.tv_nsec = now.tv_nsec;
|
traywin->time_last_render.tv_nsec = now.tv_nsec;
|
||||||
|
|
||||||
if ( traywin->width == 0 || traywin->height == 0 ) {
|
if (traywin->width == 0 || traywin->height == 0) {
|
||||||
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
||||||
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||||
return;
|
return;
|
||||||
|
@ -697,44 +684,21 @@ void systray_render_icon_composited(void* t)
|
||||||
traywin->render_timeout = NULL;
|
traywin->render_timeout = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int empty = 1;
|
{
|
||||||
XImage *ximage = tintXGetImage(traywin->win);
|
unsigned int border_width;
|
||||||
if (ximage) {
|
int xpos, ypos;
|
||||||
if (ximage->width != traywin->width ||
|
unsigned int width, height, depth;
|
||||||
ximage->height != traywin->height) {
|
Window root;
|
||||||
XFree(ximage);
|
if (!XGetGeometry(server.dsp, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
||||||
XCloseDisplay(display);
|
fprintf(stderr, "Couldn't get geometry of window!\n");
|
||||||
display = NULL;
|
return;
|
||||||
|
}
|
||||||
|
if (width != traywin->width || height != traywin->height) {
|
||||||
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
|
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XColor color;
|
|
||||||
if (ximage->width > 0 && ximage->height > 0) {
|
|
||||||
color.pixel = XGetPixel(ximage, ximage->width/2, ximage->height/2);
|
|
||||||
if (color.pixel != 0)
|
|
||||||
empty = 0;
|
|
||||||
int x, y;
|
|
||||||
for (x = 0; empty && x < ximage->width; x++) {
|
|
||||||
for (y = 0; empty && y < ximage->height; y++) {
|
|
||||||
color.pixel = XGetPixel(ximage, x, y);
|
|
||||||
if (color.pixel != 0)
|
|
||||||
empty = 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
XFree(ximage);
|
|
||||||
XCloseDisplay(display);
|
|
||||||
display = NULL;
|
|
||||||
}
|
|
||||||
if (traywin->empty != empty) {
|
|
||||||
traywin->empty = empty;
|
|
||||||
systray.area.resize = 1;
|
|
||||||
panel_refresh = 1;
|
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
|
||||||
}
|
|
||||||
//printf("systray_render_icon_now: %d empty %d\n", traywin->win, empty);
|
|
||||||
if (empty)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -809,6 +773,8 @@ void systray_render_icon_composited(void* t)
|
||||||
if (traywin->depth == 24) {
|
if (traywin->depth == 24) {
|
||||||
createHeuristicMask(data, traywin->width, traywin->height);
|
createHeuristicMask(data, traywin->width, traywin->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int empty = imageEmpty(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, traywin->width, traywin->height, systray.alpha, (float)systray.saturation/100, (float)systray.brightness/100);
|
adjust_asb(data, traywin->width, traywin->height, systray.alpha, (float)systray.saturation/100, (float)systray.brightness/100);
|
||||||
imlib_image_put_back_data(data);
|
imlib_image_put_back_data(data);
|
||||||
|
@ -822,14 +788,19 @@ void systray_render_icon_composited(void* t)
|
||||||
|
|
||||||
if (traywin->damage)
|
if (traywin->damage)
|
||||||
XDamageSubtract(server.dsp, traywin->damage, None, None);
|
XDamageSubtract(server.dsp, traywin->damage, None, None);
|
||||||
XFlush(server.dsp);
|
|
||||||
|
|
||||||
XSync(server.dsp, False);
|
XSync(server.dsp, False);
|
||||||
XSetErrorHandler(old);
|
XSetErrorHandler(old);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
|
if (traywin->empty != empty) {
|
||||||
|
traywin->empty = empty;
|
||||||
|
systray.area.resize = 1;
|
||||||
|
panel_refresh = 1;
|
||||||
|
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
|
@ -847,8 +818,16 @@ on_systray_error:
|
||||||
|
|
||||||
void systray_render_icon(TrayWindow* traywin)
|
void systray_render_icon(TrayWindow* traywin)
|
||||||
{
|
{
|
||||||
|
if (!traywin->reparented) {
|
||||||
if (!reparent_icon(traywin))
|
if (!reparent_icon(traywin))
|
||||||
return;
|
return;
|
||||||
|
if (systray_composited) {
|
||||||
|
// We need to process the events in the main loop first
|
||||||
|
stop_timeout(traywin->render_timeout);
|
||||||
|
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (systray_composited) {
|
if (systray_composited) {
|
||||||
if (!traywin->render_timeout)
|
if (!traywin->render_timeout)
|
||||||
|
|
|
@ -362,6 +362,37 @@ void createHeuristicMask(DATA32* data, int w, int h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pixelEmpty(DATA32 argb)
|
||||||
|
{
|
||||||
|
|
||||||
|
DATA32 a = (argb >> 24) & 0xff;
|
||||||
|
if (a == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
DATA32 rgb = argb & 0xffFFff;
|
||||||
|
return rgb == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int imageEmpty(DATA32* data, int w, int h)
|
||||||
|
{
|
||||||
|
unsigned int x, y;
|
||||||
|
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
x = w / 2;
|
||||||
|
y = h / 2;
|
||||||
|
if (!pixelEmpty(data[y * w + x]))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
if (!pixelEmpty(data[y * w + x]))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void render_image(Drawable d, int x, int y)
|
void render_image(Drawable d, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,6 +62,7 @@ void extract_values (const char *value, char **value1, char **value2, char **val
|
||||||
// alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
// alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
||||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
|
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
|
||||||
void createHeuristicMask(DATA32* data, int w, int h);
|
void createHeuristicMask(DATA32* data, int w, int h);
|
||||||
|
int imageEmpty(DATA32* data, int w, int h);
|
||||||
|
|
||||||
void render_image(Drawable d, int x, int y);
|
void render_image(Drawable d, int x, int y);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue