Merge lp:~pitti/indicator-session/libupower-glib into lp:indicator-session/0.1
- libupower-glib
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Ted Gould |
Proposed branch: | lp:~pitti/indicator-session/libupower-glib |
Merge into: | lp:indicator-session/0.1 |
Diff against target: |
261 lines (+39/-138) 2 files modified
configure.ac (+3/-1) src/session-service.c (+36/-137) |
To merge this branch: | bzr merge lp:~pitti/indicator-session/libupower-glib |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Pitt | Needs Resubmitting | ||
Ted Gould (community) | Needs Information | ||
David Barth | Needs Information | ||
Review via email: mp+19392@code.launchpad.net |
Commit message
Description of the change
Martin Pitt (pitti) wrote : | # |
David Barth (dbarth) wrote : | # |
The simplification of the code + relying on a specialized library seems better. Any disadvantages or compatibility issues with using /only/ libupower?
Martin Pitt (pitti) wrote : | # |
Well, the client-side library (libdevkit-
The obvious disadvantage that this patch brings is that it now introduces a dependency on a new library. I don't personally see a problem with it, but if you want to support upstream releases which build without dk-power/upower, I'm happy to add some configure autodetection and just disable the suspend/hibernate bits if libupower-glib is not available.
David Barth (dbarth) wrote : | # |
Martin Pitt wrote:
> The obvious disadvantage that this patch brings is that it now introduces a dependency on a new library. I don't personally see a problem with it, but if you want to support upstream releases which build without dk-power/upower, I'm happy to add some configure autodetection and just disable the suspend/hibernate bits if libupower-glib is not available.
>
I think that's fine. Adding that compatibility option can be restored
later, whereas getting user testing should be as soon as possible.
I'll let Ted comment, but would support the patch as is.
Thanks
David
Ted Gould (ted) wrote : | # |
There are a few issues with the patch.
It uses the _sync calls, but we have a requirement to make all DBus
operations async in the various indicator code. I'm unclear whether
up_client_
I generally prefer to check for all the libraries at once in
configure.ac. I find that this frustrates users less as they get all
the errors at once instead of getting one error, the next error, as they
go through the configure script.
It should really use g_strcmp0 instead of strcmp as it protects from
NULL strings which will otherwise be crashers.
It seems that the screensaver_
sleep is issued, and I don't see where it was re-added.
review needs-info
- 74. By Martin Pitt
-
do upower pkg-config check in the same block as the other libraries
- 75. By Martin Pitt
-
use g_strcmp0() for robustness
Martin Pitt (pitti) wrote : | # |
> It uses the _sync calls, but we have a requirement to make all DBus
> operations async in the various indicator code. I'm unclear whether
> up_client_
It gets the property synchronously on the first call (i. e. during initialization of indicator-session, and then just returns the cached value. I. e. in the "changed" signal handler the property values are already in the UpClient object's cache and no D-Bus communication needs to happen at all.
> I generally prefer to check for all the libraries at once in
> configure.ac. I find that this frustrates users less as they get all
.> the errors at once instead of getting one error, the next error, as they
> go through the configure script.
Fixed, r74.
> It should really use g_strcmp0 instead of strcmp as it protects from
> NULL strings which will otherwise be crashers.
Fixed, r75.
> It seems that the screensaver_
> sleep is issued, and I don't see where it was re-added.
Right after the up_client_
Ted Gould (ted) wrote : | # |
On Tue, 2010-02-16 at 15:28 +0000, Martin Pitt wrote:
> Review: Resubmit
> > It uses the _sync calls, but we have a requirement to make all DBus
> > operations async in the various indicator code. I'm unclear whether
> > up_client_
>
> It gets the property synchronously on the first call (i. e. during
> initialization of indicator-session, and then just returns the cached
> value. I. e. in the "changed" signal handler the property values are
> already in the UpClient object's cache and no D-Bus communication
> needs to happen at all.
So I went and grabbed the upower code and basically none of this is
Async. At all. I'd love to use the libupower library so that we're in
a better place with the interface, but man:
ted@shi:
*
src/up-daemon.c: ret = g_spawn_
ted@shi:
I'm not sure what to do here. David, do you have opinion? I'd hate to
rewrite the PolicyKit code, but we've made it a core architectural point
to only use async DBus. I doubt we could patch libupower at this point
as it'd be a pretty big patch.
Martin Pitt (pitti) wrote : | # |
> On Tue, 2010-02-16 at 15:28 +0000, Martin Pitt wrote:
> So I went and grabbed the upower code and basically none of this is
> Async. At all.
All the properties are cached on the client side, though, so reading properties is usually not using D-Bus at all (except for the first time, as I said).
The suspend/hibernate calls are also sync. libupower-glib deliberately does it that way, since it makes the program structure so much easier, since the machine will just die/stop underneath you anyway, and it saves you from dealing with all the async handlers.
> I'm not sure what to do here. David, do you have opinion? I'd hate to
> rewrite the PolicyKit code, but we've made it a core architectural point
> to only use async DBus.
OK, deferring to David for the general decision.
You don't actually need to ask PolicyKit yourself, though. I added upower D-Bus methods {Suspend,
> I doubt we could patch libupower at this point as it'd be a pretty big patch.
Might be worth discussing with Richard upstream, but I don't think he'd be happy about this. With my upstream hat on, I certainly wouldn't accept it, since it's not what libupower-glib is designed to be. The current API is meant to be an easy and robust integration into a glib/gobject context, and avoiding all unnecessary D-Bus calls. Adding a series of async D-Bus calls to it would make it (1) unnecessarily more complex, and (2) not provide any significant benefit over D-Bus directly.
So in summary, if i-s wants to use async calls only, we should keep the direct D-Bus interface, and need to add a call to {Suspend,
Thanks!
David Barth (dbarth) wrote : | # |
Ted Gould wrote:
> On Tue, 2010-02-16 at 15:28 +0000, Martin Pitt wrote:
>
>> Review: Resubmit
>>
>>> It uses the _sync calls, but we have a requirement to make all DBus
>>> operations async in the various indicator code. I'm unclear whether
>>> up_client_
>>>
>> It gets the property synchronously on the first call (i. e. during
>> initialization of indicator-session, and then just returns the cached
>> value. I. e. in the "changed" signal handler the property values are
>> already in the UpClient object's cache and no D-Bus communication
>> needs to happen at all.
>>
>
> So I went and grabbed the upower code and basically none of this is
> Async. At all. I'd love to use the libupower library so that we're in
> a better place with the interface, but man:
>
> ted@shi:
> *
> src/up-daemon.c: ret = g_spawn_
> ted@shi:
>
Ouch.
> I'm not sure what to do here. David, do you have opinion? I'd hate to
> rewrite the PolicyKit code, but we've made it a core architectural point
> to only use async DBus. I doubt we could patch libupower at this point
> as it'd be a pretty big patch.
>
Well, I guess then it means either keeping your async code, and...
ugh... adding the PK per-user policy bits (no idea how complex that can
be), or...
...adding a thread where calls to upower can block. The lib is not
advertised as being thread safe, but I haven't spotted big static
variables in the library source, so that may reasonably work.
David
Martin Pitt (pitti) wrote : | # |
Guys,
I'll work on an alternative branch which ports to the upower D-Bus interface directly. Then you can pick what you like better.
Martin Pitt (pitti) wrote : | # |
https:/
Ted Gould (ted) wrote : | # |
Accepted merge 19472 so this one is not valid.
Unmerged revisions
- 75. By Martin Pitt
-
use g_strcmp0() for robustness
- 74. By Martin Pitt
-
do upower pkg-config check in the same block as the other libraries
- 73. By Martin Pitt
-
port to libupower-glib
Stop talking to DeviceKit-power directly. Use the glib client library instead,
which is much easier to use, and also respects the per-user PolicyKit settings
(LP #432598).Also go straight to upower.
Preview Diff
1 | === modified file 'configure.ac' | |||
2 | --- configure.ac 2010-02-11 16:47:17 +0000 | |||
3 | +++ configure.ac 2010-02-16 15:30:33 +0000 | |||
4 | @@ -29,6 +29,7 @@ | |||
5 | 29 | INDICATOR_REQUIRED_VERSION=0.3.0 | 29 | INDICATOR_REQUIRED_VERSION=0.3.0 |
6 | 30 | DBUSMENUGTK_REQUIRED_VERSION=0.2.2 | 30 | DBUSMENUGTK_REQUIRED_VERSION=0.2.2 |
7 | 31 | POLKIT_REQUIRED_VERSION=0.92 | 31 | POLKIT_REQUIRED_VERSION=0.92 |
8 | 32 | UPOWER_REQUIRED_VERSION=0.9 | ||
9 | 32 | 33 | ||
10 | 33 | PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION | 34 | PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION |
11 | 34 | indicator >= $INDICATOR_REQUIRED_VERSION | 35 | indicator >= $INDICATOR_REQUIRED_VERSION |
12 | @@ -39,7 +40,8 @@ | |||
13 | 39 | DBUSMENUGLIB_REQUIRED_VERSION=0.1.1 | 40 | DBUSMENUGLIB_REQUIRED_VERSION=0.1.1 |
14 | 40 | 41 | ||
15 | 41 | PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION | 42 | PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION |
17 | 42 | indicator >= $INDICATOR_REQUIRED_VERSION) | 43 | indicator >= $INDICATOR_REQUIRED_VERSION |
18 | 44 | upower-glib >= $UPOWER_REQUIRED_VERSION) | ||
19 | 43 | 45 | ||
20 | 44 | AC_SUBST(SESSIONERVICE_CFLAGS) | 46 | AC_SUBST(SESSIONERVICE_CFLAGS) |
21 | 45 | AC_SUBST(SESSIONERVICE_LIBS) | 47 | AC_SUBST(SESSIONERVICE_LIBS) |
22 | 46 | 48 | ||
23 | === modified file 'src/session-service.c' | |||
24 | --- src/session-service.c 2010-02-08 22:46:35 +0000 | |||
25 | +++ src/session-service.c 2010-02-16 15:30:33 +0000 | |||
26 | @@ -31,6 +31,8 @@ | |||
27 | 31 | #include <dbus/dbus-glib.h> | 31 | #include <dbus/dbus-glib.h> |
28 | 32 | #include <dbus/dbus-glib-bindings.h> | 32 | #include <dbus/dbus-glib-bindings.h> |
29 | 33 | 33 | ||
30 | 34 | #include <upower.h> | ||
31 | 35 | |||
32 | 34 | #include <libdbusmenu-glib/server.h> | 36 | #include <libdbusmenu-glib/server.h> |
33 | 35 | #include <libdbusmenu-glib/menuitem.h> | 37 | #include <libdbusmenu-glib/menuitem.h> |
34 | 36 | #include <libdbusmenu-glib/client.h> | 38 | #include <libdbusmenu-glib/client.h> |
35 | @@ -44,10 +46,6 @@ | |||
36 | 44 | #include "users-service-dbus.h" | 46 | #include "users-service-dbus.h" |
37 | 45 | #include "lock-helper.h" | 47 | #include "lock-helper.h" |
38 | 46 | 48 | ||
39 | 47 | #define DKP_ADDRESS "org.freedesktop.DeviceKit.Power" | ||
40 | 48 | #define DKP_OBJECT "/org/freedesktop/DeviceKit/Power" | ||
41 | 49 | #define DKP_INTERFACE "org.freedesktop.DeviceKit.Power" | ||
42 | 50 | |||
43 | 51 | #define GUEST_SESSION_LAUNCHER "/usr/share/gdm/guest-session/guest-session-launch" | 49 | #define GUEST_SESSION_LAUNCHER "/usr/share/gdm/guest-session/guest-session-launch" |
44 | 52 | 50 | ||
45 | 53 | #define LOCKDOWN_DIR "/desktop/gnome/lockdown" | 51 | #define LOCKDOWN_DIR "/desktop/gnome/lockdown" |
46 | @@ -72,11 +70,7 @@ | |||
47 | 72 | 70 | ||
48 | 73 | static DbusmenuMenuitem * root_menuitem = NULL; | 71 | static DbusmenuMenuitem * root_menuitem = NULL; |
49 | 74 | static GMainLoop * mainloop = NULL; | 72 | static GMainLoop * mainloop = NULL; |
55 | 75 | static DBusGProxy * dkp_main_proxy = NULL; | 73 | static UpClient * up_client = NULL; |
51 | 76 | static DBusGProxy * dkp_prop_proxy = NULL; | ||
52 | 77 | |||
53 | 78 | static DBusGProxyCall * suspend_call = NULL; | ||
54 | 79 | static DBusGProxyCall * hibernate_call = NULL; | ||
56 | 80 | 74 | ||
57 | 81 | static DbusmenuMenuitem * hibernate_mi = NULL; | 75 | static DbusmenuMenuitem * hibernate_mi = NULL; |
58 | 82 | static DbusmenuMenuitem * suspend_mi = NULL; | 76 | static DbusmenuMenuitem * suspend_mi = NULL; |
59 | @@ -131,15 +125,6 @@ | |||
60 | 131 | } | 125 | } |
61 | 132 | } | 126 | } |
62 | 133 | 127 | ||
63 | 134 | /* A return from the command to sleep the system. Make sure | ||
64 | 135 | that we unthrottle the screensaver. */ | ||
65 | 136 | static void | ||
66 | 137 | sleep_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) | ||
67 | 138 | { | ||
68 | 139 | screensaver_unthrottle(); | ||
69 | 140 | return; | ||
70 | 141 | } | ||
71 | 142 | |||
72 | 143 | /* Let's put this machine to sleep, with some info on how | 128 | /* Let's put this machine to sleep, with some info on how |
73 | 144 | it should sleep. */ | 129 | it should sleep. */ |
74 | 145 | static void | 130 | static void |
75 | @@ -147,105 +132,41 @@ | |||
76 | 147 | { | 132 | { |
77 | 148 | gchar * type = (gchar *)userdata; | 133 | gchar * type = (gchar *)userdata; |
78 | 149 | 134 | ||
81 | 150 | if (dkp_main_proxy == NULL) { | 135 | if (up_client == NULL) { |
82 | 151 | g_warning("Can not %s as no DeviceKit Power Proxy", type); | 136 | g_warning("Can not %s as we have no upower client", type); |
83 | 152 | } | 137 | } |
84 | 153 | 138 | ||
85 | 154 | screensaver_throttle(type); | 139 | screensaver_throttle(type); |
86 | 155 | lock_screen(NULL, 0, NULL); | 140 | lock_screen(NULL, 0, NULL); |
87 | 156 | 141 | ||
143 | 157 | dbus_g_proxy_begin_call(dkp_main_proxy, | 142 | if (g_strcmp0(type, "Suspend") == 0) { |
144 | 158 | type, | 143 | up_client_suspend_sync(up_client, NULL, NULL); |
145 | 159 | sleep_response, | 144 | } else { |
146 | 160 | NULL, | 145 | up_client_hibernate_sync(up_client, NULL, NULL); |
147 | 161 | NULL, | 146 | } |
148 | 162 | G_TYPE_INVALID); | 147 | screensaver_unthrottle(); |
149 | 163 | 148 | ||
150 | 164 | return; | 149 | return; |
151 | 165 | } | 150 | } |
152 | 166 | 151 | ||
98 | 167 | /* A response to getting the suspend property */ | ||
99 | 168 | static void | ||
100 | 169 | suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) | ||
101 | 170 | { | ||
102 | 171 | suspend_call = NULL; | ||
103 | 172 | |||
104 | 173 | GValue candoit = {0}; | ||
105 | 174 | GError * error = NULL; | ||
106 | 175 | dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID); | ||
107 | 176 | if (error != NULL) { | ||
108 | 177 | g_warning("Unable to check suspend: %s", error->message); | ||
109 | 178 | g_error_free(error); | ||
110 | 179 | return; | ||
111 | 180 | } | ||
112 | 181 | g_debug("Got Suspend: %s", g_value_get_boolean(&candoit) ? "true" : "false"); | ||
113 | 182 | |||
114 | 183 | if (suspend_mi != NULL) { | ||
115 | 184 | dbusmenu_menuitem_property_set_value(suspend_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, &candoit); | ||
116 | 185 | } | ||
117 | 186 | |||
118 | 187 | return; | ||
119 | 188 | } | ||
120 | 189 | |||
121 | 190 | /* Response to getting the hibernate property */ | ||
122 | 191 | static void | ||
123 | 192 | hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) | ||
124 | 193 | { | ||
125 | 194 | hibernate_call = NULL; | ||
126 | 195 | |||
127 | 196 | GValue candoit = {0}; | ||
128 | 197 | GError * error = NULL; | ||
129 | 198 | dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID); | ||
130 | 199 | if (error != NULL) { | ||
131 | 200 | g_warning("Unable to check hibernate: %s", error->message); | ||
132 | 201 | g_error_free(error); | ||
133 | 202 | return; | ||
134 | 203 | } | ||
135 | 204 | g_debug("Got Hibernate: %s", g_value_get_boolean(&candoit) ? "true" : "false"); | ||
136 | 205 | |||
137 | 206 | if (suspend_mi != NULL) { | ||
138 | 207 | dbusmenu_menuitem_property_set_value(hibernate_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, &candoit); | ||
139 | 208 | } | ||
140 | 209 | |||
141 | 210 | return; | ||
142 | 211 | } | ||
153 | 212 | 152 | ||
154 | 213 | /* A signal that we need to recheck to ensure we can still | 153 | /* A signal that we need to recheck to ensure we can still |
155 | 214 | hibernate and/or suspend */ | 154 | hibernate and/or suspend */ |
156 | 215 | static void | 155 | static void |
158 | 216 | dpk_changed_cb (DBusGProxy * proxy, gpointer user_data) | 156 | up_changed_cb (UpClient * client, gpointer user_data) |
159 | 217 | { | 157 | { |
191 | 218 | /* Start Async call to see if we can hibernate */ | 158 | GValue candoit = {0}; |
192 | 219 | if (suspend_call == NULL) { | 159 | g_value_init (&candoit, G_TYPE_BOOLEAN); |
193 | 220 | suspend_call = dbus_g_proxy_begin_call(dkp_prop_proxy, | 160 | |
194 | 221 | "Get", | 161 | /* can we suspend? */ |
195 | 222 | suspend_prop_cb, | 162 | g_value_set_boolean(&candoit, up_client_get_can_suspend(up_client)); |
196 | 223 | NULL, | 163 | dbusmenu_menuitem_property_set_value(suspend_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, &candoit); |
197 | 224 | NULL, | 164 | g_debug("upower changed: can suspend: %s", g_value_get_boolean(&candoit) ? "true" : "false"); |
198 | 225 | G_TYPE_STRING, | 165 | |
199 | 226 | DKP_INTERFACE, | 166 | /* can we hibernate? */ |
200 | 227 | G_TYPE_STRING, | 167 | g_value_set_boolean(&candoit, up_client_get_can_hibernate(up_client)); |
201 | 228 | "can-suspend", | 168 | dbusmenu_menuitem_property_set_value(hibernate_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, &candoit); |
202 | 229 | G_TYPE_INVALID, | 169 | g_debug("upower changed: can hibernate: %s", g_value_get_boolean(&candoit) ? "true" : "false"); |
172 | 230 | G_TYPE_VALUE, | ||
173 | 231 | G_TYPE_INVALID); | ||
174 | 232 | } | ||
175 | 233 | |||
176 | 234 | /* Start Async call to see if we can suspend */ | ||
177 | 235 | if (hibernate_call == NULL) { | ||
178 | 236 | hibernate_call = dbus_g_proxy_begin_call(dkp_prop_proxy, | ||
179 | 237 | "Get", | ||
180 | 238 | hibernate_prop_cb, | ||
181 | 239 | NULL, | ||
182 | 240 | NULL, | ||
183 | 241 | G_TYPE_STRING, | ||
184 | 242 | DKP_INTERFACE, | ||
185 | 243 | G_TYPE_STRING, | ||
186 | 244 | "can-hibernate", | ||
187 | 245 | G_TYPE_INVALID, | ||
188 | 246 | G_TYPE_VALUE, | ||
189 | 247 | G_TYPE_INVALID); | ||
190 | 248 | } | ||
203 | 249 | 170 | ||
204 | 250 | return; | 171 | return; |
205 | 251 | } | 172 | } |
206 | @@ -254,39 +175,17 @@ | |||
207 | 254 | DKp checking. We're even setting up the calls for the props | 175 | DKp checking. We're even setting up the calls for the props |
208 | 255 | we need */ | 176 | we need */ |
209 | 256 | static void | 177 | static void |
229 | 257 | setup_dkp (void) { | 178 | setup_up (void) { |
230 | 258 | DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); | 179 | up_client = up_client_new(); |
231 | 259 | g_return_if_fail(bus != NULL); | 180 | g_return_if_fail(up_client != NULL); |
213 | 260 | |||
214 | 261 | if (dkp_main_proxy == NULL) { | ||
215 | 262 | dkp_main_proxy = dbus_g_proxy_new_for_name(bus, | ||
216 | 263 | DKP_ADDRESS, | ||
217 | 264 | DKP_OBJECT, | ||
218 | 265 | DKP_INTERFACE); | ||
219 | 266 | } | ||
220 | 267 | g_return_if_fail(dkp_main_proxy != NULL); | ||
221 | 268 | |||
222 | 269 | if (dkp_prop_proxy == NULL) { | ||
223 | 270 | dkp_prop_proxy = dbus_g_proxy_new_for_name(bus, | ||
224 | 271 | DKP_ADDRESS, | ||
225 | 272 | DKP_OBJECT, | ||
226 | 273 | DBUS_INTERFACE_PROPERTIES); | ||
227 | 274 | } | ||
228 | 275 | g_return_if_fail(dkp_prop_proxy != NULL); | ||
232 | 276 | 181 | ||
233 | 277 | /* Connect to changed signal */ | 182 | /* Connect to changed signal */ |
243 | 278 | dbus_g_proxy_add_signal(dkp_main_proxy, | 183 | g_signal_connect (up_client, "changed", |
244 | 279 | "Changed", | 184 | G_CALLBACK(up_changed_cb), |
245 | 280 | G_TYPE_INVALID); | 185 | NULL); |
237 | 281 | |||
238 | 282 | dbus_g_proxy_connect_signal(dkp_main_proxy, | ||
239 | 283 | "Changed", | ||
240 | 284 | G_CALLBACK(dpk_changed_cb), | ||
241 | 285 | NULL, | ||
242 | 286 | NULL); | ||
246 | 287 | 186 | ||
247 | 288 | /* Force an original "changed" event */ | 187 | /* Force an original "changed" event */ |
249 | 289 | dpk_changed_cb(dkp_main_proxy, NULL); | 188 | up_changed_cb(up_client, NULL); |
250 | 290 | 189 | ||
251 | 291 | return; | 190 | return; |
252 | 292 | } | 191 | } |
253 | @@ -639,7 +538,7 @@ | |||
254 | 639 | G_CALLBACK (user_removed), | 538 | G_CALLBACK (user_removed), |
255 | 640 | root_menuitem); | 539 | root_menuitem); |
256 | 641 | 540 | ||
258 | 642 | setup_dkp(); | 541 | setup_up(); |
259 | 643 | 542 | ||
260 | 644 | DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT); | 543 | DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT); |
261 | 645 | dbusmenu_server_set_root(server, root_menuitem); | 544 | dbusmenu_server_set_root(server, root_menuitem); |
DeviceKit-power, and now upower provide a very convenient client-side library, which also respects per-user PolicyKit privileges (see bug 432598).
This branch provides the port from DeviceKit-power D-Bus to libupower-glib.
I'd like to upload this into lucid really soon, to get it into alpha-3. Can you please merge this and do a new upstream release?
Thanks!