RockingOutwithlibunity
Dev Week -- Rocking Out with libunity -- kamstrup -- Wed, Mar 2nd, 2011
1 [20:02] <kamstrup> Hi all, so I guess I'm next one up...
2 [20:02] <kamstrup> And thanks to Terence Simpson for the cool talk
3 [20:02] <kamstrup> I am Mikkel Kamstrup Erlandsen
4 [20:02] <kamstrup> and I work on the DX team for Canonical
5 [20:03] <kamstrup> I am working on the backend side of all things unity
6 [20:03] <kamstrup> My work is primarily around the "places"
7 [20:03] <kamstrup> and in my spare time I hack on Zeitgeist
8 [20:04] <kamstrup> so its all searching and backend code for me :-)
9 [20:04] <kamstrup> So for today
10 [20:04] <kamstrup> It's about libunity
11 [20:04] <kamstrup> Here's what I plan to go over:
12 [20:04] <kamstrup> - libunity background
13 [20:04] <kamstrup> - libunity feature set
14 [20:04] <kamstrup> - the unity launcher integration
15 [20:05] <kamstrup> - the unity places integration
16 [20:05] <kamstrup> - some working examples of ^^
17 [20:05] <kamstrup> - and finally a bit about what you can expect for the future of libunity
18 [20:05] <kamstrup> Hopefully this should empower you all to go out and rock the world with awesome unity integration
19 [20:06] <kamstrup> So first item on the agenda: About libunity
20 [20:06] <kamstrup> It's a native library written in Vala
21 [20:06] <kamstrup> We use Vala to generate GObject Introspection files so we can have automagic bings for Python and friends
22 [20:07] <kamstrup> It's important to underline that libunity is strictly a client side library
23 [20:07] <kamstrup> that is
24 [20:07] <kamstrup> Unity itself does *not* link to it
25 [20:07] <kamstrup> We focus on making the API simple and fun
26 [20:07] <kamstrup> So we've chosen to very "property based"
27 [20:08] <kamstrup> so you get access to a bunch of object on which you set properties
28 [20:08] <kamstrup> and that is automatically reflect on unity
29 [20:08] <kamstrup> all of the communication it does is pretty much DBus
30 [20:08] <kamstrup> and it leverages libdbusmenu and libdee
31 [20:08] <kamstrup> to perform some of the more complex dbus-stuff
32 [20:09] <kamstrup> Now let's move on to talk about the feature set of libunity
33 [20:09] <kamstrup> Right now there are 2 main things supportedd
34 [20:09] <kamstrup> - the launcher inetgration
35 [20:10] <kamstrup> - with progress, counter, emblems, and quicklist attached to application tiles in the launcher
36 [20:10] <kamstrup> - and then place inetgration
37 [20:10] <kamstrup> - which allows you to hook into the place framework and write you own places
38 [20:11] <kamstrup> Maybe some of you already saw the wiki page about the launccher API: https://wiki.ubuntu.com/Unity/LauncherAPI
39 [20:11] <kamstrup> let's slowly step through it
40 [20:11] <kamstrup> looking at the first screenshot
41 [20:12] <kamstrup> you'll see the progress bar and counter in action
42 [20:12] <kamstrup> and the screenie below is a quicklist
43 [20:12] <kamstrup> So if you scroll down to the Vala example
44 [20:12] <kamstrup> you can see it's all property based
45 [20:13] <kamstrup> all of the attributes has a _visible cousin
46 [20:13] <kamstrup> like emblem_visible
47 [20:13] <kamstrup> these allow you to keep the state of you variables around
48 [20:13] <kamstrup> by just hiding the overlay
49 [20:14] <kamstrup> there is one thing worth mentioning here
50 [20:14] <kamstrup> it is that the quicklists are not 100% wired up on the unity side yet
51 [20:14] <kamstrup> there are 2 ways to write quicklists
52 [20:14] <kamstrup> "static quicklists" are there even when your app is not running
53 [20:15] <kamstrup> these are defined inside the .desktop files for the apps
54 [20:15] <kamstrup> then there are "dyanmic quicklists"
55 [20:15] <kamstrup> dynamic
56 [20:15] <kamstrup> these are created at runtime by your app
57 [20:15] <kamstrup> and can be very funky
58 [20:15] <kamstrup> they use the Dbusmenu API which some of you may already know from the indicators
59 [20:16] <kamstrup> it's a powerful api that let's you create arbitrarily complex menus
60 [20:16] <kamstrup> if you want to compile the vala example you'll need the very latest libunity from the archives
61 [20:17] <kamstrup> that would be 3.4.6 i believe
62 [20:17] <kamstrup> if you run the example as is, you'll need to start evolution before you run the example
63 [20:18] <kamstrup> if you want to use the python example
64 [20:18] <kamstrup> make sure you have the packages:
65 [20:18] <kamstrup> gir1.2-unity-3.0
66 [20:18] <kamstrup> gir1.2-dee-0.5
67 [20:18] <kamstrup> so i hope you don't have trouble running that if you try
68 [20:19] <kamstrup> don't hesitate to ask if you have trouble
69 [20:19] <kamstrup> chances are that 50% of the other people here have the same problem
70 [20:19] <kamstrup> Ok, that was hopefully pretty light
71 [20:19] <kamstrup> The next thing we'll look at is the places
72 [20:20] <kamstrup> as you may expect that's more complex
73 [20:20] <kamstrup> There is a wiki page which gives a rought overview of the places architecture: https://wiki.ubuntu.com/Unity/Places
74 === photerran is now known as lz0
75 [20:20] <kamstrup> it probably can't stand for itself though
76 [20:21] <kamstrup> The first thing unity will look for when integrating with a place is a ".place file"
77 [20:21] <kamstrup> The .place files define the basic access point for your place
78 [20:22] <kamstrup> It's a standard .ini or .desktop format what ever we call it
79 [20:22] <kamstrup> [Place]
80 [20:22] <kamstrup> DBusName=Well known bus name the place can be found under
81 [20:22] <kamstrup> DBusObjectPath=DBus object path the place object lives at
82 [20:22] <kamstrup> This is the main section
83 [20:22] <kamstrup> defining the dbus name and dbus object path your place can be found on
84 [20:22] <kamstrup> doing it like this allows you to have more than one place inside the same process
85 [20:22] <kamstrup> although noone is doing that right now
86 === marnux_ is now known as marnux
87 [20:23] <kamstrup> A "place" consist of a set of "place entries"
88 [20:23] <kamstrup> A place in itself has no icon in the launcher - it's just a container for place entries
89 [20:23] <kamstrup> For each Place Entry you implement there will be one icon in the launcher
90 [20:23] <kamstrup> (or you can hide it if you want)
91 [20:24] <kamstrup> So in the .place files you specify each of the place entries you expose
92 [20:24] <kamstrup> It can look like:
93 [20:24] <kamstrup> [Entry:Stuff]
94 [20:24] <kamstrup> DBusObjectPath=DBus path for the place entry (must be a direct child of Places' DBusPath)
95 [20:24] <kamstrup> Icon=Icon for the place entry
96 [20:24] <kamstrup> Name=Display name for the entry
97 [20:24] <kamstrup> Description=Short description of what the entry provides. Suitable for display as tooltip or other
98 [20:24] <kamstrup> ShowGlobal=True|False (defaults to True)
99 [20:24] <kamstrup> ShowEntry=True|False (defaults to True)
100 [20:24] <kamstrup> In theory Unity could just as well look all this up over DBus once it has your address from the main [Place] group in the .place file
101 [20:25] <kamstrup> but
102 [20:25] <kamstrup> having it in the .place file allows unity to put icons on screen even before you place has started up
103 [20:25] <kamstrup> so this is good for startup time
104 [20:25] <kamstrup> So going over the [Entry:Stuff]
105 [20:25] <kamstrup> There is another dbus path for the place entry itself
106 [20:26] <kamstrup> And you can assign an icon, name, and description
107 [20:26] <kamstrup> ShowGlobal tells unity whether or not this entry has search result to show in the Dash
108 [20:26] <kamstrup> Dash - aka the homescreen
109 [20:26] <kamstrup> you get when you click the ubuntu button in the top left corner
110 [20:27] <kamstrup> so setting ShowGlobal=False will make unity not call you when it needs to update the results for the Dash
111 [20:27] <kamstrup> Likewise the SHowEntry
112 [20:27] <kamstrup> it determines whether you have a tile in the Launcher on the right
113 [20:28] <kamstrup> You can check out your current .place files in /usr/share/unity/places
114 [20:28] <kamstrup> You'll also notice a "Shortcut" entry in the .place files you have
115 [20:28] <kamstrup> It defines the letter you need to press in combo with <super> to bring up the dash showing your particular place
116 [20:29] <kamstrup> And you'll also notice
117 [20:29] <kamstrup> that since the groups in the .place file are formatted like [Entry:NameOfEntry]
118 === mrjazzcat-lunch is now known as mrjazzcat
119 [20:29] <kamstrup> You can define more than one entry per .place file
120 [20:29] <kamstrup> so far so good - given a .place file unity can now find you
121 [20:30] <kamstrup> so before we proceed I need to talk to you about how unity shares datamodels with the place daemons
122 [20:30] <kamstrup> There is a central library called Dee (or libdee if you will)
123 [20:31] <kamstrup> Dee implements a set of datamodels you can share across dbus
124 [20:31] <kamstrup> And they are like peer-2-peer models
125 [20:31] <kamstrup> So both unity and the place daemon can modify the models
126 [20:31] <kamstrup> although in practice it's mostly just the place daemons
127 [20:32] <kamstrup> This makes implement searching and all that very convenient
128 [20:32] <kamstrup> So when you search (fx. with Zzeitgeist) you don't have to collect a result set an send it to unity
129 [20:32] <kamstrup> you simply update your model
130 [20:32] <kamstrup> this gives a neat way to implement "incremental searches" if you want
131 [20:33] <kamstrup> meaning - iteratively removing hits from the result set as the user types
132 [20:33] <kamstrup> so we don't have to send the entire result set over and over
133 [20:33] <kamstrup> you just update your model removing the rows that no longer match
134 [20:33] <kamstrup> under the hood Dee basically sends a "diff" to all the peers sharing the model
135 [20:34] <kamstrup> So Dee is very powerful
136 [20:34] <kamstrup> If we go back to the wiki page...
137 [20:34] <kamstrup> https://wiki.ubuntu.com/Unity/Places
138 [20:35] <kamstrup> We need to establish the "terminology" on the top of the page
139 [20:35] <kamstrup> There are three words you need to know the meaning of:
140 [20:35] <kamstrup> - result model
141 [20:35] <kamstrup> - groups model
142 [20:35] <kamstrup> - sections model
143 [20:36] <kamstrup> It's probably easiest if we take the Apps place as an example
144 [20:36] <kamstrup> The "result model" here is (surprise!) what you see when you search
145 [20:36] <kamstrup> The "groups model" defines the user visible grouping of the result model
146 [20:36] <kamstrup> If you open the apps place
147 [20:37] <kamstrup> (super-a)
148 [20:37] <kamstrup> You'll see two groups there
149 [20:37] <kamstrup> or wait - maybe you don't just yet
150 [20:37] <kamstrup> ... sorry
151 [20:37] <kamstrup> But there are 3 groups - let me write them for you
152 [20:37] <kamstrup> Installed
153 [20:37] <kamstrup> Available for Install
154 [20:37] <kamstrup> and Most Popular Apps
155 [20:38] <kamstrup> These partition the result set in 3
156 [20:38] <kamstrup> So on to the "sections"
157 [20:38] <kamstrup> Sections in the apps place are like "Accesories", "Media", "System", ...
158 [20:38] <kamstrup> Ie they partition not the result set, but more the "browsable space"
159 [20:38] <kamstrup> or the entire set of items you can potentially find
160 [20:39] <kamstrup> I think it'll be most easy for all if I spring my surprise now
161 [20:39] <kamstrup> So the surprise is that just today I have a fully working stack supporting place daemon implementations in Python!
162 [20:40] <kamstrup> This makes playing around with this stuff so much easier
163 [20:40] <kamstrup> So let me point you to a fully working place implemented in Python
164 [20:41] <kamstrup> Here: http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/files
165 [20:41] <kamstrup> So let's dig into unity-place-pythhon.py
166 [20:42] <kamstrup> Let's start at line 28 http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/view/head:/unity-place-python.py#L28
167 [20:42] <kamstrup> Here we create the Place Entry i talked about
168 [20:42] <kamstrup> we give it some random dbus path
169 [20:42] <kamstrup> The models we create are all DeeSharedModels
170 [20:43] <kamstrup> On each of the models we need to call set_schema()
171 [20:43] <kamstrup> The schema *must* be like this
172 [20:43] <kamstrup> you can see the definitions on https://wiki.ubuntu.com/Unity/Places#Results%20Model
173 [20:44] <kamstrup> The "model schemas" is really just a list of GVariant or DBus signatures
174 [20:44] <kamstrup> one signature for each column you want to have in the model
175 [20:44] <kamstrup> and you can even shove arbitrarily complex variants in the schema
176 [20:44] <kamstrup> it works
177 [20:44] <kamstrup> but for unity places we only use simple types such as strings "s" and uints "u"
178 [20:45] <kamstrup> On line 42
179 [20:45] <kamstrup> I create the sections model
180 [20:45] <kamstrup> i give it a bus name
181 [20:45] <kamstrup> which the model will use to rendevouz with other models with the same name
182 [20:45] <kamstrup> and sync up with them
183 [20:45] <kamstrup> and on line 44 i tell the place entry that i want to use this model as my sections
184 [20:46] <kamstrup> ditto for all the other models created in there
185 === neversfelde_ is now known as neversfelde
186 [20:46] <kamstrup> notice the models with a _global in the variable names
187 [20:46] <kamstrup> these models will be used for searches via the Dash
188 [20:47] <kamstrup> while those without global_ will be used when you search dedicated within this particular place
189 [20:47] <kamstrup> Let's skip a bit forward an look at line 73: http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/view/head:/unity-place-python.py#L73
190 [20:48] <kamstrup> here I connect to a bog standard Gobject signal from the place entry
191 [20:48] <kamstrup> The notify signal when the "active-search" property changes
192 [20:48] <kamstrup> On line 127 http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/view/head:/unity-place-python.py#L127
193 [20:48] <kamstrup> you'll see the callback i connect to this signal
194 [20:49] <kamstrup> Here i simply figure out what the new search string is and I start updating the model
195 [20:49] <kamstrup> the results model that is
196 [20:49] <kamstrup> To keep this example simple i always just call model.clear()
197 [20:50] <kamstrup> the "real" places - files and apps - don't do this, but they iteratively narrow down the results_model as you type
198 [20:50] <kamstrup> but that's quite a lot more complex and it works very well without it
199 [20:50] <kamstrup> So what does this particular place do..?
200 [20:51] <ClassBot> There are 10 minutes remaining in the current session.
201 [20:51] <kamstrup> It simply just splits the search string into letters and adds a hit for each letter pointing to the wikipedia article for that letter
202 [20:51] <kamstrup> You can see it splits the results into different groups
203 [20:51] <kamstrup> ok, I need to start wrapping up
204 [20:52] <kamstrup> One important note:
205 [20:52] <kamstrup> If you want to run the Python example you need a small hack for now
206 [20:52] <kamstrup> because all the latest jazz isn't in the package archives just yet
207 [20:52] <kamstrup> The hack you need is to take this file: http://bazaar.launchpad.net/~unity-team/dee/trunk/view/head:/bindings/python/Dee.py
208 [20:52] <kamstrup> and then:
209 [20:53] <kamstrup> download it somewhere and copy it to the right location like so:
210 [20:53] <kamstrup> sudo cp Dee.py /usr/lib/pymodules/python2.7/gi/overrides/Dee.py
211 [20:53] <kamstrup> This is needed to make Dee play well with Python
212 [20:53] <kamstrup> With that in place you should follow the guidelines in http://bazaar.launchpad.net/~unity-team/unity-place-sample/unity-place-python/view/head:/README
213 [20:55] <kamstrup> We probably don't have a lot of time to debug any problems now, but if you poke at it and find problems don't hesitate to ping me on the #ayatana channel
214 [20:55] <kamstrup> While I'm throwing links around - the most basic Vala example is lp:unity-place-sample
215 [20:56] <kamstrup> but you can dig in and find an example a tad more complex - doing youtube searches
216 [20:56] <ClassBot> There are 5 minutes remaining in the current session.
217 [20:56] <kamstrup> You can see the list of example places here https://code.launchpad.net/unity-place-sample
218 [20:56] <kamstrup> I'll try and put all illustrative examples there
219 [20:56] <kamstrup> when new ones crop up
220 [20:57] <kamstrup> So quickly on the future of libunity:
221 [20:57] <kamstrup> - We'll have API docs for C, Python, and Vala up very soon
222 [20:57] <kamstrup> - Dee already have good docs for C in the libdee-doc package . but we'll have Vala and Python docs for it too
223 [20:58] <kamstrup> - the longer term goal for libunity is to be able to integrate and instrument the entire Unity shell from top to bottom
224 [20:58] <kamstrup> So launcher and places is just the prelimanry goodies we can deliver for Natty
225 [20:58] <kamstrup> For N+1 you see some nice APIs to work with the various indicators and menus
226 [20:59] <kamstrup> And lastly - a disclaimer
227 [20:59] <kamstrup> Sorry to end with that
228 [20:59] <kamstrup> But we can't guarantee API or ABI stability at this point
229 [20:59] <kamstrup> we hope there will be no landslide changes
230 [20:59] <kamstrup> but small changes will trickle in
231 [21:00] <kamstrup> but we we'll provide stability at some point
232 [21:00] <kamstrup> Maybe N+1 or +2
233 [21:00] <kamstrup> and that's a wrap!
234 [21:00] <kamstrup> Any questions can go in #ayatana
MeetingLogs/devweek1103/RockingOutwithlibunity (last edited 2011-03-03 13:26:41 by ip98-182-50-39)