Cooperating with GNOME startup in a Java application

In February I wrote Finishing GNOME startup in a Java Swing application which showed how you could set the StartupNotify flag in your Java application's ".desktop" file, provided you were prepared to call a little C++ program.

This week I realized it would actually be of some use to me to be able to initiate a startup notification session. Sometimes my Java programs launch other programs, and it's nice to be able to make use of the same startup notification system the rest of the desktop's using.

The extra code is minimal:

static std::string invent_startup_id() {
char hostname[256];
if (gethostname(hostname, sizeof(hostname)) != 0) {
strcpy(hostname, "localhost");

std::ostringstream oss;
oss << hostname << getpid() << "_TIME" << time(0);
return oss.str();

static void start_startup(const std::string& name) {
std::string startup_id = invent_startup_id();
XDisplay xdisplay;
std::ostringstream oss;
oss << "new:"
<< " ID=" << escape_for_xmessage(startup_id)
<< " SCREEN=" << DefaultScreenOfDisplay(xdisplay.display)
<< " NAME=" << escape_for_xmessage(name);
std::cout << startup_id << std::endl;

The full program is in salma-hayek.

To make use of it, I add something like this to the application's start-up script:

if ENV['DISPLAY'] != nil && ENV['DESKTOP_STARTUP_ID'] == nil
id=`gnome-startup start Starting #{tool_name}`.chomp()

You can use it with any old application, though. To start gnome-calculator(1) from the command-line but with startup-notification (which you usually only get from the GNOME panel), you could do something like this:

export DESKTOP_STARTUP_ID=`gnome-startup start Starting Calculator`