Merge lp:~darkxst/gnome-session/3.14 into lp:~ubuntu-desktop/gnome-session/ubuntu

Proposed by Tim Lunn on 2014-10-31
Status: Merged
Merged at revision: 320
Proposed branch: lp:~darkxst/gnome-session/3.14
Merge into: lp:~ubuntu-desktop/gnome-session/ubuntu
Diff against target: 6468 lines (+4434/-1736)
22 files modified
debian/changelog (+167/-0)
debian/control (+13/-15)
debian/control.in (+12/-10)
debian/defaults.list (+198/-200)
debian/gnome-session-common.dirs (+1/-0)
debian/gnome-session-common.install (+1/-0)
debian/gnome-session.install (+2/-0)
debian/patches/01_gnome-wm.patch (+0/-11)
debian/patches/02_fallback_desktop.patch (+0/-12)
debian/patches/03_fallback_desktop_makefile.patch (+0/-13)
debian/patches/101_screen_lock_on_suspend.patch (+0/-92)
debian/patches/10_session_save.patch (+0/-536)
debian/patches/12_no_gdm_fallback.patch (+0/-27)
debian/patches/13_display_session_properties.patch (+4/-4)
debian/patches/50_ubuntu_sessions.patch (+23/-13)
debian/patches/52_xdg_current_desktop.patch (+0/-46)
debian/patches/80_new_upstream_session_dialog.patch (+0/-699)
debian/patches/95_dbus_request_shutdown.patch (+12/-18)
debian/patches/git_fix_wrong_unref_call.patch (+0/-32)
debian/patches/revert_remove_gnome_session_properties.patch (+3992/-0)
debian/patches/series (+1/-6)
debian/rules (+8/-2)
To merge this branch: bzr merge lp:~darkxst/gnome-session/3.14
Reviewer Review Type Date Requested Status
Martin Pitt 2014-10-31 Approve on 2014-10-31
Review via email: mp+240212@code.launchpad.net

Description of the change

gnome-session-properties app was removed upstream, I have reverted it since I assume its used in Ubuntu.

To post a comment you must log in.
Martin Pitt (pitti) wrote :

Thanks for the merge! debian/control needed an update for commenting out xwayland and @GNOME_TEAM@, I did that. Otherwise looks good, merged/uploaded.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-10-15 10:18:16 +0000
3+++ debian/changelog 2014-10-31 04:52:33 +0000
4@@ -1,3 +1,142 @@
5+gnome-session (3.14.0-2ubuntu1) UNRELEASED; urgency=medium
6+
7+ * Merge from Debian, Remaining Changes:
8+ - debian/control.in:
9+ + Recommend session-migration
10+ * don't depend on xwayland
11+ - debian/gnome-session.install: Don't install wayland session for now
12+ since its not yet possible to run it
13+ - Split ubuntu-session out of gnome-session.
14+ - Add upstart user session
15+ - debian/gnome-session-bin.postinst, debian/gnome-session-bin.prerm:
16+ Moved registering gnome-session binary as a session manager to
17+ gnome-session-bin package
18+ - don't install defaults.list (installed by desktop-file-utils in ubuntu):
19+ debian/gnome-session-common.dirs and gnome-session-common.install
20+ - debian/patches/22_support_autostart_delay.patch:
21+ Bugzilla patch to support adding a delay to autostart apps, using
22+ a "X-GNOME-Autostart-Delay" key in the desktop file
23+ - debian/patches/50_ubuntu_sessions.patch:
24+ + Add Ubuntu session
25+ + gnome-shell.desktop adds --session=gnome now that the "ubuntu" session
26+ is the default. Use TryExec to test if gnome-shell is installed.
27+ - debian/patches/51_remove_session_saving_from_gui.patch:
28+ add GNOME_SESSION_SAVE environment variable for people wanting to
29+ use the save session still, knowing that it can break your system
30+ if used unwisely (LP: #771896)
31+ - debian/patches/52_xdg_current_desktop.patch:
32+ Set XDG_CURRENT_DESKTOP inside gnome-session based on a
33+ new key 'DesktopName' in gnome-session .desktop files.
34+ - debian/patches/53_add_sessionmigration.patch, debian/control:
35+ recommends and launch the session-migration if present at the start
36+ of the session. This sync tool is running different session migration
37+ scripts that can be provided in various desktop packages.
38+ - debian/patches/95_dbus_request_shutdown.patch:
39+ Add "RequestShutdown" and "RequestReboot" DBus methods to allow other
40+ applications to shutdown or reboot the machine via the session manager.
41+ - debian/patches/103_kill_the_fail_whale.patch:
42+ Kill the Fail Whale as it tends to be more annoying than helpful
43+ * debian/patches/revert_remove_gnome_session_properties.patch
44+ * Dropped Changes:
45+ * debian/patches/52_xdg_current_desktop.patch: Dropped Upsream includes a
46+ fallback to set this now.
47+ * Remove patches that have been disabled since 3.8
48+
49+ -- Tim Lunn <tim@feathertop.org> Fri, 31 Oct 2014 09:57:57 +1100
50+
51+gnome-session (3.14.0-2) unstable; urgency=medium
52+
53+ * Update debian/defaults.list to catch up with times:
54+ - Drop swfdec-player which is long gone.
55+ - Update File-Roller to new .desktop file name.
56+ - Update GEdit to new .desktop file name.
57+ - Update Font Viewer to new .desktop file name.
58+ - Update Nautilus to new .desktop file name.
59+ - Update Totem to new .desktop file name.
60+ (Closes: #763595)
61+ Note: This breaks the defaults for those who install the new
62+ gnome-session-common and keep their << 3.14 application
63+ packages (partial upgrades).
64+
65+ -- Andreas Henriksson <andreas@fatal.se> Wed, 01 Oct 2014 16:11:51 +0200
66+
67+gnome-session (3.14.0-1) unstable; urgency=medium
68+
69+ * New upstream release.
70+ * Upload to unstable.
71+
72+ -- Andreas Henriksson <andreas@fatal.se> Mon, 22 Sep 2014 20:42:37 +0200
73+
74+gnome-session (3.13.3-1) experimental; urgency=medium
75+
76+ [ Andreas Henriksson ]
77+ * New upstream development release.
78+
79+ [ Josselin Mouette ]
80+ * Fix typos in defaults.list. Closes: #759429.
81+
82+ -- Andreas Henriksson <andreas@fatal.se> Fri, 05 Sep 2014 15:09:51 -0700
83+
84+gnome-session (3.12.1-4) experimental; urgency=medium
85+
86+ * gnome-session: Install wayland session files.
87+ * gnome-session-bin: add xwayland dependency on linux-any.
88+
89+ -- Andreas Henriksson <andreas@fatal.se> Sat, 02 Aug 2014 17:22:46 +0200
90+
91+gnome-session (3.12.1-3) unstable; urgency=medium
92+
93+ [ Laurent Bigonville ]
94+ * debian/control.in: Recommends libpam-systemd instead of systemd on linux
95+ architectures and add recommends against consolekit on non linux arch.
96+ Also move the Recommends to the arch any package.
97+
98+ [ Andreas Henriksson ]
99+ * Drop build-dependency on libupower-glib-dev (<< 0.99.0) [!linux-any]
100+ - This can no longer be fulfilled anyway.
101+ * Upload to unstable.
102+
103+ -- Andreas Henriksson <andreas@fatal.se> Mon, 14 Jul 2014 23:57:59 +0200
104+
105+gnome-session (3.12.1-2) experimental; urgency=medium
106+
107+ * Enable systemd support on linux architectures only
108+
109+ -- Laurent Bigonville <bigon@debian.org> Sun, 04 May 2014 15:02:14 +0200
110+
111+gnome-session (3.12.1-1) experimental; urgency=medium
112+
113+ * New upstream release
114+
115+ -- Sjoerd Simons <sjoerd@debian.org> Sun, 27 Apr 2014 18:03:58 +0200
116+
117+gnome-session (3.12.0-1) experimental; urgency=medium
118+
119+ * New upstream release.
120+ * Require upower build-dependency to be lower then 0.99.x and
121+ only on non-linux.
122+ - The new upower 0.99.x does not implement the used interfaces.
123+ - Functionality is available via logind.
124+ * Drop installing /usr/share/applications
125+ - new upstream no longer ships gnome-session-properties
126+ * Bump build-dependency on libglib2.0-dev to >= 2.39.90
127+ - using g_subprocess requires a recent glib.
128+ * Bump Standards-Version to 3.9.5
129+
130+ -- Andreas Henriksson <andreas@fatal.se> Wed, 26 Mar 2014 22:51:00 +0100
131+
132+gnome-session (3.10.1-1) experimental; urgency=low
133+
134+ * New upstream release
135+ * debian/patches/13_display_session_properties.patch
136+ + Dropped. gnome-session-properties has been dropped upstream
137+ * debian/rules, debian/control.in: Explicitely enabled systemd support and
138+ recommend systemd for logind. Recommends is enough as gnome-session should
139+ fall back to consolekit
140+ * debian/control.in: Update build-depends
141+
142+ -- Sjoerd Simons <sjoerd@debian.org> Fri, 01 Nov 2013 23:04:59 +0100
143+
144 gnome-session (3.9.90-0ubuntu16) utopic; urgency=medium
145
146 * set GNOME_SHELL_SESSION_MODE for gnome-classic sessions (LP: #1381297)
147@@ -136,6 +275,34 @@
148
149 -- Jeremy Bicha <jbicha@ubuntu.com> Mon, 26 Aug 2013 08:47:31 -0400
150
151+gnome-session (3.8.4-3) unstable; urgency=medium
152+
153+ * debian/control.in:
154+ +Break gdm3 < 3.8. Closes: #726498.
155+
156+ -- Emilio Pozuelo Monfort <pochu@debian.org> Sat, 26 Oct 2013 16:12:19 +0200
157+
158+gnome-session (3.8.4-2) unstable; urgency=low
159+
160+ * Upload to unstable.
161+
162+ -- Emilio Pozuelo Monfort <pochu@debian.org> Sun, 13 Oct 2013 17:27:19 +0200
163+
164+gnome-session (3.8.4-1) experimental; urgency=low
165+
166+ [ Jeremy Bicha ]
167+ * New upstream release
168+ * debian/control.in:
169+ - Don't recommend gnome-power-manager
170+ * Completely drop gnome-session-fallback (moved to gnome-panel source)
171+
172+ [ Michael Biebl ]
173+ * Drop Build-Depends on libnotify-dev. No longer necessary after
174+ debian/patches/04_fallback_warning_notify.patch has been removed.
175+ * Bump Standards-Version to 3.9.4. No further changes.
176+
177+ -- Michael Biebl <biebl@debian.org> Fri, 11 Oct 2013 17:07:46 +0200
178+
179 gnome-session (3.8.2.1-1ubuntu5) saucy; urgency=low
180
181 * debian/patches/50_ubuntu_sessions.patch:
182
183=== modified file 'debian/control'
184--- debian/control 2014-09-30 17:01:54 +0000
185+++ debian/control 2014-10-31 04:52:33 +0000
186@@ -1,31 +1,22 @@
187-# This file is autogenerated. DO NOT EDIT!
188-#
189-# Modifications should be made to debian/control.in instead.
190-# This file is regenerated automatically in the clean target.
191 Source: gnome-session
192 Section: gnome
193 Priority: optional
194 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
195 XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
196-Uploaders: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
197-Standards-Version: 3.9.3
198+Uploaders: @GNOME_TEAM@
199+Standards-Version: 3.9.5
200 Build-Depends: cdbs (>= 0.4.41),
201 dh-autoreconf,
202 debhelper (>= 8),
203 gnome-pkg-tools (>= 0.13),
204 gnome-common,
205 intltool (>= 0.40.6),
206- libglib2.0-dev (>= 2.34.0),
207+ libglib2.0-dev (>= 2.39.90),
208 libgtk-3-dev (>= 2.90.7),
209- libupower-glib-dev (>= 0.9.0),
210 libdbus-glib-1-dev (>= 0.76),
211 libjson-glib-dev (>= 0.10),
212- libnotify-dev (>= 0.7),
213- libgnome-desktop-3-dev (>= 3.7.90),
214+ libgnome-desktop-3-dev (>= 3.9.91),
215 libsm-dev,
216- libsystemd-daemon-dev,
217- libsystemd-journal-dev,
218- libsystemd-login-dev (>= 183),
219 libice-dev,
220 libx11-dev,
221 libxt-dev,
222@@ -37,13 +28,17 @@
223 libxrender-dev,
224 xmlto,
225 xsltproc,
226- xtrans-dev
227+ xtrans-dev,
228+ libsystemd-login-dev (>= 183) [linux-any],
229+ libsystemd-daemon-dev [linux-any],
230+ libsystemd-journal-dev [linux-any]
231 Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu
232
233 Package: gnome-session
234 Architecture: all
235 Depends: ${misc:Depends},
236 gnome-settings-daemon (>= 3.0),
237+ gnome-shell (>= 3.0),
238 gnome-session-bin (>= ${binary:Version}),
239 gnome-session-bin (<< ${gnome:NextVersion}),
240 gnome-session-common (= ${binary:Version})
241@@ -92,8 +87,11 @@
242 ${misc:Depends},
243 dbus-x11,
244 gsettings-desktop-schemas,
245- upower (>= 0.9.0)
246+ upower (>= 0.9.0),
247+ xwayland [linux-any]
248+Recommends: libpam-systemd [linux-any], consolekit [!linux-any]
249 Conflicts: gnome-session (<< 3.9.90-0ubuntu8)
250+Breaks: gdm (<< 3.8)
251 Description: GNOME Session Manager - Minimal runtime
252 The GNOME Session Manager is in charge of starting the core components
253 of the GNOME desktop, and applications that should be launched at
254
255=== modified file 'debian/control.in'
256--- debian/control.in 2014-02-20 07:56:43 +0000
257+++ debian/control.in 2014-10-31 04:52:33 +0000
258@@ -4,24 +4,19 @@
259 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
260 XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
261 Uploaders: @GNOME_TEAM@
262-Standards-Version: 3.9.3
263+Standards-Version: 3.9.5
264 Build-Depends: cdbs (>= 0.4.41),
265 dh-autoreconf,
266 debhelper (>= 8),
267 gnome-pkg-tools (>= 0.13),
268 gnome-common,
269 intltool (>= 0.40.6),
270- libglib2.0-dev (>= 2.34.0),
271+ libglib2.0-dev (>= 2.39.90),
272 libgtk-3-dev (>= 2.90.7),
273- libupower-glib-dev (>= 0.9.0),
274 libdbus-glib-1-dev (>= 0.76),
275 libjson-glib-dev (>= 0.10),
276- libnotify-dev (>= 0.7),
277- libgnome-desktop-3-dev (>= 3.7.90),
278+ libgnome-desktop-3-dev (>= 3.9.91),
279 libsm-dev,
280- libsystemd-daemon-dev,
281- libsystemd-journal-dev,
282- libsystemd-login-dev (>= 183),
283 libice-dev,
284 libx11-dev,
285 libxt-dev,
286@@ -33,13 +28,17 @@
287 libxrender-dev,
288 xmlto,
289 xsltproc,
290- xtrans-dev
291+ xtrans-dev,
292+ libsystemd-login-dev (>= 183) [linux-any],
293+ libsystemd-daemon-dev [linux-any],
294+ libsystemd-journal-dev [linux-any]
295 Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu
296
297 Package: gnome-session
298 Architecture: all
299 Depends: ${misc:Depends},
300 gnome-settings-daemon (>= 3.0),
301+ gnome-shell (>= 3.0),
302 gnome-session-bin (>= ${binary:Version}),
303 gnome-session-bin (<< ${gnome:NextVersion}),
304 gnome-session-common (= ${binary:Version})
305@@ -88,8 +87,11 @@
306 ${misc:Depends},
307 dbus-x11,
308 gsettings-desktop-schemas,
309- upower (>= 0.9.0)
310+ upower (>= 0.9.0),
311+# xwayland [linux-any]
312+Recommends: libpam-systemd [linux-any], consolekit [!linux-any]
313 Conflicts: gnome-session (<< 3.9.90-0ubuntu8)
314+Breaks: gdm (<< 3.8)
315 Description: GNOME Session Manager - Minimal runtime
316 The GNOME Session Manager is in charge of starting the core components
317 of the GNOME desktop, and applications that should be launched at
318
319=== modified file 'debian/defaults.list'
320--- debian/defaults.list 2014-09-11 20:52:35 +0000
321+++ debian/defaults.list 2014-10-31 04:52:33 +0000
322@@ -64,84 +64,84 @@
323 application/mbox=evolution.desktop
324 message/rfc822=evolution.desktop
325 x-scheme-handler/mailto=evolution.desktop
326-application/x-7z-compressed=file-roller.desktop
327-application/x-7z-compressed-tar=file-roller.desktop
328-application/x-ace=file-roller.desktop
329-application/x-alz=file-roller.desktop
330-application/x-ar=file-roller.desktop
331-application/x-arj=file-roller.desktop
332-application/x-bzip=file-roller.desktop
333-application/x-bzip-compressed-tar=file-roller.desktop
334-application/x-bzip1=file-roller.desktop
335-application/x-bzip1-compressed-tar=file-roller.desktop
336-application/x-cabinet=file-roller.desktop
337-application/x-cd-image=file-roller.desktop
338-application/x-compress=file-roller.desktop
339-application/x-compressed-tar=file-roller.desktop
340-application/x-cpio=file-roller.desktop
341-application/x-deb=file-roller.desktop
342-application/x-ear=file-roller.desktop
343-application/x-gtar=file-roller.desktop
344-application/x-gzip=file-roller.desktop
345-application/x-java-archive=file-roller.desktop
346-application/x-lha=file-roller.desktop
347-application/x-lhz=file-roller.desktop
348-application/x-lzip=file-roller.desktop
349-application/x-lzip-compressed-tar=file-roller.desktop
350-application/x-lzma=file-roller.desktop
351-application/x-lzma-compressed-tar=file-roller.desktop
352-application/x-lzop=file-roller.desktop
353-application/x-lzop-compressed-tar=file-roller.desktop
354-application/x-rar=file-roller.desktop
355-application/x-rar-compressed=file-roller.desktop
356-application/x-rpm=file-roller.desktop
357-application/x-rzip=file-roller.desktop
358-application/x-tar=file-roller.desktop
359-application/x-tarz=file-roller.desktop
360-application/x-stuffit=file-roller.desktop
361-application/x-war=file-roller.desktop
362-application/x-xz=file-roller.desktop
363-application/x-xz-compressed-tar=file-roller.desktop
364-application/x-zip=file-roller.desktop
365-application/x-zip-compressed=file-roller.desktop
366-application/x-zoo=file-roller.desktop
367-application/zip=file-roller.desktop
368-multipart/x-zip=file-roller.desktop
369-text/plain=gedit.desktop
370-text/css=gedit.desktop
371-text/javascript=gedit.desktop
372-text/mathml=gedit.desktop
373-text/x-c++hdr=gedit.desktop
374-text/x-c++src=gedit.desktop
375-text/x-csrc=gedit.desktop
376-text/x-chdr=gedit.desktop
377-text/x-dtd=gedit.desktop
378-text/x-java=gedit.desktop
379-text/x-javascript=gedit.desktop
380-text/x-makefile=gedit.desktop
381-text/x-moc=gedit.desktop
382-text/x-pascal=gedit.desktop
383-text/x-patch=gedit.desktop
384-text/x-perl=gedit.desktop
385-text/x-php=gedit.desktop
386-text/x-python=gedit.desktop
387-text/x-sql=gedit.desktop
388-text/x-tcl=gedit.desktop
389-text/x-tex=gedit.desktop
390-text/xml=gedit.desktop
391-application/javascript=gedit.desktop
392-application/x-cgi=gedit.desktop
393-application/x-javascript=gedit.desktop
394-application/x-perl=gedit.desktop
395-application/x-php=gedit.desktop
396-application/x-python=gedit.desktop
397-application/x-shellscript=gedit.desktop
398-application/xml=gedit.desktop
399-application/xml-dtd=gedit.desktop
400-application/x-font-ttf=gnome-font-viewer.desktop
401-application/x-font-pcf=gnome-font-viewer.desktop
402-application/x-font-type1=gnome-font-viewer.desktop
403-application/x-font-otf=gnome-font-viewer.desktop
404+application/x-7z-compressed=org.gnome.FileRoller.desktop
405+application/x-7z-compressed-tar=org.gnome.FileRoller.desktop
406+application/x-ace=org.gnome.FileRoller.desktop
407+application/x-alz=org.gnome.FileRoller.desktop
408+application/x-ar=org.gnome.FileRoller.desktop
409+application/x-arj=org.gnome.FileRoller.desktop
410+application/x-bzip=org.gnome.FileRoller.desktop
411+application/x-bzip-compressed-tar=org.gnome.FileRoller.desktop
412+application/x-bzip1=org.gnome.FileRoller.desktop
413+application/x-bzip1-compressed-tar=org.gnome.FileRoller.desktop
414+application/x-cabinet=org.gnome.FileRoller.desktop
415+application/x-cd-image=org.gnome.FileRoller.desktop
416+application/x-compress=org.gnome.FileRoller.desktop
417+application/x-compressed-tar=org.gnome.FileRoller.desktop
418+application/x-cpio=org.gnome.FileRoller.desktop
419+application/x-deb=org.gnome.FileRoller.desktop
420+application/x-ear=org.gnome.FileRoller.desktop
421+application/x-gtar=org.gnome.FileRoller.desktop
422+application/x-gzip=org.gnome.FileRoller.desktop
423+application/x-java-archive=org.gnome.FileRoller.desktop
424+application/x-lha=org.gnome.FileRoller.desktop
425+application/x-lhz=org.gnome.FileRoller.desktop
426+application/x-lzip=org.gnome.FileRoller.desktop
427+application/x-lzip-compressed-tar=org.gnome.FileRoller.desktop
428+application/x-lzma=org.gnome.FileRoller.desktop
429+application/x-lzma-compressed-tar=org.gnome.FileRoller.desktop
430+application/x-lzop=org.gnome.FileRoller.desktop
431+application/x-lzop-compressed-tar=org.gnome.FileRoller.desktop
432+application/x-rar=org.gnome.FileRoller.desktop
433+application/x-rar-compressed=org.gnome.FileRoller.desktop
434+application/x-rpm=org.gnome.FileRoller.desktop
435+application/x-rzip=org.gnome.FileRoller.desktop
436+application/x-tar=org.gnome.FileRoller.desktop
437+application/x-tarz=org.gnome.FileRoller.desktop
438+application/x-stuffit=org.gnome.FileRoller.desktop
439+application/x-war=org.gnome.FileRoller.desktop
440+application/x-xz=org.gnome.FileRoller.desktop
441+application/x-xz-compressed-tar=org.gnome.FileRoller.desktop
442+application/x-zip=org.gnome.FileRoller.desktop
443+application/x-zip-compressed=org.gnome.FileRoller.desktop
444+application/x-zoo=org.gnome.FileRoller.desktop
445+application/zip=org.gnome.FileRoller.desktop
446+multipart/x-zip=org.gnome.FileRoller.desktop
447+text/plain=org.gnome.gedit.desktop
448+text/css=org.gnome.gedit.desktop
449+text/javascript=org.gnome.gedit.desktop
450+text/mathml=org.gnome.gedit.desktop
451+text/x-c++hdr=org.gnome.gedit.desktop
452+text/x-c++src=org.gnome.gedit.desktop
453+text/x-csrc=org.gnome.gedit.desktop
454+text/x-chdr=org.gnome.gedit.desktop
455+text/x-dtd=org.gnome.gedit.desktop
456+text/x-java=org.gnome.gedit.desktop
457+text/x-javascript=org.gnome.gedit.desktop
458+text/x-makefile=org.gnome.gedit.desktop
459+text/x-moc=org.gnome.gedit.desktop
460+text/x-pascal=org.gnome.gedit.desktop
461+text/x-patch=org.gnome.gedit.desktop
462+text/x-perl=org.gnome.gedit.desktop
463+text/x-php=org.gnome.gedit.desktop
464+text/x-python=org.gnome.gedit.desktop
465+text/x-sql=org.gnome.gedit.desktop
466+text/x-tcl=org.gnome.gedit.desktop
467+text/x-tex=org.gnome.gedit.desktop
468+text/xml=org.gnome.gedit.desktop
469+application/javascript=org.gnome.gedit.desktop
470+application/x-cgi=org.gnome.gedit.desktop
471+application/x-javascript=org.gnome.gedit.desktop
472+application/x-perl=org.gnome.gedit.desktop
473+application/x-php=org.gnome.gedit.desktop
474+application/x-python=org.gnome.gedit.desktop
475+application/x-shellscript=org.gnome.gedit.desktop
476+application/xml=org.gnome.gedit.desktop
477+application/xml-dtd=org.gnome.gedit.desktop
478+application/x-font-ttf=org.gnome.font-viewer.desktop
479+application/x-font-pcf=org.gnome.font-viewer.desktop
480+application/x-font-type1=org.gnome.font-viewer.desktop
481+application/x-font-otf=org.gnome.font-viewer.desktop
482 application/x-gnumeric=gnumeric.desktop
483 application/tab-separated-values=gnumeric.desktop
484 text/tab-separated-values=gnumeric.desktop
485@@ -218,130 +218,128 @@
486 application/vnd.openxmlformats-officedocument.wordprocessingml.template=libreoffice-writer.desktop
487 application/vnd.ms-word.template.macroenabled.12=libreoffice-writer.desktop
488 x-content/software=nautilus-autorun-software.desktop
489-inode/directory=nautilus.desktop
490-application/x-gnome-saved-search=nautilus.desktop
491+inode/directory=org.gnome.Nautilus.desktop
492+application/x-gnome-saved-search=org.gnome.Nautilus.desktop
493 x-content/audio-player=rhythmbox.desktop
494 x-content/audio-cdda=sound-juicer.desktop
495-application/x-shockwave-flash=swfdec-player.desktop
496-application/futuresplash=swfdec-player.desktop
497-application/mxf=totem.desktop
498-application/ogg=totem.desktop
499-application/ram=totem.desktop
500-application/sdp=totem.desktop
501-application/smil=totem.desktop
502-application/smil+xml=totem.desktop
503-application/vnd.ms-wpl=totem.desktop
504-application/vnd.rn-realmedia=totem.desktop
505-application/x-extension-m4a=totem.desktop
506-application/x-extension-mp4=totem.desktop
507-application/x-flac=totem.desktop
508-application/x-flash-video=totem.desktop
509-application/x-matroska=totem.desktop
510-application/x-netshow-channel=totem.desktop
511-application/x-ogg=totem.desktop
512-application/x-quicktime-media-link=totem.desktop
513-application/x-quicktimeplayer=totem.desktop
514-application/x-shorten=totem.desktop
515-application/x-smil=totem.desktop
516-application/xspf+xml=totem.desktop
517-audio/3gpp=totem.desktop
518-audio/ac3=totem.desktop
519-audio/AMR=totem.desktop
520-audio/AMR-WB=totem.desktop
521-audio/basic=totem.desktop
522-audio/flac=totem.desktop
523-audio/midi=totem.desktop
524-audio/mp4=totem.desktop
525-audio/mpeg=totem.desktop
526-audio/mpegurl=totem.desktop
527-audio/ogg=totem.desktop
528-audio/prs.sid=totem.desktop
529-audio/vnd.rn-realaudio=totem.desktop
530-audio/x-ape=totem.desktop
531-audio/x-flac=totem.desktop
532-audio/x-gsm=totem.desktop
533-audio/x-it=totem.desktop
534-audio/x-m4a=totem.desktop
535-audio/x-matroska=totem.desktop
536-audio/x-mod=totem.desktop
537-audio/x-mp3=totem.desktop
538-audio/x-mpeg=totem.desktop
539-audio/x-mpegurl=totem.desktop
540-audio/x-ms-asf=totem.desktop
541-audio/x-ms-asx=totem.desktop
542-audio/x-ms-wax=totem.desktop
543-audio/x-ms-wma=totem.desktop
544-audio/x-musepack=totem.desktop
545-audio/x-pn-aiff=totem.desktop
546-audio/x-pn-au=totem.desktop
547-audio/x-pn-realaudio=totem.desktop
548-audio/x-pn-realaudio-plugin=totem.desktop
549-audio/x-pn-wav=totem.desktop
550-audio/x-pn-windows-acm=totem.desktop
551-audio/x-realaudio=totem.desktop
552-audio/x-real-audio=totem.desktop
553-audio/x-sbc=totem.desktop
554-audio/x-scpls=totem.desktop
555-audio/x-speex=totem.desktop
556-audio/x-tta=totem.desktop
557-audio/x-vorbis=totem.desktop
558-audio/x-vorbis+ogg=totem.desktop
559-audio/x-wav=totem.desktop
560-audio/x-wavpack=totem.desktop
561-audio/x-xm=totem.desktop
562-image/vnd.rn-realpix=totem.desktop
563-image/x-pict=totem.desktop
564-misc/ultravox=totem.desktop
565-text/google-video-pointer=totem.desktop
566-text/x-google-video-pointer=totem.desktop
567-video/3gpp=totem.desktop
568-video/dv=totem.desktop
569-video/fli=totem.desktop
570-video/flv=totem.desktop
571-video/mp2t=totem.desktop
572-video/mp4=totem.desktop
573-video/mp4v-es=totem.desktop
574-video/mpeg=totem.desktop
575-video/msvideo=totem.desktop
576-video/ogg=totem.desktop
577-video/quicktime=totem.desktop
578-video/vivo=totem.desktop
579-video/vnd.divx=totem.desktop
580-video/vnd.rn-realvideo=totem.desktop
581-video/vnd.vivo=totem.desktop
582-video/webm=totem.desktop
583-video/x-anim=totem.desktop
584-video/x-avi=totem.desktop
585-video/x-flc=totem.desktop
586-video/x-fli=totem.desktop
587-video/x-flic=totem.desktop
588-video/x-flv=totem.desktop
589-video/x-m4v=totem.desktop
590-video/x-matroska=totem.desktop
591-video/x-mpeg=totem.desktop
592-video/x-ms-asf=totem.desktop
593-video/x-ms-asx=totem.desktop
594-video/x-msvideo=totem.desktop
595-video/x-ms-wm=totem.desktop
596-video/x-ms-wmv=totem.desktop
597-video/x-ms-wmx=totem.desktop
598-video/x-ms-wvx=totem.desktop
599-video/x-nsv=totem.desktop
600-video/x-ogm+ogg=totem.desktop
601-video/x-theora+ogg=totem.desktop
602-video/x-totem-stream=totem.desktop
603-x-content/video-dvd=totem.desktop
604-x-content/video-vcd=totem.desktop
605-x-content/video-svcd=totem.desktop
606-x-scheme-handler/pnm=totem.desktop
607-x-scheme-handler/mms=totem.desktop
608-x-scheme-handler/net=totem.desktop
609-x-scheme-handler/rtp=totem.desktop
610-x-scheme-handler/rtsp=totem.desktop
611-x-scheme-handler/mmsh=totem.desktop
612-x-scheme-handler/uvox=totem.desktop
613-x-scheme-handler/icy=totem.desktop
614-x-scheme-handler/icyx=totem.desktop
615+application/mxf=org.gnome.Totem.desktop
616+application/ogg=org.gnome.Totem.desktop
617+application/ram=org.gnome.Totem.desktop
618+application/sdp=org.gnome.Totem.desktop
619+application/smil=org.gnome.Totem.desktop
620+application/smil+xml=org.gnome.Totem.desktop
621+application/vnd.ms-wpl=org.gnome.Totem.desktop
622+application/vnd.rn-realmedia=org.gnome.Totem.desktop
623+application/x-extension-m4a=org.gnome.Totem.desktop
624+application/x-extension-mp4=org.gnome.Totem.desktop
625+application/x-flac=org.gnome.Totem.desktop
626+application/x-flash-video=org.gnome.Totem.desktop
627+application/x-matroska=org.gnome.Totem.desktop
628+application/x-netshow-channel=org.gnome.Totem.desktop
629+application/x-ogg=org.gnome.Totem.desktop
630+application/x-quicktime-media-link=org.gnome.Totem.desktop
631+application/x-quicktimeplayer=org.gnome.Totem.desktop
632+application/x-shorten=org.gnome.Totem.desktop
633+application/x-smil=org.gnome.Totem.desktop
634+application/xspf+xml=org.gnome.Totem.desktop
635+audio/3gpp=org.gnome.Totem.desktop
636+audio/ac3=org.gnome.Totem.desktop
637+audio/AMR=org.gnome.Totem.desktop
638+audio/AMR-WB=org.gnome.Totem.desktop
639+audio/basic=org.gnome.Totem.desktop
640+audio/flac=org.gnome.Totem.desktop
641+audio/midi=org.gnome.Totem.desktop
642+audio/mp4=org.gnome.Totem.desktop
643+audio/mpeg=org.gnome.Totem.desktop
644+audio/mpegurl=org.gnome.Totem.desktop
645+audio/ogg=org.gnome.Totem.desktop
646+audio/prs.sid=org.gnome.Totem.desktop
647+audio/vnd.rn-realaudio=org.gnome.Totem.desktop
648+audio/x-ape=org.gnome.Totem.desktop
649+audio/x-flac=org.gnome.Totem.desktop
650+audio/x-gsm=org.gnome.Totem.desktop
651+audio/x-it=org.gnome.Totem.desktop
652+audio/x-m4a=org.gnome.Totem.desktop
653+audio/x-matroska=org.gnome.Totem.desktop
654+audio/x-mod=org.gnome.Totem.desktop
655+audio/x-mp3=org.gnome.Totem.desktop
656+audio/x-mpeg=org.gnome.Totem.desktop
657+audio/x-mpegurl=org.gnome.Totem.desktop
658+audio/x-ms-asf=org.gnome.Totem.desktop
659+audio/x-ms-asx=org.gnome.Totem.desktop
660+audio/x-ms-wax=org.gnome.Totem.desktop
661+audio/x-ms-wma=org.gnome.Totem.desktop
662+audio/x-musepack=org.gnome.Totem.desktop
663+audio/x-pn-aiff=org.gnome.Totem.desktop
664+audio/x-pn-au=org.gnome.Totem.desktop
665+audio/x-pn-realaudio=org.gnome.Totem.desktop
666+audio/x-pn-realaudio-plugin=org.gnome.Totem.desktop
667+audio/x-pn-wav=org.gnome.Totem.desktop
668+audio/x-pn-windows-acm=org.gnome.Totem.desktop
669+audio/x-realaudio=org.gnome.Totem.desktop
670+audio/x-real-audio=org.gnome.Totem.desktop
671+audio/x-sbc=org.gnome.Totem.desktop
672+audio/x-scpls=org.gnome.Totem.desktop
673+audio/x-speex=org.gnome.Totem.desktop
674+audio/x-tta=org.gnome.Totem.desktop
675+audio/x-vorbis=org.gnome.Totem.desktop
676+audio/x-vorbis+ogg=org.gnome.Totem.desktop
677+audio/x-wav=org.gnome.Totem.desktop
678+audio/x-wavpack=org.gnome.Totem.desktop
679+audio/x-xm=org.gnome.Totem.desktop
680+image/vnd.rn-realpix=org.gnome.Totem.desktop
681+image/x-pict=org.gnome.Totem.desktop
682+misc/ultravox=org.gnome.Totem.desktop
683+text/google-video-pointer=org.gnome.Totem.desktop
684+text/x-google-video-pointer=org.gnome.Totem.desktop
685+video/3gpp=org.gnome.Totem.desktop
686+video/dv=org.gnome.Totem.desktop
687+video/fli=org.gnome.Totem.desktop
688+video/flv=org.gnome.Totem.desktop
689+video/mp2t=org.gnome.Totem.desktop
690+video/mp4=org.gnome.Totem.desktop
691+video/mp4v-es=org.gnome.Totem.desktop
692+video/mpeg=org.gnome.Totem.desktop
693+video/msvideo=org.gnome.Totem.desktop
694+video/ogg=org.gnome.Totem.desktop
695+video/quicktime=org.gnome.Totem.desktop
696+video/vivo=org.gnome.Totem.desktop
697+video/vnd.divx=org.gnome.Totem.desktop
698+video/vnd.rn-realvideo=org.gnome.Totem.desktop
699+video/vnd.vivo=org.gnome.Totem.desktop
700+video/webm=org.gnome.Totem.desktop
701+video/x-anim=org.gnome.Totem.desktop
702+video/x-avi=org.gnome.Totem.desktop
703+video/x-flc=org.gnome.Totem.desktop
704+video/x-fli=org.gnome.Totem.desktop
705+video/x-flic=org.gnome.Totem.desktop
706+video/x-flv=org.gnome.Totem.desktop
707+video/x-m4v=org.gnome.Totem.desktop
708+video/x-matroska=org.gnome.Totem.desktop
709+video/x-mpeg=org.gnome.Totem.desktop
710+video/x-ms-asf=org.gnome.Totem.desktop
711+video/x-ms-asx=org.gnome.Totem.desktop
712+video/x-msvideo=org.gnome.Totem.desktop
713+video/x-ms-wm=org.gnome.Totem.desktop
714+video/x-ms-wmv=org.gnome.Totem.desktop
715+video/x-ms-wmx=org.gnome.Totem.desktop
716+video/x-ms-wvx=org.gnome.Totem.desktop
717+video/x-nsv=org.gnome.Totem.desktop
718+video/x-ogm+ogg=org.gnome.Totem.desktop
719+video/x-theora+ogg=org.gnome.Totem.desktop
720+video/x-totem-stream=org.gnome.Totem.desktop
721+x-content/video-dvd=org.gnome.Totem.desktop
722+x-content/video-vcd=org.gnome.Totem.desktop
723+x-content/video-svcd=org.gnome.Totem.desktop
724+x-scheme-handler/pnm=org.gnome.Totem.desktop
725+x-scheme-handler/mms=org.gnome.Totem.desktop
726+x-scheme-handler/net=org.gnome.Totem.desktop
727+x-scheme-handler/rtp=org.gnome.Totem.desktop
728+x-scheme-handler/rtsp=org.gnome.Totem.desktop
729+x-scheme-handler/mmsh=org.gnome.Totem.desktop
730+x-scheme-handler/uvox=org.gnome.Totem.desktop
731+x-scheme-handler/icy=org.gnome.Totem.desktop
732+x-scheme-handler/icyx=org.gnome.Totem.desktop
733 x-scheme-handler/ghelp=yelp.desktop
734 x-scheme-handler/help=yelp.desktop
735 x-scheme-handler/info=yelp.desktop
736
737=== added file 'debian/gnome-session-common.dirs'
738--- debian/gnome-session-common.dirs 1970-01-01 00:00:00 +0000
739+++ debian/gnome-session-common.dirs 2014-10-31 04:52:33 +0000
740@@ -0,0 +1,1 @@
741+usr/share/gnome/applications
742
743=== modified file 'debian/gnome-session-common.install'
744--- debian/gnome-session-common.install 2012-05-07 02:35:47 +0000
745+++ debian/gnome-session-common.install 2014-10-31 04:52:33 +0000
746@@ -3,3 +3,4 @@
747 usr/share/locale
748 debian/55gnome-session_gnomerc etc/X11/Xsession.d
749 #debian/defaults.list etc/gnome
750+
751
752=== modified file 'debian/gnome-session.install'
753--- debian/gnome-session.install 2014-02-20 02:02:54 +0000
754+++ debian/gnome-session.install 2014-10-31 04:52:33 +0000
755@@ -1,3 +1,5 @@
756 usr/share/doc
757 usr/share/xsessions/gnome.desktop
758 usr/share/gnome-session/sessions/gnome.session
759+#usr/share/gnome-session/sessions/gnome-wayland.session
760+#usr/share/wayland-sessions/gnome-wayland.desktop
761
762=== removed file 'debian/patches/01_gnome-wm.patch'
763--- debian/patches/01_gnome-wm.patch 2011-05-23 14:00:56 +0000
764+++ debian/patches/01_gnome-wm.patch 1970-01-01 00:00:00 +0000
765@@ -1,11 +0,0 @@
766-Index: gnome-session-3.0.0/data/gnome-fallback.session.desktop.in.in
767-===================================================================
768---- gnome-session-3.0.0.orig/data/gnome-fallback.session.desktop.in.in 2011-04-20 21:19:19.751604438 +0200
769-+++ gnome-session-3.0.0/data/gnome-fallback.session.desktop.in.in 2011-04-20 21:19:24.495627620 +0200
770-@@ -2,5 +2,5 @@
771- _Name=GNOME fallback
772- RequiredComponents=gnome-panel;gnome-settings-daemon;
773- RequiredProviders=windowmanager;notifications;
774--DefaultProvider-windowmanager=metacity
775-+DefaultProvider-windowmanager=gnome-wm
776- DefaultProvider-notifications=notification-daemon
777
778=== removed file 'debian/patches/02_fallback_desktop.patch'
779--- debian/patches/02_fallback_desktop.patch 2012-05-07 02:35:47 +0000
780+++ debian/patches/02_fallback_desktop.patch 1970-01-01 00:00:00 +0000
781@@ -1,12 +0,0 @@
782-Index: gnome-session-3.0.2/data/gnome-fallback.desktop.in
783-===================================================================
784---- /dev/null 1970-01-01 00:00:00.000000000 +0000
785-+++ gnome-session-3.0.2/data/gnome-fallback.desktop.in 2011-11-04 20:06:03.653307488 +0100
786-@@ -0,0 +1,7 @@
787-+[Desktop Entry]
788-+_Name=GNOME Classic
789-+_Comment=This session logs you into GNOME
790-+Exec=gnome-session-fallback
791-+TryExec=gnome-session
792-+Icon=
793-+Type=Application
794
795=== removed file 'debian/patches/03_fallback_desktop_makefile.patch'
796--- debian/patches/03_fallback_desktop_makefile.patch 2012-05-07 02:35:47 +0000
797+++ debian/patches/03_fallback_desktop_makefile.patch 1970-01-01 00:00:00 +0000
798@@ -1,13 +0,0 @@
799-Index: gnome-session-3.4.0/data/Makefile.am
800-===================================================================
801---- gnome-session-3.4.0.orig/data/Makefile.am 2011-10-21 16:35:39.000000000 +0200
802-+++ gnome-session-3.4.0/data/Makefile.am 2012-04-06 23:20:36.422851504 +0200
803-@@ -9,7 +9,7 @@
804- hwcompat_DATA = hardware-compatibility
805-
806- xsessiondir = $(datadir)/xsessions
807--xsession_in_files = gnome.desktop.in
808-+xsession_in_files = gnome.desktop.in gnome-fallback.desktop.in
809- xsession_DATA = $(xsession_in_files:.desktop.in=.desktop)
810-
811- desktopdir = $(datadir)/applications
812
813=== removed file 'debian/patches/101_screen_lock_on_suspend.patch'
814--- debian/patches/101_screen_lock_on_suspend.patch 2010-12-06 12:26:37 +0000
815+++ debian/patches/101_screen_lock_on_suspend.patch 1970-01-01 00:00:00 +0000
816@@ -1,92 +0,0 @@
817-Description: Use the same logic as gnome-power-manager for deciding the "screen lock on suspend" policy. This restores the Jaunty behaviour rather than just using the screensaver settings, which is surprising for users
818-Bug: https://bugzilla.gnome.org/show_bug.cgi?id=598118
819-Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/karmic/+source/gnome-session/+bug/446191
820-
821-Index: gnome-session-2.32.1/gnome-session/gsm-manager.c
822-===================================================================
823---- gnome-session-2.32.1.orig/gnome-session/gsm-manager.c 2010-12-06 13:26:17.733212002 +0100
824-+++ gnome-session-2.32.1/gnome-session/gsm-manager.c 2010-12-06 13:26:17.829212002 +0100
825-@@ -85,6 +85,9 @@
826- #define KEY_AUTOSAVE KEY_GNOME_SESSION_DIR "/auto_save_session"
827-
828- #define KEY_SLEEP_LOCK "/apps/gnome-screensaver/lock_enabled"
829-+#define KEY_SLEEP_LOCK_USE_SCREENSAVER "/apps/gnome-power-manager/lock/use_screensaver_settings"
830-+#define GPM_CONF_LOCK_ON_SUSPEND "/apps/gnome-power-manager/lock/suspend"
831-+#define GPM_CONF_LOCK_ON_HIBERNATE "/apps/gnome-power-manager/lock/hibernate"
832-
833- typedef enum
834- {
835-@@ -975,18 +978,33 @@
836- }
837-
838- static gboolean
839--sleep_lock_is_enabled (GsmManager *manager)
840-+sleep_lock_is_enabled (GsmManager *manager,
841-+ const gchar *policy)
842- {
843-- GError *error;
844-- gboolean enable_lock;
845-+ GError *error;
846-+ gboolean enable_lock;
847-+ gboolean use_ss_setting;
848-+ const gchar *real_policy;
849-
850- error = NULL;
851-+ use_ss_setting = gconf_client_get_bool (manager->priv->gconf_client,
852-+ KEY_SLEEP_LOCK_USE_SCREENSAVER, &error);
853-+ if (error) {
854-+ g_warning ("Error retrieving configuration key '%s': %s",
855-+ KEY_SLEEP_LOCK_USE_SCREENSAVER, error->message);
856-+ g_error_free (error);
857-+
858-+ use_ss_setting = FALSE;
859-+ }
860-+
861-+ real_policy = (use_ss_setting ? KEY_SLEEP_LOCK : policy);
862-+
863- enable_lock = gconf_client_get_bool (manager->priv->gconf_client,
864-- KEY_SLEEP_LOCK, &error);
865-+ real_policy, &error);
866-
867- if (error) {
868- g_warning ("Error retrieving configuration key '%s': %s",
869-- KEY_SLEEP_LOCK, error->message);
870-+ real_policy, error->message);
871- g_error_free (error);
872-
873- /* If we fail to query gconf key, just enable locking */
874-@@ -997,13 +1015,14 @@
875- }
876-
877- static void
878--manager_perhaps_lock (GsmManager *manager)
879-+manager_perhaps_lock (GsmManager *manager,
880-+ const gchar *policy)
881- {
882- GError *error;
883- gboolean ret;
884-
885- /* only lock if gnome-screensaver is set to lock */
886-- if (!sleep_lock_is_enabled (manager)) {
887-+ if (!sleep_lock_is_enabled (manager, policy)) {
888- return;
889- }
890-
891-@@ -1035,7 +1054,7 @@
892- if (can_hibernate) {
893-
894- /* lock the screen before we suspend */
895-- manager_perhaps_lock (manager);
896-+ manager_perhaps_lock (manager, GPM_CONF_LOCK_ON_HIBERNATE);
897-
898- error = NULL;
899- ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
900-@@ -1059,7 +1078,7 @@
901- if (can_suspend) {
902-
903- /* lock the screen before we suspend */
904-- manager_perhaps_lock (manager);
905-+ manager_perhaps_lock (manager, GPM_CONF_LOCK_ON_SUSPEND);
906-
907- error = NULL;
908- ret = up_client_suspend_sync (manager->priv->up_client, NULL, &error);
909
910=== removed file 'debian/patches/10_session_save.patch'
911--- debian/patches/10_session_save.patch 2011-05-23 14:00:56 +0000
912+++ debian/patches/10_session_save.patch 1970-01-01 00:00:00 +0000
913@@ -1,536 +0,0 @@
914-Based on the patch in GNOME #575544
915-
916-Index: gnome-session-3.0.0/gnome-session/gsm-manager.c
917-===================================================================
918---- gnome-session-3.0.0.orig/gnome-session/gsm-manager.c 2011-03-30 09:47:33.000000000 +0200
919-+++ gnome-session-3.0.0/gnome-session/gsm-manager.c 2011-04-20 21:13:32.237905522 +0200
920-@@ -79,6 +79,7 @@
921- * let's make this fairly long.
922- */
923- #define GSM_MANAGER_PHASE_TIMEOUT 30 /* seconds */
924-+#define GSM_MANAGER_SAVE_SESSION_TIMEOUT 2
925-
926- #define GDM_FLEXISERVER_COMMAND "gdmflexiserver"
927- #define GDM_FLEXISERVER_ARGS "--startnew Standard"
928-@@ -1405,6 +1406,69 @@ query_end_session_complete (GsmManager *
929-
930- }
931-
932-+static gboolean
933-+_client_request_save (GsmClient *client,
934-+ ClientEndSessionData *data)
935-+{
936-+ gboolean ret;
937-+ GError *error;
938-+
939-+ error = NULL;
940-+ ret = gsm_client_request_save (client, data->flags, &error);
941-+ if (ret) {
942-+ g_debug ("GsmManager: adding client to query clients: %s", gsm_client_peek_id (client));
943-+ data->manager->priv->query_clients = g_slist_prepend (data->manager->priv->query_clients,
944-+ client);
945-+ } else if (error) {
946-+ g_debug ("GsmManager: unable to query client: %s", error->message);
947-+ g_error_free (error);
948-+ }
949-+
950-+ return FALSE;
951-+}
952-+
953-+static gboolean
954-+_client_request_save_helper (const char *id,
955-+ GsmClient *client,
956-+ ClientEndSessionData *data)
957-+{
958-+ return _client_request_save (client, data);
959-+}
960-+
961-+static void
962-+query_save_session_complete (GsmManager *manager)
963-+{
964-+ GError *error = NULL;
965-+
966-+ if (g_slist_length (manager->priv->next_query_clients) > 0) {
967-+ ClientEndSessionData data;
968-+
969-+ data.manager = manager;
970-+ data.flags = GSM_CLIENT_END_SESSION_FLAG_LAST;
971-+
972-+ g_slist_foreach (manager->priv->next_query_clients,
973-+ (GFunc)_client_request_save,
974-+ &data);
975-+
976-+ g_slist_free (manager->priv->next_query_clients);
977-+ manager->priv->next_query_clients = NULL;
978-+
979-+ return;
980-+ }
981-+
982-+ if (manager->priv->query_timeout_id > 0) {
983-+ g_source_remove (manager->priv->query_timeout_id);
984-+ manager->priv->query_timeout_id = 0;
985-+ }
986-+
987-+ gsm_session_save (manager->priv->clients, &error);
988-+
989-+ if (error) {
990-+ g_warning ("Error saving session: %s", error->message);
991-+ g_error_free (error);
992-+ }
993-+}
994-+
995- static guint32
996- generate_cookie (void)
997- {
998-@@ -1485,6 +1549,21 @@ _on_query_end_session_timeout (GsmManage
999- return FALSE;
1000- }
1001-
1002-+static gboolean
1003-+_on_query_save_session_timeout (GsmManager *manager)
1004-+{
1005-+ manager->priv->query_timeout_id = 0;
1006-+
1007-+ g_debug ("GsmManager: query to save session timed out");
1008-+
1009-+ g_slist_free (manager->priv->query_clients);
1010-+ manager->priv->query_clients = NULL;
1011-+
1012-+ query_save_session_complete (manager);
1013-+
1014-+ return FALSE;
1015-+}
1016-+
1017- static void
1018- do_phase_query_end_session (GsmManager *manager)
1019- {
1020-@@ -2160,13 +2239,32 @@ _handle_client_end_session_response (Gsm
1021- gboolean cancel,
1022- const char *reason)
1023- {
1024-- /* just ignore if received outside of shutdown */
1025-- if (manager->priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1026-+ /* just ignore if we are not yet running */
1027-+ if (manager->priv->phase < GSM_MANAGER_PHASE_RUNNING) {
1028- return;
1029- }
1030-
1031- g_debug ("GsmManager: Response from end session request: is-ok=%d do-last=%d cancel=%d reason=%s", is_ok, do_last, cancel, reason ? reason :"");
1032-
1033-+ if (manager->priv->phase == GSM_MANAGER_PHASE_RUNNING) {
1034-+ /* Ignore responses when no requests were sent */
1035-+ if (manager->priv->query_clients == NULL) {
1036-+ return;
1037-+ }
1038-+
1039-+ manager->priv->query_clients = g_slist_remove (manager->priv->query_clients, client);
1040-+
1041-+ if (do_last) {
1042-+ manager->priv->next_query_clients = g_slist_prepend (manager->priv->next_query_clients,
1043-+ client);
1044-+ }
1045-+
1046-+ if (manager->priv->query_clients == NULL) {
1047-+ query_save_session_complete (manager);
1048-+ }
1049-+ return;
1050-+ }
1051-+
1052- if (cancel) {
1053- cancel_end_session (manager);
1054- return;
1055-@@ -2281,6 +2379,15 @@ on_xsmp_client_logout_request (GsmXSMPCl
1056- }
1057-
1058- static void
1059-+on_xsmp_client_save_request (GsmXSMPClient *client,
1060-+ gboolean show_dialog,
1061-+ GsmManager *manager)
1062-+{
1063-+ g_debug ("GsmManager: save_request");
1064-+ gsm_manager_save_session (manager, NULL);
1065-+}
1066-+
1067-+static void
1068- on_store_client_added (GsmStore *store,
1069- const char *id,
1070- GsmManager *manager)
1071-@@ -2301,6 +2408,10 @@ on_store_client_added (GsmStore *store
1072- "logout-request",
1073- G_CALLBACK (on_xsmp_client_logout_request),
1074- manager);
1075-+ g_signal_connect (client,
1076-+ "save-request",
1077-+ G_CALLBACK (on_xsmp_client_save_request),
1078-+ manager);
1079- }
1080-
1081- g_signal_connect (client,
1082-@@ -3324,6 +3435,41 @@ gsm_manager_shutdown (GsmManager *manage
1083- }
1084-
1085- gboolean
1086-+gsm_manager_save_session (GsmManager *manager,
1087-+ GError **error)
1088-+{
1089-+ ClientEndSessionData data;
1090-+
1091-+ g_debug ("GsmManager: SaveSession called");
1092-+
1093-+ g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
1094-+
1095-+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
1096-+ g_set_error (error,
1097-+ GSM_MANAGER_ERROR,
1098-+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
1099-+ "SaveSession interface is only available during the Running phase");
1100-+ return FALSE;
1101-+ }
1102-+
1103-+ data.manager = manager;
1104-+ data.flags = 0;
1105-+ gsm_store_foreach (manager->priv->clients,
1106-+ (GsmStoreFunc)_client_request_save_helper,
1107-+ &data);
1108-+
1109-+ if (manager->priv->query_clients) {
1110-+ manager->priv->query_timeout_id = g_timeout_add_seconds (GSM_MANAGER_SAVE_SESSION_TIMEOUT,
1111-+ (GSourceFunc)_on_query_save_session_timeout,
1112-+ manager);
1113-+ return TRUE;
1114-+ } else {
1115-+ g_debug ("GsmManager: Nothing to save");
1116-+ return FALSE;
1117-+ }
1118-+}
1119-+
1120-+gboolean
1121- gsm_manager_can_shutdown (GsmManager *manager,
1122- gboolean *shutdown_available,
1123- GError **error)
1124-Index: gnome-session-3.0.0/gnome-session/gsm-manager.h
1125-===================================================================
1126---- gnome-session-3.0.0.orig/gnome-session/gsm-manager.h 2011-03-22 21:31:43.000000000 +0100
1127-+++ gnome-session-3.0.0/gnome-session/gsm-manager.h 2011-04-20 21:12:54.057718875 +0200
1128-@@ -164,6 +164,9 @@ gboolean gsm_manager_is_inhib
1129- gboolean gsm_manager_shutdown (GsmManager *manager,
1130- GError **error);
1131-
1132-+gboolean gsm_manager_save_session (GsmManager *manager,
1133-+ GError **error);
1134-+
1135- gboolean gsm_manager_can_shutdown (GsmManager *manager,
1136- gboolean *shutdown_available,
1137- GError **error);
1138-Index: gnome-session-3.0.0/gnome-session/gsm-xsmp-client.c
1139-===================================================================
1140---- gnome-session-3.0.0.orig/gnome-session/gsm-xsmp-client.c 2011-03-22 21:31:43.000000000 +0100
1141-+++ gnome-session-3.0.0/gnome-session/gsm-xsmp-client.c 2011-04-20 21:12:54.057718875 +0200
1142-@@ -68,6 +68,7 @@ enum {
1143- enum {
1144- REGISTER_REQUEST,
1145- LOGOUT_REQUEST,
1146-+ SAVE_REQUEST,
1147- LAST_SIGNAL
1148- };
1149-
1150-@@ -501,6 +502,30 @@ xsmp_cancel_end_session (GsmClient *clie
1151- return TRUE;
1152- }
1153-
1154-+static gboolean
1155-+xsmp_request_save (GsmClient *client,
1156-+ guint flags,
1157-+ GError **error)
1158-+{
1159-+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
1160-+
1161-+ g_debug ("GsmXSMPClient: xsmp_request_save ('%s')", xsmp->priv->description);
1162-+
1163-+ if (xsmp->priv->conn == NULL) {
1164-+ g_set_error (error,
1165-+ GSM_CLIENT_ERROR,
1166-+ GSM_CLIENT_ERROR_NOT_REGISTERED,
1167-+ "Client is not registered");
1168-+ return FALSE;
1169-+ }
1170-+
1171-+ if (flags & GSM_CLIENT_END_SESSION_FLAG_LAST)
1172-+ xsmp_save_yourself_phase2 (client);
1173-+ else
1174-+ do_save_yourself (xsmp, SmSaveLocal, FALSE);
1175-+
1176-+ return TRUE;
1177-+}
1178- static char *
1179- get_desktop_file_path (GsmXSMPClient *client)
1180- {
1181-@@ -970,6 +995,7 @@ gsm_xsmp_client_class_init (GsmXSMPClien
1182- object_class->get_property = gsm_xsmp_client_get_property;
1183- object_class->set_property = gsm_xsmp_client_set_property;
1184-
1185-+ client_class->impl_request_save = xsmp_request_save;
1186- client_class->impl_save = xsmp_save;
1187- client_class->impl_stop = xsmp_stop;
1188- client_class->impl_query_end_session = xsmp_query_end_session;
1189-@@ -997,6 +1023,17 @@ gsm_xsmp_client_class_init (GsmXSMPClien
1190- NULL,
1191- NULL,
1192- g_cclosure_marshal_VOID__BOOLEAN,
1193-+ G_TYPE_NONE,
1194-+ 1, G_TYPE_BOOLEAN);
1195-+
1196-+ signals[SAVE_REQUEST] =
1197-+ g_signal_new ("save-request",
1198-+ G_OBJECT_CLASS_TYPE (object_class),
1199-+ G_SIGNAL_RUN_LAST,
1200-+ G_STRUCT_OFFSET (GsmXSMPClientClass, save_request),
1201-+ NULL,
1202-+ NULL,
1203-+ g_cclosure_marshal_VOID__BOOLEAN,
1204- G_TYPE_NONE,
1205- 1, G_TYPE_BOOLEAN);
1206-
1207-Index: gnome-session-3.0.0/gnome-session/gsm-xsmp-client.h
1208-===================================================================
1209---- gnome-session-3.0.0.orig/gnome-session/gsm-xsmp-client.h 2010-02-09 14:22:01.000000000 +0100
1210-+++ gnome-session-3.0.0/gnome-session/gsm-xsmp-client.h 2011-04-20 21:12:54.061718891 +0200
1211-@@ -54,7 +54,8 @@ struct _GsmXSMPClientClass
1212- char **client_id);
1213- gboolean (*logout_request) (GsmXSMPClient *client,
1214- gboolean prompt);
1215--
1216-+ gboolean (*save_request) (GsmXSMPClient *client,
1217-+ gboolean prompt);
1218-
1219- void (*saved_state) (GsmXSMPClient *client);
1220-
1221-Index: gnome-session-3.0.0/gnome-session/org.gnome.SessionManager.xml
1222-===================================================================
1223---- gnome-session-3.0.0.orig/gnome-session/org.gnome.SessionManager.xml 2010-02-09 14:22:01.000000000 +0100
1224-+++ gnome-session-3.0.0/gnome-session/org.gnome.SessionManager.xml 2011-04-20 21:12:54.061718891 +0200
1225-@@ -256,6 +256,14 @@
1226- </doc:doc>
1227- </method>
1228-
1229-+ <method name="SaveSession">
1230-+ <doc:doc>
1231-+ <doc:description>
1232-+ <doc:para>Request to save session</doc:para>
1233-+ </doc:description>
1234-+ </doc:doc>
1235-+ </method>
1236-+
1237- <method name="CanShutdown">
1238- <arg name="is_available" direction="out" type="b">
1239- <doc:doc>
1240-Index: gnome-session-3.0.0/capplet/gsm-properties-dialog.c
1241-===================================================================
1242---- gnome-session-3.0.0.orig/capplet/gsm-properties-dialog.c 2011-03-22 21:31:42.000000000 +0100
1243-+++ gnome-session-3.0.0/capplet/gsm-properties-dialog.c 2011-04-20 21:12:54.061718891 +0200
1244-@@ -33,6 +33,12 @@
1245- #include "gsm-util.h"
1246- #include "gsp-app.h"
1247- #include "gsp-app-manager.h"
1248-+#include <dbus/dbus-glib.h>
1249-+#include <dbus/dbus-glib-lowlevel.h>
1250-+
1251-+#define GSM_SERVICE_DBUS "org.gnome.SessionManager"
1252-+#define GSM_PATH_DBUS "/org/gnome/SessionManager"
1253-+#define GSM_INTERFACE_DBUS "org.gnome.SessionManager"
1254-
1255- #define GSM_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogPrivate))
1256-
1257-@@ -43,6 +49,7 @@
1258- #define CAPPLET_DELETE_WIDGET_NAME "session_properties_delete_button"
1259- #define CAPPLET_EDIT_WIDGET_NAME "session_properties_edit_button"
1260- #define CAPPLET_SAVE_WIDGET_NAME "session_properties_save_button"
1261-+#define CAPPLET_SESSION_SAVED_WIDGET_NAME "session_properties_session_saved_label"
1262- #define CAPPLET_REMEMBER_WIDGET_NAME "session_properties_remember_toggle"
1263-
1264- #define STARTUP_APP_ICON "system-run"
1265-@@ -455,10 +462,64 @@ on_row_activated (GtkTreeView *t
1266- }
1267-
1268- static void
1269-+session_saved_message (GsmPropertiesDialog *dialog,
1270-+ const char *msg,
1271-+ gboolean is_error)
1272-+{
1273-+ GtkLabel *label;
1274-+ gchar *markup;
1275-+ label = GTK_LABEL (gtk_builder_get_object (dialog->priv->xml, CAPPLET_SESSION_SAVED_WIDGET_NAME));
1276-+ if (is_error)
1277-+ markup = g_markup_printf_escaped ("<span foreground=\"red\">%s</span>", msg);
1278-+ else
1279-+ markup = g_markup_escape_text (msg, -1);
1280-+ gtk_label_set_markup (label, markup);
1281-+ g_free (markup);
1282-+}
1283-+
1284-+static void
1285-+session_saved_cb (DBusGProxy *proxy,
1286-+ DBusGProxyCall *call_id,
1287-+ void *user_data)
1288-+{
1289-+ gboolean res;
1290-+ GsmPropertiesDialog *dialog = user_data;
1291-+
1292-+ res = dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_INVALID);
1293-+ if (res)
1294-+ session_saved_message (dialog, _("Your session has been saved."), FALSE);
1295-+ else
1296-+ session_saved_message (dialog, _("Failed to save session"), TRUE);
1297-+
1298-+ g_object_unref (proxy);
1299-+}
1300-+
1301-+static void
1302- on_save_session_clicked (GtkWidget *widget,
1303- GsmPropertiesDialog *dialog)
1304- {
1305-- g_debug ("Session saving is not implemented yet!");
1306-+ DBusGConnection *conn;
1307-+ DBusGProxy *proxy;
1308-+ DBusGProxyCall *call;
1309-+
1310-+ conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
1311-+ if (conn == NULL) {
1312-+ session_saved_message (dialog, _("Could not connect to the session bus"), TRUE);
1313-+ return;
1314-+ }
1315-+
1316-+ proxy = dbus_g_proxy_new_for_name (conn, GSM_SERVICE_DBUS, GSM_PATH_DBUS, GSM_INTERFACE_DBUS);
1317-+ if (proxy == NULL) {
1318-+ session_saved_message (dialog, _("Could not connect to the session manager"), TRUE);
1319-+ return;
1320-+ }
1321-+
1322-+ call = dbus_g_proxy_begin_call (proxy, "SaveSession", session_saved_cb, dialog, NULL, G_TYPE_INVALID);
1323-+ if (call == NULL) {
1324-+ session_saved_message (dialog, _("Failed to save session"), TRUE);
1325-+ g_object_unref (proxy);
1326-+ return;
1327-+ }
1328- }
1329-
1330- static void
1331-Index: gnome-session-3.0.0/configure.ac
1332-===================================================================
1333---- gnome-session-3.0.0.orig/configure.ac 2011-03-30 09:47:33.000000000 +0200
1334-+++ gnome-session-3.0.0/configure.ac 2011-04-20 21:12:54.061718891 +0200
1335-@@ -63,6 +63,7 @@ PKG_CHECK_MODULES(GNOME_SESSION,
1336- PKG_CHECK_MODULES(SESSION_PROPERTIES,
1337- glib-2.0 >= $GLIB_REQUIRED
1338- gtk+-3.0 >= $GTK3_REQUIRED
1339-+ dbus-glib-1 >= $DBUS_GLIB_REQUIRED
1340- )
1341-
1342- PKG_CHECK_MODULES(SM, sm)
1343-Index: gnome-session-3.0.0/gnome-session/gsm-client.h
1344-===================================================================
1345---- gnome-session-3.0.0.orig/gnome-session/gsm-client.h 2010-02-09 14:22:01.000000000 +0100
1346-+++ gnome-session-3.0.0/gnome-session/gsm-client.h 2011-04-20 21:12:54.061718891 +0200
1347-@@ -92,6 +92,9 @@ struct _GsmClientClass
1348- GError **error);
1349- gboolean (*impl_stop) (GsmClient *client,
1350- GError **error);
1351-+ gboolean (*impl_request_save) (GsmClient *client,
1352-+ guint flags,
1353-+ GError **error);
1354- GKeyFile * (*impl_save) (GsmClient *client,
1355- GError **error);
1356- };
1357-@@ -137,6 +140,9 @@ gboolean gsm_client_cancel_
1358-
1359- void gsm_client_disconnected (GsmClient *client);
1360-
1361-+gboolean gsm_client_request_save (GsmClient *client,
1362-+ guint flags,
1363-+ GError **error);
1364- GKeyFile *gsm_client_save (GsmClient *client,
1365- GError **error);
1366- /* exported to bus */
1367-Index: gnome-session-3.0.0/gnome-session/gsm-dbus-client.c
1368-===================================================================
1369---- gnome-session-3.0.0.orig/gnome-session/gsm-dbus-client.c 2011-03-22 21:31:43.000000000 +0100
1370-+++ gnome-session-3.0.0/gnome-session/gsm-dbus-client.c 2011-04-20 21:12:54.061718891 +0200
1371-@@ -412,6 +412,19 @@ gsm_dbus_client_finalize (GObject *objec
1372- G_OBJECT_CLASS (gsm_dbus_client_parent_class)->finalize (object);
1373- }
1374-
1375-+static gboolean
1376-+dbus_client_request_save (GsmClient *client,
1377-+ guint flags,
1378-+ GError **error)
1379-+{
1380-+ g_debug ("GsmDBusClient: sending save request to client with id %s",
1381-+ gsm_client_peek_id (client));
1382-+
1383-+ /* FIXME: The protocol does not support this */
1384-+
1385-+ return FALSE;
1386-+}
1387-+
1388- static GKeyFile *
1389- dbus_client_save (GsmClient *client,
1390- GError **error)
1391-@@ -664,6 +677,7 @@ gsm_dbus_client_class_init (GsmDBusClien
1392- object_class->set_property = gsm_dbus_client_set_property;
1393- object_class->dispose = gsm_dbus_client_dispose;
1394-
1395-+ client_class->impl_request_save = dbus_client_request_save;
1396- client_class->impl_save = dbus_client_save;
1397- client_class->impl_stop = dbus_client_stop;
1398- client_class->impl_query_end_session = dbus_client_query_end_session;
1399-Index: gnome-session-3.0.0/gnome-session/gsm-client.c
1400-===================================================================
1401---- gnome-session-3.0.0.orig/gnome-session/gsm-client.c 2010-02-09 14:22:01.000000000 +0100
1402-+++ gnome-session-3.0.0/gnome-session/gsm-client.c 2011-04-20 21:12:54.061718891 +0200
1403-@@ -510,6 +510,16 @@ gsm_client_disconnected (GsmClient *clie
1404- g_signal_emit (client, signals[DISCONNECTED], 0);
1405- }
1406-
1407-+gboolean
1408-+gsm_client_request_save (GsmClient *client,
1409-+ guint flags,
1410-+ GError **error)
1411-+{
1412-+ g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
1413-+
1414-+ return GSM_CLIENT_GET_CLASS (client)->impl_request_save (client, flags, error);
1415-+}
1416-+
1417- GKeyFile *
1418- gsm_client_save (GsmClient *client,
1419- GError **error)
1420-Index: gnome-session-3.0.0/data/session-properties.ui
1421-===================================================================
1422---- gnome-session-3.0.0.orig/data/session-properties.ui 2011-03-22 21:31:43.000000000 +0100
1423-+++ gnome-session-3.0.0/data/session-properties.ui 2011-04-20 21:12:54.061718891 +0200
1424-@@ -148,6 +148,7 @@
1425- <property name="visible">True</property>
1426- <child>
1427- <object class="GtkButton" id="session_properties_save_button">
1428-+ <property name="visible">True</property>
1429- <property name="can_focus">True</property>
1430- <property name="receives_default">True</property>
1431- <child>
1432-@@ -191,6 +192,17 @@
1433- <property name="position">1</property>
1434- </packing>
1435- </child>
1436-+ <child>
1437-+ <object class="GtkLabel" id="session_properties_session_saved_label">
1438-+ <property name="visible">True</property>
1439-+ <property name="wrap">True</property>
1440-+ </object>
1441-+ <packing>
1442-+ <property name="expand">False</property>
1443-+ <property name="fill">False</property>
1444-+ <property name="position">2</property>
1445-+ </packing>
1446-+ </child>
1447- </object>
1448- <packing>
1449- <property name="position">1</property>
1450
1451=== removed file 'debian/patches/12_no_gdm_fallback.patch'
1452--- debian/patches/12_no_gdm_fallback.patch 2012-07-29 14:22:20 +0000
1453+++ debian/patches/12_no_gdm_fallback.patch 1970-01-01 00:00:00 +0000
1454@@ -1,27 +0,0 @@
1455-Debian #572085
1456-
1457-Don’t fall back to GDM when ConsoleKit fails. If CK is not available, it
1458-will not be attempted anyway.
1459-
1460-Index: gnome-session-3.5.4/gnome-session/gsm-manager.c
1461-===================================================================
1462---- gnome-session-3.5.4.orig/gnome-session/gsm-manager.c 2012-07-19 13:41:23.511406643 +1200
1463-+++ gnome-session-3.5.4/gnome-session/gsm-manager.c 2012-07-19 13:41:50.227405715 +1200
1464-@@ -492,7 +492,7 @@
1465- g_signal_connect (manager->priv->system,
1466- "request-completed",
1467- G_CALLBACK (quit_request_completed),
1468-- GINT_TO_POINTER (GDM_LOGOUT_ACTION_REBOOT));
1469-+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_NONE));
1470- gsm_system_attempt_restart (manager->priv->system);
1471- break;
1472- case GSM_MANAGER_LOGOUT_REBOOT_GDM:
1473-@@ -506,7 +506,7 @@
1474- g_signal_connect (manager->priv->system,
1475- "request-completed",
1476- G_CALLBACK (quit_request_completed),
1477-- GINT_TO_POINTER (GDM_LOGOUT_ACTION_SHUTDOWN));
1478-+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_NONE));
1479- gsm_system_attempt_stop (manager->priv->system);
1480- break;
1481- case GSM_MANAGER_LOGOUT_SHUTDOWN_GDM:
1482
1483=== modified file 'debian/patches/13_display_session_properties.patch'
1484--- debian/patches/13_display_session_properties.patch 2013-06-08 23:25:03 +0000
1485+++ debian/patches/13_display_session_properties.patch 2014-10-31 04:52:33 +0000
1486@@ -4,11 +4,11 @@
1487 the builtian search.
1488 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683814
1489
1490-Index: gnome-session-3.4.2.1/data/session-properties.desktop.in.in
1491+Index: gnome-session/data/gnome-session-properties.desktop.in.in
1492 ===================================================================
1493---- gnome-session-3.4.2.1.orig/data/session-properties.desktop.in.in 2012-05-17 20:26:07.000000000 +0200
1494-+++ gnome-session-3.4.2.1/data/session-properties.desktop.in.in 2012-08-07 01:08:23.755210722 +0200
1495-@@ -8,7 +8,6 @@
1496+--- gnome-session.orig/data/gnome-session-properties.desktop.in.in
1497++++ gnome-session/data/gnome-session-properties.desktop.in.in
1498+@@ -8,7 +8,6 @@ Type=Application
1499 StartupNotify=true
1500 Categories=GTK;GNOME;Settings;X-GNOME-PersonalSettings;
1501 OnlyShowIn=GNOME;Unity;
1502
1503=== modified file 'debian/patches/50_ubuntu_sessions.patch'
1504--- debian/patches/50_ubuntu_sessions.patch 2014-06-04 12:26:37 +0000
1505+++ debian/patches/50_ubuntu_sessions.patch 2014-10-31 04:52:33 +0000
1506@@ -4,9 +4,11 @@
1507 (TryExec enables to show them or not depends on the package installed)
1508 Forwarded: Not needed
1509
1510---- a/data/gnome.desktop.in
1511-+++ b/data/gnome.desktop.in
1512-@@ -1,7 +1,8 @@
1513+Index: gnome-session/data/gnome.desktop.in
1514+===================================================================
1515+--- gnome-session.orig/data/gnome.desktop.in
1516++++ gnome-session/data/gnome.desktop.in
1517+@@ -1,8 +1,9 @@
1518 [Desktop Entry]
1519 _Name=GNOME
1520 _Comment=This session logs you into GNOME
1521@@ -16,10 +18,13 @@
1522 +TryExec=gnome-shell
1523 Icon=
1524 Type=Application
1525+ DesktopNames=GNOME
1526 +X-LightDM-DesktopName=GNOME
1527---- a/data/Makefile.am
1528-+++ b/data/Makefile.am
1529-@@ -13,7 +13,7 @@
1530+Index: gnome-session/data/Makefile.am
1531+===================================================================
1532+--- gnome-session.orig/data/Makefile.am
1533++++ gnome-session/data/Makefile.am
1534+@@ -12,7 +12,7 @@ hwcompatdir = $(pkgdatadir)
1535 hwcompat_DATA = hardware-compatibility
1536
1537 xsessiondir = $(datadir)/xsessions
1538@@ -28,25 +33,29 @@
1539
1540 if BUILD_SESSION_SELECTOR
1541 xsession_in_files += gnome-custom-session.desktop.in
1542-@@ -26,7 +26,7 @@
1543+@@ -29,7 +29,7 @@ desktop_in_files = gnome-session-propert
1544 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
1545
1546 sessiondir = $(datadir)/gnome-session/sessions
1547--session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in
1548-+session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in ubuntu.session.desktop.in.in
1549+-session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in gnome-wayland.session.desktop.in.in
1550++session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in gnome-wayland.session.desktop.in.in ubuntu.session.desktop.in.in
1551 session_in_files = $(session_in_in_files:.session.desktop.in.in=.session.desktop.in)
1552 session_DATA = $(session_in_files:.session.desktop.in=.session)
1553
1554+Index: gnome-session/data/ubuntu.session.desktop.in.in
1555+===================================================================
1556 --- /dev/null
1557-+++ b/data/ubuntu.session.desktop.in.in
1558++++ gnome-session/data/ubuntu.session.desktop.in.in
1559 @@ -0,0 +1,4 @@
1560 +[GNOME Session]
1561 +_Name=Ubuntu
1562-+RequiredComponents=unity-settings-daemon;
1563++RequiredComponents=unity-settings-daemon;compiz;
1564 +DesktopName=Unity
1565+Index: gnome-session/data/ubuntu.desktop.in
1566+===================================================================
1567 --- /dev/null
1568-+++ b/data/ubuntu.desktop.in
1569-@@ -0,0 +1,8 @@
1570++++ gnome-session/data/ubuntu.desktop.in
1571+@@ -0,0 +1,9 @@
1572 +[Desktop Entry]
1573 +_Name=Ubuntu
1574 +_Comment=This session logs you into Ubuntu
1575@@ -54,4 +63,5 @@
1576 +TryExec=unity
1577 +Icon=
1578 +Type=Application
1579++DesktopNames=Unity
1580 +X-LightDM-DesktopName=Unity
1581
1582=== removed file 'debian/patches/52_xdg_current_desktop.patch'
1583--- debian/patches/52_xdg_current_desktop.patch 2014-02-17 03:42:04 +0000
1584+++ debian/patches/52_xdg_current_desktop.patch 1970-01-01 00:00:00 +0000
1585@@ -1,46 +0,0 @@
1586-Index: gnome-session-3.7.4/gnome-session/gsm-session-fill.c
1587-===================================================================
1588---- gnome-session-3.7.4.orig/gnome-session/gsm-session-fill.c 2013-02-07 18:04:28.954708097 -0500
1589-+++ gnome-session-3.7.4/gnome-session/gsm-session-fill.c 2013-02-07 18:04:28.946708097 -0500
1590-@@ -31,6 +31,7 @@
1591- #define GSM_KEYFILE_SESSION_GROUP "GNOME Session"
1592- #define GSM_KEYFILE_RUNNABLE_KEY "IsRunnableHelper"
1593- #define GSM_KEYFILE_FALLBACK_KEY "FallbackSession"
1594-+#define GSM_KEYFILE_DESKTOP_NAME_KEY "DesktopName"
1595- #define GSM_KEYFILE_REQUIRED_COMPONENTS_KEY "RequiredComponents"
1596-
1597- /* See https://bugzilla.gnome.org/show_bug.cgi?id=641992 for discussion */
1598-@@ -315,6 +316,24 @@
1599- return keyfile;
1600- }
1601-
1602-+static void
1603-+set_xdg_current_desktop (GKeyFile *keyfile)
1604-+{
1605-+ char *value;
1606-+
1607-+ value = g_key_file_get_string (keyfile,
1608-+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_DESKTOP_NAME_KEY,
1609-+ NULL);
1610-+
1611-+ if (!IS_STRING_EMPTY (value)) {
1612-+ gsm_util_setenv ("XDG_CURRENT_DESKTOP", value);
1613-+ }
1614-+ else {
1615-+ gsm_util_setenv ("XDG_CURRENT_DESKTOP", "GNOME");
1616-+ }
1617-+ g_free (value);
1618-+}
1619-+
1620- gboolean
1621- gsm_session_fill (GsmManager *manager,
1622- const char *session)
1623-@@ -332,6 +351,8 @@
1624-
1625- g_free (actual_session);
1626-
1627-+ set_xdg_current_desktop (keyfile);
1628-+
1629- load_standard_apps (manager, keyfile);
1630-
1631- g_key_file_free (keyfile);
1632
1633=== removed file 'debian/patches/80_new_upstream_session_dialog.patch'
1634--- debian/patches/80_new_upstream_session_dialog.patch 2011-05-24 08:56:36 +0000
1635+++ debian/patches/80_new_upstream_session_dialog.patch 1970-01-01 00:00:00 +0000
1636@@ -1,699 +0,0 @@
1637-Description: change the logout dialog to the opensuse proposal.
1638-Bug: https://bugzilla.gnome.org/show_bug.cgi?id=507101
1639-Author: Vincent Untz
1640-
1641-Index: gnome-session-3.0.0/gnome-session/gsm-manager.c
1642-===================================================================
1643---- gnome-session-3.0.0.orig/gnome-session/gsm-manager.c 2011-05-24 10:17:22.244968980 +0200
1644-+++ gnome-session-3.0.0/gnome-session/gsm-manager.c 2011-05-24 10:17:22.284969173 +0200
1645-@@ -3050,7 +3050,8 @@
1646-
1647- display = gtk_widget_get_display (GTK_WIDGET (logout_dialog));
1648-
1649-- gtk_widget_destroy (GTK_WIDGET (logout_dialog));
1650-+ if (response_id != GTK_RESPONSE_HELP)
1651-+ gtk_widget_destroy (GTK_WIDGET (logout_dialog));
1652-
1653- /* In case of dialog cancel, switch user, hibernate and
1654- * suspend, we just perform the respective action and return,
1655-@@ -3060,6 +3061,10 @@
1656- case GTK_RESPONSE_NONE:
1657- case GTK_RESPONSE_DELETE_EVENT:
1658- break;
1659-+ case GTK_RESPONSE_HELP:
1660-+ gsm_util_help_display (GTK_WINDOW (logout_dialog),
1661-+ "gosgetstarted-73");
1662-+ break;
1663- case GSM_LOGOUT_RESPONSE_SWITCH_USER:
1664- request_switch_user (display, manager);
1665- break;
1666-Index: gnome-session-3.0.0/gnome-session/gsm-util.c
1667-===================================================================
1668---- gnome-session-3.0.0.orig/gnome-session/gsm-util.c 2011-03-22 21:31:43.000000000 +0100
1669-+++ gnome-session-3.0.0/gnome-session/gsm-util.c 2011-05-24 10:17:22.284969173 +0200
1670-@@ -21,6 +21,7 @@
1671- #include <config.h>
1672- #include <stdlib.h>
1673- #include <ctype.h>
1674-+#include <string.h>
1675- #include <sys/types.h>
1676- #include <unistd.h>
1677- #include <sys/time.h>
1678-@@ -519,3 +520,86 @@
1679-
1680- return icon_size;
1681- }
1682-+
1683-+void
1684-+gsm_util_help_display (GtkWindow *parent,
1685-+ const char *link_id)
1686-+{
1687-+ GError *error = NULL;
1688-+ const char *lang;
1689-+ char *uri = NULL;
1690-+ gboolean found;
1691-+
1692-+ int i;
1693-+
1694-+ const char * const * langs = g_get_language_names ();
1695-+
1696-+ uri = NULL;
1697-+ found = FALSE;
1698-+
1699-+ for (i = 0; langs[i]; i++) {
1700-+ lang = langs[i];
1701-+ if (strchr (lang, '.')) {
1702-+ continue;
1703-+ }
1704-+
1705-+ uri = g_build_filename (DATADIR,
1706-+ "/gnome/help/user-guide/",
1707-+ lang,
1708-+ "/user-guide.xml",
1709-+ NULL);
1710-+
1711-+ if (g_file_test (uri, G_FILE_TEST_EXISTS)) {
1712-+ found = TRUE;
1713-+ break;
1714-+ }
1715-+ }
1716-+
1717-+ if (found) {
1718-+ GAppInfo *app_info;
1719-+ char *command;
1720-+
1721-+ if (link_id) {
1722-+ command = g_strconcat ("gnome-open ghelp://", uri, "?", link_id, NULL);
1723-+ } else {
1724-+ command = g_strconcat ("gnome-open ghelp://", uri, NULL);
1725-+ }
1726-+
1727-+ app_info = g_app_info_create_from_commandline (command, "gnome-open",G_APP_INFO_CREATE_NONE, &error);
1728-+ g_free (command);
1729-+
1730-+ if (error == NULL && app_info != NULL) {
1731-+ GdkScreen *screen;
1732-+ GdkAppLaunchContext *context;
1733-+
1734-+ screen = gtk_widget_get_screen (GTK_WIDGET (parent));
1735-+ context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
1736-+ g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (context), &error);
1737-+
1738-+ g_object_unref (context);
1739-+ g_object_unref (app_info);
1740-+ }
1741-+ }
1742-+
1743-+ if (!found || error != NULL) {
1744-+ GtkWidget *d;
1745-+ const char *errmsg;
1746-+
1747-+ if (!found)
1748-+ errmsg = _("Cannot find help.");
1749-+ else {
1750-+ errmsg = error->message;
1751-+ g_error_free (error);
1752-+ }
1753-+
1754-+ d = gtk_message_dialog_new (parent,
1755-+ GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1756-+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1757-+ "%s", errmsg);
1758-+ gtk_widget_show (GTK_WIDGET (d));
1759-+ g_signal_connect (d, "response",
1760-+ G_CALLBACK (gtk_widget_destroy), NULL);
1761-+ }
1762-+
1763-+ g_free (uri);
1764-+}
1765-Index: gnome-session-3.0.0/gnome-session/Makefile.am
1766-===================================================================
1767---- gnome-session-3.0.0.orig/gnome-session/Makefile.am 2011-03-22 21:36:21.000000000 +0100
1768-+++ gnome-session-3.0.0/gnome-session/Makefile.am 2011-05-24 10:17:22.288969198 +0200
1769-@@ -94,6 +94,10 @@
1770- gsm-util.c \
1771- gsm-util.h
1772-
1773-+libgsmutil_la_CPPFLAGS = \
1774-+ $(AM_CPPFLAGS) \
1775-+ -DDATADIR=\""$(datadir)"\"
1776-+
1777- libgsmutil_la_LIBADD = \
1778- $(GNOME_SESSION_LIBS)
1779-
1780-Index: gnome-session-3.0.0/gnome-session/gsm-logout-dialog.c
1781-===================================================================
1782---- gnome-session-3.0.0.orig/gnome-session/gsm-logout-dialog.c 2011-03-22 21:31:43.000000000 +0100
1783-+++ gnome-session-3.0.0/gnome-session/gsm-logout-dialog.c 2011-05-24 10:29:39.732625980 +0200
1784-@@ -43,6 +43,14 @@
1785- #define LOCKDOWN_SCHEMA "org.gnome.desktop.lockdown"
1786- #define KEY_DISABLE_USER_SWITCHING "disable-user-switching"
1787-
1788-+#define GSM_ICON_LOGOUT "system-log-out"
1789-+#define GSM_ICON_SWITCH "system-users"
1790-+#define GSM_ICON_SHUTDOWN "system-shutdown"
1791-+#define GSM_ICON_REBOOT "view-refresh"
1792-+/* TODO: use gpm icons? */
1793-+#define GSM_ICON_HIBERNATE "drive-harddisk"
1794-+#define GSM_ICON_SLEEP "gnome-session-sleep"
1795-+
1796- typedef enum {
1797- GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
1798- GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
1799-@@ -50,11 +58,12 @@
1800-
1801- struct _GsmLogoutDialogPrivate
1802- {
1803-- GsmDialogLogoutType type;
1804--
1805- UpClient *up_client;
1806- GsmConsolekit *consolekit;
1807-
1808-+ GtkWidget *info_label;
1809-+ GtkWidget *cancel_button;
1810-+
1811- int timeout;
1812- unsigned int timeout_id;
1813-
1814-@@ -63,7 +72,8 @@
1815-
1816- static GsmLogoutDialog *current_dialog = NULL;
1817-
1818--static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
1819-+static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog,
1820-+ int seconds);
1821-
1822- static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
1823- gpointer data);
1824-@@ -71,43 +81,10 @@
1825- static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
1826- gpointer data);
1827-
1828--enum {
1829-- PROP_0,
1830-- PROP_MESSAGE_TYPE
1831--};
1832--
1833--G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_MESSAGE_DIALOG);
1834--
1835--static void
1836--gsm_logout_dialog_set_property (GObject *object,
1837-- guint prop_id,
1838-- const GValue *value,
1839-- GParamSpec *pspec)
1840--{
1841-- switch (prop_id) {
1842-- case PROP_MESSAGE_TYPE:
1843-- break;
1844-- default:
1845-- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1846-- break;
1847-- }
1848--}
1849-+static void gsm_logout_set_info_text (GsmLogoutDialog *logout_dialog,
1850-+ int seconds);
1851-
1852--static void
1853--gsm_logout_dialog_get_property (GObject *object,
1854-- guint prop_id,
1855-- GValue *value,
1856-- GParamSpec *pspec)
1857--{
1858-- switch (prop_id) {
1859-- case PROP_MESSAGE_TYPE:
1860-- g_value_set_enum (value, GTK_MESSAGE_WARNING);
1861-- break;
1862-- default:
1863-- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1864-- break;
1865-- }
1866--}
1867-+G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_DIALOG);
1868-
1869- static void
1870- gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass)
1871-@@ -116,18 +93,6 @@
1872-
1873- gobject_class = G_OBJECT_CLASS (klass);
1874-
1875-- /* This is a workaround to avoid a stupid crash: libgnomeui
1876-- * listens for the "show" signal on all GtkMessageDialog and
1877-- * gets the "message-type" of the dialogs. We will crash when
1878-- * it accesses this property if we don't override it since we
1879-- * didn't define it. */
1880-- gobject_class->set_property = gsm_logout_dialog_set_property;
1881-- gobject_class->get_property = gsm_logout_dialog_get_property;
1882--
1883-- g_object_class_override_property (gobject_class,
1884-- PROP_MESSAGE_TYPE,
1885-- "message-type");
1886--
1887- g_type_class_add_private (klass, sizeof (GsmLogoutDialogPrivate));
1888- }
1889-
1890-@@ -139,11 +104,22 @@
1891- logout_dialog->priv->timeout_id = 0;
1892- logout_dialog->priv->timeout = 0;
1893- logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
1894-+ logout_dialog->priv->info_label = NULL;
1895-
1896-- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE);
1897-+ gtk_window_set_resizable (GTK_WINDOW (logout_dialog), FALSE);
1898- gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE);
1899- gtk_window_stick (GTK_WINDOW (logout_dialog));
1900-
1901-+ /* use HIG spacings */
1902-+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog))), 12);
1903-+ gtk_container_set_border_width (GTK_CONTAINER (logout_dialog), 6);
1904-+
1905-+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog), GTK_STOCK_HELP,
1906-+ GTK_RESPONSE_HELP);
1907-+ logout_dialog->priv->cancel_button =
1908-+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
1909-+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1910-+
1911- logout_dialog->priv->up_client = up_client_new ();
1912-
1913- logout_dialog->priv->consolekit = gsm_get_consolekit ();
1914-@@ -239,38 +215,26 @@
1915- static void
1916- gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
1917- {
1918-- gsm_logout_dialog_set_timeout (logout_dialog);
1919--}
1920-+ gsm_logout_set_info_text (logout_dialog, AUTOMATIC_ACTION_TIMEOUT);
1921-
1922--static gboolean
1923--gsm_logout_dialog_timeout (gpointer data)
1924--{
1925-- GsmLogoutDialog *logout_dialog;
1926-- char *seconds_warning;
1927-- char *secondary_text;
1928-- int seconds_to_show;
1929-- static char *session_type = NULL;
1930--
1931-- logout_dialog = (GsmLogoutDialog *) data;
1932--
1933-- if (!logout_dialog->priv->timeout) {
1934-- gtk_dialog_response (GTK_DIALOG (logout_dialog),
1935-- logout_dialog->priv->default_response);
1936--
1937-- return FALSE;
1938-- }
1939-+ if (logout_dialog->priv->default_response != GTK_RESPONSE_CANCEL)
1940-+ gsm_logout_dialog_set_timeout (logout_dialog,
1941-+ AUTOMATIC_ACTION_TIMEOUT);
1942-+}
1943-
1944-- if (logout_dialog->priv->timeout <= 30) {
1945-- seconds_to_show = logout_dialog->priv->timeout;
1946-- } else {
1947-- seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
1948-
1949-- if (logout_dialog->priv->timeout % 10)
1950-- seconds_to_show += 10;
1951-- }
1952-+static void
1953-+gsm_logout_set_info_text (GsmLogoutDialog *logout_dialog,
1954-+ int seconds_to_show)
1955-+{
1956-+ const char *seconds_warning;
1957-+ char *secondary_text;
1958-+ char *buf;
1959-+ char *markup;
1960-+ static char *session_type = NULL;
1961-
1962-- switch (logout_dialog->priv->type) {
1963-- case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
1964-+ switch (logout_dialog->priv->default_response) {
1965-+ case GSM_LOGOUT_RESPONSE_LOGOUT:
1966- /* This string is shared with gsm-fail-whale-dialog.c */
1967- seconds_warning = ngettext ("You will be automatically logged "
1968- "out in %d second.",
1969-@@ -279,7 +243,7 @@
1970- seconds_to_show);
1971- break;
1972-
1973-- case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
1974-+ case GSM_LOGOUT_RESPONSE_SHUTDOWN:
1975- seconds_warning = ngettext ("This system will be automatically "
1976- "shut down in %d second.",
1977- "This system will be automatically "
1978-@@ -287,6 +251,10 @@
1979- seconds_to_show);
1980- break;
1981-
1982-+ case GTK_RESPONSE_CANCEL:
1983-+ seconds_warning = "";
1984-+ break;
1985-+
1986- default:
1987- g_assert_not_reached ();
1988- }
1989-@@ -321,25 +289,50 @@
1990- secondary_text = g_strdup (seconds_warning);
1991- }
1992-
1993-- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
1994-- secondary_text,
1995-- seconds_to_show,
1996-- NULL);
1997-+ buf = g_strdup_printf (secondary_text, seconds_to_show);
1998-+ markup = g_markup_printf_escaped ("<i>%s</i>", buf);
1999-+ g_free (buf);
2000-+ gtk_label_set_markup (GTK_LABEL (logout_dialog->priv->info_label),
2001-+ markup);
2002-+ g_free (markup);
2003-+}
2004-
2005-- logout_dialog->priv->timeout--;
2006-+static gboolean
2007-+gsm_logout_dialog_timeout (gpointer data)
2008-+{
2009-+ GsmLogoutDialog *logout_dialog;
2010-+ int seconds_to_show;
2011-+
2012-+ logout_dialog = (GsmLogoutDialog *) data;
2013-+
2014-+ if (!logout_dialog->priv->timeout) {
2015-+ gtk_dialog_response (GTK_DIALOG (logout_dialog),
2016-+ logout_dialog->priv->default_response);
2017-+
2018-+ return FALSE;
2019-+ }
2020-+
2021-+ if (logout_dialog->priv->timeout <= 30) {
2022-+ seconds_to_show = logout_dialog->priv->timeout;
2023-+ } else {
2024-+ seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
2025-+
2026-+ if (logout_dialog->priv->timeout % 10)
2027-+ seconds_to_show += 10;
2028-+ }
2029-
2030-- g_free (secondary_text);
2031-+ gsm_logout_set_info_text (logout_dialog, seconds_to_show);
2032-+
2033-+ logout_dialog->priv->timeout--;
2034-
2035- return TRUE;
2036- }
2037-
2038- static void
2039--gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog)
2040-+gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog,
2041-+ int seconds)
2042- {
2043-- logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT;
2044--
2045-- /* Sets the secondary text */
2046-- gsm_logout_dialog_timeout (logout_dialog);
2047-+ logout_dialog->priv->timeout = seconds;
2048-
2049- if (logout_dialog->priv->timeout_id != 0) {
2050- g_source_remove (logout_dialog->priv->timeout_id);
2051-@@ -351,14 +344,120 @@
2052- }
2053-
2054- static GtkWidget *
2055-+gsm_logout_tile_new (const char *icon_name,
2056-+ const char *title,
2057-+ const char *description)
2058-+{
2059-+ GtkWidget *button;
2060-+ GtkWidget *alignment;
2061-+ GtkWidget *hbox;
2062-+ GtkWidget *vbox;
2063-+ GtkWidget *image;
2064-+ GtkWidget *label;
2065-+ char *markup;
2066-+
2067-+ g_assert (title != NULL);
2068-+
2069-+ button = GTK_WIDGET (gtk_button_new ());
2070-+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
2071-+
2072-+ alignment = gtk_alignment_new (0, 0.5, 0, 0);
2073-+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 6, 6);
2074-+ gtk_container_add (GTK_CONTAINER (button), alignment);
2075-+
2076-+ hbox = gtk_hbox_new (FALSE, 12);
2077-+ gtk_container_add (GTK_CONTAINER (alignment), hbox);
2078-+ if (icon_name != NULL) {
2079-+ image = gtk_image_new_from_icon_name (icon_name,
2080-+ GTK_ICON_SIZE_DIALOG);
2081-+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
2082-+ }
2083-+
2084-+ vbox = gtk_vbox_new (FALSE, 2);
2085-+
2086-+ markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
2087-+ title);
2088-+ label = gtk_label_new (markup);
2089-+ g_free (markup);
2090-+
2091-+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
2092-+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2093-+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
2094-+
2095-+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
2096-+
2097-+ if (description != NULL) {
2098-+ gchar *markup;
2099-+ GdkColor *color;
2100-+ GtkWidget *label;
2101-+ GtkStyle *style;
2102-+
2103-+ style = gtk_widget_get_style (GTK_WIDGET (button));
2104-+ color = &style->fg[GTK_STATE_INSENSITIVE];
2105-+ markup = g_markup_printf_escaped ("<span size=\"small\" foreground=\"#%.2x%.2x%.2x\">%s</span>",
2106-+ color->red,
2107-+ color->green,
2108-+ color->blue,
2109-+ description);
2110-+ label = gtk_label_new (markup);
2111-+ g_free (markup);
2112-+
2113-+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
2114-+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2115-+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
2116-+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2117-+
2118-+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
2119-+ }
2120-+
2121-+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2122-+
2123-+ return button;
2124-+}
2125-+
2126-+static void
2127-+gsm_logout_tile_clicked (GtkWidget *tile,
2128-+ gpointer response_p)
2129-+{
2130-+ GtkWidget *dialog;
2131-+
2132-+ dialog = gtk_widget_get_toplevel (tile);
2133-+ g_assert (GTK_IS_DIALOG (dialog));
2134-+ gtk_dialog_response (GTK_DIALOG (dialog),
2135-+ GPOINTER_TO_UINT (response_p));
2136-+}
2137-+
2138-+static GtkWidget *
2139-+gsm_logout_append_tile (GtkWidget *vbox,
2140-+ unsigned int response,
2141-+ const char *icon_name,
2142-+ const char *title,
2143-+ const char *description)
2144-+{
2145-+ GtkWidget *tile;
2146-+
2147-+ tile = gsm_logout_tile_new (icon_name, title, description);
2148-+ gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
2149-+ gtk_widget_show_all (tile);
2150-+
2151-+ g_signal_connect (tile,
2152-+ "clicked",
2153-+ G_CALLBACK (gsm_logout_tile_clicked),
2154-+ GUINT_TO_POINTER (response));
2155-+
2156-+ return tile;
2157-+}
2158-+
2159-+static GtkWidget *
2160- gsm_get_dialog (GsmDialogLogoutType type,
2161- GdkScreen *screen,
2162- guint32 activate_time)
2163- {
2164- GsmLogoutDialog *logout_dialog;
2165-- GtkWidget *dialog_image;
2166-- const char *primary_text;
2167-+ GtkWidget *vbox;
2168-+ GtkWidget *tile;
2169- const char *icon_name;
2170-+ const char *title;
2171-
2172- if (current_dialog != NULL) {
2173- gtk_widget_destroy (GTK_WIDGET (current_dialog));
2174-@@ -368,83 +467,119 @@
2175-
2176- current_dialog = logout_dialog;
2177-
2178-- gtk_window_set_title (GTK_WINDOW (logout_dialog), "");
2179--
2180-- logout_dialog->priv->type = type;
2181-+ vbox = gtk_vbox_new (FALSE, 12);
2182-+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog))), vbox,
2183-+ FALSE, FALSE, 0);
2184-+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
2185-+ gtk_widget_show (vbox);
2186-
2187- icon_name = NULL;
2188-- primary_text = NULL;
2189-+ title = NULL;
2190-
2191- switch (type) {
2192- case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
2193- icon_name = GSM_ICON_LOGOUT;
2194-- primary_text = _("Log out of this system now?");
2195-+ title = _("Log Out of the Session");
2196-
2197- logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
2198-
2199-- if (gsm_logout_supports_switch_user (logout_dialog)) {
2200-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2201-+
2202-+ gsm_logout_append_tile (vbox, GSM_LOGOUT_RESPONSE_LOGOUT,
2203-+ GSM_ICON_LOGOUT, _("_Log Out"),
2204-+ _("Ends your session and logs you "
2205-+ "out."));
2206-+
2207-+ tile = gsm_logout_append_tile (vbox,
2208-+ GSM_LOGOUT_RESPONSE_SWITCH_USER,
2209-+ GSM_ICON_SWITCH,
2210- _("_Switch User"),
2211-- GSM_LOGOUT_RESPONSE_SWITCH_USER);
2212-+ _("Suspends your session, "
2213-+ "allowing another user to "
2214-+ "log in and use the "
2215-+ "computer."));
2216-+ if (!gsm_logout_supports_switch_user (logout_dialog)) {
2217-+ gtk_widget_set_sensitive (tile, FALSE);
2218- }
2219-
2220-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2221-- GTK_STOCK_CANCEL,
2222-- GTK_RESPONSE_CANCEL);
2223--
2224-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2225-- _("_Log Out"),
2226-- GSM_LOGOUT_RESPONSE_LOGOUT);
2227--
2228- break;
2229- case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
2230- icon_name = GSM_ICON_SHUTDOWN;
2231-- primary_text = _("Shut down this system now?");
2232-+ title = _("Shut Down the Computer");
2233-
2234- logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
2235-
2236-- if (gsm_logout_supports_system_suspend (logout_dialog)) {
2237-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2238-- _("S_uspend"),
2239-- GSM_LOGOUT_RESPONSE_SLEEP);
2240-+ tile = gsm_logout_append_tile (vbox,
2241-+ GSM_LOGOUT_RESPONSE_SHUTDOWN,
2242-+ GSM_ICON_SHUTDOWN,
2243-+ _("_Shut Down"),
2244-+ _("Ends your session and turns "
2245-+ "off the computer."));
2246-+ if (!gsm_logout_supports_shutdown (logout_dialog)) {
2247-+ gtk_widget_set_sensitive (tile, FALSE);
2248-+ /* If shutdown is not available, let's just fallback
2249-+ * on cancel as the default action. We could fallback
2250-+ * on reboot first, then suspend and then hibernate
2251-+ * but it's not that useful, really */
2252-+ logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
2253- }
2254-
2255-- if (gsm_logout_supports_system_hibernate (logout_dialog)) {
2256-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2257-- _("_Hibernate"),
2258-- GSM_LOGOUT_RESPONSE_HIBERNATE);
2259-+ tile = gsm_logout_append_tile (vbox,
2260-+ GSM_LOGOUT_RESPONSE_REBOOT,
2261-+ GSM_ICON_REBOOT, _("_Restart"),
2262-+ _("Ends your session and "
2263-+ "restarts the computer."));
2264-+ if (!gsm_logout_supports_reboot (logout_dialog)) {
2265-+ gtk_widget_set_sensitive (tile, FALSE);
2266- }
2267-
2268-- if (gsm_logout_supports_reboot (logout_dialog)) {
2269-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2270-- _("_Restart"),
2271-- GSM_LOGOUT_RESPONSE_REBOOT);
2272-+ /* We don't set those options insensitive if they are no
2273-+ * supported (like we do for shutdown/restart) since some
2274-+ * hardware just don't support suspend/hibernate. So we
2275-+ * don't show those options in this case. */
2276-+ if (gsm_logout_supports_system_suspend (logout_dialog)) {
2277-+ gsm_logout_append_tile (vbox,
2278-+ GSM_LOGOUT_RESPONSE_SLEEP,
2279-+ GSM_ICON_SLEEP, _("S_uspend"),
2280-+ _("Suspends your session "
2281-+ "quickly, using minimal "
2282-+ "power while the computer "
2283-+ "stands by."));
2284- }
2285-
2286-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2287-- GTK_STOCK_CANCEL,
2288-- GTK_RESPONSE_CANCEL);
2289--
2290-- if (gsm_logout_supports_shutdown (logout_dialog)) {
2291-- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
2292-- _("_Shut Down"),
2293-- GSM_LOGOUT_RESPONSE_SHUTDOWN);
2294-+ if (gsm_logout_supports_system_hibernate (logout_dialog)) {
2295-+ gsm_logout_append_tile (vbox,
2296-+ GSM_LOGOUT_RESPONSE_HIBERNATE,
2297-+ GSM_ICON_HIBERNATE,
2298-+ _("_Hibernate"),
2299-+ _("Suspends your session, "
2300-+ "using no power until the "
2301-+ "computer is restarted."));
2302- }
2303-+
2304- break;
2305- default:
2306- g_assert_not_reached ();
2307- }
2308-
2309-- dialog_image = gtk_message_dialog_get_image (GTK_MESSAGE_DIALOG (logout_dialog));
2310-+ logout_dialog->priv->info_label = gtk_label_new ("");
2311-+ gtk_label_set_line_wrap (GTK_LABEL (logout_dialog->priv->info_label),
2312-+ TRUE);
2313-+ gtk_box_pack_start (GTK_BOX (vbox), logout_dialog->priv->info_label,
2314-+ TRUE, TRUE, 0);
2315-+ gtk_widget_show (logout_dialog->priv->info_label);
2316-
2317-- gtk_image_set_from_icon_name (GTK_IMAGE (dialog_image),
2318-- icon_name, GTK_ICON_SIZE_DIALOG);
2319- gtk_window_set_icon_name (GTK_WINDOW (logout_dialog), icon_name);
2320-- gtk_window_set_position (GTK_WINDOW (logout_dialog), GTK_WIN_POS_CENTER_ALWAYS);
2321-- gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (logout_dialog), primary_text);
2322-+ gtk_window_set_title (GTK_WINDOW (logout_dialog), title);
2323-+ gtk_window_set_position (GTK_WINDOW (logout_dialog),
2324-+ GTK_WIN_POS_CENTER_ALWAYS);
2325-
2326- gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
2327- logout_dialog->priv->default_response);
2328-+ /* Note that focus is on the widget for the default response by default
2329-+ * (since they're the first widget, except when it's Cancel */
2330-+ if (logout_dialog->priv->default_response == GTK_RESPONSE_CANCEL)
2331-+ gtk_window_set_focus (GTK_WINDOW (logout_dialog),
2332-+ logout_dialog->priv->cancel_button);
2333-
2334- gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
2335-
2336
2337=== modified file 'debian/patches/95_dbus_request_shutdown.patch'
2338--- debian/patches/95_dbus_request_shutdown.patch 2013-06-08 23:25:03 +0000
2339+++ debian/patches/95_dbus_request_shutdown.patch 2014-10-31 04:52:33 +0000
2340@@ -2,11 +2,9 @@
2341 other applications to shutdown or reboot the machine via the session manager
2342 Author: Chris Coulson <chrisccoulson@ubuntu.com>
2343
2344-Index: gnome-session-3.7.3/gnome-session/gsm-manager.c
2345-===================================================================
2346---- gnome-session-3.7.3.orig/gnome-session/gsm-manager.c 2013-01-07 12:51:02.026999067 +1300
2347-+++ gnome-session-3.7.3/gnome-session/gsm-manager.c 2013-01-07 12:51:02.022999066 +1300
2348-@@ -3664,6 +3664,48 @@
2349+--- a/gnome-session/gsm-manager.c
2350++++ b/gnome-session/gsm-manager.c
2351+@@ -3116,6 +3116,48 @@
2352 }
2353
2354 gboolean
2355@@ -52,14 +50,12 @@
2356 +}
2357 +
2358 +gboolean
2359- gsm_manager_shutdown (GsmManager *manager,
2360- GError **error)
2361+ gsm_manager_shutdown (GsmManager *manager,
2362+ DBusGMethodInvocation *context)
2363 {
2364-Index: gnome-session-3.7.3/gnome-session/gsm-manager.h
2365-===================================================================
2366---- gnome-session-3.7.3.orig/gnome-session/gsm-manager.h 2013-01-07 12:51:02.026999067 +1300
2367-+++ gnome-session-3.7.3/gnome-session/gsm-manager.h 2013-01-07 12:51:02.022999066 +1300
2368-@@ -160,7 +160,10 @@
2369+--- a/gnome-session/gsm-manager.h
2370++++ b/gnome-session/gsm-manager.h
2371+@@ -159,7 +159,10 @@
2372 guint flags,
2373 gboolean *is_inhibited,
2374 GError *error);
2375@@ -69,13 +65,11 @@
2376 +gboolean gsm_manager_request_reboot (GsmManager *manager,
2377 + GError **error);
2378 gboolean gsm_manager_shutdown (GsmManager *manager,
2379- GError **error);
2380+ DBusGMethodInvocation *context);
2381 gboolean gsm_manager_reboot (GsmManager *manager,
2382-Index: gnome-session-3.7.3/gnome-session/org.gnome.SessionManager.xml
2383-===================================================================
2384---- gnome-session-3.7.3.orig/gnome-session/org.gnome.SessionManager.xml 2013-01-07 12:51:02.026999067 +1300
2385-+++ gnome-session-3.7.3/gnome-session/org.gnome.SessionManager.xml 2013-01-07 12:51:02.022999066 +1300
2386-@@ -346,6 +346,23 @@
2387+--- a/gnome-session/org.gnome.SessionManager.xml
2388++++ b/gnome-session/org.gnome.SessionManager.xml
2389+@@ -348,6 +348,23 @@
2390 </doc:doc>
2391 </method>
2392
2393
2394=== removed file 'debian/patches/git_fix_wrong_unref_call.patch'
2395--- debian/patches/git_fix_wrong_unref_call.patch 2013-10-11 13:45:07 +0000
2396+++ debian/patches/git_fix_wrong_unref_call.patch 1970-01-01 00:00:00 +0000
2397@@ -1,32 +0,0 @@
2398-Subject: shell: unref correct proxy on destroy
2399-
2400-gsm-shell.c tries to automatically clear it's reference to the
2401-EndSessionDialog proxy when the proxy is destroyed.
2402-
2403-It accidentally unrefs the wrong object though. This commit
2404-fixes that by changing the open coded unref+nullify to g_clear_object
2405-
2406-I believe this will address this crasher:
2407-
2408-https://retrace.fedoraproject.org/faf/problems/1214348/
2409-
2410-https://bugzilla.gnome.org/show_bug.cgi?id=709221
2411----
2412-diff --git a/gnome-session/gsm-shell.c b/gnome-session/gsm-shell.c
2413-index 450ca40..1c7f053 100644
2414---- a/gnome-session/gsm-shell.c
2415-+++ b/gnome-session/gsm-shell.c
2416-@@ -534,11 +534,7 @@ static void
2417- on_end_session_dialog_proxy_destroyed (DBusGProxy *proxy,
2418- GsmShell *shell)
2419- {
2420-- /* FIXME - is this right? */
2421-- if (shell->priv->end_session_dialog_proxy != NULL) {
2422-- g_object_unref (shell->priv->proxy);
2423-- shell->priv->end_session_dialog_proxy = NULL;
2424-- }
2425-+ g_clear_object (&shell->priv->end_session_dialog_proxy);
2426- }
2427-
2428- static gboolean
2429-
2430
2431=== added file 'debian/patches/revert_remove_gnome_session_properties.patch'
2432--- debian/patches/revert_remove_gnome_session_properties.patch 1970-01-01 00:00:00 +0000
2433+++ debian/patches/revert_remove_gnome_session_properties.patch 2014-10-31 04:52:33 +0000
2434@@ -0,0 +1,3992 @@
2435+From 172a7377d00be077c96e9951941c070d491b0b4b Mon Sep 17 00:00:00 2001
2436+From: Tim Lunn <tim@feathertop.org>
2437+Date: Fri, 31 Oct 2014 09:23:49 +1100
2438+Subject: [PATCH] Revert "Remove gnome-session-properties"
2439+
2440+This reverts commit ea285af9962313ee2675fff27d3a852bb61e936a.
2441+---
2442+ Makefile.am | 1 +
2443+ capplet/Makefile.am | 31 +
2444+ capplet/gsm-app-dialog.c | 540 +++++++++++++
2445+ capplet/gsm-app-dialog.h | 66 ++
2446+ capplet/gsm-properties-dialog.c | 774 +++++++++++++++++++
2447+ capplet/gsm-properties-dialog.h | 57 ++
2448+ capplet/gsp-app-manager.c | 593 ++++++++++++++
2449+ capplet/gsp-app-manager.h | 81 ++
2450+ capplet/gsp-app.c | 1102 +++++++++++++++++++++++++++
2451+ capplet/gsp-app.h | 108 +++
2452+ capplet/gsp-keyfile.c | 201 +++++
2453+ capplet/gsp-keyfile.h | 65 ++
2454+ capplet/main.c | 108 +++
2455+ configure.ac | 2 +
2456+ data/Makefile.am | 6 +
2457+ data/gnome-session-properties.desktop.in.in | 15 +
2458+ doc/man/Makefile.am | 1 +
2459+ doc/man/gnome-session-properties.1 | 24 +
2460+ po/POTFILES.in | 5 +
2461+ 19 files changed, 3780 insertions(+)
2462+ create mode 100644 capplet/Makefile.am
2463+ create mode 100644 capplet/gsm-app-dialog.c
2464+ create mode 100644 capplet/gsm-app-dialog.h
2465+ create mode 100644 capplet/gsm-properties-dialog.c
2466+ create mode 100644 capplet/gsm-properties-dialog.h
2467+ create mode 100644 capplet/gsp-app-manager.c
2468+ create mode 100644 capplet/gsp-app-manager.h
2469+ create mode 100644 capplet/gsp-app.c
2470+ create mode 100644 capplet/gsp-app.h
2471+ create mode 100644 capplet/gsp-keyfile.c
2472+ create mode 100644 capplet/gsp-keyfile.h
2473+ create mode 100644 capplet/main.c
2474+ create mode 100644 data/gnome-session-properties.desktop.in.in
2475+ create mode 100644 doc/man/gnome-session-properties.1
2476+
2477+Index: gnome-session/Makefile.am
2478+===================================================================
2479+--- gnome-session.orig/Makefile.am
2480++++ gnome-session/Makefile.am
2481+@@ -1,5 +1,6 @@
2482+ SUBDIRS = \
2483+ gnome-session \
2484++ capplet \
2485+ tools \
2486+ data \
2487+ doc \
2488+Index: gnome-session/capplet/Makefile.am
2489+===================================================================
2490+--- /dev/null
2491++++ gnome-session/capplet/Makefile.am
2492+@@ -0,0 +1,31 @@
2493++bin_PROGRAMS = gnome-session-properties
2494++
2495++AM_CPPFLAGS = \
2496++ $(SESSION_PROPERTIES_CFLAGS) \
2497++ $(GCONF_CFLAGS) \
2498++ -I$(top_srcdir)/gnome-session \
2499++ -DLOCALE_DIR=\""$(datadir)/locale"\" \
2500++ -DGTKBUILDER_DIR=\""$(pkgdatadir)"\" \
2501++ $(DISABLE_DEPRECATED_CFLAGS)
2502++
2503++AM_CFLAGS = $(WARN_CFLAGS)
2504++
2505++gnome_session_properties_SOURCES = \
2506++ main.c \
2507++ gsm-properties-dialog.h \
2508++ gsm-properties-dialog.c \
2509++ gsm-app-dialog.h \
2510++ gsm-app-dialog.c \
2511++ gsp-app.h \
2512++ gsp-app.c \
2513++ gsp-app-manager.h \
2514++ gsp-app-manager.c \
2515++ gsp-keyfile.h \
2516++ gsp-keyfile.c
2517++
2518++gnome_session_properties_LDADD = \
2519++ $(SESSION_PROPERTIES_LIBS) \
2520++ $(top_builddir)/gnome-session/libgsmutil.la \
2521++ $(GCONF_LIBS)
2522++
2523++-include $(top_srcdir)/git.mk
2524+Index: gnome-session/capplet/gsm-app-dialog.c
2525+===================================================================
2526+--- /dev/null
2527++++ gnome-session/capplet/gsm-app-dialog.c
2528+@@ -0,0 +1,540 @@
2529++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2530++ *
2531++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
2532++ *
2533++ * This program is free software; you can redistribute it and/or modify
2534++ * it under the terms of the GNU General Public License as published by
2535++ * the Free Software Foundation; either version 2 of the License, or
2536++ * (at your option) any later version.
2537++ *
2538++ * This program is distributed in the hope that it will be useful,
2539++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2540++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2541++ * GNU General Public License for more details.
2542++ *
2543++ * You should have received a copy of the GNU General Public License
2544++ * along with this program; if not, write to the Free Software
2545++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2546++ *
2547++ */
2548++
2549++#include "config.h"
2550++
2551++#include <glib.h>
2552++#include <glib/gi18n.h>
2553++#include <gtk/gtk.h>
2554++
2555++#include "gsm-util.h"
2556++
2557++#include "gsm-app-dialog.h"
2558++
2559++#define GTKBUILDER_FILE "session-properties.ui"
2560++
2561++#define CAPPLET_NAME_ENTRY_WIDGET_NAME "session_properties_name_entry"
2562++#define CAPPLET_COMMAND_ENTRY_WIDGET_NAME "session_properties_command_entry"
2563++#define CAPPLET_COMMENT_ENTRY_WIDGET_NAME "session_properties_comment_entry"
2564++#define CAPPLET_BROWSE_WIDGET_NAME "session_properties_browse_button"
2565++
2566++
2567++#define GSM_APP_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_APP_DIALOG, GsmAppDialogPrivate))
2568++
2569++struct GsmAppDialogPrivate
2570++{
2571++ GtkWidget *name_entry;
2572++ GtkWidget *command_entry;
2573++ GtkWidget *comment_entry;
2574++ GtkWidget *browse_button;
2575++ char *name;
2576++ char *command;
2577++ char *comment;
2578++};
2579++
2580++static void gsm_app_dialog_class_init (GsmAppDialogClass *klass);
2581++static void gsm_app_dialog_init (GsmAppDialog *app_dialog);
2582++static void gsm_app_dialog_finalize (GObject *object);
2583++
2584++enum {
2585++ PROP_0,
2586++ PROP_NAME,
2587++ PROP_COMMAND,
2588++ PROP_COMMENT
2589++};
2590++
2591++G_DEFINE_TYPE (GsmAppDialog, gsm_app_dialog, GTK_TYPE_DIALOG)
2592++
2593++static char *
2594++make_exec_uri (const char *exec)
2595++{
2596++ GString *str;
2597++ const char *c;
2598++
2599++ if (exec == NULL) {
2600++ return g_strdup ("");
2601++ }
2602++
2603++ if (strchr (exec, ' ') == NULL) {
2604++ return g_strdup (exec);
2605++ }
2606++
2607++ str = g_string_new_len (NULL, strlen (exec));
2608++
2609++ str = g_string_append_c (str, '"');
2610++ for (c = exec; *c != '\0'; c++) {
2611++ /* FIXME: GKeyFile will add an additional backslach so we'll
2612++ * end up with toto\\" instead of toto\"
2613++ * We could use g_key_file_set_value(), but then we don't
2614++ * benefit from the other escaping that glib is doing...
2615++ */
2616++ if (*c == '"') {
2617++ str = g_string_append (str, "\\\"");
2618++ } else {
2619++ str = g_string_append_c (str, *c);
2620++ }
2621++ }
2622++ str = g_string_append_c (str, '"');
2623++
2624++ return g_string_free (str, FALSE);
2625++}
2626++
2627++static void
2628++on_browse_button_clicked (GtkWidget *widget,
2629++ GsmAppDialog *dialog)
2630++{
2631++ GtkWidget *chooser;
2632++ int response;
2633++
2634++ chooser = gtk_file_chooser_dialog_new ("",
2635++ GTK_WINDOW (dialog),
2636++ GTK_FILE_CHOOSER_ACTION_OPEN,
2637++ GTK_STOCK_CANCEL,
2638++ GTK_RESPONSE_CANCEL,
2639++ GTK_STOCK_OPEN,
2640++ GTK_RESPONSE_ACCEPT,
2641++ NULL);
2642++
2643++ gtk_window_set_transient_for (GTK_WINDOW (chooser),
2644++ GTK_WINDOW (dialog));
2645++
2646++ gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
2647++
2648++ gtk_window_set_title (GTK_WINDOW (chooser), _("Select Command"));
2649++
2650++ gtk_widget_show (chooser);
2651++
2652++ response = gtk_dialog_run (GTK_DIALOG (chooser));
2653++
2654++ if (response == GTK_RESPONSE_ACCEPT) {
2655++ char *text;
2656++ char *uri;
2657++
2658++ text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
2659++
2660++ uri = make_exec_uri (text);
2661++
2662++ g_free (text);
2663++
2664++ gtk_entry_set_text (GTK_ENTRY (dialog->priv->command_entry), uri);
2665++
2666++ g_free (uri);
2667++ }
2668++
2669++ gtk_widget_destroy (chooser);
2670++}
2671++
2672++static void
2673++on_entry_activate (GtkEntry *entry,
2674++ GsmAppDialog *dialog)
2675++{
2676++ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
2677++}
2678++
2679++static void
2680++setup_dialog (GsmAppDialog *dialog)
2681++{
2682++ GtkWidget *content_area;
2683++ GtkWidget *widget;
2684++ GtkBuilder *xml;
2685++ GError *error;
2686++
2687++ xml = gtk_builder_new ();
2688++ gtk_builder_set_translation_domain (xml, GETTEXT_PACKAGE);
2689++
2690++ error = NULL;
2691++ if (!gtk_builder_add_from_file (xml,
2692++ GTKBUILDER_DIR "/" GTKBUILDER_FILE,
2693++ &error)) {
2694++ if (error) {
2695++ g_warning ("Could not load capplet UI file: %s",
2696++ error->message);
2697++ g_error_free (error);
2698++ } else {
2699++ g_warning ("Could not load capplet UI file.");
2700++ }
2701++ }
2702++
2703++ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
2704++ widget = GTK_WIDGET (gtk_builder_get_object (xml, "main-table"));
2705++ gtk_container_add (GTK_CONTAINER (content_area), widget);
2706++
2707++ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
2708++ gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
2709++
2710++ g_object_set (dialog,
2711++ "allow-shrink", FALSE,
2712++ "allow-grow", FALSE,
2713++ NULL);
2714++
2715++ gtk_dialog_add_button (GTK_DIALOG (dialog),
2716++ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
2717++
2718++ if (dialog->priv->name == NULL
2719++ && dialog->priv->command == NULL
2720++ && dialog->priv->comment == NULL) {
2721++ gtk_window_set_title (GTK_WINDOW (dialog), _("Add Startup Program"));
2722++ gtk_dialog_add_button (GTK_DIALOG (dialog),
2723++ GTK_STOCK_ADD, GTK_RESPONSE_OK);
2724++ } else {
2725++ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Startup Program"));
2726++ gtk_dialog_add_button (GTK_DIALOG (dialog),
2727++ GTK_STOCK_SAVE, GTK_RESPONSE_OK);
2728++ }
2729++
2730++ dialog->priv->name_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_NAME_ENTRY_WIDGET_NAME));
2731++ g_signal_connect (dialog->priv->name_entry,
2732++ "activate",
2733++ G_CALLBACK (on_entry_activate),
2734++ dialog);
2735++ if (dialog->priv->name != NULL) {
2736++ gtk_entry_set_text (GTK_ENTRY (dialog->priv->name_entry), dialog->priv->name);
2737++ }
2738++
2739++ dialog->priv->browse_button = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_BROWSE_WIDGET_NAME));
2740++ g_signal_connect (dialog->priv->browse_button,
2741++ "clicked",
2742++ G_CALLBACK (on_browse_button_clicked),
2743++ dialog);
2744++
2745++ dialog->priv->command_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMAND_ENTRY_WIDGET_NAME));
2746++ g_signal_connect (dialog->priv->command_entry,
2747++ "activate",
2748++ G_CALLBACK (on_entry_activate),
2749++ dialog);
2750++ if (dialog->priv->command != NULL) {
2751++ gtk_entry_set_text (GTK_ENTRY (dialog->priv->command_entry), dialog->priv->command);
2752++ }
2753++
2754++ dialog->priv->comment_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMENT_ENTRY_WIDGET_NAME));
2755++ g_signal_connect (dialog->priv->comment_entry,
2756++ "activate",
2757++ G_CALLBACK (on_entry_activate),
2758++ dialog);
2759++ if (dialog->priv->comment != NULL) {
2760++ gtk_entry_set_text (GTK_ENTRY (dialog->priv->comment_entry), dialog->priv->comment);
2761++ }
2762++
2763++ if (xml != NULL) {
2764++ g_object_unref (xml);
2765++ }
2766++}
2767++
2768++static GObject *
2769++gsm_app_dialog_constructor (GType type,
2770++ guint n_construct_app,
2771++ GObjectConstructParam *construct_app)
2772++{
2773++ GsmAppDialog *dialog;
2774++
2775++ dialog = GSM_APP_DIALOG (G_OBJECT_CLASS (gsm_app_dialog_parent_class)->constructor (type,
2776++ n_construct_app,
2777++ construct_app));
2778++
2779++ setup_dialog (dialog);
2780++
2781++ gtk_widget_show_all (GTK_WIDGET (dialog));
2782++
2783++ return G_OBJECT (dialog);
2784++}
2785++
2786++static void
2787++gsm_app_dialog_dispose (GObject *object)
2788++{
2789++ GsmAppDialog *dialog;
2790++
2791++ g_return_if_fail (object != NULL);
2792++ g_return_if_fail (GSM_IS_APP_DIALOG (object));
2793++
2794++ dialog = GSM_APP_DIALOG (object);
2795++
2796++ g_free (dialog->priv->name);
2797++ dialog->priv->name = NULL;
2798++ g_free (dialog->priv->command);
2799++ dialog->priv->command = NULL;
2800++ g_free (dialog->priv->comment);
2801++ dialog->priv->comment = NULL;
2802++
2803++ G_OBJECT_CLASS (gsm_app_dialog_parent_class)->dispose (object);
2804++}
2805++
2806++static void
2807++gsm_app_dialog_set_name (GsmAppDialog *dialog,
2808++ const char *name)
2809++{
2810++ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
2811++
2812++ g_free (dialog->priv->name);
2813++
2814++ dialog->priv->name = g_strdup (name);
2815++ g_object_notify (G_OBJECT (dialog), "name");
2816++}
2817++
2818++static void
2819++gsm_app_dialog_set_command (GsmAppDialog *dialog,
2820++ const char *name)
2821++{
2822++ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
2823++
2824++ g_free (dialog->priv->command);
2825++
2826++ dialog->priv->command = g_strdup (name);
2827++ g_object_notify (G_OBJECT (dialog), "command");
2828++}
2829++
2830++static void
2831++gsm_app_dialog_set_comment (GsmAppDialog *dialog,
2832++ const char *name)
2833++{
2834++ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
2835++
2836++ g_free (dialog->priv->comment);
2837++
2838++ dialog->priv->comment = g_strdup (name);
2839++ g_object_notify (G_OBJECT (dialog), "comment");
2840++}
2841++
2842++const char *
2843++gsm_app_dialog_get_name (GsmAppDialog *dialog)
2844++{
2845++ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
2846++ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->name_entry));
2847++}
2848++
2849++const char *
2850++gsm_app_dialog_get_command (GsmAppDialog *dialog)
2851++{
2852++ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
2853++ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->command_entry));
2854++}
2855++
2856++const char *
2857++gsm_app_dialog_get_comment (GsmAppDialog *dialog)
2858++{
2859++ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
2860++ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->comment_entry));
2861++}
2862++
2863++static void
2864++gsm_app_dialog_set_property (GObject *object,
2865++ guint prop_id,
2866++ const GValue *value,
2867++ GParamSpec *pspec)
2868++{
2869++ GsmAppDialog *dialog = GSM_APP_DIALOG (object);
2870++
2871++ switch (prop_id) {
2872++ case PROP_NAME:
2873++ gsm_app_dialog_set_name (dialog, g_value_get_string (value));
2874++ break;
2875++ case PROP_COMMAND:
2876++ gsm_app_dialog_set_command (dialog, g_value_get_string (value));
2877++ break;
2878++ case PROP_COMMENT:
2879++ gsm_app_dialog_set_comment (dialog, g_value_get_string (value));
2880++ break;
2881++ default:
2882++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2883++ break;
2884++ }
2885++}
2886++
2887++static void
2888++gsm_app_dialog_get_property (GObject *object,
2889++ guint prop_id,
2890++ GValue *value,
2891++ GParamSpec *pspec)
2892++{
2893++ GsmAppDialog *dialog = GSM_APP_DIALOG (object);
2894++
2895++ switch (prop_id) {
2896++ case PROP_NAME:
2897++ g_value_set_string (value, dialog->priv->name);
2898++ break;
2899++ case PROP_COMMAND:
2900++ g_value_set_string (value, dialog->priv->command);
2901++ break;
2902++ case PROP_COMMENT:
2903++ g_value_set_string (value, dialog->priv->comment);
2904++ break;
2905++ default:
2906++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2907++ break;
2908++ }
2909++}
2910++
2911++static void
2912++gsm_app_dialog_class_init (GsmAppDialogClass *klass)
2913++{
2914++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
2915++
2916++ object_class->get_property = gsm_app_dialog_get_property;
2917++ object_class->set_property = gsm_app_dialog_set_property;
2918++ object_class->constructor = gsm_app_dialog_constructor;
2919++ object_class->dispose = gsm_app_dialog_dispose;
2920++ object_class->finalize = gsm_app_dialog_finalize;
2921++
2922++ g_object_class_install_property (object_class,
2923++ PROP_NAME,
2924++ g_param_spec_string ("name",
2925++ "name",
2926++ "name",
2927++ NULL,
2928++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2929++ g_object_class_install_property (object_class,
2930++ PROP_COMMAND,
2931++ g_param_spec_string ("command",
2932++ "command",
2933++ "command",
2934++ NULL,
2935++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2936++ g_object_class_install_property (object_class,
2937++ PROP_COMMENT,
2938++ g_param_spec_string ("comment",
2939++ "comment",
2940++ "comment",
2941++ NULL,
2942++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2943++
2944++ g_type_class_add_private (klass, sizeof (GsmAppDialogPrivate));
2945++}
2946++
2947++static void
2948++gsm_app_dialog_init (GsmAppDialog *dialog)
2949++{
2950++
2951++ dialog->priv = GSM_APP_DIALOG_GET_PRIVATE (dialog);
2952++}
2953++
2954++static void
2955++gsm_app_dialog_finalize (GObject *object)
2956++{
2957++ GsmAppDialog *dialog;
2958++
2959++ g_return_if_fail (object != NULL);
2960++ g_return_if_fail (GSM_IS_APP_DIALOG (object));
2961++
2962++ dialog = GSM_APP_DIALOG (object);
2963++
2964++ g_return_if_fail (dialog->priv != NULL);
2965++
2966++ G_OBJECT_CLASS (gsm_app_dialog_parent_class)->finalize (object);
2967++}
2968++
2969++GtkWidget *
2970++gsm_app_dialog_new (const char *name,
2971++ const char *command,
2972++ const char *comment)
2973++{
2974++ GObject *object;
2975++
2976++ object = g_object_new (GSM_TYPE_APP_DIALOG,
2977++ "name", name,
2978++ "command", command,
2979++ "comment", comment,
2980++ NULL);
2981++
2982++ return GTK_WIDGET (object);
2983++}
2984++
2985++gboolean
2986++gsm_app_dialog_run (GsmAppDialog *dialog,
2987++ char **name_p,
2988++ char **command_p,
2989++ char **comment_p)
2990++{
2991++ gboolean retval;
2992++
2993++ retval = FALSE;
2994++
2995++ while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2996++ const char *name;
2997++ const char *exec;
2998++ const char *comment;
2999++ const char *error_msg;
3000++ GError *error;
3001++ char **argv;
3002++ int argc;
3003++
3004++ name = gsm_app_dialog_get_name (GSM_APP_DIALOG (dialog));
3005++ exec = gsm_app_dialog_get_command (GSM_APP_DIALOG (dialog));
3006++ comment = gsm_app_dialog_get_comment (GSM_APP_DIALOG (dialog));
3007++
3008++ error = NULL;
3009++ error_msg = NULL;
3010++
3011++ if (gsm_util_text_is_blank (exec)) {
3012++ error_msg = _("The startup command cannot be empty");
3013++ } else {
3014++ if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
3015++ if (error != NULL) {
3016++ error_msg = error->message;
3017++ } else {
3018++ error_msg = _("The startup command is not valid");
3019++ }
3020++ }
3021++ }
3022++
3023++ if (error_msg != NULL) {
3024++ GtkWidget *msgbox;
3025++
3026++ msgbox = gtk_message_dialog_new (GTK_WINDOW (dialog),
3027++ GTK_DIALOG_MODAL,
3028++ GTK_MESSAGE_ERROR,
3029++ GTK_BUTTONS_CLOSE,
3030++ "%s", error_msg);
3031++
3032++ if (error != NULL) {
3033++ g_error_free (error);
3034++ }
3035++
3036++ gtk_dialog_run (GTK_DIALOG (msgbox));
3037++
3038++ gtk_widget_destroy (msgbox);
3039++
3040++ continue;
3041++ }
3042++
3043++ if (gsm_util_text_is_blank (name)) {
3044++ name = argv[0];
3045++ }
3046++
3047++ if (name_p) {
3048++ *name_p = g_strdup (name);
3049++ }
3050++
3051++ g_strfreev (argv);
3052++
3053++ if (command_p) {
3054++ *command_p = g_strdup (exec);
3055++ }
3056++
3057++ if (comment_p) {
3058++ *comment_p = g_strdup (comment);
3059++ }
3060++
3061++ retval = TRUE;
3062++ break;
3063++ }
3064++
3065++ gtk_widget_destroy (GTK_WIDGET (dialog));
3066++
3067++ return retval;
3068++}
3069+Index: gnome-session/capplet/gsm-app-dialog.h
3070+===================================================================
3071+--- /dev/null
3072++++ gnome-session/capplet/gsm-app-dialog.h
3073+@@ -0,0 +1,66 @@
3074++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3075++ *
3076++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
3077++ *
3078++ * This program is free software; you can redistribute it and/or modify
3079++ * it under the terms of the GNU General Public License as published by
3080++ * the Free Software Foundation; either version 2 of the License, or
3081++ * (at your option) any later version.
3082++ *
3083++ * This program is distributed in the hope that it will be useful,
3084++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3085++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3086++ * GNU General Public License for more details.
3087++ *
3088++ * You should have received a copy of the GNU General Public License
3089++ * along with this program; if not, write to the Free Software
3090++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3091++ *
3092++ */
3093++
3094++#ifndef __GSM_APP_DIALOG_H
3095++#define __GSM_APP_DIALOG_H
3096++
3097++#include <glib-object.h>
3098++#include <gtk/gtk.h>
3099++
3100++G_BEGIN_DECLS
3101++
3102++#define GSM_TYPE_APP_DIALOG (gsm_app_dialog_get_type ())
3103++#define GSM_APP_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_APP_DIALOG, GsmAppDialog))
3104++#define GSM_APP_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_APP_DIALOG, GsmAppDialogClass))
3105++#define GSM_IS_APP_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_APP_DIALOG))
3106++#define GSM_IS_APP_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_APP_DIALOG))
3107++#define GSM_APP_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_APP_DIALOG, GsmAppDialogClass))
3108++
3109++typedef struct GsmAppDialogPrivate GsmAppDialogPrivate;
3110++
3111++typedef struct
3112++{
3113++ GtkDialog parent;
3114++ GsmAppDialogPrivate *priv;
3115++} GsmAppDialog;
3116++
3117++typedef struct
3118++{
3119++ GtkDialogClass parent_class;
3120++} GsmAppDialogClass;
3121++
3122++GType gsm_app_dialog_get_type (void);
3123++
3124++GtkWidget * gsm_app_dialog_new (const char *name,
3125++ const char *command,
3126++ const char *comment);
3127++
3128++gboolean gsm_app_dialog_run (GsmAppDialog *dialog,
3129++ char **name_p,
3130++ char **command_p,
3131++ char **comment_p);
3132++
3133++const char * gsm_app_dialog_get_name (GsmAppDialog *dialog);
3134++const char * gsm_app_dialog_get_command (GsmAppDialog *dialog);
3135++const char * gsm_app_dialog_get_comment (GsmAppDialog *dialog);
3136++
3137++G_END_DECLS
3138++
3139++#endif /* __GSM_APP_DIALOG_H */
3140+Index: gnome-session/capplet/gsm-properties-dialog.c
3141+===================================================================
3142+--- /dev/null
3143++++ gnome-session/capplet/gsm-properties-dialog.c
3144+@@ -0,0 +1,774 @@
3145++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3146++ *
3147++ * Copyright (C) 1999 Free Software Foundation, Inc.
3148++ * Copyright (C) 2007 Vincent Untz.
3149++ * Copyright (C) 2008 Lucas Rocha.
3150++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
3151++ *
3152++ * This program is free software; you can redistribute it and/or modify
3153++ * it under the terms of the GNU General Public License as published by
3154++ * the Free Software Foundation; either version 2 of the License, or
3155++ * (at your option) any later version.
3156++ *
3157++ * This program is distributed in the hope that it will be useful,
3158++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3159++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3160++ * GNU General Public License for more details.
3161++ *
3162++ * You should have received a copy of the GNU General Public License
3163++ * along with this program; if not, write to the Free Software
3164++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3165++ *
3166++ */
3167++
3168++#include "config.h"
3169++
3170++#include <glib.h>
3171++#include <glib/gi18n.h>
3172++#include <gtk/gtk.h>
3173++
3174++#include "gsm-properties-dialog.h"
3175++#include "gsm-app-dialog.h"
3176++#include "gsm-util.h"
3177++#include "gsp-app.h"
3178++#include "gsp-app-manager.h"
3179++
3180++#define GSM_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogPrivate))
3181++
3182++#define GTKBUILDER_FILE "session-properties.ui"
3183++
3184++#define CAPPLET_TREEVIEW_WIDGET_NAME "session_properties_treeview"
3185++#define CAPPLET_ADD_WIDGET_NAME "session_properties_add_button"
3186++#define CAPPLET_DELETE_WIDGET_NAME "session_properties_delete_button"
3187++#define CAPPLET_EDIT_WIDGET_NAME "session_properties_edit_button"
3188++#define CAPPLET_SAVE_WIDGET_NAME "session_properties_save_button"
3189++#define CAPPLET_REMEMBER_WIDGET_NAME "session_properties_remember_toggle"
3190++
3191++#define STARTUP_APP_ICON "system-run"
3192++
3193++#define SPC_SETTINGS_SCHEMA "org.gnome.SessionManager"
3194++#define SPC_SETTINGS_AUTOSAVE_KEY "auto-save-session"
3195++
3196++struct GsmPropertiesDialogPrivate
3197++{
3198++ GtkBuilder *xml;
3199++ GtkListStore *list_store;
3200++ GtkTreeModel *tree_filter;
3201++
3202++ GtkTreeView *treeview;
3203++ GtkWidget *add_button;
3204++ GtkWidget *delete_button;
3205++ GtkWidget *edit_button;
3206++
3207++ GSettings *settings;
3208++
3209++ GspAppManager *manager;
3210++};
3211++
3212++enum {
3213++ STORE_COL_VISIBLE = 0,
3214++ STORE_COL_ENABLED,
3215++ STORE_COL_GICON,
3216++ STORE_COL_DESCRIPTION,
3217++ STORE_COL_APP,
3218++ STORE_COL_SEARCH,
3219++ NUMBER_OF_COLUMNS
3220++};
3221++
3222++static void gsm_properties_dialog_class_init (GsmPropertiesDialogClass *klass);
3223++static void gsm_properties_dialog_init (GsmPropertiesDialog *properties_dialog);
3224++static void gsm_properties_dialog_finalize (GObject *object);
3225++
3226++G_DEFINE_TYPE (GsmPropertiesDialog, gsm_properties_dialog, GTK_TYPE_DIALOG)
3227++
3228++static gboolean
3229++find_by_app (GtkTreeModel *model,
3230++ GtkTreeIter *iter,
3231++ GspApp *app)
3232++{
3233++ GspApp *iter_app = NULL;
3234++
3235++ if (!gtk_tree_model_get_iter_first (model, iter)) {
3236++ return FALSE;
3237++ }
3238++
3239++ do {
3240++ gtk_tree_model_get (model, iter,
3241++ STORE_COL_APP, &iter_app,
3242++ -1);
3243++
3244++ if (iter_app == app) {
3245++ g_object_unref (iter_app);
3246++ return TRUE;
3247++ }
3248++ } while (gtk_tree_model_iter_next (model, iter));
3249++
3250++ return FALSE;
3251++}
3252++
3253++static void
3254++_fill_iter_from_app (GtkListStore *list_store,
3255++ GtkTreeIter *iter,
3256++ GspApp *app)
3257++{
3258++ gboolean hidden;
3259++ gboolean display;
3260++ gboolean enabled;
3261++ gboolean shown;
3262++ GIcon *icon;
3263++ const char *description;
3264++ const char *app_name;
3265++
3266++ hidden = gsp_app_get_hidden (app);
3267++ display = gsp_app_get_display (app);
3268++ enabled = gsp_app_get_enabled (app);
3269++ shown = gsp_app_get_shown (app);
3270++ icon = gsp_app_get_icon (app);
3271++ description = gsp_app_get_description (app);
3272++ app_name = gsp_app_get_name (app);
3273++
3274++ if (G_IS_THEMED_ICON (icon)) {
3275++ GtkIconTheme *theme;
3276++ const char * const *icon_names;
3277++
3278++ theme = gtk_icon_theme_get_default ();
3279++ icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon));
3280++ if (icon_names[0] == NULL ||
3281++ !gtk_icon_theme_has_icon (theme, icon_names[0])) {
3282++ g_object_unref (icon);
3283++ icon = NULL;
3284++ }
3285++ } else if (G_IS_FILE_ICON (icon)) {
3286++ GFile *iconfile;
3287++
3288++ iconfile = g_file_icon_get_file (G_FILE_ICON (icon));
3289++ if (!g_file_query_exists (iconfile, NULL)) {
3290++ g_object_unref (icon);
3291++ icon = NULL;
3292++ }
3293++ }
3294++
3295++ if (icon == NULL) {
3296++ icon = g_themed_icon_new (STARTUP_APP_ICON);
3297++ }
3298++
3299++ gtk_list_store_set (list_store, iter,
3300++ STORE_COL_VISIBLE, !hidden && shown && display,
3301++ STORE_COL_ENABLED, enabled,
3302++ STORE_COL_GICON, icon,
3303++ STORE_COL_DESCRIPTION, description,
3304++ STORE_COL_APP, app,
3305++ STORE_COL_SEARCH, app_name,
3306++ -1);
3307++ g_object_unref (icon);
3308++}
3309++
3310++static void
3311++_app_changed (GsmPropertiesDialog *dialog,
3312++ GspApp *app)
3313++{
3314++ GtkTreeIter iter;
3315++
3316++ if (!find_by_app (GTK_TREE_MODEL (dialog->priv->list_store),
3317++ &iter, app)) {
3318++ return;
3319++ }
3320++
3321++ _fill_iter_from_app (dialog->priv->list_store, &iter, app);
3322++}
3323++
3324++static void
3325++append_app (GsmPropertiesDialog *dialog,
3326++ GspApp *app)
3327++{
3328++ GtkTreeIter iter;
3329++
3330++ gtk_list_store_append (dialog->priv->list_store, &iter);
3331++ _fill_iter_from_app (dialog->priv->list_store, &iter, app);
3332++
3333++ g_signal_connect_swapped (app, "changed",
3334++ G_CALLBACK (_app_changed), dialog);
3335++}
3336++
3337++static void
3338++_app_added (GsmPropertiesDialog *dialog,
3339++ GspApp *app,
3340++ GspAppManager *manager)
3341++{
3342++ append_app (dialog, app);
3343++}
3344++
3345++static void
3346++_app_removed (GsmPropertiesDialog *dialog,
3347++ GspApp *app,
3348++ GspAppManager *manager)
3349++{
3350++ GtkTreeIter iter;
3351++
3352++ if (!find_by_app (GTK_TREE_MODEL (dialog->priv->list_store),
3353++ &iter, app)) {
3354++ return;
3355++ }
3356++
3357++ g_signal_handlers_disconnect_by_func (app,
3358++ _app_changed,
3359++ dialog);
3360++ gtk_list_store_remove (dialog->priv->list_store, &iter);
3361++}
3362++
3363++static void
3364++populate_model (GsmPropertiesDialog *dialog)
3365++{
3366++ GSList *apps;
3367++ GSList *l;
3368++
3369++ apps = gsp_app_manager_get_apps (dialog->priv->manager);
3370++ for (l = apps; l != NULL; l = l->next) {
3371++ append_app (dialog, GSP_APP (l->data));
3372++ }
3373++ g_slist_free (apps);
3374++}
3375++
3376++static void
3377++on_selection_changed (GtkTreeSelection *selection,
3378++ GsmPropertiesDialog *dialog)
3379++{
3380++ gboolean sel;
3381++
3382++ sel = gtk_tree_selection_get_selected (selection, NULL, NULL);
3383++
3384++ gtk_widget_set_sensitive (dialog->priv->edit_button, sel);
3385++ gtk_widget_set_sensitive (dialog->priv->delete_button, sel);
3386++}
3387++
3388++static void
3389++on_startup_enabled_toggled (GtkCellRendererToggle *cell_renderer,
3390++ char *path,
3391++ GsmPropertiesDialog *dialog)
3392++{
3393++ GtkTreeIter iter;
3394++ GspApp *app;
3395++ gboolean active;
3396++
3397++ if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (dialog->priv->tree_filter),
3398++ &iter, path)) {
3399++ return;
3400++ }
3401++
3402++ app = NULL;
3403++ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
3404++ &iter,
3405++ STORE_COL_APP, &app,
3406++ -1);
3407++
3408++ active = gtk_cell_renderer_toggle_get_active (cell_renderer);
3409++ active = !active;
3410++
3411++ if (app) {
3412++ gsp_app_set_enabled (app, active);
3413++ g_object_unref (app);
3414++ }
3415++}
3416++
3417++static void
3418++on_drag_data_received (GtkWidget *widget,
3419++ GdkDragContext *drag_context,
3420++ gint x,
3421++ gint y,
3422++ GtkSelectionData *data,
3423++ guint info,
3424++ guint time,
3425++ GsmPropertiesDialog *dialog)
3426++{
3427++ gboolean dnd_success;
3428++
3429++ dnd_success = FALSE;
3430++
3431++ if (data != NULL) {
3432++ char **filenames;
3433++ int i;
3434++
3435++ filenames = gtk_selection_data_get_uris (data);
3436++
3437++ for (i = 0; filenames[i] && filenames[i][0]; i++) {
3438++ /* Return success if at least one file succeeded */
3439++ gboolean file_success;
3440++ file_success = gsp_app_copy_desktop_file (filenames[i]);
3441++ dnd_success = dnd_success || file_success;
3442++ }
3443++
3444++ g_strfreev (filenames);
3445++ }
3446++
3447++ gtk_drag_finish (drag_context, dnd_success, FALSE, time);
3448++ g_signal_stop_emission_by_name (widget, "drag_data_received");
3449++}
3450++
3451++static void
3452++on_drag_begin (GtkWidget *widget,
3453++ GdkDragContext *context,
3454++ GsmPropertiesDialog *dialog)
3455++{
3456++ GtkTreePath *path;
3457++ GtkTreeIter iter;
3458++ GspApp *app;
3459++
3460++ gtk_tree_view_get_cursor (GTK_TREE_VIEW (widget), &path, NULL);
3461++ gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->tree_filter),
3462++ &iter, path);
3463++ gtk_tree_path_free (path);
3464++
3465++ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
3466++ &iter,
3467++ STORE_COL_APP, &app,
3468++ -1);
3469++
3470++ if (app) {
3471++ g_object_set_data_full (G_OBJECT (context), "gsp-app",
3472++ g_object_ref (app), g_object_unref);
3473++ g_object_unref (app);
3474++ }
3475++
3476++}
3477++
3478++static void
3479++on_drag_data_get (GtkWidget *widget,
3480++ GdkDragContext *context,
3481++ GtkSelectionData *selection_data,
3482++ guint info,
3483++ guint time,
3484++ GsmPropertiesDialog *dialog)
3485++{
3486++ GspApp *app;
3487++
3488++ app = g_object_get_data (G_OBJECT (context), "gsp-app");
3489++ if (app) {
3490++ const char *uris[2];
3491++ char *uri;
3492++
3493++ uri = g_filename_to_uri (gsp_app_get_path (app), NULL, NULL);
3494++
3495++ uris[0] = uri;
3496++ uris[1] = NULL;
3497++ gtk_selection_data_set_uris (selection_data, (char **) uris);
3498++
3499++ g_free (uri);
3500++ }
3501++}
3502++
3503++static void
3504++on_add_app_clicked (GtkWidget *widget,
3505++ GsmPropertiesDialog *dialog)
3506++{
3507++ GtkWidget *add_dialog;
3508++ char *name;
3509++ char *exec;
3510++ char *comment;
3511++
3512++ add_dialog = gsm_app_dialog_new (NULL, NULL, NULL);
3513++ gtk_window_set_transient_for (GTK_WINDOW (add_dialog),
3514++ GTK_WINDOW (dialog));
3515++
3516++ if (gsm_app_dialog_run (GSM_APP_DIALOG (add_dialog),
3517++ &name, &exec, &comment)) {
3518++ gsp_app_create (name, comment, exec);
3519++ g_free (name);
3520++ g_free (exec);
3521++ g_free (comment);
3522++ }
3523++}
3524++
3525++static void
3526++on_delete_app_clicked (GtkWidget *widget,
3527++ GsmPropertiesDialog *dialog)
3528++{
3529++ GtkTreeSelection *selection;
3530++ GtkTreeIter iter;
3531++ GspApp *app;
3532++
3533++ selection = gtk_tree_view_get_selection (dialog->priv->treeview);
3534++
3535++ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
3536++ return;
3537++ }
3538++
3539++ app = NULL;
3540++ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
3541++ &iter,
3542++ STORE_COL_APP, &app,
3543++ -1);
3544++
3545++ if (app) {
3546++ gsp_app_delete (app);
3547++ g_object_unref (app);
3548++ }
3549++}
3550++
3551++static void
3552++on_edit_app_clicked (GtkWidget *widget,
3553++ GsmPropertiesDialog *dialog)
3554++{
3555++ GtkTreeSelection *selection;
3556++ GtkTreeIter iter;
3557++ GspApp *app;
3558++
3559++ selection = gtk_tree_view_get_selection (dialog->priv->treeview);
3560++
3561++ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
3562++ return;
3563++ }
3564++
3565++ app = NULL;
3566++ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
3567++ &iter,
3568++ STORE_COL_APP, &app,
3569++ -1);
3570++
3571++ if (app) {
3572++ GtkWidget *edit_dialog;
3573++ char *name;
3574++ char *exec;
3575++ char *comment;
3576++
3577++ edit_dialog = gsm_app_dialog_new (gsp_app_get_name (app),
3578++ gsp_app_get_exec (app),
3579++ gsp_app_get_comment (app));
3580++ gtk_window_set_transient_for (GTK_WINDOW (edit_dialog),
3581++ GTK_WINDOW (dialog));
3582++
3583++ if (gsm_app_dialog_run (GSM_APP_DIALOG (edit_dialog),
3584++ &name, &exec, &comment)) {
3585++ gsp_app_update (app, name, comment, exec);
3586++ g_free (name);
3587++ g_free (exec);
3588++ g_free (comment);
3589++ }
3590++
3591++ g_object_unref (app);
3592++ }
3593++}
3594++
3595++static void
3596++on_row_activated (GtkTreeView *tree_view,
3597++ GtkTreePath *path,
3598++ GtkTreeViewColumn *column,
3599++ GsmPropertiesDialog *dialog)
3600++{
3601++ on_edit_app_clicked (NULL, dialog);
3602++}
3603++
3604++static void
3605++on_save_session_clicked (GtkWidget *widget,
3606++ GsmPropertiesDialog *dialog)
3607++{
3608++ g_debug ("Session saving is not implemented yet!");
3609++}
3610++
3611++static void
3612++setup_dialog (GsmPropertiesDialog *dialog)
3613++{
3614++ GtkTreeView *treeview;
3615++ GtkWidget *button;
3616++ GtkTreeModel *tree_filter;
3617++ GtkTreeViewColumn *column;
3618++ GtkCellRenderer *renderer;
3619++ GtkTreeSelection *selection;
3620++ GtkTargetList *targetlist;
3621++
3622++ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
3623++ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3624++ NULL);
3625++
3626++ dialog->priv->list_store = gtk_list_store_new (NUMBER_OF_COLUMNS,
3627++ G_TYPE_BOOLEAN,
3628++ G_TYPE_BOOLEAN,
3629++ G_TYPE_ICON,
3630++ G_TYPE_STRING,
3631++ G_TYPE_OBJECT,
3632++ G_TYPE_STRING);
3633++ tree_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (dialog->priv->list_store),
3634++ NULL);
3635++ g_object_unref (dialog->priv->list_store);
3636++ dialog->priv->tree_filter = tree_filter;
3637++
3638++ gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (tree_filter),
3639++ STORE_COL_VISIBLE);
3640++
3641++ treeview = GTK_TREE_VIEW (gtk_builder_get_object (dialog->priv->xml,
3642++ CAPPLET_TREEVIEW_WIDGET_NAME));
3643++ dialog->priv->treeview = treeview;
3644++
3645++ gtk_tree_view_set_model (treeview, tree_filter);
3646++ g_object_unref (tree_filter);
3647++
3648++ gtk_tree_view_set_headers_visible (treeview, FALSE);
3649++ g_signal_connect (treeview,
3650++ "row-activated",
3651++ G_CALLBACK (on_row_activated),
3652++ dialog);
3653++
3654++ selection = gtk_tree_view_get_selection (treeview);
3655++ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
3656++ g_signal_connect (selection,
3657++ "changed",
3658++ G_CALLBACK (on_selection_changed),
3659++ dialog);
3660++
3661++ /* CHECKBOX COLUMN */
3662++ renderer = gtk_cell_renderer_toggle_new ();
3663++ column = gtk_tree_view_column_new_with_attributes (_("Enabled"),
3664++ renderer,
3665++ "active", STORE_COL_ENABLED,
3666++ NULL);
3667++ gtk_tree_view_append_column (treeview, column);
3668++ g_signal_connect (renderer,
3669++ "toggled",
3670++ G_CALLBACK (on_startup_enabled_toggled),
3671++ dialog);
3672++
3673++ /* ICON COLUMN */
3674++ renderer = gtk_cell_renderer_pixbuf_new ();
3675++ column = gtk_tree_view_column_new_with_attributes (_("Icon"),
3676++ renderer,
3677++ "gicon", STORE_COL_GICON,
3678++ "sensitive", STORE_COL_ENABLED,
3679++ NULL);
3680++ g_object_set (renderer,
3681++ "stock-size", GSM_PROPERTIES_ICON_SIZE,
3682++ NULL);
3683++ gtk_tree_view_append_column (treeview, column);
3684++
3685++ /* NAME COLUMN */
3686++ renderer = gtk_cell_renderer_text_new ();
3687++ column = gtk_tree_view_column_new_with_attributes (_("Program"),
3688++ renderer,
3689++ "markup", STORE_COL_DESCRIPTION,
3690++ "sensitive", STORE_COL_ENABLED,
3691++ NULL);
3692++ g_object_set (renderer,
3693++ "ellipsize", PANGO_ELLIPSIZE_END,
3694++ NULL);
3695++ gtk_tree_view_append_column (treeview, column);
3696++
3697++
3698++ gtk_tree_view_column_set_sort_column_id (column, STORE_COL_DESCRIPTION);
3699++ gtk_tree_view_set_search_column (treeview, STORE_COL_SEARCH);
3700++ gtk_tree_view_set_rules_hint (treeview, TRUE);
3701++
3702++ gtk_tree_view_enable_model_drag_source (treeview,
3703++ GDK_BUTTON1_MASK|GDK_BUTTON2_MASK,
3704++ NULL, 0,
3705++ GDK_ACTION_COPY);
3706++ gtk_drag_source_add_uri_targets (GTK_WIDGET (treeview));
3707++
3708++ gtk_drag_dest_set (GTK_WIDGET (treeview),
3709++ GTK_DEST_DEFAULT_ALL,
3710++ NULL, 0,
3711++ GDK_ACTION_COPY);
3712++
3713++ gtk_drag_dest_add_uri_targets (GTK_WIDGET (treeview));
3714++ /* we don't want to accept drags coming from this widget */
3715++ targetlist = gtk_drag_dest_get_target_list (GTK_WIDGET (treeview));
3716++ if (targetlist != NULL) {
3717++ GtkTargetEntry *targets;
3718++ gint n_targets;
3719++ gint i;
3720++
3721++ targets = gtk_target_table_new_from_list (targetlist, &n_targets);
3722++ for (i = 0; i < n_targets; i++)
3723++ targets[i].flags = GTK_TARGET_OTHER_WIDGET;
3724++
3725++ targetlist = gtk_target_list_new (targets, n_targets);
3726++ gtk_drag_dest_set_target_list (GTK_WIDGET (treeview), targetlist);
3727++ gtk_target_list_unref (targetlist);
3728++
3729++ gtk_target_table_free (targets, n_targets);
3730++ }
3731++
3732++ g_signal_connect (treeview, "drag_begin",
3733++ G_CALLBACK (on_drag_begin),
3734++ dialog);
3735++ g_signal_connect (treeview, "drag_data_get",
3736++ G_CALLBACK (on_drag_data_get),
3737++ dialog);
3738++ g_signal_connect (treeview, "drag_data_received",
3739++ G_CALLBACK (on_drag_data_received),
3740++ dialog);
3741++
3742++ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dialog->priv->list_store),
3743++ STORE_COL_DESCRIPTION,
3744++ GTK_SORT_ASCENDING);
3745++
3746++
3747++ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3748++ CAPPLET_ADD_WIDGET_NAME));
3749++ dialog->priv->add_button = button;
3750++ g_signal_connect (button,
3751++ "clicked",
3752++ G_CALLBACK (on_add_app_clicked),
3753++ dialog);
3754++
3755++ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3756++ CAPPLET_DELETE_WIDGET_NAME));
3757++ dialog->priv->delete_button = button;
3758++ g_signal_connect (button,
3759++ "clicked",
3760++ G_CALLBACK (on_delete_app_clicked),
3761++ dialog);
3762++
3763++ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3764++ CAPPLET_EDIT_WIDGET_NAME));
3765++ dialog->priv->edit_button = button;
3766++ g_signal_connect (button,
3767++ "clicked",
3768++ G_CALLBACK (on_edit_app_clicked),
3769++ dialog);
3770++
3771++ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3772++ CAPPLET_REMEMBER_WIDGET_NAME));
3773++ g_settings_bind (dialog->priv->settings, SPC_SETTINGS_AUTOSAVE_KEY,
3774++ button, "active", G_SETTINGS_BIND_DEFAULT);
3775++
3776++ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3777++ CAPPLET_SAVE_WIDGET_NAME));
3778++ g_signal_connect (button,
3779++ "clicked",
3780++ G_CALLBACK (on_save_session_clicked),
3781++ dialog);
3782++
3783++ dialog->priv->manager = gsp_app_manager_get ();
3784++ gsp_app_manager_fill (dialog->priv->manager);
3785++ g_signal_connect_swapped (dialog->priv->manager, "added",
3786++ G_CALLBACK (_app_added), dialog);
3787++ g_signal_connect_swapped (dialog->priv->manager, "removed",
3788++ G_CALLBACK (_app_removed), dialog);
3789++
3790++ populate_model (dialog);
3791++}
3792++
3793++static GObject *
3794++gsm_properties_dialog_constructor (GType type,
3795++ guint n_construct_properties,
3796++ GObjectConstructParam *construct_properties)
3797++{
3798++ GsmPropertiesDialog *dialog;
3799++
3800++ dialog = GSM_PROPERTIES_DIALOG (G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->constructor (type,
3801++ n_construct_properties,
3802++ construct_properties));
3803++
3804++ setup_dialog (dialog);
3805++
3806++ gtk_widget_show (GTK_WIDGET (dialog));
3807++
3808++ return G_OBJECT (dialog);
3809++}
3810++
3811++static void
3812++gsm_properties_dialog_dispose (GObject *object)
3813++{
3814++ GsmPropertiesDialog *dialog;
3815++
3816++ g_return_if_fail (object != NULL);
3817++ g_return_if_fail (GSM_IS_PROPERTIES_DIALOG (object));
3818++
3819++ dialog = GSM_PROPERTIES_DIALOG (object);
3820++
3821++ if (dialog->priv->xml != NULL) {
3822++ g_object_unref (dialog->priv->xml);
3823++ dialog->priv->xml = NULL;
3824++ }
3825++
3826++ if (dialog->priv->settings != NULL) {
3827++ g_object_unref (dialog->priv->settings);
3828++ dialog->priv->settings = NULL;
3829++ }
3830++
3831++ G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->dispose (object);
3832++
3833++ /* it's important to do this after chaining to the parent dispose
3834++ * method because we want to make sure the treeview has been disposed
3835++ * and removed all its references to GspApp objects */
3836++ if (dialog->priv->manager != NULL) {
3837++ g_object_unref (dialog->priv->manager);
3838++ dialog->priv->manager = NULL;
3839++ }
3840++}
3841++
3842++static void
3843++gsm_properties_dialog_class_init (GsmPropertiesDialogClass *klass)
3844++{
3845++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
3846++
3847++ object_class->constructor = gsm_properties_dialog_constructor;
3848++ object_class->dispose = gsm_properties_dialog_dispose;
3849++ object_class->finalize = gsm_properties_dialog_finalize;
3850++
3851++ g_type_class_add_private (klass, sizeof (GsmPropertiesDialogPrivate));
3852++}
3853++
3854++static void
3855++gsm_properties_dialog_init (GsmPropertiesDialog *dialog)
3856++{
3857++ GtkWidget *content_area;
3858++ GtkWidget *widget;
3859++ GError *error;
3860++
3861++ dialog->priv = GSM_PROPERTIES_DIALOG_GET_PRIVATE (dialog);
3862++
3863++ dialog->priv->settings = g_settings_new (SPC_SETTINGS_SCHEMA);
3864++
3865++ dialog->priv->xml = gtk_builder_new ();
3866++ gtk_builder_set_translation_domain (dialog->priv->xml, GETTEXT_PACKAGE);
3867++
3868++ error = NULL;
3869++ if (!gtk_builder_add_from_file (dialog->priv->xml,
3870++ GTKBUILDER_DIR "/" GTKBUILDER_FILE,
3871++ &error)) {
3872++ if (error) {
3873++ g_warning ("Could not load capplet UI file: %s",
3874++ error->message);
3875++ g_error_free (error);
3876++ } else {
3877++ g_warning ("Could not load capplet UI file.");
3878++ }
3879++ }
3880++
3881++ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
3882++ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
3883++ "main-notebook"));
3884++ gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
3885++
3886++ gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 450);
3887++ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
3888++ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
3889++ gtk_box_set_spacing (GTK_BOX (content_area), 2);
3890++ gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
3891++ gtk_window_set_title (GTK_WINDOW (dialog), _("Startup Applications Preferences"));
3892++}
3893++
3894++static void
3895++gsm_properties_dialog_finalize (GObject *object)
3896++{
3897++ GsmPropertiesDialog *dialog;
3898++
3899++ g_return_if_fail (object != NULL);
3900++ g_return_if_fail (GSM_IS_PROPERTIES_DIALOG (object));
3901++
3902++ dialog = GSM_PROPERTIES_DIALOG (object);
3903++
3904++ g_return_if_fail (dialog->priv != NULL);
3905++
3906++ G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->finalize (object);
3907++}
3908++
3909++GtkWidget *
3910++gsm_properties_dialog_new (void)
3911++{
3912++ GObject *object;
3913++
3914++ object = g_object_new (GSM_TYPE_PROPERTIES_DIALOG,
3915++ NULL);
3916++
3917++ return GTK_WIDGET (object);
3918++}
3919+Index: gnome-session/capplet/gsm-properties-dialog.h
3920+===================================================================
3921+--- /dev/null
3922++++ gnome-session/capplet/gsm-properties-dialog.h
3923+@@ -0,0 +1,57 @@
3924++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3925++ *
3926++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
3927++ *
3928++ * This program is free software; you can redistribute it and/or modify
3929++ * it under the terms of the GNU General Public License as published by
3930++ * the Free Software Foundation; either version 2 of the License, or
3931++ * (at your option) any later version.
3932++ *
3933++ * This program is distributed in the hope that it will be useful,
3934++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3935++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3936++ * GNU General Public License for more details.
3937++ *
3938++ * You should have received a copy of the GNU General Public License
3939++ * along with this program; if not, write to the Free Software
3940++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3941++ *
3942++ */
3943++
3944++#ifndef __GSM_PROPERTIES_DIALOG_H
3945++#define __GSM_PROPERTIES_DIALOG_H
3946++
3947++#include <glib-object.h>
3948++#include <gtk/gtk.h>
3949++
3950++G_BEGIN_DECLS
3951++
3952++#define GSM_TYPE_PROPERTIES_DIALOG (gsm_properties_dialog_get_type ())
3953++#define GSM_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialog))
3954++#define GSM_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogClass))
3955++#define GSM_IS_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_PROPERTIES_DIALOG))
3956++#define GSM_IS_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_PROPERTIES_DIALOG))
3957++#define GSM_PROPERTIES_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogClass))
3958++
3959++typedef struct GsmPropertiesDialogPrivate GsmPropertiesDialogPrivate;
3960++
3961++typedef struct
3962++{
3963++ GtkDialog parent;
3964++ GsmPropertiesDialogPrivate *priv;
3965++} GsmPropertiesDialog;
3966++
3967++typedef struct
3968++{
3969++ GtkDialogClass parent_class;
3970++} GsmPropertiesDialogClass;
3971++
3972++GType gsm_properties_dialog_get_type (void);
3973++
3974++GtkWidget * gsm_properties_dialog_new (void);
3975++
3976++#define GSM_PROPERTIES_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
3977++
3978++G_END_DECLS
3979++
3980++#endif /* __GSM_PROPERTIES_DIALOG_H */
3981+Index: gnome-session/capplet/gsp-app-manager.c
3982+===================================================================
3983+--- /dev/null
3984++++ gnome-session/capplet/gsp-app-manager.c
3985+@@ -0,0 +1,593 @@
3986++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3987++ *
3988++ * Copyright (C) 1999 Free Software Foundation, Inc.
3989++ * Copyright (C) 2007, 2009 Vincent Untz.
3990++ * Copyright (C) 2008 Lucas Rocha.
3991++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
3992++ *
3993++ * This program is free software; you can redistribute it and/or modify
3994++ * it under the terms of the GNU General Public License as published by
3995++ * the Free Software Foundation; either version 2 of the License, or
3996++ * (at your option) any later version.
3997++ *
3998++ * This program is distributed in the hope that it will be useful,
3999++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4000++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4001++ * GNU General Public License for more details.
4002++ *
4003++ * You should have received a copy of the GNU General Public License
4004++ * along with this program; if not, write to the Free Software
4005++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4006++ *
4007++ */
4008++
4009++#include <string.h>
4010++
4011++#include "gsm-util.h"
4012++#include "gsp-app.h"
4013++
4014++#include "gsp-app-manager.h"
4015++
4016++static GspAppManager *manager = NULL;
4017++
4018++typedef struct {
4019++ char *dir;
4020++ int index;
4021++ GFileMonitor *monitor;
4022++} GspXdgDir;
4023++
4024++struct _GspAppManagerPrivate {
4025++ GSList *apps;
4026++ GSList *dirs;
4027++};
4028++
4029++#define GSP_APP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSP_TYPE_APP_MANAGER, GspAppManagerPrivate))
4030++
4031++
4032++enum {
4033++ ADDED,
4034++ REMOVED,
4035++ LAST_SIGNAL
4036++};
4037++
4038++static guint gsp_app_manager_signals[LAST_SIGNAL] = { 0 };
4039++
4040++
4041++G_DEFINE_TYPE (GspAppManager, gsp_app_manager, G_TYPE_OBJECT)
4042++
4043++static void gsp_app_manager_dispose (GObject *object);
4044++static void gsp_app_manager_finalize (GObject *object);
4045++static void _gsp_app_manager_app_unref (GspApp *app,
4046++ GspAppManager *manager);
4047++static void _gsp_app_manager_app_removed (GspAppManager *manager,
4048++ GspApp *app);
4049++
4050++static GspXdgDir *
4051++_gsp_xdg_dir_new (const char *dir,
4052++ int index)
4053++{
4054++ GspXdgDir *xdgdir;
4055++
4056++ xdgdir = g_slice_new (GspXdgDir);
4057++
4058++ xdgdir->dir = g_strdup (dir);
4059++ xdgdir->index = index;
4060++ xdgdir->monitor = NULL;
4061++
4062++ return xdgdir;
4063++}
4064++
4065++static void
4066++_gsp_xdg_dir_free (GspXdgDir *xdgdir)
4067++{
4068++ if (xdgdir->dir) {
4069++ g_free (xdgdir->dir);
4070++ xdgdir->dir = NULL;
4071++ }
4072++
4073++ if (xdgdir->monitor) {
4074++ g_file_monitor_cancel (xdgdir->monitor);
4075++ g_object_unref (xdgdir->monitor);
4076++ xdgdir->monitor = NULL;
4077++ }
4078++
4079++ g_slice_free (GspXdgDir, xdgdir);
4080++}
4081++
4082++static void
4083++gsp_app_manager_class_init (GspAppManagerClass *class)
4084++{
4085++ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
4086++
4087++ gobject_class->dispose = gsp_app_manager_dispose;
4088++ gobject_class->finalize = gsp_app_manager_finalize;
4089++
4090++ gsp_app_manager_signals[ADDED] =
4091++ g_signal_new ("added",
4092++ G_TYPE_FROM_CLASS (gobject_class),
4093++ G_SIGNAL_RUN_LAST,
4094++ G_STRUCT_OFFSET (GspAppManagerClass,
4095++ added),
4096++ NULL,
4097++ NULL,
4098++ g_cclosure_marshal_VOID__OBJECT,
4099++ G_TYPE_NONE, 1, G_TYPE_OBJECT);
4100++
4101++ gsp_app_manager_signals[REMOVED] =
4102++ g_signal_new ("removed",
4103++ G_TYPE_FROM_CLASS (gobject_class),
4104++ G_SIGNAL_RUN_LAST,
4105++ G_STRUCT_OFFSET (GspAppManagerClass,
4106++ removed),
4107++ NULL,
4108++ NULL,
4109++ g_cclosure_marshal_VOID__OBJECT,
4110++ G_TYPE_NONE, 1, G_TYPE_OBJECT);
4111++
4112++ g_type_class_add_private (class, sizeof (GspAppManagerPrivate));
4113++}
4114++
4115++static void
4116++gsp_app_manager_init (GspAppManager *manager)
4117++{
4118++ manager->priv = GSP_APP_MANAGER_GET_PRIVATE (manager);
4119++
4120++ memset (manager->priv, 0, sizeof (GspAppManagerPrivate));
4121++}
4122++
4123++static void
4124++gsp_app_manager_dispose (GObject *object)
4125++{
4126++ GspAppManager *manager;
4127++
4128++ g_return_if_fail (object != NULL);
4129++ g_return_if_fail (GSP_IS_APP_MANAGER (object));
4130++
4131++ manager = GSP_APP_MANAGER (object);
4132++
4133++ /* we unref GspApp objects in dispose since they might need to
4134++ * reference us during their dispose/finalize */
4135++ g_slist_foreach (manager->priv->apps,
4136++ (GFunc) _gsp_app_manager_app_unref, manager);
4137++ g_slist_free (manager->priv->apps);
4138++ manager->priv->apps = NULL;
4139++
4140++ G_OBJECT_CLASS (gsp_app_manager_parent_class)->dispose (object);
4141++}
4142++
4143++static void
4144++gsp_app_manager_finalize (GObject *object)
4145++{
4146++ GspAppManager *manager;
4147++
4148++ g_return_if_fail (object != NULL);
4149++ g_return_if_fail (GSP_IS_APP_MANAGER (object));
4150++
4151++ manager = GSP_APP_MANAGER (object);
4152++
4153++ g_slist_foreach (manager->priv->dirs,
4154++ (GFunc) _gsp_xdg_dir_free, NULL);
4155++ g_slist_free (manager->priv->dirs);
4156++ manager->priv->dirs = NULL;
4157++
4158++ G_OBJECT_CLASS (gsp_app_manager_parent_class)->finalize (object);
4159++
4160++ manager = NULL;
4161++}
4162++
4163++static void
4164++_gsp_app_manager_emit_added (GspAppManager *manager,
4165++ GspApp *app)
4166++{
4167++ g_signal_emit (G_OBJECT (manager), gsp_app_manager_signals[ADDED],
4168++ 0, app);
4169++}
4170++
4171++static void
4172++_gsp_app_manager_emit_removed (GspAppManager *manager,
4173++ GspApp *app)
4174++{
4175++ g_signal_emit (G_OBJECT (manager), gsp_app_manager_signals[REMOVED],
4176++ 0, app);
4177++}
4178++
4179++/*
4180++ * Directories
4181++ */
4182++
4183++static int
4184++gsp_app_manager_get_dir_index (GspAppManager *manager,
4185++ const char *dir)
4186++{
4187++ GSList *l;
4188++ GspXdgDir *xdgdir;
4189++
4190++ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), -1);
4191++ g_return_val_if_fail (dir != NULL, -1);
4192++
4193++ for (l = manager->priv->dirs; l != NULL; l = l->next) {
4194++ xdgdir = l->data;
4195++ if (strcmp (dir, xdgdir->dir) == 0) {
4196++ return xdgdir->index;
4197++ }
4198++ }
4199++
4200++ return -1;
4201++}
4202++
4203++const char *
4204++gsp_app_manager_get_dir (GspAppManager *manager,
4205++ unsigned int index)
4206++{
4207++ GSList *l;
4208++ GspXdgDir *xdgdir;
4209++
4210++ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
4211++
4212++ for (l = manager->priv->dirs; l != NULL; l = l->next) {
4213++ xdgdir = l->data;
4214++ if (index == xdgdir->index) {
4215++ return xdgdir->dir;
4216++ }
4217++ }
4218++
4219++ return NULL;
4220++}
4221++
4222++static int
4223++_gsp_app_manager_find_dir_with_basename (GspAppManager *manager,
4224++ const char *basename,
4225++ int minimum_index)
4226++{
4227++ GSList *l;
4228++ GspXdgDir *xdgdir;
4229++ char *path;
4230++ GKeyFile *keyfile;
4231++ int result = -1;
4232++
4233++ path = NULL;
4234++ keyfile = g_key_file_new ();
4235++
4236++ for (l = manager->priv->dirs; l != NULL; l = l->next) {
4237++ xdgdir = l->data;
4238++
4239++ if (xdgdir->index <= minimum_index) {
4240++ continue;
4241++ }
4242++
4243++ g_free (path);
4244++ path = g_build_filename (xdgdir->dir, basename, NULL);
4245++ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
4246++ continue;
4247++ }
4248++
4249++ if (!g_key_file_load_from_file (keyfile, path,
4250++ G_KEY_FILE_NONE, NULL)) {
4251++ continue;
4252++ }
4253++
4254++ /* the file exists and is readable */
4255++ if (result == -1) {
4256++ result = xdgdir->index;
4257++ } else {
4258++ result = MIN (result, xdgdir->index);
4259++ }
4260++ }
4261++
4262++ g_key_file_free (keyfile);
4263++ g_free (path);
4264++
4265++ return result;
4266++}
4267++
4268++static void
4269++_gsp_app_manager_handle_delete (GspAppManager *manager,
4270++ GspApp *app,
4271++ const char *basename,
4272++ int index)
4273++{
4274++ unsigned int position;
4275++ unsigned int system_position;
4276++
4277++ position = gsp_app_get_xdg_position (app);
4278++ system_position = gsp_app_get_xdg_system_position (app);
4279++
4280++ if (system_position < index) {
4281++ /* it got deleted, but we don't even care about it */
4282++ return;
4283++ }
4284++
4285++ if (index < position) {
4286++ /* it got deleted, but in a position earlier than the current
4287++ * one. This happens when the user file was changed and became
4288++ * identical to the system file; in this case, the user file is
4289++ * simply removed. */
4290++ g_assert (index == 0);
4291++ return;
4292++ }
4293++
4294++ if (position == index &&
4295++ (system_position == index || system_position == G_MAXUINT)) {
4296++ /* the file used by the user was deleted, and there's no other
4297++ * file in system directories. So it really got deleted. */
4298++ _gsp_app_manager_app_removed (manager, app);
4299++ return;
4300++ }
4301++
4302++ if (system_position == index) {
4303++ /* then we know that position != index; we just hae to tell
4304++ * GspApp if there's still a system directory containing this
4305++ * basename */
4306++ int new_system;
4307++
4308++ new_system = _gsp_app_manager_find_dir_with_basename (manager,
4309++ basename,
4310++ index);
4311++ if (new_system < 0) {
4312++ gsp_app_set_xdg_system_position (app, G_MAXUINT);
4313++ } else {
4314++ gsp_app_set_xdg_system_position (app, new_system);
4315++ }
4316++
4317++ return;
4318++ }
4319++
4320++ if (position == index) {
4321++ /* then we know that system_position != G_MAXUINT; we need to
4322++ * tell GspApp to change position to system_position */
4323++ const char *dir;
4324++
4325++ dir = gsp_app_manager_get_dir (manager, system_position);
4326++ if (dir) {
4327++ char *path;
4328++
4329++ path = g_build_filename (dir, basename, NULL);
4330++ gsp_app_reload_at (app, path,
4331++ (unsigned int) system_position);
4332++ g_free (path);
4333++ } else {
4334++ _gsp_app_manager_app_removed (manager, app);
4335++ }
4336++
4337++ return;
4338++ }
4339++
4340++ g_assert_not_reached ();
4341++}
4342++
4343++static gboolean
4344++gsp_app_manager_xdg_dir_monitor (GFileMonitor *monitor,
4345++ GFile *child,
4346++ GFile *other_file,
4347++ GFileMonitorEvent flags,
4348++ gpointer data)
4349++{
4350++ GspAppManager *manager;
4351++ GspApp *old_app;
4352++ GspApp *app;
4353++ GFile *parent;
4354++ char *basename;
4355++ char *dir;
4356++ char *path;
4357++ int index;
4358++
4359++ manager = GSP_APP_MANAGER (data);
4360++
4361++ basename = g_file_get_basename (child);
4362++ if (!g_str_has_suffix (basename, ".desktop")) {
4363++ /* not a desktop file, we can ignore */
4364++ g_free (basename);
4365++ return TRUE;
4366++ }
4367++ old_app = gsp_app_manager_find_app_with_basename (manager, basename);
4368++
4369++ parent = g_file_get_parent (child);
4370++ dir = g_file_get_path (parent);
4371++ g_object_unref (parent);
4372++
4373++ index = gsp_app_manager_get_dir_index (manager, dir);
4374++ if (index < 0) {
4375++ /* not a directory we know; should never happen, though */
4376++ g_free (dir);
4377++ return TRUE;
4378++ }
4379++
4380++ path = g_file_get_path (child);
4381++
4382++ switch (flags) {
4383++ case G_FILE_MONITOR_EVENT_CHANGED:
4384++ case G_FILE_MONITOR_EVENT_CREATED:
4385++ /* we just do as if it was a new file: GspApp is clever enough
4386++ * to do the right thing */
4387++ app = gsp_app_new (path, (unsigned int) index);
4388++
4389++ /* we didn't have this app before, so add it */
4390++ if (old_app == NULL && app != NULL) {
4391++ gsp_app_manager_add (manager, app);
4392++ g_object_unref (app);
4393++ }
4394++ /* else: it was just updated, GspApp took care of
4395++ * sending the event */
4396++ break;
4397++ case G_FILE_MONITOR_EVENT_DELETED:
4398++ if (!old_app) {
4399++ /* it got deleted, but we don't know about it, so
4400++ * nothing to do */
4401++ break;
4402++ }
4403++
4404++ _gsp_app_manager_handle_delete (manager, old_app,
4405++ basename, index);
4406++ break;
4407++ default:
4408++ break;
4409++ }
4410++
4411++ g_free (path);
4412++ g_free (dir);
4413++ g_free (basename);
4414++
4415++ return TRUE;
4416++}
4417++
4418++/*
4419++ * Initialization
4420++ */
4421++
4422++static void
4423++_gsp_app_manager_fill_from_dir (GspAppManager *manager,
4424++ GspXdgDir *xdgdir)
4425++{
4426++ GFile *file;
4427++ GDir *dir;
4428++ const char *name;
4429++
4430++ file = g_file_new_for_path (xdgdir->dir);
4431++ xdgdir->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE,
4432++ NULL, NULL);
4433++ g_object_unref (file);
4434++
4435++ if (xdgdir->monitor) {
4436++ g_signal_connect (xdgdir->monitor, "changed",
4437++ G_CALLBACK (gsp_app_manager_xdg_dir_monitor),
4438++ manager);
4439++ }
4440++
4441++ dir = g_dir_open (xdgdir->dir, 0, NULL);
4442++ if (!dir) {
4443++ return;
4444++ }
4445++
4446++ while ((name = g_dir_read_name (dir))) {
4447++ GspApp *app;
4448++ char *desktop_file_path;
4449++
4450++ if (!g_str_has_suffix (name, ".desktop")) {
4451++ continue;
4452++ }
4453++
4454++ desktop_file_path = g_build_filename (xdgdir->dir, name, NULL);
4455++ app = gsp_app_new (desktop_file_path, xdgdir->index);
4456++
4457++ if (app != NULL) {
4458++ gsp_app_manager_add (manager, app);
4459++ g_object_unref (app);
4460++ }
4461++
4462++ g_free (desktop_file_path);
4463++ }
4464++
4465++ g_dir_close (dir);
4466++}
4467++
4468++void
4469++gsp_app_manager_fill (GspAppManager *manager)
4470++{
4471++ char **autostart_dirs;
4472++ int i;
4473++
4474++ if (manager->priv->apps != NULL)
4475++ return;
4476++
4477++ autostart_dirs = gsm_util_get_autostart_dirs ();
4478++ /* we always assume that the first directory is the user one */
4479++ g_assert (g_str_has_prefix (autostart_dirs[0],
4480++ g_get_user_config_dir ()));
4481++
4482++ for (i = 0; autostart_dirs[i] != NULL; i++) {
4483++ GspXdgDir *xdgdir;
4484++
4485++ if (gsp_app_manager_get_dir_index (manager,
4486++ autostart_dirs[i]) >= 0) {
4487++ continue;
4488++ }
4489++
4490++ xdgdir = _gsp_xdg_dir_new (autostart_dirs[i], i);
4491++ manager->priv->dirs = g_slist_prepend (manager->priv->dirs,
4492++ xdgdir);
4493++
4494++ _gsp_app_manager_fill_from_dir (manager, xdgdir);
4495++ }
4496++
4497++ g_strfreev (autostart_dirs);
4498++}
4499++
4500++/*
4501++ * App handling
4502++ */
4503++
4504++static void
4505++_gsp_app_manager_app_unref (GspApp *app,
4506++ GspAppManager *manager)
4507++{
4508++ g_signal_handlers_disconnect_by_func (app,
4509++ _gsp_app_manager_app_removed,
4510++ manager);
4511++ g_object_unref (app);
4512++}
4513++
4514++static void
4515++_gsp_app_manager_app_removed (GspAppManager *manager,
4516++ GspApp *app)
4517++{
4518++ _gsp_app_manager_emit_removed (manager, app);
4519++ manager->priv->apps = g_slist_remove (manager->priv->apps, app);
4520++ _gsp_app_manager_app_unref (app, manager);
4521++}
4522++
4523++void
4524++gsp_app_manager_add (GspAppManager *manager,
4525++ GspApp *app)
4526++{
4527++ g_return_if_fail (GSP_IS_APP_MANAGER (manager));
4528++ g_return_if_fail (GSP_IS_APP (app));
4529++
4530++ manager->priv->apps = g_slist_prepend (manager->priv->apps,
4531++ g_object_ref (app));
4532++ g_signal_connect_swapped (app, "removed",
4533++ G_CALLBACK (_gsp_app_manager_app_removed),
4534++ manager);
4535++ _gsp_app_manager_emit_added (manager, app);
4536++}
4537++
4538++GspApp *
4539++gsp_app_manager_find_app_with_basename (GspAppManager *manager,
4540++ const char *basename)
4541++{
4542++ GSList *l;
4543++ GspApp *app;
4544++
4545++ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
4546++ g_return_val_if_fail (basename != NULL, NULL);
4547++
4548++ for (l = manager->priv->apps; l != NULL; l = l->next) {
4549++ app = GSP_APP (l->data);
4550++ if (strcmp (basename, gsp_app_get_basename (app)) == 0)
4551++ return app;
4552++ }
4553++
4554++ return NULL;
4555++}
4556++
4557++/*
4558++ * Singleton
4559++ */
4560++
4561++GspAppManager *
4562++gsp_app_manager_get (void)
4563++{
4564++ if (manager == NULL) {
4565++ manager = g_object_new (GSP_TYPE_APP_MANAGER, NULL);
4566++ return manager;
4567++ } else {
4568++ return g_object_ref (manager);
4569++ }
4570++}
4571++
4572++GSList *
4573++gsp_app_manager_get_apps (GspAppManager *manager)
4574++{
4575++ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
4576++
4577++ return g_slist_copy (manager->priv->apps);
4578++}
4579+Index: gnome-session/capplet/gsp-app-manager.h
4580+===================================================================
4581+--- /dev/null
4582++++ gnome-session/capplet/gsp-app-manager.h
4583+@@ -0,0 +1,81 @@
4584++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4585++ *
4586++ * Copyright (C) 1999 Free Software Foundation, Inc.
4587++ * Copyright (C) 2007, 2009 Vincent Untz.
4588++ * Copyright (C) 2008 Lucas Rocha.
4589++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4590++ *
4591++ * This program is free software; you can redistribute it and/or modify
4592++ * it under the terms of the GNU General Public License as published by
4593++ * the Free Software Foundation; either version 2 of the License, or
4594++ * (at your option) any later version.
4595++ *
4596++ * This program is distributed in the hope that it will be useful,
4597++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4598++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4599++ * GNU General Public License for more details.
4600++ *
4601++ * You should have received a copy of the GNU General Public License
4602++ * along with this program; if not, write to the Free Software
4603++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4604++ *
4605++ */
4606++
4607++#ifndef __GSP_APP_MANAGER_H
4608++#define __GSP_APP_MANAGER_H
4609++
4610++#include <glib-object.h>
4611++
4612++#include <gsp-app.h>
4613++
4614++G_BEGIN_DECLS
4615++
4616++#define GSP_TYPE_APP_MANAGER (gsp_app_manager_get_type ())
4617++#define GSP_APP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSP_TYPE_APP_MANAGER, GspAppManager))
4618++#define GSP_APP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSP_TYPE_APP_MANAGER, GspAppManagerClass))
4619++#define GSP_IS_APP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSP_TYPE_APP_MANAGER))
4620++#define GSP_IS_APP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSP_TYPE_APP_MANAGER))
4621++#define GSP_APP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSP_TYPE_APP_MANAGER, GspAppManagerClass))
4622++
4623++typedef struct _GspAppManager GspAppManager;
4624++typedef struct _GspAppManagerClass GspAppManagerClass;
4625++
4626++typedef struct _GspAppManagerPrivate GspAppManagerPrivate;
4627++
4628++struct _GspAppManagerClass
4629++{
4630++ GObjectClass parent_class;
4631++
4632++ void (* added) (GspAppManager *manager,
4633++ GspApp *app);
4634++ void (* removed) (GspAppManager *manager,
4635++ GspApp *app);
4636++};
4637++
4638++struct _GspAppManager
4639++{
4640++ GObject parent_instance;
4641++
4642++ GspAppManagerPrivate *priv;
4643++};
4644++
4645++GType gsp_app_manager_get_type (void);
4646++
4647++GspAppManager *gsp_app_manager_get (void);
4648++
4649++void gsp_app_manager_fill (GspAppManager *manager);
4650++
4651++GSList *gsp_app_manager_get_apps (GspAppManager *manager);
4652++
4653++GspApp *gsp_app_manager_find_app_with_basename (GspAppManager *manager,
4654++ const char *basename);
4655++
4656++const char *gsp_app_manager_get_dir (GspAppManager *manager,
4657++ unsigned int index);
4658++
4659++void gsp_app_manager_add (GspAppManager *manager,
4660++ GspApp *app);
4661++
4662++G_END_DECLS
4663++
4664++#endif /* __GSP_APP_MANAGER_H */
4665+Index: gnome-session/capplet/gsp-app.c
4666+===================================================================
4667+--- /dev/null
4668++++ gnome-session/capplet/gsp-app.c
4669+@@ -0,0 +1,1129 @@
4670++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4671++ *
4672++ * Copyright (C) 1999 Free Software Foundation, Inc.
4673++ * Copyright (C) 2007, 2009 Vincent Untz.
4674++ * Copyright (C) 2008 Lucas Rocha.
4675++ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4676++ *
4677++ * This program is free software; you can redistribute it and/or modify
4678++ * it under the terms of the GNU General Public License as published by
4679++ * the Free Software Foundation; either version 2 of the License, or
4680++ * (at your option) any later version.
4681++ *
4682++ * This program is distributed in the hope that it will be useful,
4683++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4684++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4685++ * GNU General Public License for more details.
4686++ *
4687++ * You should have received a copy of the GNU General Public License
4688++ * along with this program; if not, write to the Free Software
4689++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4690++ *
4691++ */
4692++
4693++#ifdef HAVE_CONFIG_H
4694++#include <config.h>
4695++#endif
4696++
4697++#include <string.h>
4698++#include <sys/stat.h>
4699++
4700++#include <glib/gi18n.h>
4701++#include <glib/gstdio.h>
4702++
4703++#include "gsm-app-dialog.h"
4704++#include "gsm-properties-dialog.h"
4705++#include "gsm-util.h"
4706++#include "gsp-app-manager.h"
4707++#include "gsp-keyfile.h"
4708++
4709++#include "gsp-app.h"
4710++
4711++#define GSP_APP_SAVE_DELAY 2
4712++
4713++#define GSP_ASP_SAVE_MASK_HIDDEN 0x0001
4714++#define GSP_ASP_SAVE_MASK_ENABLED 0x0002
4715++#define GSP_ASP_SAVE_MASK_NAME 0x0004
4716++#define GSP_ASP_SAVE_MASK_EXEC 0x0008
4717++#define GSP_ASP_SAVE_MASK_COMMENT 0x0010
4718++#define GSP_ASP_SAVE_MASK_NO_DISPLAY 0x0020
4719++#define GSP_ASP_SAVE_MASK_ALL 0xffff
4720++
4721++struct _GspAppPrivate {
4722++ char *basename;
4723++ char *path;
4724++
4725++ gboolean hidden;
4726++ gboolean no_display;
4727++ gboolean enabled;
4728++ gboolean shown;
4729++
4730++ char *name;
4731++ char *exec;
4732++ char *comment;
4733++ char *icon;
4734++
4735++ GIcon *gicon;
4736++ char *description;
4737++
4738++ /* position of the directory in the XDG environment variable */
4739++ unsigned int xdg_position;
4740++ /* position of the first system directory in the XDG env var containing
4741++ * this autostart app too (G_MAXUINT means none) */
4742++ unsigned int xdg_system_position;
4743++
4744++ unsigned int save_timeout;
4745++ /* mask of what has changed */
4746++ unsigned int save_mask;
4747++ /* path that contains the original file that needs to be saved */
4748++ char *old_system_path;
4749++ /* after writing to file, we skip the next file monitor event of type
4750++ * CHANGED */
4751++ gboolean skip_next_monitor_event;
4752++};
4753++
4754++#define GSP_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSP_TYPE_APP, GspAppPrivate))
4755++
4756++
4757++enum {
4758++ CHANGED,
4759++ REMOVED,
4760++ LAST_SIGNAL
4761++};
4762++
4763++static guint gsp_app_signals[LAST_SIGNAL] = { 0 };
4764++
4765++
4766++G_DEFINE_TYPE (GspApp, gsp_app, G_TYPE_OBJECT)
4767++
4768++static void gsp_app_dispose (GObject *object);
4769++static void gsp_app_finalize (GObject *object);
4770++static gboolean _gsp_app_save (gpointer data);
4771++
4772++
4773++static gboolean
4774++_gsp_str_equal (const char *a,
4775++ const char *b)
4776++{
4777++ if (g_strcmp0 (a, b) == 0) {
4778++ return TRUE;
4779++ }
4780++
4781++ if (a && !b && a[0] == '\0') {
4782++ return TRUE;
4783++ }
4784++
4785++ if (b && !a && b[0] == '\0') {
4786++ return TRUE;
4787++ }
4788++
4789++ return FALSE;
4790++}
4791++
4792++
4793++static void
4794++gsp_app_class_init (GspAppClass *class)
4795++{
4796++ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
4797++
4798++ gobject_class->dispose = gsp_app_dispose;
4799++ gobject_class->finalize = gsp_app_finalize;
4800++
4801++ gsp_app_signals[CHANGED] =
4802++ g_signal_new ("changed",
4803++ G_TYPE_FROM_CLASS (gobject_class),
4804++ G_SIGNAL_RUN_LAST,
4805++ G_STRUCT_OFFSET (GspAppClass,
4806++ changed),
4807++ NULL,
4808++ NULL,
4809++ g_cclosure_marshal_VOID__VOID,
4810++ G_TYPE_NONE, 0);
4811++
4812++ gsp_app_signals[REMOVED] =
4813++ g_signal_new ("removed",
4814++ G_TYPE_FROM_CLASS (gobject_class),
4815++ G_SIGNAL_RUN_LAST,
4816++ G_STRUCT_OFFSET (GspAppClass,
4817++ removed),
4818++ NULL,
4819++ NULL,
4820++ g_cclosure_marshal_VOID__VOID,
4821++ G_TYPE_NONE, 0);
4822++
4823++ g_type_class_add_private (class, sizeof (GspAppPrivate));
4824++}
4825++
4826++static void
4827++gsp_app_init (GspApp *app)
4828++{
4829++ app->priv = GSP_APP_GET_PRIVATE (app);
4830++
4831++ memset (app->priv, 0, sizeof (GspAppPrivate));
4832++ app->priv->xdg_position = G_MAXUINT;
4833++ app->priv->xdg_system_position = G_MAXUINT;
4834++}
4835++
4836++static void
4837++_gsp_app_free_reusable_data (GspApp *app)
4838++{
4839++ if (app->priv->path) {
4840++ g_free (app->priv->path);
4841++ app->priv->path = NULL;
4842++ }
4843++
4844++ if (app->priv->name) {
4845++ g_free (app->priv->name);
4846++ app->priv->name = NULL;
4847++ }
4848++
4849++ if (app->priv->exec) {
4850++ g_free (app->priv->exec);
4851++ app->priv->exec = NULL;
4852++ }
4853++
4854++ if (app->priv->comment) {
4855++ g_free (app->priv->comment);
4856++ app->priv->comment = NULL;
4857++ }
4858++
4859++ if (app->priv->icon) {
4860++ g_free (app->priv->icon);
4861++ app->priv->icon = NULL;
4862++ }
4863++
4864++ if (app->priv->gicon) {
4865++ g_object_unref (app->priv->gicon);
4866++ app->priv->gicon = NULL;
4867++ }
4868++
4869++ if (app->priv->description) {
4870++ g_free (app->priv->description);
4871++ app->priv->description = NULL;
4872++ }
4873++
4874++ if (app->priv->old_system_path) {
4875++ g_free (app->priv->old_system_path);
4876++ app->priv->old_system_path = NULL;
4877++ }
4878++}
4879++
4880++static void
4881++gsp_app_dispose (GObject *object)
4882++{
4883++ GspApp *app;
4884++
4885++ g_return_if_fail (object != NULL);
4886++ g_return_if_fail (GSP_IS_APP (object));
4887++
4888++ app = GSP_APP (object);
4889++
4890++ /* we save in dispose since we might need to reference GspAppManager */
4891++ if (app->priv->save_timeout) {
4892++ g_source_remove (app->priv->save_timeout);
4893++ app->priv->save_timeout = 0;
4894++
4895++ /* save now */
4896++ _gsp_app_save (app);
4897++ }
4898++
4899++ G_OBJECT_CLASS (gsp_app_parent_class)->dispose (object);
4900++}
4901++
4902++static void
4903++gsp_app_finalize (GObject *object)
4904++{
4905++ GspApp *app;
4906++
4907++ g_return_if_fail (object != NULL);
4908++ g_return_if_fail (GSP_IS_APP (object));
4909++
4910++ app = GSP_APP (object);
4911++
4912++ if (app->priv->basename) {
4913++ g_free (app->priv->basename);
4914++ app->priv->basename = NULL;
4915++ }
4916++
4917++ _gsp_app_free_reusable_data (app);
4918++
4919++ G_OBJECT_CLASS (gsp_app_parent_class)->finalize (object);
4920++}
4921++
4922++static void
4923++_gsp_app_emit_changed (GspApp *app)
4924++{
4925++ g_signal_emit (G_OBJECT (app), gsp_app_signals[CHANGED], 0);
4926++}
4927++
4928++static void
4929++_gsp_app_emit_removed (GspApp *app)
4930++{
4931++ g_signal_emit (G_OBJECT (app), gsp_app_signals[REMOVED], 0);
4932++}
4933++
4934++static void
4935++_gsp_app_update_description (GspApp *app)
4936++{
4937++ const char *primary;
4938++ const char *secondary;
4939++
4940++ if (!gsm_util_text_is_blank (app->priv->name)) {
4941++ primary = app->priv->name;
4942++ } else if (!gsm_util_text_is_blank (app->priv->exec)) {
4943++ primary = app->priv->exec;
4944++ } else {
4945++ primary = _("No name");
4946++ }
4947++
4948++ if (!gsm_util_text_is_blank (app->priv->comment)) {
4949++ secondary = app->priv->comment;
4950++ } else {
4951++ secondary = _("No description");
4952++ }
4953++
4954++ g_free (app->priv->description);
4955++ app->priv->description = g_markup_printf_escaped ("<b>%s</b>\n%s",
4956++ primary,
4957++ secondary);
4958++}
4959++
4960++/*
4961++ * Saving
4962++ */
4963++
4964++static void
4965++_gsp_ensure_user_autostart_dir (void)
4966++{
4967++ char *dir;
4968++
4969++ dir = g_build_filename (g_get_user_config_dir (), "autostart", NULL);
4970++ g_mkdir_with_parents (dir, S_IRWXU);
4971++
4972++ g_free (dir);
4973++}
4974++
4975++static char *
4976++_gsp_get_current_desktop ()
4977++{
4978++ static char *current_desktop = NULL;
4979++
4980++ /* Support XDG_CURRENT_DESKTOP environment variable; this can be used
4981++ * to abuse gnome-session in non-GNOME desktops. */
4982++ if (!current_desktop) {
4983++ const char *desktop;
4984++
4985++ desktop = g_getenv ("XDG_CURRENT_DESKTOP");
4986++
4987++ /* Note: if XDG_CURRENT_DESKTOP is set but empty, do as if it
4988++ * was not set */
4989++ if (!desktop || desktop[0] == '\0')
4990++ current_desktop = g_strdup ("GNOME");
4991++ else
4992++ current_desktop = g_strdup (desktop);
4993++ }
4994++
4995++ /* Using "*" means skipping desktop-related checks */
4996++ if (g_strcmp0 (current_desktop, "*") == 0)
4997++ return NULL;
4998++
4999++ return current_desktop;
5000++}
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: