Re: Problem setting icon for Gtk2::StatusIcon



On Mon, 2009-03-02 at 13:33 +0100, January Weiner wrote:
Hello,

I am trying to add a small notification feature for a program that I
wrote. This program runs in background and at regular intervals does
something. I have added a Gtk2::StatusIcon to let the user know what
is going on. The idea is that the icon changes when the program starts
doing its job.

I use Gtk2::StatusIcon->new_from_stock( 'gtk-apply' ) to set the initial icon.
I use $icon->set_from_stock( 'gtk-refresh' ) to change the icon when
the program is working. After calling set_from_stock, I run the
following to make sure that the icon is properly displayed:

while( Gtk2->events_pending() ) { Gtk2->main_iterate() ; }

Problem:
  1) when the icon is changed, the icon first disappears completely
from the notification area, and then it appears again. Throughout this
process, the notification area "flickers" (adapts to the removed /
inserted icon).
  2) sometimes the second (gtk-refresh) icon is not displayed at all,
especially if the GUI is busy doing other things (ie. I am moving the
cursor, typing, ...)

What am I doing wrong?

I think, based on how Gtk2::TrayIcon worked, that, at least on linux,
Gtk2::StatusIcon works by creating a widget. And, like other widgets,
drawing the widget, and responding to resize event, is done in the main
loop of your program. To make things worse, the widget interacts with
widgets from other process (the gnome panel).
So what I think is happening, is that when you change the icon, not all
needed events are generated right away, as some are only generated after
an other process has replied (maybe there is a size negotiation going
on, between your widget and the panel), so the "while
Gtk2->events_pending" loop finishes before all the work is done.

I doubt that there is an easy way to fix that, gtk2 is made to have a
main loop running.
Adding a main loop may not be so hard.
- if the long calculating part is done in another process, you can
launch it in a way that doesn't interrupt the main loop, and set up a
watch (for example on the standard output file descriptor of the
process) to generate a signal once it's finished.
- if it's perl code, there may be an easy way to do small chunks of it
in an idle callback. Or you may launch it in another process.

Quentin




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]