4

I've been battling the horrendous Gnome API documentation and came up with this extension:

const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const GLib = imports.gi.GLib;

let label;

function init() {
    label = new St.Bin({ style_class: 'panel-label' });

    let stuff = GLib.spawn_command_line_sync("cat /home/user/temp/hello")[1].toString();
    let text = new St.Label({ text: stuff });

    label.set_child(text);
}

function enable() {
    Main.panel._rightBox.insert_child_at_index(label, 0);
}

function disable() {
    Main.panel._rightBox.remove_child(label);
}

This should read whatever is in the hello file and display it in the top panel. However, if I change the contents of the hello file, I have to restart Gnome for that new content to be shown. Now, surely there is a way to do this dynamically but I just couldn't find anything in the documentation. The message in the panel should basically always mirror whatever is in the file. Any ideas how to do this?

mart1n
  • 5,969
  • 5
  • 46
  • 83

2 Answers2

5

You'll want to obtain a Gio.File handle for your hello file, and then monitor it:

let helloFile = Gio.File.new_for_path('/home/user/temp/hello');
let monitor = helloFile.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed', function (file, otherFile, eventType) {
    // change your UI here
});
ptomato
  • 56,175
  • 13
  • 112
  • 165
  • This is great! I wish this stuff was clearly documented somewhere :( One more question: how would you monitor the output of a command? Let's say I want to run ping and display the time of each packet in the top panel? Thanks for your help! – mart1n Sep 30 '13 at 08:09
  • 1
    That's worth an entire question-and-answer on its own, but this C code might get you started: https://github.com/ptomato/gnome-inform7/blob/master/src/spawn.c#L215 Speaking of C code, unfortunately your best alternative to proper GJS documentation is to read the C API: https://developer.gnome.org/gio/stable/GFileMonitor.html#GFileMonitor-changed – ptomato Oct 01 '13 at 03:05
0

This worked for me. It will refresh the label value each 30 seconds.

  • Add the following import

    const Mainloop = imports.mainloop;

  • In your init method

    Mainloop.timeout_add(30000, function () { 
     let stuff = GLib.spawn_command_line_sync("your_command")[1].toString();
     let label = new St.Label({ text: stuff });
     button.set_child(label);return true});