LauncherAPI

Differences between revisions 11 and 12
Revision 11 as of 2011-02-14 13:39:33
Size: 4550
Editor: 188
Comment: Add a Dislaimer, TOC, and make clear that libunity is unstable API
Revision 12 as of 2011-02-14 13:43:48
Size: 10265
Editor: 188
Comment: Mention emblems. Document DBus wire format. Add FAQ
Deletions are marked like this. Additions are marked like this.
Line 27: Line 27:
{{{LauncherEntry}}}es are able to control 3 major components of a Launcher Icon: {{{LauncherEntry}}}es are able to control 4 major components of a Launcher Icon:
Line 55: Line 55:
=== Emblems ===

You can set an emblem to be rendered on top of your launcher icon by setting a {{{GIcon}}} instance on the {{{emblem}}} property:
{{{
unity_launcher_entry_set_emblem (UnityLauncherEntry *self, GIcon *emblem)
}}}
and made visible by calling
{{{
unity_launcher_entry_set_emblem_visible (UnityLauncherEntry *self, gbloolean visible);
}}}
Line 67: Line 78:
= Example Code = == Example Code ==
Line 69: Line 80:
== Vala Example == === Vala Example ===
Line 107: Line 118:

== Low level DBus API: com.canonical.Unity.LauncherEntry ==

||<#ffeeee> (!) '''While the libunity is unstable, the DBus protocol underneath is even more so. We strongly discourage anyone from relying on it''' ||

Application authors normally should not need to care about the raw DBus API. {{{libunity}}} implements all of this in a nice and convenient API.

This API is designed to minimize the number of DBus messages needed in order to set up the launcher icons, and generally cater for devices with less-than-desktop processing powers. Unity ships not only on netbooks but also on several 3rd party tablet setups. This demands special attention to CPU hungriness, power consumption, and IO.

 {{{signal}}} '''com.canonical.Unity.!LauncherEntry.Update ({{{in s app_uri, in a{sv} properties}}})'''

This signal is emitted by an application whenever it wishes to change state of any of its launcher properties. It's important to emphasise that the signal ''only includes the properties that have changed''. This ensures that the protocol is extensible without changing libunity.

Unity will pick up the {{{Update}}} signal by having a DBus match rule catching all signals from {{{com.canonical.Unity.LauncherEntry}}} disregarding its origin. It's the responsibility of the emitting party to {{{Update}}} with all know state when the name {{{com.canonical.Unity}}} becomes owned on the bus. Otherwise there may be synchronization issues on boot up or if the Unity shell is restarted for some reason.

 . '''app_uri''' : A URI on the form {{{application://$desktop_file_id}}}. The desktop file id of an application is defined to be the basename of the application's {{{.desktop}}}-file including the extension. So taking Firefox as an example it would be {{{application://firefox.desktop}}}


 . '''properties''' : A map of strings to variants with the properties to set on the launcher icon. Valid properties are:
  . {{{"count"}}} (type signature {{{x}}}): A number to display on the launcher icon. You must also set the {{{"count-visible"}}} property to {{{true}}} in order for this to show.
  . {{{"progress"}}} (type signature {{{d}}}) : A double precision floating point number between 0 and 1. This will be rendered as a progress bar or similar on the launcher icon. You must also set the {{{"progress-visible"}}} property to {{{true}}} in order for this to show.
  . {{{"emblem"}}} (type signature {{{s}}}) : A serialized {{{GIcon}}} to use as an emblem on the launcher icon. You must also set the {{{"emblem-visible"}}} property to {{{true}}} in order for this to show.
  . {{{"quicklist"}}} (type signature {{{s}}}) : The object path to a {{{DbusmenuServer}}} instance on the emitting process. An empty string denotes that the quicklist has been unset. This also explains why we use signature {{{s}}} and not {{{o}}}. The empty string is not a valid object path.
  . {{{count-visible}}} (type signature {{{b}}}) : Determines whether the {{{"count"}}} is visible
  . {{{progress-visible}}} (type signature {{{b}}}) : Determines whether the {{{"progress"}}} is visible
  . {{{emblem-visible}}} (type signature {{{b}}}) : Determines whether the {{{"emblem"}}} is visible

Mainly for debugging purposes applications using the {{{Update()}}} signal must also expose a {{{Query}}} method on the same object path as they emitted the {{{Update}}} signal from:

 {{{method}}} '''com.canonical.Unity.!LauncherEntry.Query ({{{out s app_uri, in a{sv} properties}}})'''

The return values match exactly the paramters described in the {{{Update}}} signal.


== FAQ ==

 * ''Why not use the {{{org.freedesktop.DBus.Properties}}} interface instead?''
 . Good question! The standard properties interface of DBus is designed in a polling fashion, and would require Unity to query a well known address for the properties, which in turn demands that we use some sort of registration mechanism. The beauty of the custom API is that it flips the roles, it's a pushing mechanism instead of a pulling mechanism. This makes the registration step implicit and book keeping easier. Not to mention requiring fewer DBus roundtrips.

 * ''Why not use the de-facto standard [[http://wiki.go-docky.com/index.php?title=Writing_Helpers#DockManager_DBus_Interface_Specification|DockMangaer API]] instead?''
 . Good question again! The introductory paragraph on the DBus API section gives the clue here. The !DockManager API is great for a desktop dock. But if you analyze it you'll see that it requires a great many DBus messages exchanged when exercised fully. Thus not a great choice for devices with less-than-desktop powers.
 . The !DockManager interface also doesn't interface with the [[http://people.canonical.com/~agateau/dbusmenu/spec/classorg_1_1ayatana_1_1dbusmenu.html|Dbusmenu protocol]] which is more expressive than the !DockManager counterpart. There are also both technical- and UI choices in the !DockManager API that doesn't fit well with the vision for Unity.
 . Summing up; if we had gone with the !DockManager interface it would have been an strict subset with a suite of custom non-compatible extensions. Some companies does not flinch from calling this behaviour "standard compliance", but let's be honest with our selves. It's no longer the !DockManager interface we'd be supporting, but a custom one.

Launcher API

We support adding quicklists, counters, and progress bars for apps in the Unity Launcher:

unityapi.png

Disclaimer

The APIs described in this document are subject to change. We are trying very hard to bring you a powerful, fun, and coherent API to instrument the Unity shell from top to bottom. We acknowledge that this is a non trivial task and we might not get it Just Right (TM) in the first cut, and since we really want to give you, dear app developer, the best, we have to make reservations for API breaks until we've really nailed it down.

When everyone is happy we will guarantee API and ABI stability, but not just yet. Sorry Smile :-)

Using the Launcher API

Info (!) The libunity API does not currently have any ABI or API stability guarantees

The recommended and supported way to take control of your launcher icon is to use the API provided by libunity. This library wraps a low level DBus protocol which is documented below.

Each launcher icon can be controlled remotely by a discrete LauncherEntry object. New launcher entry object may be created by call unity_launcher_entry_get_for_desktop_id (char *id); where id is the name of the desktop file shipped by the application you wish to control. For example evolution ships "evolution.desktop" or empathy ships "empathy.desktop".

LauncherEntryes are able to control 4 major components of a Launcher Icon:

Count

The first aspect they can control is the count associated with the icon. The count may be set by calling

unity_launcher_entry_set_count (UnityLauncherEntry *self, gint64 count);

This will remotely prime the count, then calling

unity_launcher_entry_set_count_visible (UnityLauncherEntry *self, gboolean visible)

can toggle its visible status. Updates to the count and other properties are live, unsetting and resetting the visibility is not require nor is it encouraged.

Progress

progress can be set by

unity_launcher_entry_set_progress (UnityLauncherEntry *self, gdouble progress)

and made visible by calling

unity_launcher_entry_set_progress_visible (UnityLauncherEntry *self, gbloolean visible);

The progress value should be between 0.0 and 1.0.

Emblems

You can set an emblem to be rendered on top of your launcher icon by setting a GIcon instance on the emblem property:

unity_launcher_entry_set_emblem (UnityLauncherEntry *self, GIcon *emblem)

and made visible by calling

unity_launcher_entry_set_emblem_visible (UnityLauncherEntry *self, gbloolean visible);

Quicklists

Quicklists may also be created and appended to the launcher. To create a quicklist a root node must first be created as a container, and then child nodes are added to it. This final result may be packed into the launcher which is then shipped over the bus to Unity. Updates to the quicklist are also live. Rather than describe the entire API, an example of using quicklist (as well as progress and count) is provided below using the vala bindings.

It is important to note that the main loop must be invoked for the program to actual work. Libunity requires the usage of the main loop as work may be done async.

Filing Bugs

  • https://launchpad.net/libunity

  • If you're having a problem with the launcher not displaying or incrementing, then it's probably a libunity problem. If the rendering is wrong, it's probably a unity bug and not libunity.
  • Contact Us

Example Code

Vala Example

/* Compile with: valac --pkg unity --pkg dee-1.0 --pkg gee-1.0 --pkg Dbusmenu-Glib-0.4 launcherexample.vala */
namespace LauncherExample {

  public static void main ()
  {
    /* Pretend to be evolution for the sake of the example */
    var l = Unity.LauncherEntry.get_for_desktop_id ("evolution.desktop");

    /* Show a count of 124 on the icon */
    l.count = 124;
    l.count_visible = true;

    /* Set progress to 42% done */
    l.progress = 0.42;
    l.progress_visible = true;

    /* Set an emblem as well (this is not shown the in the screenshot above) */
    l.emblem = new ThemedIcon ("emblem-important");
    l.emblem_visible = true;
    
    /* We also want a quicklist */
    var ql = new Dbusmenu.Menuitem ();
    var item1 = new Dbusmenu.Menuitem ();
    item1.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Item 1");
    var item2 = new Dbusmenu.Menuitem ();
    item2.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Item 2");
    ql.child_append (item1);
    ql.child_append (item2);
    l.quicklist = ql;

    new MainLoop().run();
  }
  
}

Low level DBus API: com.canonical.Unity.LauncherEntry

Info (!) While the libunity is unstable, the DBus protocol underneath is even more so. We strongly discourage anyone from relying on it

Application authors normally should not need to care about the raw DBus API. libunity implements all of this in a nice and convenient API.

This API is designed to minimize the number of DBus messages needed in order to set up the launcher icons, and generally cater for devices with less-than-desktop processing powers. Unity ships not only on netbooks but also on several 3rd party tablet setups. This demands special attention to CPU hungriness, power consumption, and IO.

  • signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties)

This signal is emitted by an application whenever it wishes to change state of any of its launcher properties. It's important to emphasise that the signal only includes the properties that have changed. This ensures that the protocol is extensible without changing libunity.

Unity will pick up the Update signal by having a DBus match rule catching all signals from com.canonical.Unity.LauncherEntry disregarding its origin. It's the responsibility of the emitting party to Update with all know state when the name com.canonical.Unity becomes owned on the bus. Otherwise there may be synchronization issues on boot up or if the Unity shell is restarted for some reason.

  • app_uri : A URI on the form application://$desktop_file_id. The desktop file id of an application is defined to be the basename of the application's .desktop-file including the extension. So taking Firefox as an example it would be application://firefox.desktop

  • properties : A map of strings to variants with the properties to set on the launcher icon. Valid properties are:

    • "count" (type signature x): A number to display on the launcher icon. You must also set the "count-visible" property to true in order for this to show.

    • "progress" (type signature d) : A double precision floating point number between 0 and 1. This will be rendered as a progress bar or similar on the launcher icon. You must also set the "progress-visible" property to true in order for this to show.

    • "emblem" (type signature s) : A serialized GIcon to use as an emblem on the launcher icon. You must also set the "emblem-visible" property to true in order for this to show.

    • "quicklist" (type signature s) : The object path to a DbusmenuServer instance on the emitting process. An empty string denotes that the quicklist has been unset. This also explains why we use signature s and not o. The empty string is not a valid object path.

    • count-visible (type signature b) : Determines whether the "count" is visible

    • progress-visible (type signature b) : Determines whether the "progress" is visible

    • emblem-visible (type signature b) : Determines whether the "emblem" is visible

Mainly for debugging purposes applications using the Update() signal must also expose a Query method on the same object path as they emitted the Update signal from:

  • method com.canonical.Unity.LauncherEntry.Query (out s app_uri, in a{sv} properties)

The return values match exactly the paramters described in the Update signal.

FAQ

  • Why not use the org.freedesktop.DBus.Properties interface instead?

  • Good question! The standard properties interface of DBus is designed in a polling fashion, and would require Unity to query a well known address for the properties, which in turn demands that we use some sort of registration mechanism. The beauty of the custom API is that it flips the roles, it's a pushing mechanism instead of a pulling mechanism. This makes the registration step implicit and book keeping easier. Not to mention requiring fewer DBus roundtrips.
  • Why not use the de-facto standard DockMangaer API instead?

  • Good question again! The introductory paragraph on the DBus API section gives the clue here. The DockManager API is great for a desktop dock. But if you analyze it you'll see that it requires a great many DBus messages exchanged when exercised fully. Thus not a great choice for devices with less-than-desktop powers.

  • The DockManager interface also doesn't interface with the Dbusmenu protocol which is more expressive than the DockManager counterpart. There are also both technical- and UI choices in the DockManager API that doesn't fit well with the vision for Unity.

  • Summing up; if we had gone with the DockManager interface it would have been an strict subset with a suite of custom non-compatible extensions. Some companies does not flinch from calling this behaviour "standard compliance", but let's be honest with our selves. It's no longer the DockManager interface we'd be supporting, but a custom one.

Unity/LauncherAPI (last edited 2013-08-09 12:17:35 by 3v1n0)