Application Based GNOME 3

Gnome 3 is an "application based" system, as opposed to "window based". This page will describe this change in terms of concerns developers, testers, and documenters need to be aware of. For more information about the user experience, see this design PDF, and this blog post.

Executive summary of application changes that should be made for GNOME 3

  • Ensure that your .desktop file Has StartupNotify=true and that your app handles startup notification correctly

  • If it ever makes sense to run multiple windows for your application, you need to have a "new window" menu item inside your application

What's an application?

There are several components that technically compose to form an "application" from the user experience point of view.

  • required Exactly one visible .desktop file

    • A .desktop file has at least Name, and Icon

  • required One or more processes

  • required One or more X windows (this may be a system tray icon)

    • An X window has a window icon, a window title, and (usually) a WM_CLASS property

  • One or more DBus session bus names

GNOME 2

First, we'll explain briefly at how the GNOME 2 UI displays application data.

  • The panel menu (Reference UI is Applications in the top left) displays .desktop files. When clicked, the panel looks in .desktop file for an Exec line giving the command to run. When that command is executed, it creates one or more processes. Those processes create one or more X windows.

  • A "window list" (reference UI is at the bottom), which lists X windows.

The crucial thing to grasp about GNOME 2 is that there is no default association between what's in the menu and what's listed at the bottom. For example, if you select the "Calculator" item twice, the Exec line from the .desktop file will be re-executed, and by default you'll get two Calculator windows, and two Calculator processes.

What's changing in GNOME 3

In GNOME 3 Shell, the primary UI component is the .desktop file. An application can only be running once (but can still have multiple windows). When clicking on an already-running application, GNOME Shell will simply let the user select between the already open windows (or if there's just one, take the user to it). It will not re-run the .desktop file. So without any code changes to (for example) Calculator, you will have at most one calculator window.

There are a variety of heuristics used to make the association between X windows and .desktop files for backwards compatibility. These heuristics are complex and still evolving, and will not be detailed here.

The window data (icon, and title) are de-emphasized in GNOME 3. Instead, the top area will contain a persistent display of your application's .desktop file name.

Startup Notification

One mechanism GNOME 3 uses to associate windows with applications is startup notification. Ensure that your application's .desktop file has StartupNotify=true.

The WM_CLASS X Window property

To ensure the GNOME 3 Shell will track your application, you can also set the WM_CLASS X window property to be the same as your application's .desktop file name, without the .desktop extension (the desktop file should be lower-case).

The easiest way to achieve this is to have your application's process name match the .desktop file name, and ensure you use g_option_context_parse.

Example

myapp.desktop:

Name=MyApp
Exec=myapp

And inside myapp.c:

int main(int argc, char **argv)
{
  /* ... set up option parsing context, see GOption link above */
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print ("option parsing failed: %s\n", error->message);
    exit (1);
  }
  ...

The way this works default in GTK+, the WM_CLASS property is derived from the g_set_prgname function. This function is called by g_option_context_parse. GTK+ will uppercase the first letter of the program name; you can ignore this.

Inspecting your program's WM_CLASS PROPERTY

From a Unix shell, type:

sleep 5; xprop WM_CLASS

5 seconds later your cursor will change to a + symbol; click on your window. You will see output like this:

WM_CLASS(STRING) = "chromium-browser", "Chromium-browser"

The second item here is the WM_CLASS. Chromium-browser (when lowercased) matches the chromium-browser.desktop as we want.

Binding interpreters

Many language bindings use a runtime environment like gjs, seed, python, java, mono.exe, and these programs often do not use GLib's option parser. In this case, it's easiest to call g_set_prgname manually before you map your first window. In this example we assume your application ships a .desktop file named virt-manager.desktop.

JavaScript (gjs, seed)

const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;

// Other code 

GLib.set_prgname('virt-manager');

// Create application windows

Gtk.main();

PyGObject

from gi.repository import GLib

GLib.set_prgname('virt-manager')

# create application windows

GLib.main()

Projects/GnomeShell/ApplicationBased (last edited 2013-11-22 17:00:27 by WilliamJonMcCann)