UnityLauncherIntegration
Supercharging Your Apps with Unity Launcher Integration - Instructors: DBO
Hi everyone, my name is Jason Smith, I am a developer from the Canonical Desktop Experience team (DX for short) I'll be giving a talk on supercharging applications with unity launcher integration for the next hour or so anyone reading along should feel free to ask questions as they pop into their heads First I want to start off by making sure everyone is familiar with the general terminology I am going to be using through this talk Unity is (of course) the new shell being developed on top of GNOME for Ubuntu 11.04 and newer the Launcher refers to the bar full of icons on the left side of the screen during usage of Unity what we have found over the course of the last year is that application developers have desired a better way to display tiny pieces of information to users without doing rather drastic things like popping up alert boxes many application authors have resorted to doing things like changing the title of their application to indicate new messages, urgency, or task progress so we decided to make those three things in particular an explicit and consistent API for usage with the Unity Launcher this API has been included in a library called libunity, and is available in the Ubuntu main repositories, you can also find its source code here: https://launchpad.net/libunity Libunity will allow application developers to convey tiny bits of information about their application (or actually any application) they wish with very little work we'll look at this piece by piece I'll be using Vala as code snippets, but python and C bindings are also available (or anything else that supports GIR) The first thing we do with libunity is get a LauncherEntry object LauncherEntry objects serve as a control center for a single item on the launcher. They are asyncronous and currently one way (can be used to push information but not to inspect remote state) LauncherEntry objects are keyed on the desktop file, so to create an entry for banshee, we would do: var launcher_entry = Unity.LauncherEntry.get_for_desktop_file ("banshee.desktop"); the resulting launcher_entry will be remotely watched and tracked by the Unity Launcher as soon as it is created (there is a caveat here that you must have a running main loop for any communication to work, otherwise it will queue until you run your main loop) you may create as many launcher entry objects as you like, for as many different applications as you like in a single program. This is useful for creating applications to bridge public API's between two different programs (say skype where we dont have source code access) now that we have a LauncherEntry, we can do 4 different, useful things with it 1) Mark or unmark the application as urgent 2) Set a count on the object (useful for unread messages) 3) Set a progress on the object 4) Add quicklist menu items to the object Each of these is very simple, so we will just go through them in order, at the end I will post the entire source code for the example program Setting our launcher_entry as urgent is as easy as "launcher_entry.urgent = true" this state will be immediately communicated over dbus to unity where it will be reflected on the launcher setting this back to false will reset the state mhr3 asked: aren't there other methods to mark app urgent? shouldn't those be used instead? Yes, there are other methods for marking an application as urgent these methods are based on window hints applied to the xproperties of a related window while these methods are quite useful, and should be preferred when the make sense there are some cases where they dont, such as when an application that has no mapped windows still wishes to be marked urgent Ubuntu One is an example of such an application it will mark itself urgent when the user runs out of space, even though it has no mapped windows kermit66676 asked: so there has to exist an <app_name>.desktop file somewhere? That file has to be included in a deb package by convention? In short yes, there must be a desktop file somewhere. This is what the unity launcher considers an "application" However, that file does not have to be added by a deb package there was a bug last cycle where the daemon responsible for matching wouldn't seen manually added desktop files but that has been fixed now Libunity also allows users to set a count and a progress very simply, the api is almost identical for this so we'll just do them together launcher_entry.count = 1; launcher_entry.count_visible = true; these two lines of code set the count to 1, then instruct the launcher to actually display the count. The count and its display are decoupled so it can be turned on and off as needed similarly, progress can be done as: launcher_entry.progress = 0.0; launcher_entry.progress_visible = true; again, the progress is set to 0, and then made visible Trevinho asked: is actually impossible to check if a launcher entry is actually shown in the unity bar and maybe notified when it is there... Is this something planned (or that I can do :) )? Currently there is no method for checking the contents of the launcher, this is a planned feature we feel desperately needs fixing :) and yes Trevinho, this is certainly something you could do :) ask me in #ayatana later and I will help you with the dbus work if needed The last major item libunity allows developers to modify the launcher with is the addition of new quicklist items is now known as Guest738 these are done using the dbusmenu library, which has been covered in previous sessions and is fairly well documented, so I will only deal with the basic coupling code required for libunity first we need to create a quicklist some example code looks a bit like: 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); this will create a quicklist, called ql, containing two label items those items have signals on them you can subscribe to in order to get information about when they are clicked :) adding them to the launcher is then as easy as: launcher_entry.quicklist = ql; This concludes the basic usage of libunity unfortunately there are some limitations currently and they mostly deal with applications wishing to use concurrent libunity connections First, an application wishing to show a state on the launcher MUST remain active. The launcher watches the application on the session bus, and when it dies it reverts any changes it has made to the launcher icons state so progress, count, urgent, and menu items all go away if you application dies Second, state is currently last write overwrites previous data for multiple connections this is very limiting and needs to be fixed, but people should be aware of it in the mean time :) mhr3 asked: what is undone when the process which changed something on the launcher disappears? The changes go away :) I think I was slow to answer this but if I wasn't clear, yeah, the changes just get reverted :) mhr3 asked: any plans with the DockManager spec? :) DockManager is a beautiful specification, and I really deeply regret we dont support it its very comprehensive and covers a lot of corner cases pretty well the one major advantage I think the libunity implementation covers better is it allows multiple consumers AND multiple subscribers so you could, in theory, have many docks all listening to the same signals from applications this was a shortcoming of dock manager (if I recall correctly) kermit66676 asked: how come the Dbusmenu code is not masked using something more intuitive, such as ql = new Unity.Quicklist()? That would make it independent of the underlying technology (even though it might never change to something else). I think the thought process is that dbusmenu is used in more places that just libunity (in the indicators for example), so making it a consistent API across the entire ecosystem was important oh I forgot to pastebin the program :) here we are: http://paste2.org/p/1636674 As libunity grows, I hope we can see it used more consistently across the ubuntu desktop. Items in the desktop switcher, nautilus, and maybe the dash will see increased usage of these signals and display the same hints anyhow, unless there are more questions, that is about all I got rsajdok asked: Why did you choose value instead python? Vala is just the language I used in the example its all gobject introspection so you can use python too I picked vala here just because thats what my test program is written in and I didn't feel like re-writing it :)
MeetingLogs/appdevweek1109/UnityLauncherIntegration (last edited 2011-09-08 09:15:59 by dpm)