1 [21:02] <kamstrup> Hi all! 2 [21:02] <kamstrup> So I guess I am up now 3 [21:02] <kamstrup> My name is Mikkel Kamstrup Erlandsen and i work for Canonical on the DX team 4 [21:02] <kamstrup> In my spare time I also dabble with software, namely Zeitgeist and search engines 5 [21:03] <kamstrup> On the DX team I am working on all the backend and infrastructure stuff 6 [21:03] <kamstrup> so not so much all the fancy graphics you see in Unity 7 [21:03] <kamstrup> but all that goes on beneath it :-) 8 [21:03] <kamstrup> In particular relevant for this session libunity 9 [21:04] <kamstrup> libunity is a library with the purpose of instrumenting and integrating with Unity 10 [21:04] <kamstrup> For the Natty cycle you'll be able to integrate with the Launcher and the Places/Lenses 11 [21:05] <kamstrup> (btw for this session I'll call it Places - but in the Oneriric cycle we'll officially change to Lenses) 12 [21:05] <kamstrup> (it's just that "places" is in my muscle memory right now :-)) 13 [21:05] <kamstrup> One big caveat emptor before we proceed too far 14 [21:06] <kamstrup> libunity does not currently have API or ABI stability guarantees 15 [21:06] <kamstrup> we will work on that - promised - but we also want to ensure that the API is really really nice before we freeze it 16 [21:06] <kamstrup> and in fact 17 [21:06] <kamstrup> I can already guarantee that there will be slight changes when we begin the Oneiric cycle 18 [21:07] <kamstrup> but that said 19 [21:07] <kamstrup> You can already take libunity for a spin and do some pretty impressive stuff with it 20 [21:07] <kamstrup> fx. both the Apps and Files places are implemented with libunity 21 [21:07] <kamstrup> there's no "priviledged" Unity API for those two buggers 22 [21:08] <kamstrup> anyone here will be able to do exactly what they do 23 [21:08] <kamstrup> Before we start talking about the places let's talk about the Launcher integration 24 [21:08] <kamstrup> The Launcher integration is a lot simpler than the places 25 [21:09] <kamstrup> So enough with the intro talk 26 [21:09] <kamstrup> -------------------- 27 [21:09] <kamstrup> The Unity Launcher 28 [21:09] <kamstrup> The simplest way you can integrate with the launcher is via what is called "static quicklists" 29 [21:09] <kamstrup> https://wiki.ubuntu.com/Unity/LauncherAPI#Static%20Quicklist%20entries 30 [21:10] <kamstrup> If you follow that link you'll see a snippet from a normal .desktop file 31 [21:10] <kamstrup> If you take a normal .desktop file and add [Foo Shortcut Group] entries to it like shown 32 [21:10] <kamstrup> you can add quicklist right there 33 [21:11] <kamstrup> Look at your own /usr/share/applications/evolution.desktop for a live example 34 [21:12] <kamstrup> What static quicklist elements can basically do is launch an executable 35 [21:12] <kamstrup> so very simple 36 [21:12] <kamstrup> no programming required 37 [21:12] <kamstrup> If you want to get a bit more power 38 [21:12] <kamstrup> you need to use libunity 39 [21:13] <kamstrup> More specifically the LauncherEntry API 40 [21:13] <kamstrup> For the sake of the examples we'll use Python examples today, but you can also code in Vala, C 41 [21:13] <kamstrup> (or C++ if you manually write the C calls out) 42 [21:14] <kamstrup> You'll see the API here http://developer.ubuntu.com/api/ubuntu-11.04/GIR/python/Unity-3.0.html#Unity.LauncherEntry 43 [21:14] <kamstrup> it may deserve mention that we are starting to push up Python docs for the libs generated via GObject Introspection to http://developer.ubuntu.com/api/ 44 [21:14] <kamstrup> Anyway 45 [21:15] <kamstrup> Looking at the LauncherEntry docs you'll see that it only has static constructors - not conventional constructors 46 [21:15] <kamstrup> that's because you always get a "singleton" back for the particular app 47 [21:15] <kamstrup> Let me find an example 48 [21:16] <kamstrup> Here http://bazaar.launchpad.net/~unity-team/libunity/trunk/view/head:/examples/launcher.py 49 [21:16] <kamstrup> You can set 3 main properties on the launcher entry 50 [21:16] <kamstrup> A "count" that will be displayed as a number on the top part of the tile 51 [21:17] <kamstrup> you may have seen this on apps like Evolution displaying the number of unread mails this way 52 [21:17] <kamstrup> Then you can add a progress bar 53 [21:17] <kamstrup> the values for progress must be between 0 and 1 54 [21:17] <kamstrup> (and it's a float) 55 [21:17] <kamstrup> You can also set the urgency hint 56 [21:18] <kamstrup> Some may know that an "urgency hint" is something you normally have on X11 windows 57 [21:18] <kamstrup> it makes the WM flash the window icon 58 [21:18] <kamstrup> the difference here is that the libunity urgency doesn't require a window on the screen in order to mark an app as requiring attention 59 [21:19] <kamstrup> this can be useful for background processes like Ubuntu One or others that need to draw your attention to their icon when they don't have a window on screen somewhere 60 [21:20] <kamstrup> The last part of the LauncherEntry API is that you can set a "dynamic quicklist" 61 [21:20] <kamstrup> The dynamic quicklists differ from the static ones in that you can build and update them programmatically at runtime 62 [21:21] <kamstrup> You simply have access to a libdbusmenu DbusmenuMenuItem instance that you can populate how you like 63 [21:21] <kamstrup> ok 64 [21:21] <kamstrup> any questions on the laucnher api before we move on? 65 [21:22] <kamstrup> ------------ 66 [21:22] <kamstrup> so now to Places 67 [21:22] <kamstrup> As said before the situation here is slightly regretable 68 [21:22] <kamstrup> It's known both as Lenses and Places in Natty 69 [21:23] <kamstrup> For Oneiric we'll change to Lenses only 70 [21:23] <kamstrup> (also in the all the public APIs) 71 [21:23] <kamstrup> but for now let me call them Places 72 [21:23] <kamstrup> Places run outside the core Unity process 73 [21:24] <kamstrup> Think of them very much like remote database that provides data for Unity to render 74 [21:24] <kamstrup> if you've worked with modern web development frameworks or MVC in UIs think that the place provides the *model* and Unity is a generic View 75 [21:25] <kamstrup> Of course we have the standard Apps and Files places 76 [21:25] <kamstrup> they are not very good beginner examples unfortunately 77 [21:25] <kamstrup> but there are a few simple examples to start from that lots of ppl have found instructive 78 [21:25] <kamstrup> If we stick to the Python example again 79 [21:26] <kamstrup> you can check it out from lp:~unity-team/unity-place-sample/unity-place-python 80 [21:26] <kamstrup> or for now just browse it online at http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/files 81 [21:27] <kamstrup> First look at python.place 82 [21:27] <kamstrup> All places register themselves to unity via a .place file 83 [21:27] <kamstrup> installed under /usr/share/unity/places 84 [21:27] <kamstrup> in a .place file you specify some contact info for Unity to find you on dbus 85 [21:28] <kamstrup> Then each place has one or more PlaceEntries 86 [21:28] <kamstrup> A placeentry is prettymuch what maps to an icon in the launcher 87 [21:28] <kamstrup> You'll probably have the Apps and Files entries in your launcher at the bottom 88 [21:29] <kamstrup> For each entry you want to expose from your place's process you need a [Entry:Foo] line in the .place file 89 [21:29] <kamstrup> The only place that actually has more than one place entry is the Apps place 90 [21:30] <kamstrup> although the second one is hidden 91 [21:30] <kamstrup> Try looking at /usr/share/unity/places/applications.place 92 [21:30] <kamstrup> you'll see that [Entry:Runner] has ShowEntry=false and ShowGlobal=false 93 [21:31] <kamstrup> First ShowEntry=false tells unity to not put a tile in the launcher bar for this place entry 94 [21:31] <kamstrup> the ShowGlobal=false clause tells Unity to not include this entry's results when searching from the Dash 95 [21:31] <kamstrup> aka home screen 96 [21:31] <kamstrup> (the one you get when you hit <super>) 97 [21:32] <kamstrup> There is in fact a spec for these .place files 98 [21:32] <kamstrup> Check https://wiki.ubuntu.com/Unity/Lenses#Registration 99 [21:32] <kamstrup> You'll also note that you can define a keyboard shortcut for you place 100 [21:33] <kamstrup> And now we're talking about this 101 [21:33] <kamstrup> A general best-practice is to *not* include your search results in the Dash 102 [21:33] <kamstrup> that is please set ShowGlobal=false 103 [21:34] <kamstrup> When I write my code I am as excited as anyone to get people using it 104 [21:34] <kamstrup> but people really want a fast Dash 105 [21:34] <kamstrup> and if we have Dash searches laucnhing off 3 http requests, 5 disk searches, and whatnot for each letter typed... 106 [21:34] <kamstrup> so if you want to integrate with the Dash results make sure your results are: 107 [21:35] <kamstrup> 1) almost always relevant 108 [21:35] <kamstrup> 2) Super snappy 109 [21:35] <kamstrup> 3) Doesn't use to many resources to compute 110 [21:35] <kamstrup> and 1) is probably the key point 111 [21:35] <kamstrup> So most places would just have their tile in the launcher and a keyboard shortcut 112 [21:36] <kamstrup> Ok back to the code 113 [21:36] <kamstrup> In the .place file you specify the dbus contact details for your place daemon 114 [21:36] <kamstrup> this means that Unity will start your daemon via dbus activation 115 [21:37] <kamstrup> no need to start it yourself on login or anything 116 [21:37] <kamstrup> this way unity has a chance of not starting all daemons at once when you log in 117 [21:37] <kamstrup> which would run the risk of hogging your disk 118 [21:38] <kamstrup> ok 119 [21:38] <kamstrup> now look at http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/view/head:/unity-place-python.py 120 [21:38] <kamstrup> This is the code for the sample place daemon 121 [21:38] <kamstrup> There are 3 concepts you need to know about when writing a place dameon 122 [21:38] <kamstrup> that is 1) results 2) groups 3) sections 123 [21:39] <kamstrup> each of these three have a Dee.Model associated with them 124 [21:39] <kamstrup> Dee.Model is implement by a library called libdee which we use for almost all of the data sharing behind Unity 125 [21:39] <kamstrup> Dee.Model is like a table that is shared between multiple processes 126 [21:40] <kamstrup> if any one changes, adds, or removes from the model all the other processes watching that model will be notified of what's changed 127 [21:40] <kamstrup> pretty powerful stuff 128 [21:40] <kamstrup> this allows us to do a kind of "distributed MVC" 129 [21:41] <kamstrup> so in one we have the place daemon that updates the results Dee.Model and Unity is watching that same model, updating the View whenever it changes 130 [21:41] <kamstrup> So obviously the results_model contains all the search results 131 [21:41] <kamstrup> then we have a sections_model 132 [21:42] <kamstrup> the sections partition the results into disjoint logical components 133 [21:42] <kamstrup> A sections should represent a "browsable" subset of the result space 134 [21:42] <kamstrup> If you consider the space of all apps then the sections could be Video, Audio, Games, Office 135 [21:42] <kamstrup> etc 136 [21:43] <kamstrup> The sections contribute the elements of the dropdown embedded in the search bar 137 [21:43] <kamstrup> you can also access the sections of a place via the right-click context menu on a place entry in the laucncher 138 [21:43] <kamstrup> then there a groups 139 [21:44] <kamstrup> the groups partition the visible result set into meaning subgroups 140 [21:44] <kamstrup> If you are watching all hits from a file search the groups could be Today, Yesterdat, Last Week, Last Month, ... etc 141 [21:45] <kamstrup> the groups_model and results_model both have a _global_ counterparts 142 [21:46] <kamstrup> the global models are the ones used for searching from the dash 143 [21:46] <kamstrup> (so you normally don't need those) 144 [21:46] <kamstrup> btw 145 [21:46] <kamstrup> the API docs for Dee.Model are here http://developer.ubuntu.com/api/ubuntu-11.04/GIR/python/Dee-0.5.html#Dee.Model 146 [21:46] <kamstrup> The API docs for Dee are not fully true though 147 [21:47] <kamstrup> it has been augmented with some Python sweetness 148 [21:48] <kamstrup> There is currenlty no easy way to document this Python magic, but you can find a demo of the Python magic for Dee.Model here http://bazaar.launchpad.net/~unity-team/dee/trunk/view/head:/examples/pythontricks.py 149 [21:49] <kamstrup> You can also find the docs for what exactly the columns are in all the different models on https://wiki.ubuntu.com/Unity/Lenses#Results%20Model 150 [21:49] <kamstrup> One last thing I want to mention is "Activation" 151 [21:50] <kamstrup> So places require special callbacks when activating some special results 152 [21:50] <kamstrup> Fx. 153 [21:50] <kamstrup> the apps place returns Apps Available for Download that open in the Software Center when you click the,m 154 [21:50] <kamstrup> this is achieved via the Activation API 155 [21:51] <kamstrup> you basically register a handler for a regex matching URIs or mimetypes 156 [21:51] <ClassBot> There are 10 minutes remaining in the current session. 157 [21:51] <kamstrup> then when unity tries to laucnh a it it looks for any places registered for launchoing that hit 158 [21:51] <kamstrup> and does a Dbus callback to the place daemon giving it the URI to activate 159 [21:52] <kamstrup> the place daemon then responds whether Unity should hide the Dash as a response or if the Dash should still be shown 160 [21:52] <kamstrup> in case for Apps Availabale for Download we ask Unity to hide the dash 161 [21:52] <kamstrup> (so we can load S-C) 162 [21:53] <kamstrup> but if we fx. wanted to implemen 163 [21:53] <kamstrup> implement 164 [21:53] <kamstrup> a file browser fx 165 [21:53] <kamstrup> then we could ask unity to keep the dash on screen, and then just clear our results_model and repopulate it with the contents of the clicked directory 166 [21:54] <kamstrup> I guess I'll leave the rest for your own exploration 167 [21:54] <kamstrup> So if anyone has questions don't hold back 168 [21:55] <kamstrup> if that's not the case then let me take 2 minutes to talk about "renderers" 169 [21:56] <kamstrup> if you browse https://wiki.ubuntu.com/Unity/Lenses#Renderers 170 [21:56] <kamstrup> you'll see that we have a concept called renderers which you can specify in various places in the API 171 [21:56] <ClassBot> There are 5 minutes remaining in the current session. 172 [21:57] <ClassBot> tronda asked: How much focus is the Python based API getting? 173 [21:57] <kamstrup> Almost as much as the C/Vala API 174 [21:58] <kamstrup> we really want it to be a 1st class experience 175 [21:58] <kamstrup> and honestly i almost think that the Python API is better than the Vala/C api right now :-O) 176 [21:58] <ClassBot> tronda asked: Any plans to get browser to work with the libunity for web applications? 177 [21:59] <kamstrup> not short term 178 [21:59] <kamstrup> there are some far out plans, but nothing to hold your breath for :-) 179 [21:59] <ClassBot> tronda asked: If working with a web service which is potentially slow - would one use Tracker/Zeitgest to index content. Any help from Unity to make this simpler? 180 [22:00] <kamstrup> Because the place daemon is another process than Unity it's not super critical if web services are slow 181 [22:00] <kamstrup> so I'd say "don't worry in most cases" 182 [22:01] <ClassBot> alecu asked: when a lens adds item, I see that it can add a url to get the item picture from it, like the books lens does with book covers. Will this be standard? 183 [22:01] <kamstrup> yes, yes it will 184 [22:01] <kamstrup> i believe that you can simply insert a URL as icon and Unity will try and load it 185