[Vala] Updating Indicator Menu Items



Hello,

Long time listener, first time caller :)

I have a problem that I can't seem to solve involving updating items on a
menu connected to a system Indicator.  I have two classes defined:  one
that gathers info, and one that displays it.  The flow of the program is

  - Create a status object and define things to be done, along with the
main thread
  - Create an indicator object which creates the menu, along with a method
to update the indicator
  - Run the thread, which periodically gathers information and updates the
indicator menu and icon

The status object gathers the correct data and the indicator icon updates
as expected.  However, the menu does not update after the first time
through the thread loop.  Note that I instrumented the radioMenuItem label
(flagged as DEBUG in the code) and it prints out the updated label (as
expected), so the label itself *is* being updated.  It just doesn't update
on the menu itself.

Any help would be greatly appreciated!

Thanks,
Bruce

Here is the stripped down code:

------------------------------  SystemIndicator.vala
------------------------------

using Gtk;
using AppIndicator;

public class SystemIndicator : Window {
  public const string [] FORMAT = { /* ... etc ... */ };

  public  Indicator            appIcon;
  public  int                  selected { get; set; default = 0; }

  private Gtk.Menu             trayMenu;
  public  Gtk.RadioMenuItem [] radioItem;

//  Constructor:

  public SystemIndicator () {
    unowned SList<Gtk.RadioMenuItem> radioGroup = null;
    trayMenu = new Gtk.Menu ();

    radioItem.resize (FORMAT.length);

//  Create radio menu items:

    int i = 0;
    foreach (string s in FORMAT) {
      radioItem [i] = new Gtk.RadioMenuItem.with_label (radioGroup, s);
      radioItem [i].activate.connect (select);
      radioGroup = radioItem [i].get_group ();
      trayMenu.append (radioItem [i++]);
    }

    trayMenu.show_all ();

    appIcon = new Indicator (NAME, ICON,
IndicatorCategory.APPLICATION_STATUS);
    appIcon.set_status      (IndicatorStatus.ACTIVE);
    appIcon.set_icon        (@"$ICON-0");
    appIcon.set_menu        (trayMenu);
  }

//  Menu update:

  public void update (int index, float value, ...) {
    var args = va_list ();
    radioItem [index].set_label (FORMAT [index].vprintf (args));  //  Try
to update menu item
    stdout.printf (radioItem [index].label + "\n");  //  DEBUG

    var ind = ((int) (value / 10.0f)) * 10;
    appIcon.set_icon ( @"$ICON-$ind");
  }
}

------------------------------  SystemStatus.vala
------------------------------

using Gtk;

class SystemStatus {
  public  SystemIndicator appIcon { get; set; }

//  Things to do:

  private void doSomething () {
//  ... do something ...
    appIcon.update (0, value, arg);  //  Update Indicator item 0
  }

  private void doSomethingElse () {
//  ... do something else...
    appIcon.update (1, value, arg);  //  Update Indicator item 1
  }

//  Thread entry:

  public void* run () {
    while (true) {
      doSomething     ();
      doSomethingElse ();
      Thread.usleep   (1000000);
    }
  }
}

//  Main program entry:

int main (string [] args) {
  if (!Thread.supported ()) {
    stderr.printf ("Cannot run without thread support.\n");
    return 1;
  }

  Gtk.init (ref args);

  var status     = new SystemStatus    ();  //  Create the status object
  status.appIcon = new SystemIndicator ();  //  Connect the indicator to
the status object

  try {
    unowned Thread <void *> thread = Thread.create <void *> (status.run,
true);
  } catch (ThreadError e) {
    error ("main: %s\n", e.message);
    return 1;
  }

  Gtk.main ();
  return 0;
}


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