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

Proposed by Tim Lunn
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 Approve
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.
Revision history for this message
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
=== modified file 'debian/changelog'
--- debian/changelog 2014-10-15 10:18:16 +0000
+++ debian/changelog 2014-10-31 04:52:33 +0000
@@ -1,3 +1,142 @@
1gnome-session (3.14.0-2ubuntu1) UNRELEASED; urgency=medium
2
3 * Merge from Debian, Remaining Changes:
4 - debian/control.in:
5 + Recommend session-migration
6 * don't depend on xwayland
7 - debian/gnome-session.install: Don't install wayland session for now
8 since its not yet possible to run it
9 - Split ubuntu-session out of gnome-session.
10 - Add upstart user session
11 - debian/gnome-session-bin.postinst, debian/gnome-session-bin.prerm:
12 Moved registering gnome-session binary as a session manager to
13 gnome-session-bin package
14 - don't install defaults.list (installed by desktop-file-utils in ubuntu):
15 debian/gnome-session-common.dirs and gnome-session-common.install
16 - debian/patches/22_support_autostart_delay.patch:
17 Bugzilla patch to support adding a delay to autostart apps, using
18 a "X-GNOME-Autostart-Delay" key in the desktop file
19 - debian/patches/50_ubuntu_sessions.patch:
20 + Add Ubuntu session
21 + gnome-shell.desktop adds --session=gnome now that the "ubuntu" session
22 is the default. Use TryExec to test if gnome-shell is installed.
23 - debian/patches/51_remove_session_saving_from_gui.patch:
24 add GNOME_SESSION_SAVE environment variable for people wanting to
25 use the save session still, knowing that it can break your system
26 if used unwisely (LP: #771896)
27 - debian/patches/52_xdg_current_desktop.patch:
28 Set XDG_CURRENT_DESKTOP inside gnome-session based on a
29 new key 'DesktopName' in gnome-session .desktop files.
30 - debian/patches/53_add_sessionmigration.patch, debian/control:
31 recommends and launch the session-migration if present at the start
32 of the session. This sync tool is running different session migration
33 scripts that can be provided in various desktop packages.
34 - debian/patches/95_dbus_request_shutdown.patch:
35 Add "RequestShutdown" and "RequestReboot" DBus methods to allow other
36 applications to shutdown or reboot the machine via the session manager.
37 - debian/patches/103_kill_the_fail_whale.patch:
38 Kill the Fail Whale as it tends to be more annoying than helpful
39 * debian/patches/revert_remove_gnome_session_properties.patch
40 * Dropped Changes:
41 * debian/patches/52_xdg_current_desktop.patch: Dropped Upsream includes a
42 fallback to set this now.
43 * Remove patches that have been disabled since 3.8
44
45 -- Tim Lunn <tim@feathertop.org> Fri, 31 Oct 2014 09:57:57 +1100
46
47gnome-session (3.14.0-2) unstable; urgency=medium
48
49 * Update debian/defaults.list to catch up with times:
50 - Drop swfdec-player which is long gone.
51 - Update File-Roller to new .desktop file name.
52 - Update GEdit to new .desktop file name.
53 - Update Font Viewer to new .desktop file name.
54 - Update Nautilus to new .desktop file name.
55 - Update Totem to new .desktop file name.
56 (Closes: #763595)
57 Note: This breaks the defaults for those who install the new
58 gnome-session-common and keep their << 3.14 application
59 packages (partial upgrades).
60
61 -- Andreas Henriksson <andreas@fatal.se> Wed, 01 Oct 2014 16:11:51 +0200
62
63gnome-session (3.14.0-1) unstable; urgency=medium
64
65 * New upstream release.
66 * Upload to unstable.
67
68 -- Andreas Henriksson <andreas@fatal.se> Mon, 22 Sep 2014 20:42:37 +0200
69
70gnome-session (3.13.3-1) experimental; urgency=medium
71
72 [ Andreas Henriksson ]
73 * New upstream development release.
74
75 [ Josselin Mouette ]
76 * Fix typos in defaults.list. Closes: #759429.
77
78 -- Andreas Henriksson <andreas@fatal.se> Fri, 05 Sep 2014 15:09:51 -0700
79
80gnome-session (3.12.1-4) experimental; urgency=medium
81
82 * gnome-session: Install wayland session files.
83 * gnome-session-bin: add xwayland dependency on linux-any.
84
85 -- Andreas Henriksson <andreas@fatal.se> Sat, 02 Aug 2014 17:22:46 +0200
86
87gnome-session (3.12.1-3) unstable; urgency=medium
88
89 [ Laurent Bigonville ]
90 * debian/control.in: Recommends libpam-systemd instead of systemd on linux
91 architectures and add recommends against consolekit on non linux arch.
92 Also move the Recommends to the arch any package.
93
94 [ Andreas Henriksson ]
95 * Drop build-dependency on libupower-glib-dev (<< 0.99.0) [!linux-any]
96 - This can no longer be fulfilled anyway.
97 * Upload to unstable.
98
99 -- Andreas Henriksson <andreas@fatal.se> Mon, 14 Jul 2014 23:57:59 +0200
100
101gnome-session (3.12.1-2) experimental; urgency=medium
102
103 * Enable systemd support on linux architectures only
104
105 -- Laurent Bigonville <bigon@debian.org> Sun, 04 May 2014 15:02:14 +0200
106
107gnome-session (3.12.1-1) experimental; urgency=medium
108
109 * New upstream release
110
111 -- Sjoerd Simons <sjoerd@debian.org> Sun, 27 Apr 2014 18:03:58 +0200
112
113gnome-session (3.12.0-1) experimental; urgency=medium
114
115 * New upstream release.
116 * Require upower build-dependency to be lower then 0.99.x and
117 only on non-linux.
118 - The new upower 0.99.x does not implement the used interfaces.
119 - Functionality is available via logind.
120 * Drop installing /usr/share/applications
121 - new upstream no longer ships gnome-session-properties
122 * Bump build-dependency on libglib2.0-dev to >= 2.39.90
123 - using g_subprocess requires a recent glib.
124 * Bump Standards-Version to 3.9.5
125
126 -- Andreas Henriksson <andreas@fatal.se> Wed, 26 Mar 2014 22:51:00 +0100
127
128gnome-session (3.10.1-1) experimental; urgency=low
129
130 * New upstream release
131 * debian/patches/13_display_session_properties.patch
132 + Dropped. gnome-session-properties has been dropped upstream
133 * debian/rules, debian/control.in: Explicitely enabled systemd support and
134 recommend systemd for logind. Recommends is enough as gnome-session should
135 fall back to consolekit
136 * debian/control.in: Update build-depends
137
138 -- Sjoerd Simons <sjoerd@debian.org> Fri, 01 Nov 2013 23:04:59 +0100
139
1gnome-session (3.9.90-0ubuntu16) utopic; urgency=medium140gnome-session (3.9.90-0ubuntu16) utopic; urgency=medium
2141
3 * set GNOME_SHELL_SESSION_MODE for gnome-classic sessions (LP: #1381297)142 * set GNOME_SHELL_SESSION_MODE for gnome-classic sessions (LP: #1381297)
@@ -136,6 +275,34 @@
136275
137 -- Jeremy Bicha <jbicha@ubuntu.com> Mon, 26 Aug 2013 08:47:31 -0400276 -- Jeremy Bicha <jbicha@ubuntu.com> Mon, 26 Aug 2013 08:47:31 -0400
138277
278gnome-session (3.8.4-3) unstable; urgency=medium
279
280 * debian/control.in:
281 +Break gdm3 < 3.8. Closes: #726498.
282
283 -- Emilio Pozuelo Monfort <pochu@debian.org> Sat, 26 Oct 2013 16:12:19 +0200
284
285gnome-session (3.8.4-2) unstable; urgency=low
286
287 * Upload to unstable.
288
289 -- Emilio Pozuelo Monfort <pochu@debian.org> Sun, 13 Oct 2013 17:27:19 +0200
290
291gnome-session (3.8.4-1) experimental; urgency=low
292
293 [ Jeremy Bicha ]
294 * New upstream release
295 * debian/control.in:
296 - Don't recommend gnome-power-manager
297 * Completely drop gnome-session-fallback (moved to gnome-panel source)
298
299 [ Michael Biebl ]
300 * Drop Build-Depends on libnotify-dev. No longer necessary after
301 debian/patches/04_fallback_warning_notify.patch has been removed.
302 * Bump Standards-Version to 3.9.4. No further changes.
303
304 -- Michael Biebl <biebl@debian.org> Fri, 11 Oct 2013 17:07:46 +0200
305
139gnome-session (3.8.2.1-1ubuntu5) saucy; urgency=low306gnome-session (3.8.2.1-1ubuntu5) saucy; urgency=low
140307
141 * debian/patches/50_ubuntu_sessions.patch:308 * debian/patches/50_ubuntu_sessions.patch:
142309
=== modified file 'debian/control'
--- debian/control 2014-09-30 17:01:54 +0000
+++ debian/control 2014-10-31 04:52:33 +0000
@@ -1,31 +1,22 @@
1# This file is autogenerated. DO NOT EDIT!
2#
3# Modifications should be made to debian/control.in instead.
4# This file is regenerated automatically in the clean target.
5Source: gnome-session1Source: gnome-session
6Section: gnome2Section: gnome
7Priority: optional3Priority: optional
8Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
9XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>5XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
10Uploaders: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>6Uploaders: @GNOME_TEAM@
11Standards-Version: 3.9.37Standards-Version: 3.9.5
12Build-Depends: cdbs (>= 0.4.41),8Build-Depends: cdbs (>= 0.4.41),
13 dh-autoreconf,9 dh-autoreconf,
14 debhelper (>= 8),10 debhelper (>= 8),
15 gnome-pkg-tools (>= 0.13),11 gnome-pkg-tools (>= 0.13),
16 gnome-common,12 gnome-common,
17 intltool (>= 0.40.6),13 intltool (>= 0.40.6),
18 libglib2.0-dev (>= 2.34.0),14 libglib2.0-dev (>= 2.39.90),
19 libgtk-3-dev (>= 2.90.7),15 libgtk-3-dev (>= 2.90.7),
20 libupower-glib-dev (>= 0.9.0),
21 libdbus-glib-1-dev (>= 0.76),16 libdbus-glib-1-dev (>= 0.76),
22 libjson-glib-dev (>= 0.10),17 libjson-glib-dev (>= 0.10),
23 libnotify-dev (>= 0.7),18 libgnome-desktop-3-dev (>= 3.9.91),
24 libgnome-desktop-3-dev (>= 3.7.90),
25 libsm-dev,19 libsm-dev,
26 libsystemd-daemon-dev,
27 libsystemd-journal-dev,
28 libsystemd-login-dev (>= 183),
29 libice-dev,20 libice-dev,
30 libx11-dev,21 libx11-dev,
31 libxt-dev,22 libxt-dev,
@@ -37,13 +28,17 @@
37 libxrender-dev,28 libxrender-dev,
38 xmlto,29 xmlto,
39 xsltproc,30 xsltproc,
40 xtrans-dev31 xtrans-dev,
32 libsystemd-login-dev (>= 183) [linux-any],
33 libsystemd-daemon-dev [linux-any],
34 libsystemd-journal-dev [linux-any]
41Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu35Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu
4236
43Package: gnome-session37Package: gnome-session
44Architecture: all38Architecture: all
45Depends: ${misc:Depends},39Depends: ${misc:Depends},
46 gnome-settings-daemon (>= 3.0),40 gnome-settings-daemon (>= 3.0),
41 gnome-shell (>= 3.0),
47 gnome-session-bin (>= ${binary:Version}),42 gnome-session-bin (>= ${binary:Version}),
48 gnome-session-bin (<< ${gnome:NextVersion}),43 gnome-session-bin (<< ${gnome:NextVersion}),
49 gnome-session-common (= ${binary:Version})44 gnome-session-common (= ${binary:Version})
@@ -92,8 +87,11 @@
92 ${misc:Depends},87 ${misc:Depends},
93 dbus-x11,88 dbus-x11,
94 gsettings-desktop-schemas,89 gsettings-desktop-schemas,
95 upower (>= 0.9.0)90 upower (>= 0.9.0),
91 xwayland [linux-any]
92Recommends: libpam-systemd [linux-any], consolekit [!linux-any]
96Conflicts: gnome-session (<< 3.9.90-0ubuntu8)93Conflicts: gnome-session (<< 3.9.90-0ubuntu8)
94Breaks: gdm (<< 3.8)
97Description: GNOME Session Manager - Minimal runtime95Description: GNOME Session Manager - Minimal runtime
98 The GNOME Session Manager is in charge of starting the core components96 The GNOME Session Manager is in charge of starting the core components
99 of the GNOME desktop, and applications that should be launched at97 of the GNOME desktop, and applications that should be launched at
10098
=== modified file 'debian/control.in'
--- debian/control.in 2014-02-20 07:56:43 +0000
+++ debian/control.in 2014-10-31 04:52:33 +0000
@@ -4,24 +4,19 @@
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>5XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
6Uploaders: @GNOME_TEAM@6Uploaders: @GNOME_TEAM@
7Standards-Version: 3.9.37Standards-Version: 3.9.5
8Build-Depends: cdbs (>= 0.4.41),8Build-Depends: cdbs (>= 0.4.41),
9 dh-autoreconf,9 dh-autoreconf,
10 debhelper (>= 8),10 debhelper (>= 8),
11 gnome-pkg-tools (>= 0.13),11 gnome-pkg-tools (>= 0.13),
12 gnome-common,12 gnome-common,
13 intltool (>= 0.40.6),13 intltool (>= 0.40.6),
14 libglib2.0-dev (>= 2.34.0),14 libglib2.0-dev (>= 2.39.90),
15 libgtk-3-dev (>= 2.90.7),15 libgtk-3-dev (>= 2.90.7),
16 libupower-glib-dev (>= 0.9.0),
17 libdbus-glib-1-dev (>= 0.76),16 libdbus-glib-1-dev (>= 0.76),
18 libjson-glib-dev (>= 0.10),17 libjson-glib-dev (>= 0.10),
19 libnotify-dev (>= 0.7),18 libgnome-desktop-3-dev (>= 3.9.91),
20 libgnome-desktop-3-dev (>= 3.7.90),
21 libsm-dev,19 libsm-dev,
22 libsystemd-daemon-dev,
23 libsystemd-journal-dev,
24 libsystemd-login-dev (>= 183),
25 libice-dev,20 libice-dev,
26 libx11-dev,21 libx11-dev,
27 libxt-dev,22 libxt-dev,
@@ -33,13 +28,17 @@
33 libxrender-dev,28 libxrender-dev,
34 xmlto,29 xmlto,
35 xsltproc,30 xsltproc,
36 xtrans-dev31 xtrans-dev,
32 libsystemd-login-dev (>= 183) [linux-any],
33 libsystemd-daemon-dev [linux-any],
34 libsystemd-journal-dev [linux-any]
37Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu35Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/gnome-session/ubuntu
3836
39Package: gnome-session37Package: gnome-session
40Architecture: all38Architecture: all
41Depends: ${misc:Depends},39Depends: ${misc:Depends},
42 gnome-settings-daemon (>= 3.0),40 gnome-settings-daemon (>= 3.0),
41 gnome-shell (>= 3.0),
43 gnome-session-bin (>= ${binary:Version}),42 gnome-session-bin (>= ${binary:Version}),
44 gnome-session-bin (<< ${gnome:NextVersion}),43 gnome-session-bin (<< ${gnome:NextVersion}),
45 gnome-session-common (= ${binary:Version})44 gnome-session-common (= ${binary:Version})
@@ -88,8 +87,11 @@
88 ${misc:Depends},87 ${misc:Depends},
89 dbus-x11,88 dbus-x11,
90 gsettings-desktop-schemas,89 gsettings-desktop-schemas,
91 upower (>= 0.9.0)90 upower (>= 0.9.0),
91# xwayland [linux-any]
92Recommends: libpam-systemd [linux-any], consolekit [!linux-any]
92Conflicts: gnome-session (<< 3.9.90-0ubuntu8)93Conflicts: gnome-session (<< 3.9.90-0ubuntu8)
94Breaks: gdm (<< 3.8)
93Description: GNOME Session Manager - Minimal runtime95Description: GNOME Session Manager - Minimal runtime
94 The GNOME Session Manager is in charge of starting the core components96 The GNOME Session Manager is in charge of starting the core components
95 of the GNOME desktop, and applications that should be launched at97 of the GNOME desktop, and applications that should be launched at
9698
=== modified file 'debian/defaults.list'
--- debian/defaults.list 2014-09-11 20:52:35 +0000
+++ debian/defaults.list 2014-10-31 04:52:33 +0000
@@ -64,84 +64,84 @@
64application/mbox=evolution.desktop64application/mbox=evolution.desktop
65message/rfc822=evolution.desktop65message/rfc822=evolution.desktop
66x-scheme-handler/mailto=evolution.desktop66x-scheme-handler/mailto=evolution.desktop
67application/x-7z-compressed=file-roller.desktop67application/x-7z-compressed=org.gnome.FileRoller.desktop
68application/x-7z-compressed-tar=file-roller.desktop68application/x-7z-compressed-tar=org.gnome.FileRoller.desktop
69application/x-ace=file-roller.desktop69application/x-ace=org.gnome.FileRoller.desktop
70application/x-alz=file-roller.desktop70application/x-alz=org.gnome.FileRoller.desktop
71application/x-ar=file-roller.desktop71application/x-ar=org.gnome.FileRoller.desktop
72application/x-arj=file-roller.desktop72application/x-arj=org.gnome.FileRoller.desktop
73application/x-bzip=file-roller.desktop73application/x-bzip=org.gnome.FileRoller.desktop
74application/x-bzip-compressed-tar=file-roller.desktop74application/x-bzip-compressed-tar=org.gnome.FileRoller.desktop
75application/x-bzip1=file-roller.desktop75application/x-bzip1=org.gnome.FileRoller.desktop
76application/x-bzip1-compressed-tar=file-roller.desktop76application/x-bzip1-compressed-tar=org.gnome.FileRoller.desktop
77application/x-cabinet=file-roller.desktop77application/x-cabinet=org.gnome.FileRoller.desktop
78application/x-cd-image=file-roller.desktop78application/x-cd-image=org.gnome.FileRoller.desktop
79application/x-compress=file-roller.desktop79application/x-compress=org.gnome.FileRoller.desktop
80application/x-compressed-tar=file-roller.desktop80application/x-compressed-tar=org.gnome.FileRoller.desktop
81application/x-cpio=file-roller.desktop81application/x-cpio=org.gnome.FileRoller.desktop
82application/x-deb=file-roller.desktop82application/x-deb=org.gnome.FileRoller.desktop
83application/x-ear=file-roller.desktop83application/x-ear=org.gnome.FileRoller.desktop
84application/x-gtar=file-roller.desktop84application/x-gtar=org.gnome.FileRoller.desktop
85application/x-gzip=file-roller.desktop85application/x-gzip=org.gnome.FileRoller.desktop
86application/x-java-archive=file-roller.desktop86application/x-java-archive=org.gnome.FileRoller.desktop
87application/x-lha=file-roller.desktop87application/x-lha=org.gnome.FileRoller.desktop
88application/x-lhz=file-roller.desktop88application/x-lhz=org.gnome.FileRoller.desktop
89application/x-lzip=file-roller.desktop89application/x-lzip=org.gnome.FileRoller.desktop
90application/x-lzip-compressed-tar=file-roller.desktop90application/x-lzip-compressed-tar=org.gnome.FileRoller.desktop
91application/x-lzma=file-roller.desktop91application/x-lzma=org.gnome.FileRoller.desktop
92application/x-lzma-compressed-tar=file-roller.desktop92application/x-lzma-compressed-tar=org.gnome.FileRoller.desktop
93application/x-lzop=file-roller.desktop93application/x-lzop=org.gnome.FileRoller.desktop
94application/x-lzop-compressed-tar=file-roller.desktop94application/x-lzop-compressed-tar=org.gnome.FileRoller.desktop
95application/x-rar=file-roller.desktop95application/x-rar=org.gnome.FileRoller.desktop
96application/x-rar-compressed=file-roller.desktop96application/x-rar-compressed=org.gnome.FileRoller.desktop
97application/x-rpm=file-roller.desktop97application/x-rpm=org.gnome.FileRoller.desktop
98application/x-rzip=file-roller.desktop98application/x-rzip=org.gnome.FileRoller.desktop
99application/x-tar=file-roller.desktop99application/x-tar=org.gnome.FileRoller.desktop
100application/x-tarz=file-roller.desktop100application/x-tarz=org.gnome.FileRoller.desktop
101application/x-stuffit=file-roller.desktop101application/x-stuffit=org.gnome.FileRoller.desktop
102application/x-war=file-roller.desktop102application/x-war=org.gnome.FileRoller.desktop
103application/x-xz=file-roller.desktop103application/x-xz=org.gnome.FileRoller.desktop
104application/x-xz-compressed-tar=file-roller.desktop104application/x-xz-compressed-tar=org.gnome.FileRoller.desktop
105application/x-zip=file-roller.desktop105application/x-zip=org.gnome.FileRoller.desktop
106application/x-zip-compressed=file-roller.desktop106application/x-zip-compressed=org.gnome.FileRoller.desktop
107application/x-zoo=file-roller.desktop107application/x-zoo=org.gnome.FileRoller.desktop
108application/zip=file-roller.desktop108application/zip=org.gnome.FileRoller.desktop
109multipart/x-zip=file-roller.desktop109multipart/x-zip=org.gnome.FileRoller.desktop
110text/plain=gedit.desktop110text/plain=org.gnome.gedit.desktop
111text/css=gedit.desktop111text/css=org.gnome.gedit.desktop
112text/javascript=gedit.desktop112text/javascript=org.gnome.gedit.desktop
113text/mathml=gedit.desktop113text/mathml=org.gnome.gedit.desktop
114text/x-c++hdr=gedit.desktop114text/x-c++hdr=org.gnome.gedit.desktop
115text/x-c++src=gedit.desktop115text/x-c++src=org.gnome.gedit.desktop
116text/x-csrc=gedit.desktop116text/x-csrc=org.gnome.gedit.desktop
117text/x-chdr=gedit.desktop117text/x-chdr=org.gnome.gedit.desktop
118text/x-dtd=gedit.desktop118text/x-dtd=org.gnome.gedit.desktop
119text/x-java=gedit.desktop119text/x-java=org.gnome.gedit.desktop
120text/x-javascript=gedit.desktop120text/x-javascript=org.gnome.gedit.desktop
121text/x-makefile=gedit.desktop121text/x-makefile=org.gnome.gedit.desktop
122text/x-moc=gedit.desktop122text/x-moc=org.gnome.gedit.desktop
123text/x-pascal=gedit.desktop123text/x-pascal=org.gnome.gedit.desktop
124text/x-patch=gedit.desktop124text/x-patch=org.gnome.gedit.desktop
125text/x-perl=gedit.desktop125text/x-perl=org.gnome.gedit.desktop
126text/x-php=gedit.desktop126text/x-php=org.gnome.gedit.desktop
127text/x-python=gedit.desktop127text/x-python=org.gnome.gedit.desktop
128text/x-sql=gedit.desktop128text/x-sql=org.gnome.gedit.desktop
129text/x-tcl=gedit.desktop129text/x-tcl=org.gnome.gedit.desktop
130text/x-tex=gedit.desktop130text/x-tex=org.gnome.gedit.desktop
131text/xml=gedit.desktop131text/xml=org.gnome.gedit.desktop
132application/javascript=gedit.desktop132application/javascript=org.gnome.gedit.desktop
133application/x-cgi=gedit.desktop133application/x-cgi=org.gnome.gedit.desktop
134application/x-javascript=gedit.desktop134application/x-javascript=org.gnome.gedit.desktop
135application/x-perl=gedit.desktop135application/x-perl=org.gnome.gedit.desktop
136application/x-php=gedit.desktop136application/x-php=org.gnome.gedit.desktop
137application/x-python=gedit.desktop137application/x-python=org.gnome.gedit.desktop
138application/x-shellscript=gedit.desktop138application/x-shellscript=org.gnome.gedit.desktop
139application/xml=gedit.desktop139application/xml=org.gnome.gedit.desktop
140application/xml-dtd=gedit.desktop140application/xml-dtd=org.gnome.gedit.desktop
141application/x-font-ttf=gnome-font-viewer.desktop141application/x-font-ttf=org.gnome.font-viewer.desktop
142application/x-font-pcf=gnome-font-viewer.desktop142application/x-font-pcf=org.gnome.font-viewer.desktop
143application/x-font-type1=gnome-font-viewer.desktop143application/x-font-type1=org.gnome.font-viewer.desktop
144application/x-font-otf=gnome-font-viewer.desktop144application/x-font-otf=org.gnome.font-viewer.desktop
145application/x-gnumeric=gnumeric.desktop145application/x-gnumeric=gnumeric.desktop
146application/tab-separated-values=gnumeric.desktop146application/tab-separated-values=gnumeric.desktop
147text/tab-separated-values=gnumeric.desktop147text/tab-separated-values=gnumeric.desktop
@@ -218,130 +218,128 @@
218application/vnd.openxmlformats-officedocument.wordprocessingml.template=libreoffice-writer.desktop218application/vnd.openxmlformats-officedocument.wordprocessingml.template=libreoffice-writer.desktop
219application/vnd.ms-word.template.macroenabled.12=libreoffice-writer.desktop219application/vnd.ms-word.template.macroenabled.12=libreoffice-writer.desktop
220x-content/software=nautilus-autorun-software.desktop220x-content/software=nautilus-autorun-software.desktop
221inode/directory=nautilus.desktop221inode/directory=org.gnome.Nautilus.desktop
222application/x-gnome-saved-search=nautilus.desktop222application/x-gnome-saved-search=org.gnome.Nautilus.desktop
223x-content/audio-player=rhythmbox.desktop223x-content/audio-player=rhythmbox.desktop
224x-content/audio-cdda=sound-juicer.desktop224x-content/audio-cdda=sound-juicer.desktop
225application/x-shockwave-flash=swfdec-player.desktop225application/mxf=org.gnome.Totem.desktop
226application/futuresplash=swfdec-player.desktop226application/ogg=org.gnome.Totem.desktop
227application/mxf=totem.desktop227application/ram=org.gnome.Totem.desktop
228application/ogg=totem.desktop228application/sdp=org.gnome.Totem.desktop
229application/ram=totem.desktop229application/smil=org.gnome.Totem.desktop
230application/sdp=totem.desktop230application/smil+xml=org.gnome.Totem.desktop
231application/smil=totem.desktop231application/vnd.ms-wpl=org.gnome.Totem.desktop
232application/smil+xml=totem.desktop232application/vnd.rn-realmedia=org.gnome.Totem.desktop
233application/vnd.ms-wpl=totem.desktop233application/x-extension-m4a=org.gnome.Totem.desktop
234application/vnd.rn-realmedia=totem.desktop234application/x-extension-mp4=org.gnome.Totem.desktop
235application/x-extension-m4a=totem.desktop235application/x-flac=org.gnome.Totem.desktop
236application/x-extension-mp4=totem.desktop236application/x-flash-video=org.gnome.Totem.desktop
237application/x-flac=totem.desktop237application/x-matroska=org.gnome.Totem.desktop
238application/x-flash-video=totem.desktop238application/x-netshow-channel=org.gnome.Totem.desktop
239application/x-matroska=totem.desktop239application/x-ogg=org.gnome.Totem.desktop
240application/x-netshow-channel=totem.desktop240application/x-quicktime-media-link=org.gnome.Totem.desktop
241application/x-ogg=totem.desktop241application/x-quicktimeplayer=org.gnome.Totem.desktop
242application/x-quicktime-media-link=totem.desktop242application/x-shorten=org.gnome.Totem.desktop
243application/x-quicktimeplayer=totem.desktop243application/x-smil=org.gnome.Totem.desktop
244application/x-shorten=totem.desktop244application/xspf+xml=org.gnome.Totem.desktop
245application/x-smil=totem.desktop245audio/3gpp=org.gnome.Totem.desktop
246application/xspf+xml=totem.desktop246audio/ac3=org.gnome.Totem.desktop
247audio/3gpp=totem.desktop247audio/AMR=org.gnome.Totem.desktop
248audio/ac3=totem.desktop248audio/AMR-WB=org.gnome.Totem.desktop
249audio/AMR=totem.desktop249audio/basic=org.gnome.Totem.desktop
250audio/AMR-WB=totem.desktop250audio/flac=org.gnome.Totem.desktop
251audio/basic=totem.desktop251audio/midi=org.gnome.Totem.desktop
252audio/flac=totem.desktop252audio/mp4=org.gnome.Totem.desktop
253audio/midi=totem.desktop253audio/mpeg=org.gnome.Totem.desktop
254audio/mp4=totem.desktop254audio/mpegurl=org.gnome.Totem.desktop
255audio/mpeg=totem.desktop255audio/ogg=org.gnome.Totem.desktop
256audio/mpegurl=totem.desktop256audio/prs.sid=org.gnome.Totem.desktop
257audio/ogg=totem.desktop257audio/vnd.rn-realaudio=org.gnome.Totem.desktop
258audio/prs.sid=totem.desktop258audio/x-ape=org.gnome.Totem.desktop
259audio/vnd.rn-realaudio=totem.desktop259audio/x-flac=org.gnome.Totem.desktop
260audio/x-ape=totem.desktop260audio/x-gsm=org.gnome.Totem.desktop
261audio/x-flac=totem.desktop261audio/x-it=org.gnome.Totem.desktop
262audio/x-gsm=totem.desktop262audio/x-m4a=org.gnome.Totem.desktop
263audio/x-it=totem.desktop263audio/x-matroska=org.gnome.Totem.desktop
264audio/x-m4a=totem.desktop264audio/x-mod=org.gnome.Totem.desktop
265audio/x-matroska=totem.desktop265audio/x-mp3=org.gnome.Totem.desktop
266audio/x-mod=totem.desktop266audio/x-mpeg=org.gnome.Totem.desktop
267audio/x-mp3=totem.desktop267audio/x-mpegurl=org.gnome.Totem.desktop
268audio/x-mpeg=totem.desktop268audio/x-ms-asf=org.gnome.Totem.desktop
269audio/x-mpegurl=totem.desktop269audio/x-ms-asx=org.gnome.Totem.desktop
270audio/x-ms-asf=totem.desktop270audio/x-ms-wax=org.gnome.Totem.desktop
271audio/x-ms-asx=totem.desktop271audio/x-ms-wma=org.gnome.Totem.desktop
272audio/x-ms-wax=totem.desktop272audio/x-musepack=org.gnome.Totem.desktop
273audio/x-ms-wma=totem.desktop273audio/x-pn-aiff=org.gnome.Totem.desktop
274audio/x-musepack=totem.desktop274audio/x-pn-au=org.gnome.Totem.desktop
275audio/x-pn-aiff=totem.desktop275audio/x-pn-realaudio=org.gnome.Totem.desktop
276audio/x-pn-au=totem.desktop276audio/x-pn-realaudio-plugin=org.gnome.Totem.desktop
277audio/x-pn-realaudio=totem.desktop277audio/x-pn-wav=org.gnome.Totem.desktop
278audio/x-pn-realaudio-plugin=totem.desktop278audio/x-pn-windows-acm=org.gnome.Totem.desktop
279audio/x-pn-wav=totem.desktop279audio/x-realaudio=org.gnome.Totem.desktop
280audio/x-pn-windows-acm=totem.desktop280audio/x-real-audio=org.gnome.Totem.desktop
281audio/x-realaudio=totem.desktop281audio/x-sbc=org.gnome.Totem.desktop
282audio/x-real-audio=totem.desktop282audio/x-scpls=org.gnome.Totem.desktop
283audio/x-sbc=totem.desktop283audio/x-speex=org.gnome.Totem.desktop
284audio/x-scpls=totem.desktop284audio/x-tta=org.gnome.Totem.desktop
285audio/x-speex=totem.desktop285audio/x-vorbis=org.gnome.Totem.desktop
286audio/x-tta=totem.desktop286audio/x-vorbis+ogg=org.gnome.Totem.desktop
287audio/x-vorbis=totem.desktop287audio/x-wav=org.gnome.Totem.desktop
288audio/x-vorbis+ogg=totem.desktop288audio/x-wavpack=org.gnome.Totem.desktop
289audio/x-wav=totem.desktop289audio/x-xm=org.gnome.Totem.desktop
290audio/x-wavpack=totem.desktop290image/vnd.rn-realpix=org.gnome.Totem.desktop
291audio/x-xm=totem.desktop291image/x-pict=org.gnome.Totem.desktop
292image/vnd.rn-realpix=totem.desktop292misc/ultravox=org.gnome.Totem.desktop
293image/x-pict=totem.desktop293text/google-video-pointer=org.gnome.Totem.desktop
294misc/ultravox=totem.desktop294text/x-google-video-pointer=org.gnome.Totem.desktop
295text/google-video-pointer=totem.desktop295video/3gpp=org.gnome.Totem.desktop
296text/x-google-video-pointer=totem.desktop296video/dv=org.gnome.Totem.desktop
297video/3gpp=totem.desktop297video/fli=org.gnome.Totem.desktop
298video/dv=totem.desktop298video/flv=org.gnome.Totem.desktop
299video/fli=totem.desktop299video/mp2t=org.gnome.Totem.desktop
300video/flv=totem.desktop300video/mp4=org.gnome.Totem.desktop
301video/mp2t=totem.desktop301video/mp4v-es=org.gnome.Totem.desktop
302video/mp4=totem.desktop302video/mpeg=org.gnome.Totem.desktop
303video/mp4v-es=totem.desktop303video/msvideo=org.gnome.Totem.desktop
304video/mpeg=totem.desktop304video/ogg=org.gnome.Totem.desktop
305video/msvideo=totem.desktop305video/quicktime=org.gnome.Totem.desktop
306video/ogg=totem.desktop306video/vivo=org.gnome.Totem.desktop
307video/quicktime=totem.desktop307video/vnd.divx=org.gnome.Totem.desktop
308video/vivo=totem.desktop308video/vnd.rn-realvideo=org.gnome.Totem.desktop
309video/vnd.divx=totem.desktop309video/vnd.vivo=org.gnome.Totem.desktop
310video/vnd.rn-realvideo=totem.desktop310video/webm=org.gnome.Totem.desktop
311video/vnd.vivo=totem.desktop311video/x-anim=org.gnome.Totem.desktop
312video/webm=totem.desktop312video/x-avi=org.gnome.Totem.desktop
313video/x-anim=totem.desktop313video/x-flc=org.gnome.Totem.desktop
314video/x-avi=totem.desktop314video/x-fli=org.gnome.Totem.desktop
315video/x-flc=totem.desktop315video/x-flic=org.gnome.Totem.desktop
316video/x-fli=totem.desktop316video/x-flv=org.gnome.Totem.desktop
317video/x-flic=totem.desktop317video/x-m4v=org.gnome.Totem.desktop
318video/x-flv=totem.desktop318video/x-matroska=org.gnome.Totem.desktop
319video/x-m4v=totem.desktop319video/x-mpeg=org.gnome.Totem.desktop
320video/x-matroska=totem.desktop320video/x-ms-asf=org.gnome.Totem.desktop
321video/x-mpeg=totem.desktop321video/x-ms-asx=org.gnome.Totem.desktop
322video/x-ms-asf=totem.desktop322video/x-msvideo=org.gnome.Totem.desktop
323video/x-ms-asx=totem.desktop323video/x-ms-wm=org.gnome.Totem.desktop
324video/x-msvideo=totem.desktop324video/x-ms-wmv=org.gnome.Totem.desktop
325video/x-ms-wm=totem.desktop325video/x-ms-wmx=org.gnome.Totem.desktop
326video/x-ms-wmv=totem.desktop326video/x-ms-wvx=org.gnome.Totem.desktop
327video/x-ms-wmx=totem.desktop327video/x-nsv=org.gnome.Totem.desktop
328video/x-ms-wvx=totem.desktop328video/x-ogm+ogg=org.gnome.Totem.desktop
329video/x-nsv=totem.desktop329video/x-theora+ogg=org.gnome.Totem.desktop
330video/x-ogm+ogg=totem.desktop330video/x-totem-stream=org.gnome.Totem.desktop
331video/x-theora+ogg=totem.desktop331x-content/video-dvd=org.gnome.Totem.desktop
332video/x-totem-stream=totem.desktop332x-content/video-vcd=org.gnome.Totem.desktop
333x-content/video-dvd=totem.desktop333x-content/video-svcd=org.gnome.Totem.desktop
334x-content/video-vcd=totem.desktop334x-scheme-handler/pnm=org.gnome.Totem.desktop
335x-content/video-svcd=totem.desktop335x-scheme-handler/mms=org.gnome.Totem.desktop
336x-scheme-handler/pnm=totem.desktop336x-scheme-handler/net=org.gnome.Totem.desktop
337x-scheme-handler/mms=totem.desktop337x-scheme-handler/rtp=org.gnome.Totem.desktop
338x-scheme-handler/net=totem.desktop338x-scheme-handler/rtsp=org.gnome.Totem.desktop
339x-scheme-handler/rtp=totem.desktop339x-scheme-handler/mmsh=org.gnome.Totem.desktop
340x-scheme-handler/rtsp=totem.desktop340x-scheme-handler/uvox=org.gnome.Totem.desktop
341x-scheme-handler/mmsh=totem.desktop341x-scheme-handler/icy=org.gnome.Totem.desktop
342x-scheme-handler/uvox=totem.desktop342x-scheme-handler/icyx=org.gnome.Totem.desktop
343x-scheme-handler/icy=totem.desktop
344x-scheme-handler/icyx=totem.desktop
345x-scheme-handler/ghelp=yelp.desktop343x-scheme-handler/ghelp=yelp.desktop
346x-scheme-handler/help=yelp.desktop344x-scheme-handler/help=yelp.desktop
347x-scheme-handler/info=yelp.desktop345x-scheme-handler/info=yelp.desktop
348346
=== added file 'debian/gnome-session-common.dirs'
--- debian/gnome-session-common.dirs 1970-01-01 00:00:00 +0000
+++ debian/gnome-session-common.dirs 2014-10-31 04:52:33 +0000
@@ -0,0 +1,1 @@
1usr/share/gnome/applications
02
=== modified file 'debian/gnome-session-common.install'
--- debian/gnome-session-common.install 2012-05-07 02:35:47 +0000
+++ debian/gnome-session-common.install 2014-10-31 04:52:33 +0000
@@ -3,3 +3,4 @@
3usr/share/locale3usr/share/locale
4debian/55gnome-session_gnomerc etc/X11/Xsession.d4debian/55gnome-session_gnomerc etc/X11/Xsession.d
5#debian/defaults.list etc/gnome5#debian/defaults.list etc/gnome
6
67
=== modified file 'debian/gnome-session.install'
--- debian/gnome-session.install 2014-02-20 02:02:54 +0000
+++ debian/gnome-session.install 2014-10-31 04:52:33 +0000
@@ -1,3 +1,5 @@
1usr/share/doc1usr/share/doc
2usr/share/xsessions/gnome.desktop2usr/share/xsessions/gnome.desktop
3usr/share/gnome-session/sessions/gnome.session3usr/share/gnome-session/sessions/gnome.session
4#usr/share/gnome-session/sessions/gnome-wayland.session
5#usr/share/wayland-sessions/gnome-wayland.desktop
46
=== removed file 'debian/patches/01_gnome-wm.patch'
--- debian/patches/01_gnome-wm.patch 2011-05-23 14:00:56 +0000
+++ debian/patches/01_gnome-wm.patch 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1Index: gnome-session-3.0.0/data/gnome-fallback.session.desktop.in.in
2===================================================================
3--- gnome-session-3.0.0.orig/data/gnome-fallback.session.desktop.in.in 2011-04-20 21:19:19.751604438 +0200
4+++ gnome-session-3.0.0/data/gnome-fallback.session.desktop.in.in 2011-04-20 21:19:24.495627620 +0200
5@@ -2,5 +2,5 @@
6 _Name=GNOME fallback
7 RequiredComponents=gnome-panel;gnome-settings-daemon;
8 RequiredProviders=windowmanager;notifications;
9-DefaultProvider-windowmanager=metacity
10+DefaultProvider-windowmanager=gnome-wm
11 DefaultProvider-notifications=notification-daemon
120
=== removed file 'debian/patches/02_fallback_desktop.patch'
--- debian/patches/02_fallback_desktop.patch 2012-05-07 02:35:47 +0000
+++ debian/patches/02_fallback_desktop.patch 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1Index: gnome-session-3.0.2/data/gnome-fallback.desktop.in
2===================================================================
3--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4+++ gnome-session-3.0.2/data/gnome-fallback.desktop.in 2011-11-04 20:06:03.653307488 +0100
5@@ -0,0 +1,7 @@
6+[Desktop Entry]
7+_Name=GNOME Classic
8+_Comment=This session logs you into GNOME
9+Exec=gnome-session-fallback
10+TryExec=gnome-session
11+Icon=
12+Type=Application
130
=== removed file 'debian/patches/03_fallback_desktop_makefile.patch'
--- debian/patches/03_fallback_desktop_makefile.patch 2012-05-07 02:35:47 +0000
+++ debian/patches/03_fallback_desktop_makefile.patch 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1Index: gnome-session-3.4.0/data/Makefile.am
2===================================================================
3--- gnome-session-3.4.0.orig/data/Makefile.am 2011-10-21 16:35:39.000000000 +0200
4+++ gnome-session-3.4.0/data/Makefile.am 2012-04-06 23:20:36.422851504 +0200
5@@ -9,7 +9,7 @@
6 hwcompat_DATA = hardware-compatibility
7
8 xsessiondir = $(datadir)/xsessions
9-xsession_in_files = gnome.desktop.in
10+xsession_in_files = gnome.desktop.in gnome-fallback.desktop.in
11 xsession_DATA = $(xsession_in_files:.desktop.in=.desktop)
12
13 desktopdir = $(datadir)/applications
140
=== removed file 'debian/patches/101_screen_lock_on_suspend.patch'
--- debian/patches/101_screen_lock_on_suspend.patch 2010-12-06 12:26:37 +0000
+++ debian/patches/101_screen_lock_on_suspend.patch 1970-01-01 00:00:00 +0000
@@ -1,92 +0,0 @@
1Description: 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
2Bug: https://bugzilla.gnome.org/show_bug.cgi?id=598118
3Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/karmic/+source/gnome-session/+bug/446191
4
5Index: gnome-session-2.32.1/gnome-session/gsm-manager.c
6===================================================================
7--- gnome-session-2.32.1.orig/gnome-session/gsm-manager.c 2010-12-06 13:26:17.733212002 +0100
8+++ gnome-session-2.32.1/gnome-session/gsm-manager.c 2010-12-06 13:26:17.829212002 +0100
9@@ -85,6 +85,9 @@
10 #define KEY_AUTOSAVE KEY_GNOME_SESSION_DIR "/auto_save_session"
11
12 #define KEY_SLEEP_LOCK "/apps/gnome-screensaver/lock_enabled"
13+#define KEY_SLEEP_LOCK_USE_SCREENSAVER "/apps/gnome-power-manager/lock/use_screensaver_settings"
14+#define GPM_CONF_LOCK_ON_SUSPEND "/apps/gnome-power-manager/lock/suspend"
15+#define GPM_CONF_LOCK_ON_HIBERNATE "/apps/gnome-power-manager/lock/hibernate"
16
17 typedef enum
18 {
19@@ -975,18 +978,33 @@
20 }
21
22 static gboolean
23-sleep_lock_is_enabled (GsmManager *manager)
24+sleep_lock_is_enabled (GsmManager *manager,
25+ const gchar *policy)
26 {
27- GError *error;
28- gboolean enable_lock;
29+ GError *error;
30+ gboolean enable_lock;
31+ gboolean use_ss_setting;
32+ const gchar *real_policy;
33
34 error = NULL;
35+ use_ss_setting = gconf_client_get_bool (manager->priv->gconf_client,
36+ KEY_SLEEP_LOCK_USE_SCREENSAVER, &error);
37+ if (error) {
38+ g_warning ("Error retrieving configuration key '%s': %s",
39+ KEY_SLEEP_LOCK_USE_SCREENSAVER, error->message);
40+ g_error_free (error);
41+
42+ use_ss_setting = FALSE;
43+ }
44+
45+ real_policy = (use_ss_setting ? KEY_SLEEP_LOCK : policy);
46+
47 enable_lock = gconf_client_get_bool (manager->priv->gconf_client,
48- KEY_SLEEP_LOCK, &error);
49+ real_policy, &error);
50
51 if (error) {
52 g_warning ("Error retrieving configuration key '%s': %s",
53- KEY_SLEEP_LOCK, error->message);
54+ real_policy, error->message);
55 g_error_free (error);
56
57 /* If we fail to query gconf key, just enable locking */
58@@ -997,13 +1015,14 @@
59 }
60
61 static void
62-manager_perhaps_lock (GsmManager *manager)
63+manager_perhaps_lock (GsmManager *manager,
64+ const gchar *policy)
65 {
66 GError *error;
67 gboolean ret;
68
69 /* only lock if gnome-screensaver is set to lock */
70- if (!sleep_lock_is_enabled (manager)) {
71+ if (!sleep_lock_is_enabled (manager, policy)) {
72 return;
73 }
74
75@@ -1035,7 +1054,7 @@
76 if (can_hibernate) {
77
78 /* lock the screen before we suspend */
79- manager_perhaps_lock (manager);
80+ manager_perhaps_lock (manager, GPM_CONF_LOCK_ON_HIBERNATE);
81
82 error = NULL;
83 ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
84@@ -1059,7 +1078,7 @@
85 if (can_suspend) {
86
87 /* lock the screen before we suspend */
88- manager_perhaps_lock (manager);
89+ manager_perhaps_lock (manager, GPM_CONF_LOCK_ON_SUSPEND);
90
91 error = NULL;
92 ret = up_client_suspend_sync (manager->priv->up_client, NULL, &error);
930
=== removed file 'debian/patches/10_session_save.patch'
--- debian/patches/10_session_save.patch 2011-05-23 14:00:56 +0000
+++ debian/patches/10_session_save.patch 1970-01-01 00:00:00 +0000
@@ -1,536 +0,0 @@
1Based on the patch in GNOME #575544
2
3Index: gnome-session-3.0.0/gnome-session/gsm-manager.c
4===================================================================
5--- gnome-session-3.0.0.orig/gnome-session/gsm-manager.c 2011-03-30 09:47:33.000000000 +0200
6+++ gnome-session-3.0.0/gnome-session/gsm-manager.c 2011-04-20 21:13:32.237905522 +0200
7@@ -79,6 +79,7 @@
8 * let's make this fairly long.
9 */
10 #define GSM_MANAGER_PHASE_TIMEOUT 30 /* seconds */
11+#define GSM_MANAGER_SAVE_SESSION_TIMEOUT 2
12
13 #define GDM_FLEXISERVER_COMMAND "gdmflexiserver"
14 #define GDM_FLEXISERVER_ARGS "--startnew Standard"
15@@ -1405,6 +1406,69 @@ query_end_session_complete (GsmManager *
16
17 }
18
19+static gboolean
20+_client_request_save (GsmClient *client,
21+ ClientEndSessionData *data)
22+{
23+ gboolean ret;
24+ GError *error;
25+
26+ error = NULL;
27+ ret = gsm_client_request_save (client, data->flags, &error);
28+ if (ret) {
29+ g_debug ("GsmManager: adding client to query clients: %s", gsm_client_peek_id (client));
30+ data->manager->priv->query_clients = g_slist_prepend (data->manager->priv->query_clients,
31+ client);
32+ } else if (error) {
33+ g_debug ("GsmManager: unable to query client: %s", error->message);
34+ g_error_free (error);
35+ }
36+
37+ return FALSE;
38+}
39+
40+static gboolean
41+_client_request_save_helper (const char *id,
42+ GsmClient *client,
43+ ClientEndSessionData *data)
44+{
45+ return _client_request_save (client, data);
46+}
47+
48+static void
49+query_save_session_complete (GsmManager *manager)
50+{
51+ GError *error = NULL;
52+
53+ if (g_slist_length (manager->priv->next_query_clients) > 0) {
54+ ClientEndSessionData data;
55+
56+ data.manager = manager;
57+ data.flags = GSM_CLIENT_END_SESSION_FLAG_LAST;
58+
59+ g_slist_foreach (manager->priv->next_query_clients,
60+ (GFunc)_client_request_save,
61+ &data);
62+
63+ g_slist_free (manager->priv->next_query_clients);
64+ manager->priv->next_query_clients = NULL;
65+
66+ return;
67+ }
68+
69+ if (manager->priv->query_timeout_id > 0) {
70+ g_source_remove (manager->priv->query_timeout_id);
71+ manager->priv->query_timeout_id = 0;
72+ }
73+
74+ gsm_session_save (manager->priv->clients, &error);
75+
76+ if (error) {
77+ g_warning ("Error saving session: %s", error->message);
78+ g_error_free (error);
79+ }
80+}
81+
82 static guint32
83 generate_cookie (void)
84 {
85@@ -1485,6 +1549,21 @@ _on_query_end_session_timeout (GsmManage
86 return FALSE;
87 }
88
89+static gboolean
90+_on_query_save_session_timeout (GsmManager *manager)
91+{
92+ manager->priv->query_timeout_id = 0;
93+
94+ g_debug ("GsmManager: query to save session timed out");
95+
96+ g_slist_free (manager->priv->query_clients);
97+ manager->priv->query_clients = NULL;
98+
99+ query_save_session_complete (manager);
100+
101+ return FALSE;
102+}
103+
104 static void
105 do_phase_query_end_session (GsmManager *manager)
106 {
107@@ -2160,13 +2239,32 @@ _handle_client_end_session_response (Gsm
108 gboolean cancel,
109 const char *reason)
110 {
111- /* just ignore if received outside of shutdown */
112- if (manager->priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
113+ /* just ignore if we are not yet running */
114+ if (manager->priv->phase < GSM_MANAGER_PHASE_RUNNING) {
115 return;
116 }
117
118 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 :"");
119
120+ if (manager->priv->phase == GSM_MANAGER_PHASE_RUNNING) {
121+ /* Ignore responses when no requests were sent */
122+ if (manager->priv->query_clients == NULL) {
123+ return;
124+ }
125+
126+ manager->priv->query_clients = g_slist_remove (manager->priv->query_clients, client);
127+
128+ if (do_last) {
129+ manager->priv->next_query_clients = g_slist_prepend (manager->priv->next_query_clients,
130+ client);
131+ }
132+
133+ if (manager->priv->query_clients == NULL) {
134+ query_save_session_complete (manager);
135+ }
136+ return;
137+ }
138+
139 if (cancel) {
140 cancel_end_session (manager);
141 return;
142@@ -2281,6 +2379,15 @@ on_xsmp_client_logout_request (GsmXSMPCl
143 }
144
145 static void
146+on_xsmp_client_save_request (GsmXSMPClient *client,
147+ gboolean show_dialog,
148+ GsmManager *manager)
149+{
150+ g_debug ("GsmManager: save_request");
151+ gsm_manager_save_session (manager, NULL);
152+}
153+
154+static void
155 on_store_client_added (GsmStore *store,
156 const char *id,
157 GsmManager *manager)
158@@ -2301,6 +2408,10 @@ on_store_client_added (GsmStore *store
159 "logout-request",
160 G_CALLBACK (on_xsmp_client_logout_request),
161 manager);
162+ g_signal_connect (client,
163+ "save-request",
164+ G_CALLBACK (on_xsmp_client_save_request),
165+ manager);
166 }
167
168 g_signal_connect (client,
169@@ -3324,6 +3435,41 @@ gsm_manager_shutdown (GsmManager *manage
170 }
171
172 gboolean
173+gsm_manager_save_session (GsmManager *manager,
174+ GError **error)
175+{
176+ ClientEndSessionData data;
177+
178+ g_debug ("GsmManager: SaveSession called");
179+
180+ g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
181+
182+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
183+ g_set_error (error,
184+ GSM_MANAGER_ERROR,
185+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
186+ "SaveSession interface is only available during the Running phase");
187+ return FALSE;
188+ }
189+
190+ data.manager = manager;
191+ data.flags = 0;
192+ gsm_store_foreach (manager->priv->clients,
193+ (GsmStoreFunc)_client_request_save_helper,
194+ &data);
195+
196+ if (manager->priv->query_clients) {
197+ manager->priv->query_timeout_id = g_timeout_add_seconds (GSM_MANAGER_SAVE_SESSION_TIMEOUT,
198+ (GSourceFunc)_on_query_save_session_timeout,
199+ manager);
200+ return TRUE;
201+ } else {
202+ g_debug ("GsmManager: Nothing to save");
203+ return FALSE;
204+ }
205+}
206+
207+gboolean
208 gsm_manager_can_shutdown (GsmManager *manager,
209 gboolean *shutdown_available,
210 GError **error)
211Index: gnome-session-3.0.0/gnome-session/gsm-manager.h
212===================================================================
213--- gnome-session-3.0.0.orig/gnome-session/gsm-manager.h 2011-03-22 21:31:43.000000000 +0100
214+++ gnome-session-3.0.0/gnome-session/gsm-manager.h 2011-04-20 21:12:54.057718875 +0200
215@@ -164,6 +164,9 @@ gboolean gsm_manager_is_inhib
216 gboolean gsm_manager_shutdown (GsmManager *manager,
217 GError **error);
218
219+gboolean gsm_manager_save_session (GsmManager *manager,
220+ GError **error);
221+
222 gboolean gsm_manager_can_shutdown (GsmManager *manager,
223 gboolean *shutdown_available,
224 GError **error);
225Index: gnome-session-3.0.0/gnome-session/gsm-xsmp-client.c
226===================================================================
227--- gnome-session-3.0.0.orig/gnome-session/gsm-xsmp-client.c 2011-03-22 21:31:43.000000000 +0100
228+++ gnome-session-3.0.0/gnome-session/gsm-xsmp-client.c 2011-04-20 21:12:54.057718875 +0200
229@@ -68,6 +68,7 @@ enum {
230 enum {
231 REGISTER_REQUEST,
232 LOGOUT_REQUEST,
233+ SAVE_REQUEST,
234 LAST_SIGNAL
235 };
236
237@@ -501,6 +502,30 @@ xsmp_cancel_end_session (GsmClient *clie
238 return TRUE;
239 }
240
241+static gboolean
242+xsmp_request_save (GsmClient *client,
243+ guint flags,
244+ GError **error)
245+{
246+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
247+
248+ g_debug ("GsmXSMPClient: xsmp_request_save ('%s')", xsmp->priv->description);
249+
250+ if (xsmp->priv->conn == NULL) {
251+ g_set_error (error,
252+ GSM_CLIENT_ERROR,
253+ GSM_CLIENT_ERROR_NOT_REGISTERED,
254+ "Client is not registered");
255+ return FALSE;
256+ }
257+
258+ if (flags & GSM_CLIENT_END_SESSION_FLAG_LAST)
259+ xsmp_save_yourself_phase2 (client);
260+ else
261+ do_save_yourself (xsmp, SmSaveLocal, FALSE);
262+
263+ return TRUE;
264+}
265 static char *
266 get_desktop_file_path (GsmXSMPClient *client)
267 {
268@@ -970,6 +995,7 @@ gsm_xsmp_client_class_init (GsmXSMPClien
269 object_class->get_property = gsm_xsmp_client_get_property;
270 object_class->set_property = gsm_xsmp_client_set_property;
271
272+ client_class->impl_request_save = xsmp_request_save;
273 client_class->impl_save = xsmp_save;
274 client_class->impl_stop = xsmp_stop;
275 client_class->impl_query_end_session = xsmp_query_end_session;
276@@ -997,6 +1023,17 @@ gsm_xsmp_client_class_init (GsmXSMPClien
277 NULL,
278 NULL,
279 g_cclosure_marshal_VOID__BOOLEAN,
280+ G_TYPE_NONE,
281+ 1, G_TYPE_BOOLEAN);
282+
283+ signals[SAVE_REQUEST] =
284+ g_signal_new ("save-request",
285+ G_OBJECT_CLASS_TYPE (object_class),
286+ G_SIGNAL_RUN_LAST,
287+ G_STRUCT_OFFSET (GsmXSMPClientClass, save_request),
288+ NULL,
289+ NULL,
290+ g_cclosure_marshal_VOID__BOOLEAN,
291 G_TYPE_NONE,
292 1, G_TYPE_BOOLEAN);
293
294Index: gnome-session-3.0.0/gnome-session/gsm-xsmp-client.h
295===================================================================
296--- gnome-session-3.0.0.orig/gnome-session/gsm-xsmp-client.h 2010-02-09 14:22:01.000000000 +0100
297+++ gnome-session-3.0.0/gnome-session/gsm-xsmp-client.h 2011-04-20 21:12:54.061718891 +0200
298@@ -54,7 +54,8 @@ struct _GsmXSMPClientClass
299 char **client_id);
300 gboolean (*logout_request) (GsmXSMPClient *client,
301 gboolean prompt);
302-
303+ gboolean (*save_request) (GsmXSMPClient *client,
304+ gboolean prompt);
305
306 void (*saved_state) (GsmXSMPClient *client);
307
308Index: gnome-session-3.0.0/gnome-session/org.gnome.SessionManager.xml
309===================================================================
310--- gnome-session-3.0.0.orig/gnome-session/org.gnome.SessionManager.xml 2010-02-09 14:22:01.000000000 +0100
311+++ gnome-session-3.0.0/gnome-session/org.gnome.SessionManager.xml 2011-04-20 21:12:54.061718891 +0200
312@@ -256,6 +256,14 @@
313 </doc:doc>
314 </method>
315
316+ <method name="SaveSession">
317+ <doc:doc>
318+ <doc:description>
319+ <doc:para>Request to save session</doc:para>
320+ </doc:description>
321+ </doc:doc>
322+ </method>
323+
324 <method name="CanShutdown">
325 <arg name="is_available" direction="out" type="b">
326 <doc:doc>
327Index: gnome-session-3.0.0/capplet/gsm-properties-dialog.c
328===================================================================
329--- gnome-session-3.0.0.orig/capplet/gsm-properties-dialog.c 2011-03-22 21:31:42.000000000 +0100
330+++ gnome-session-3.0.0/capplet/gsm-properties-dialog.c 2011-04-20 21:12:54.061718891 +0200
331@@ -33,6 +33,12 @@
332 #include "gsm-util.h"
333 #include "gsp-app.h"
334 #include "gsp-app-manager.h"
335+#include <dbus/dbus-glib.h>
336+#include <dbus/dbus-glib-lowlevel.h>
337+
338+#define GSM_SERVICE_DBUS "org.gnome.SessionManager"
339+#define GSM_PATH_DBUS "/org/gnome/SessionManager"
340+#define GSM_INTERFACE_DBUS "org.gnome.SessionManager"
341
342 #define GSM_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogPrivate))
343
344@@ -43,6 +49,7 @@
345 #define CAPPLET_DELETE_WIDGET_NAME "session_properties_delete_button"
346 #define CAPPLET_EDIT_WIDGET_NAME "session_properties_edit_button"
347 #define CAPPLET_SAVE_WIDGET_NAME "session_properties_save_button"
348+#define CAPPLET_SESSION_SAVED_WIDGET_NAME "session_properties_session_saved_label"
349 #define CAPPLET_REMEMBER_WIDGET_NAME "session_properties_remember_toggle"
350
351 #define STARTUP_APP_ICON "system-run"
352@@ -455,10 +462,64 @@ on_row_activated (GtkTreeView *t
353 }
354
355 static void
356+session_saved_message (GsmPropertiesDialog *dialog,
357+ const char *msg,
358+ gboolean is_error)
359+{
360+ GtkLabel *label;
361+ gchar *markup;
362+ label = GTK_LABEL (gtk_builder_get_object (dialog->priv->xml, CAPPLET_SESSION_SAVED_WIDGET_NAME));
363+ if (is_error)
364+ markup = g_markup_printf_escaped ("<span foreground=\"red\">%s</span>", msg);
365+ else
366+ markup = g_markup_escape_text (msg, -1);
367+ gtk_label_set_markup (label, markup);
368+ g_free (markup);
369+}
370+
371+static void
372+session_saved_cb (DBusGProxy *proxy,
373+ DBusGProxyCall *call_id,
374+ void *user_data)
375+{
376+ gboolean res;
377+ GsmPropertiesDialog *dialog = user_data;
378+
379+ res = dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_INVALID);
380+ if (res)
381+ session_saved_message (dialog, _("Your session has been saved."), FALSE);
382+ else
383+ session_saved_message (dialog, _("Failed to save session"), TRUE);
384+
385+ g_object_unref (proxy);
386+}
387+
388+static void
389 on_save_session_clicked (GtkWidget *widget,
390 GsmPropertiesDialog *dialog)
391 {
392- g_debug ("Session saving is not implemented yet!");
393+ DBusGConnection *conn;
394+ DBusGProxy *proxy;
395+ DBusGProxyCall *call;
396+
397+ conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
398+ if (conn == NULL) {
399+ session_saved_message (dialog, _("Could not connect to the session bus"), TRUE);
400+ return;
401+ }
402+
403+ proxy = dbus_g_proxy_new_for_name (conn, GSM_SERVICE_DBUS, GSM_PATH_DBUS, GSM_INTERFACE_DBUS);
404+ if (proxy == NULL) {
405+ session_saved_message (dialog, _("Could not connect to the session manager"), TRUE);
406+ return;
407+ }
408+
409+ call = dbus_g_proxy_begin_call (proxy, "SaveSession", session_saved_cb, dialog, NULL, G_TYPE_INVALID);
410+ if (call == NULL) {
411+ session_saved_message (dialog, _("Failed to save session"), TRUE);
412+ g_object_unref (proxy);
413+ return;
414+ }
415 }
416
417 static void
418Index: gnome-session-3.0.0/configure.ac
419===================================================================
420--- gnome-session-3.0.0.orig/configure.ac 2011-03-30 09:47:33.000000000 +0200
421+++ gnome-session-3.0.0/configure.ac 2011-04-20 21:12:54.061718891 +0200
422@@ -63,6 +63,7 @@ PKG_CHECK_MODULES(GNOME_SESSION,
423 PKG_CHECK_MODULES(SESSION_PROPERTIES,
424 glib-2.0 >= $GLIB_REQUIRED
425 gtk+-3.0 >= $GTK3_REQUIRED
426+ dbus-glib-1 >= $DBUS_GLIB_REQUIRED
427 )
428
429 PKG_CHECK_MODULES(SM, sm)
430Index: gnome-session-3.0.0/gnome-session/gsm-client.h
431===================================================================
432--- gnome-session-3.0.0.orig/gnome-session/gsm-client.h 2010-02-09 14:22:01.000000000 +0100
433+++ gnome-session-3.0.0/gnome-session/gsm-client.h 2011-04-20 21:12:54.061718891 +0200
434@@ -92,6 +92,9 @@ struct _GsmClientClass
435 GError **error);
436 gboolean (*impl_stop) (GsmClient *client,
437 GError **error);
438+ gboolean (*impl_request_save) (GsmClient *client,
439+ guint flags,
440+ GError **error);
441 GKeyFile * (*impl_save) (GsmClient *client,
442 GError **error);
443 };
444@@ -137,6 +140,9 @@ gboolean gsm_client_cancel_
445
446 void gsm_client_disconnected (GsmClient *client);
447
448+gboolean gsm_client_request_save (GsmClient *client,
449+ guint flags,
450+ GError **error);
451 GKeyFile *gsm_client_save (GsmClient *client,
452 GError **error);
453 /* exported to bus */
454Index: gnome-session-3.0.0/gnome-session/gsm-dbus-client.c
455===================================================================
456--- gnome-session-3.0.0.orig/gnome-session/gsm-dbus-client.c 2011-03-22 21:31:43.000000000 +0100
457+++ gnome-session-3.0.0/gnome-session/gsm-dbus-client.c 2011-04-20 21:12:54.061718891 +0200
458@@ -412,6 +412,19 @@ gsm_dbus_client_finalize (GObject *objec
459 G_OBJECT_CLASS (gsm_dbus_client_parent_class)->finalize (object);
460 }
461
462+static gboolean
463+dbus_client_request_save (GsmClient *client,
464+ guint flags,
465+ GError **error)
466+{
467+ g_debug ("GsmDBusClient: sending save request to client with id %s",
468+ gsm_client_peek_id (client));
469+
470+ /* FIXME: The protocol does not support this */
471+
472+ return FALSE;
473+}
474+
475 static GKeyFile *
476 dbus_client_save (GsmClient *client,
477 GError **error)
478@@ -664,6 +677,7 @@ gsm_dbus_client_class_init (GsmDBusClien
479 object_class->set_property = gsm_dbus_client_set_property;
480 object_class->dispose = gsm_dbus_client_dispose;
481
482+ client_class->impl_request_save = dbus_client_request_save;
483 client_class->impl_save = dbus_client_save;
484 client_class->impl_stop = dbus_client_stop;
485 client_class->impl_query_end_session = dbus_client_query_end_session;
486Index: gnome-session-3.0.0/gnome-session/gsm-client.c
487===================================================================
488--- gnome-session-3.0.0.orig/gnome-session/gsm-client.c 2010-02-09 14:22:01.000000000 +0100
489+++ gnome-session-3.0.0/gnome-session/gsm-client.c 2011-04-20 21:12:54.061718891 +0200
490@@ -510,6 +510,16 @@ gsm_client_disconnected (GsmClient *clie
491 g_signal_emit (client, signals[DISCONNECTED], 0);
492 }
493
494+gboolean
495+gsm_client_request_save (GsmClient *client,
496+ guint flags,
497+ GError **error)
498+{
499+ g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
500+
501+ return GSM_CLIENT_GET_CLASS (client)->impl_request_save (client, flags, error);
502+}
503+
504 GKeyFile *
505 gsm_client_save (GsmClient *client,
506 GError **error)
507Index: gnome-session-3.0.0/data/session-properties.ui
508===================================================================
509--- gnome-session-3.0.0.orig/data/session-properties.ui 2011-03-22 21:31:43.000000000 +0100
510+++ gnome-session-3.0.0/data/session-properties.ui 2011-04-20 21:12:54.061718891 +0200
511@@ -148,6 +148,7 @@
512 <property name="visible">True</property>
513 <child>
514 <object class="GtkButton" id="session_properties_save_button">
515+ <property name="visible">True</property>
516 <property name="can_focus">True</property>
517 <property name="receives_default">True</property>
518 <child>
519@@ -191,6 +192,17 @@
520 <property name="position">1</property>
521 </packing>
522 </child>
523+ <child>
524+ <object class="GtkLabel" id="session_properties_session_saved_label">
525+ <property name="visible">True</property>
526+ <property name="wrap">True</property>
527+ </object>
528+ <packing>
529+ <property name="expand">False</property>
530+ <property name="fill">False</property>
531+ <property name="position">2</property>
532+ </packing>
533+ </child>
534 </object>
535 <packing>
536 <property name="position">1</property>
5370
=== removed file 'debian/patches/12_no_gdm_fallback.patch'
--- debian/patches/12_no_gdm_fallback.patch 2012-07-29 14:22:20 +0000
+++ debian/patches/12_no_gdm_fallback.patch 1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
1Debian #572085
2
3Don’t fall back to GDM when ConsoleKit fails. If CK is not available, it
4will not be attempted anyway.
5
6Index: gnome-session-3.5.4/gnome-session/gsm-manager.c
7===================================================================
8--- gnome-session-3.5.4.orig/gnome-session/gsm-manager.c 2012-07-19 13:41:23.511406643 +1200
9+++ gnome-session-3.5.4/gnome-session/gsm-manager.c 2012-07-19 13:41:50.227405715 +1200
10@@ -492,7 +492,7 @@
11 g_signal_connect (manager->priv->system,
12 "request-completed",
13 G_CALLBACK (quit_request_completed),
14- GINT_TO_POINTER (GDM_LOGOUT_ACTION_REBOOT));
15+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_NONE));
16 gsm_system_attempt_restart (manager->priv->system);
17 break;
18 case GSM_MANAGER_LOGOUT_REBOOT_GDM:
19@@ -506,7 +506,7 @@
20 g_signal_connect (manager->priv->system,
21 "request-completed",
22 G_CALLBACK (quit_request_completed),
23- GINT_TO_POINTER (GDM_LOGOUT_ACTION_SHUTDOWN));
24+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_NONE));
25 gsm_system_attempt_stop (manager->priv->system);
26 break;
27 case GSM_MANAGER_LOGOUT_SHUTDOWN_GDM:
280
=== modified file 'debian/patches/13_display_session_properties.patch'
--- debian/patches/13_display_session_properties.patch 2013-06-08 23:25:03 +0000
+++ debian/patches/13_display_session_properties.patch 2014-10-31 04:52:33 +0000
@@ -4,11 +4,11 @@
4 the builtian search.4 the builtian search.
5Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=6838145Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683814
66
7Index: gnome-session-3.4.2.1/data/session-properties.desktop.in.in7Index: gnome-session/data/gnome-session-properties.desktop.in.in
8===================================================================8===================================================================
9--- gnome-session-3.4.2.1.orig/data/session-properties.desktop.in.in 2012-05-17 20:26:07.000000000 +02009--- gnome-session.orig/data/gnome-session-properties.desktop.in.in
10+++ gnome-session-3.4.2.1/data/session-properties.desktop.in.in 2012-08-07 01:08:23.755210722 +020010+++ gnome-session/data/gnome-session-properties.desktop.in.in
11@@ -8,7 +8,6 @@11@@ -8,7 +8,6 @@ Type=Application
12 StartupNotify=true12 StartupNotify=true
13 Categories=GTK;GNOME;Settings;X-GNOME-PersonalSettings;13 Categories=GTK;GNOME;Settings;X-GNOME-PersonalSettings;
14 OnlyShowIn=GNOME;Unity;14 OnlyShowIn=GNOME;Unity;
1515
=== modified file 'debian/patches/50_ubuntu_sessions.patch'
--- debian/patches/50_ubuntu_sessions.patch 2014-06-04 12:26:37 +0000
+++ debian/patches/50_ubuntu_sessions.patch 2014-10-31 04:52:33 +0000
@@ -4,9 +4,11 @@
4 (TryExec enables to show them or not depends on the package installed)4 (TryExec enables to show them or not depends on the package installed)
5Forwarded: Not needed5Forwarded: Not needed
66
7--- a/data/gnome.desktop.in7Index: gnome-session/data/gnome.desktop.in
8+++ b/data/gnome.desktop.in8===================================================================
9@@ -1,7 +1,8 @@9--- gnome-session.orig/data/gnome.desktop.in
10+++ gnome-session/data/gnome.desktop.in
11@@ -1,8 +1,9 @@
10 [Desktop Entry]12 [Desktop Entry]
11 _Name=GNOME13 _Name=GNOME
12 _Comment=This session logs you into GNOME14 _Comment=This session logs you into GNOME
@@ -16,10 +18,13 @@
16+TryExec=gnome-shell18+TryExec=gnome-shell
17 Icon=19 Icon=
18 Type=Application20 Type=Application
21 DesktopNames=GNOME
19+X-LightDM-DesktopName=GNOME22+X-LightDM-DesktopName=GNOME
20--- a/data/Makefile.am23Index: gnome-session/data/Makefile.am
21+++ b/data/Makefile.am24===================================================================
22@@ -13,7 +13,7 @@25--- gnome-session.orig/data/Makefile.am
26+++ gnome-session/data/Makefile.am
27@@ -12,7 +12,7 @@ hwcompatdir = $(pkgdatadir)
23 hwcompat_DATA = hardware-compatibility28 hwcompat_DATA = hardware-compatibility
24 29
25 xsessiondir = $(datadir)/xsessions30 xsessiondir = $(datadir)/xsessions
@@ -28,25 +33,29 @@
28 33
29 if BUILD_SESSION_SELECTOR34 if BUILD_SESSION_SELECTOR
30 xsession_in_files += gnome-custom-session.desktop.in35 xsession_in_files += gnome-custom-session.desktop.in
31@@ -26,7 +26,7 @@36@@ -29,7 +29,7 @@ desktop_in_files = gnome-session-propert
32 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)37 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
33 38
34 sessiondir = $(datadir)/gnome-session/sessions39 sessiondir = $(datadir)/gnome-session/sessions
35-session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in40-session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in gnome-wayland.session.desktop.in.in
36+session_in_in_files = gnome.session.desktop.in.in gnome-dummy.session.desktop.in.in ubuntu.session.desktop.in.in41+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
37 session_in_files = $(session_in_in_files:.session.desktop.in.in=.session.desktop.in)42 session_in_files = $(session_in_in_files:.session.desktop.in.in=.session.desktop.in)
38 session_DATA = $(session_in_files:.session.desktop.in=.session)43 session_DATA = $(session_in_files:.session.desktop.in=.session)
39 44
45Index: gnome-session/data/ubuntu.session.desktop.in.in
46===================================================================
40--- /dev/null47--- /dev/null
41+++ b/data/ubuntu.session.desktop.in.in48+++ gnome-session/data/ubuntu.session.desktop.in.in
42@@ -0,0 +1,4 @@49@@ -0,0 +1,4 @@
43+[GNOME Session]50+[GNOME Session]
44+_Name=Ubuntu51+_Name=Ubuntu
45+RequiredComponents=unity-settings-daemon;52+RequiredComponents=unity-settings-daemon;compiz;
46+DesktopName=Unity53+DesktopName=Unity
54Index: gnome-session/data/ubuntu.desktop.in
55===================================================================
47--- /dev/null56--- /dev/null
48+++ b/data/ubuntu.desktop.in57+++ gnome-session/data/ubuntu.desktop.in
49@@ -0,0 +1,8 @@58@@ -0,0 +1,9 @@
50+[Desktop Entry]59+[Desktop Entry]
51+_Name=Ubuntu60+_Name=Ubuntu
52+_Comment=This session logs you into Ubuntu61+_Comment=This session logs you into Ubuntu
@@ -54,4 +63,5 @@
54+TryExec=unity63+TryExec=unity
55+Icon=64+Icon=
56+Type=Application65+Type=Application
66+DesktopNames=Unity
57+X-LightDM-DesktopName=Unity67+X-LightDM-DesktopName=Unity
5868
=== removed file 'debian/patches/52_xdg_current_desktop.patch'
--- debian/patches/52_xdg_current_desktop.patch 2014-02-17 03:42:04 +0000
+++ debian/patches/52_xdg_current_desktop.patch 1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
1Index: gnome-session-3.7.4/gnome-session/gsm-session-fill.c
2===================================================================
3--- gnome-session-3.7.4.orig/gnome-session/gsm-session-fill.c 2013-02-07 18:04:28.954708097 -0500
4+++ gnome-session-3.7.4/gnome-session/gsm-session-fill.c 2013-02-07 18:04:28.946708097 -0500
5@@ -31,6 +31,7 @@
6 #define GSM_KEYFILE_SESSION_GROUP "GNOME Session"
7 #define GSM_KEYFILE_RUNNABLE_KEY "IsRunnableHelper"
8 #define GSM_KEYFILE_FALLBACK_KEY "FallbackSession"
9+#define GSM_KEYFILE_DESKTOP_NAME_KEY "DesktopName"
10 #define GSM_KEYFILE_REQUIRED_COMPONENTS_KEY "RequiredComponents"
11
12 /* See https://bugzilla.gnome.org/show_bug.cgi?id=641992 for discussion */
13@@ -315,6 +316,24 @@
14 return keyfile;
15 }
16
17+static void
18+set_xdg_current_desktop (GKeyFile *keyfile)
19+{
20+ char *value;
21+
22+ value = g_key_file_get_string (keyfile,
23+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_DESKTOP_NAME_KEY,
24+ NULL);
25+
26+ if (!IS_STRING_EMPTY (value)) {
27+ gsm_util_setenv ("XDG_CURRENT_DESKTOP", value);
28+ }
29+ else {
30+ gsm_util_setenv ("XDG_CURRENT_DESKTOP", "GNOME");
31+ }
32+ g_free (value);
33+}
34+
35 gboolean
36 gsm_session_fill (GsmManager *manager,
37 const char *session)
38@@ -332,6 +351,8 @@
39
40 g_free (actual_session);
41
42+ set_xdg_current_desktop (keyfile);
43+
44 load_standard_apps (manager, keyfile);
45
46 g_key_file_free (keyfile);
470
=== removed file 'debian/patches/80_new_upstream_session_dialog.patch'
--- debian/patches/80_new_upstream_session_dialog.patch 2011-05-24 08:56:36 +0000
+++ debian/patches/80_new_upstream_session_dialog.patch 1970-01-01 00:00:00 +0000
@@ -1,699 +0,0 @@
1Description: change the logout dialog to the opensuse proposal.
2Bug: https://bugzilla.gnome.org/show_bug.cgi?id=507101
3Author: Vincent Untz
4
5Index: gnome-session-3.0.0/gnome-session/gsm-manager.c
6===================================================================
7--- gnome-session-3.0.0.orig/gnome-session/gsm-manager.c 2011-05-24 10:17:22.244968980 +0200
8+++ gnome-session-3.0.0/gnome-session/gsm-manager.c 2011-05-24 10:17:22.284969173 +0200
9@@ -3050,7 +3050,8 @@
10
11 display = gtk_widget_get_display (GTK_WIDGET (logout_dialog));
12
13- gtk_widget_destroy (GTK_WIDGET (logout_dialog));
14+ if (response_id != GTK_RESPONSE_HELP)
15+ gtk_widget_destroy (GTK_WIDGET (logout_dialog));
16
17 /* In case of dialog cancel, switch user, hibernate and
18 * suspend, we just perform the respective action and return,
19@@ -3060,6 +3061,10 @@
20 case GTK_RESPONSE_NONE:
21 case GTK_RESPONSE_DELETE_EVENT:
22 break;
23+ case GTK_RESPONSE_HELP:
24+ gsm_util_help_display (GTK_WINDOW (logout_dialog),
25+ "gosgetstarted-73");
26+ break;
27 case GSM_LOGOUT_RESPONSE_SWITCH_USER:
28 request_switch_user (display, manager);
29 break;
30Index: gnome-session-3.0.0/gnome-session/gsm-util.c
31===================================================================
32--- gnome-session-3.0.0.orig/gnome-session/gsm-util.c 2011-03-22 21:31:43.000000000 +0100
33+++ gnome-session-3.0.0/gnome-session/gsm-util.c 2011-05-24 10:17:22.284969173 +0200
34@@ -21,6 +21,7 @@
35 #include <config.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38+#include <string.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #include <sys/time.h>
42@@ -519,3 +520,86 @@
43
44 return icon_size;
45 }
46+
47+void
48+gsm_util_help_display (GtkWindow *parent,
49+ const char *link_id)
50+{
51+ GError *error = NULL;
52+ const char *lang;
53+ char *uri = NULL;
54+ gboolean found;
55+
56+ int i;
57+
58+ const char * const * langs = g_get_language_names ();
59+
60+ uri = NULL;
61+ found = FALSE;
62+
63+ for (i = 0; langs[i]; i++) {
64+ lang = langs[i];
65+ if (strchr (lang, '.')) {
66+ continue;
67+ }
68+
69+ uri = g_build_filename (DATADIR,
70+ "/gnome/help/user-guide/",
71+ lang,
72+ "/user-guide.xml",
73+ NULL);
74+
75+ if (g_file_test (uri, G_FILE_TEST_EXISTS)) {
76+ found = TRUE;
77+ break;
78+ }
79+ }
80+
81+ if (found) {
82+ GAppInfo *app_info;
83+ char *command;
84+
85+ if (link_id) {
86+ command = g_strconcat ("gnome-open ghelp://", uri, "?", link_id, NULL);
87+ } else {
88+ command = g_strconcat ("gnome-open ghelp://", uri, NULL);
89+ }
90+
91+ app_info = g_app_info_create_from_commandline (command, "gnome-open",G_APP_INFO_CREATE_NONE, &error);
92+ g_free (command);
93+
94+ if (error == NULL && app_info != NULL) {
95+ GdkScreen *screen;
96+ GdkAppLaunchContext *context;
97+
98+ screen = gtk_widget_get_screen (GTK_WIDGET (parent));
99+ context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
100+ g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (context), &error);
101+
102+ g_object_unref (context);
103+ g_object_unref (app_info);
104+ }
105+ }
106+
107+ if (!found || error != NULL) {
108+ GtkWidget *d;
109+ const char *errmsg;
110+
111+ if (!found)
112+ errmsg = _("Cannot find help.");
113+ else {
114+ errmsg = error->message;
115+ g_error_free (error);
116+ }
117+
118+ d = gtk_message_dialog_new (parent,
119+ GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
120+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
121+ "%s", errmsg);
122+ gtk_widget_show (GTK_WIDGET (d));
123+ g_signal_connect (d, "response",
124+ G_CALLBACK (gtk_widget_destroy), NULL);
125+ }
126+
127+ g_free (uri);
128+}
129Index: gnome-session-3.0.0/gnome-session/Makefile.am
130===================================================================
131--- gnome-session-3.0.0.orig/gnome-session/Makefile.am 2011-03-22 21:36:21.000000000 +0100
132+++ gnome-session-3.0.0/gnome-session/Makefile.am 2011-05-24 10:17:22.288969198 +0200
133@@ -94,6 +94,10 @@
134 gsm-util.c \
135 gsm-util.h
136
137+libgsmutil_la_CPPFLAGS = \
138+ $(AM_CPPFLAGS) \
139+ -DDATADIR=\""$(datadir)"\"
140+
141 libgsmutil_la_LIBADD = \
142 $(GNOME_SESSION_LIBS)
143
144Index: gnome-session-3.0.0/gnome-session/gsm-logout-dialog.c
145===================================================================
146--- gnome-session-3.0.0.orig/gnome-session/gsm-logout-dialog.c 2011-03-22 21:31:43.000000000 +0100
147+++ gnome-session-3.0.0/gnome-session/gsm-logout-dialog.c 2011-05-24 10:29:39.732625980 +0200
148@@ -43,6 +43,14 @@
149 #define LOCKDOWN_SCHEMA "org.gnome.desktop.lockdown"
150 #define KEY_DISABLE_USER_SWITCHING "disable-user-switching"
151
152+#define GSM_ICON_LOGOUT "system-log-out"
153+#define GSM_ICON_SWITCH "system-users"
154+#define GSM_ICON_SHUTDOWN "system-shutdown"
155+#define GSM_ICON_REBOOT "view-refresh"
156+/* TODO: use gpm icons? */
157+#define GSM_ICON_HIBERNATE "drive-harddisk"
158+#define GSM_ICON_SLEEP "gnome-session-sleep"
159+
160 typedef enum {
161 GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
162 GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
163@@ -50,11 +58,12 @@
164
165 struct _GsmLogoutDialogPrivate
166 {
167- GsmDialogLogoutType type;
168-
169 UpClient *up_client;
170 GsmConsolekit *consolekit;
171
172+ GtkWidget *info_label;
173+ GtkWidget *cancel_button;
174+
175 int timeout;
176 unsigned int timeout_id;
177
178@@ -63,7 +72,8 @@
179
180 static GsmLogoutDialog *current_dialog = NULL;
181
182-static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
183+static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog,
184+ int seconds);
185
186 static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
187 gpointer data);
188@@ -71,43 +81,10 @@
189 static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
190 gpointer data);
191
192-enum {
193- PROP_0,
194- PROP_MESSAGE_TYPE
195-};
196-
197-G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_MESSAGE_DIALOG);
198-
199-static void
200-gsm_logout_dialog_set_property (GObject *object,
201- guint prop_id,
202- const GValue *value,
203- GParamSpec *pspec)
204-{
205- switch (prop_id) {
206- case PROP_MESSAGE_TYPE:
207- break;
208- default:
209- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
210- break;
211- }
212-}
213+static void gsm_logout_set_info_text (GsmLogoutDialog *logout_dialog,
214+ int seconds);
215
216-static void
217-gsm_logout_dialog_get_property (GObject *object,
218- guint prop_id,
219- GValue *value,
220- GParamSpec *pspec)
221-{
222- switch (prop_id) {
223- case PROP_MESSAGE_TYPE:
224- g_value_set_enum (value, GTK_MESSAGE_WARNING);
225- break;
226- default:
227- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
228- break;
229- }
230-}
231+G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_DIALOG);
232
233 static void
234 gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass)
235@@ -116,18 +93,6 @@
236
237 gobject_class = G_OBJECT_CLASS (klass);
238
239- /* This is a workaround to avoid a stupid crash: libgnomeui
240- * listens for the "show" signal on all GtkMessageDialog and
241- * gets the "message-type" of the dialogs. We will crash when
242- * it accesses this property if we don't override it since we
243- * didn't define it. */
244- gobject_class->set_property = gsm_logout_dialog_set_property;
245- gobject_class->get_property = gsm_logout_dialog_get_property;
246-
247- g_object_class_override_property (gobject_class,
248- PROP_MESSAGE_TYPE,
249- "message-type");
250-
251 g_type_class_add_private (klass, sizeof (GsmLogoutDialogPrivate));
252 }
253
254@@ -139,11 +104,22 @@
255 logout_dialog->priv->timeout_id = 0;
256 logout_dialog->priv->timeout = 0;
257 logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
258+ logout_dialog->priv->info_label = NULL;
259
260- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE);
261+ gtk_window_set_resizable (GTK_WINDOW (logout_dialog), FALSE);
262 gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE);
263 gtk_window_stick (GTK_WINDOW (logout_dialog));
264
265+ /* use HIG spacings */
266+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog))), 12);
267+ gtk_container_set_border_width (GTK_CONTAINER (logout_dialog), 6);
268+
269+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog), GTK_STOCK_HELP,
270+ GTK_RESPONSE_HELP);
271+ logout_dialog->priv->cancel_button =
272+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
273+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
274+
275 logout_dialog->priv->up_client = up_client_new ();
276
277 logout_dialog->priv->consolekit = gsm_get_consolekit ();
278@@ -239,38 +215,26 @@
279 static void
280 gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
281 {
282- gsm_logout_dialog_set_timeout (logout_dialog);
283-}
284+ gsm_logout_set_info_text (logout_dialog, AUTOMATIC_ACTION_TIMEOUT);
285
286-static gboolean
287-gsm_logout_dialog_timeout (gpointer data)
288-{
289- GsmLogoutDialog *logout_dialog;
290- char *seconds_warning;
291- char *secondary_text;
292- int seconds_to_show;
293- static char *session_type = NULL;
294-
295- logout_dialog = (GsmLogoutDialog *) data;
296-
297- if (!logout_dialog->priv->timeout) {
298- gtk_dialog_response (GTK_DIALOG (logout_dialog),
299- logout_dialog->priv->default_response);
300-
301- return FALSE;
302- }
303+ if (logout_dialog->priv->default_response != GTK_RESPONSE_CANCEL)
304+ gsm_logout_dialog_set_timeout (logout_dialog,
305+ AUTOMATIC_ACTION_TIMEOUT);
306+}
307
308- if (logout_dialog->priv->timeout <= 30) {
309- seconds_to_show = logout_dialog->priv->timeout;
310- } else {
311- seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
312
313- if (logout_dialog->priv->timeout % 10)
314- seconds_to_show += 10;
315- }
316+static void
317+gsm_logout_set_info_text (GsmLogoutDialog *logout_dialog,
318+ int seconds_to_show)
319+{
320+ const char *seconds_warning;
321+ char *secondary_text;
322+ char *buf;
323+ char *markup;
324+ static char *session_type = NULL;
325
326- switch (logout_dialog->priv->type) {
327- case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
328+ switch (logout_dialog->priv->default_response) {
329+ case GSM_LOGOUT_RESPONSE_LOGOUT:
330 /* This string is shared with gsm-fail-whale-dialog.c */
331 seconds_warning = ngettext ("You will be automatically logged "
332 "out in %d second.",
333@@ -279,7 +243,7 @@
334 seconds_to_show);
335 break;
336
337- case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
338+ case GSM_LOGOUT_RESPONSE_SHUTDOWN:
339 seconds_warning = ngettext ("This system will be automatically "
340 "shut down in %d second.",
341 "This system will be automatically "
342@@ -287,6 +251,10 @@
343 seconds_to_show);
344 break;
345
346+ case GTK_RESPONSE_CANCEL:
347+ seconds_warning = "";
348+ break;
349+
350 default:
351 g_assert_not_reached ();
352 }
353@@ -321,25 +289,50 @@
354 secondary_text = g_strdup (seconds_warning);
355 }
356
357- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
358- secondary_text,
359- seconds_to_show,
360- NULL);
361+ buf = g_strdup_printf (secondary_text, seconds_to_show);
362+ markup = g_markup_printf_escaped ("<i>%s</i>", buf);
363+ g_free (buf);
364+ gtk_label_set_markup (GTK_LABEL (logout_dialog->priv->info_label),
365+ markup);
366+ g_free (markup);
367+}
368
369- logout_dialog->priv->timeout--;
370+static gboolean
371+gsm_logout_dialog_timeout (gpointer data)
372+{
373+ GsmLogoutDialog *logout_dialog;
374+ int seconds_to_show;
375+
376+ logout_dialog = (GsmLogoutDialog *) data;
377+
378+ if (!logout_dialog->priv->timeout) {
379+ gtk_dialog_response (GTK_DIALOG (logout_dialog),
380+ logout_dialog->priv->default_response);
381+
382+ return FALSE;
383+ }
384+
385+ if (logout_dialog->priv->timeout <= 30) {
386+ seconds_to_show = logout_dialog->priv->timeout;
387+ } else {
388+ seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
389+
390+ if (logout_dialog->priv->timeout % 10)
391+ seconds_to_show += 10;
392+ }
393
394- g_free (secondary_text);
395+ gsm_logout_set_info_text (logout_dialog, seconds_to_show);
396+
397+ logout_dialog->priv->timeout--;
398
399 return TRUE;
400 }
401
402 static void
403-gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog)
404+gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog,
405+ int seconds)
406 {
407- logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT;
408-
409- /* Sets the secondary text */
410- gsm_logout_dialog_timeout (logout_dialog);
411+ logout_dialog->priv->timeout = seconds;
412
413 if (logout_dialog->priv->timeout_id != 0) {
414 g_source_remove (logout_dialog->priv->timeout_id);
415@@ -351,14 +344,120 @@
416 }
417
418 static GtkWidget *
419+gsm_logout_tile_new (const char *icon_name,
420+ const char *title,
421+ const char *description)
422+{
423+ GtkWidget *button;
424+ GtkWidget *alignment;
425+ GtkWidget *hbox;
426+ GtkWidget *vbox;
427+ GtkWidget *image;
428+ GtkWidget *label;
429+ char *markup;
430+
431+ g_assert (title != NULL);
432+
433+ button = GTK_WIDGET (gtk_button_new ());
434+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
435+
436+ alignment = gtk_alignment_new (0, 0.5, 0, 0);
437+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 6, 6);
438+ gtk_container_add (GTK_CONTAINER (button), alignment);
439+
440+ hbox = gtk_hbox_new (FALSE, 12);
441+ gtk_container_add (GTK_CONTAINER (alignment), hbox);
442+ if (icon_name != NULL) {
443+ image = gtk_image_new_from_icon_name (icon_name,
444+ GTK_ICON_SIZE_DIALOG);
445+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
446+ }
447+
448+ vbox = gtk_vbox_new (FALSE, 2);
449+
450+ markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
451+ title);
452+ label = gtk_label_new (markup);
453+ g_free (markup);
454+
455+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
456+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
457+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
458+
459+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
460+
461+ if (description != NULL) {
462+ gchar *markup;
463+ GdkColor *color;
464+ GtkWidget *label;
465+ GtkStyle *style;
466+
467+ style = gtk_widget_get_style (GTK_WIDGET (button));
468+ color = &style->fg[GTK_STATE_INSENSITIVE];
469+ markup = g_markup_printf_escaped ("<span size=\"small\" foreground=\"#%.2x%.2x%.2x\">%s</span>",
470+ color->red,
471+ color->green,
472+ color->blue,
473+ description);
474+ label = gtk_label_new (markup);
475+ g_free (markup);
476+
477+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
478+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
479+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
480+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
481+
482+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
483+ }
484+
485+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
486+
487+ return button;
488+}
489+
490+static void
491+gsm_logout_tile_clicked (GtkWidget *tile,
492+ gpointer response_p)
493+{
494+ GtkWidget *dialog;
495+
496+ dialog = gtk_widget_get_toplevel (tile);
497+ g_assert (GTK_IS_DIALOG (dialog));
498+ gtk_dialog_response (GTK_DIALOG (dialog),
499+ GPOINTER_TO_UINT (response_p));
500+}
501+
502+static GtkWidget *
503+gsm_logout_append_tile (GtkWidget *vbox,
504+ unsigned int response,
505+ const char *icon_name,
506+ const char *title,
507+ const char *description)
508+{
509+ GtkWidget *tile;
510+
511+ tile = gsm_logout_tile_new (icon_name, title, description);
512+ gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
513+ gtk_widget_show_all (tile);
514+
515+ g_signal_connect (tile,
516+ "clicked",
517+ G_CALLBACK (gsm_logout_tile_clicked),
518+ GUINT_TO_POINTER (response));
519+
520+ return tile;
521+}
522+
523+static GtkWidget *
524 gsm_get_dialog (GsmDialogLogoutType type,
525 GdkScreen *screen,
526 guint32 activate_time)
527 {
528 GsmLogoutDialog *logout_dialog;
529- GtkWidget *dialog_image;
530- const char *primary_text;
531+ GtkWidget *vbox;
532+ GtkWidget *tile;
533 const char *icon_name;
534+ const char *title;
535
536 if (current_dialog != NULL) {
537 gtk_widget_destroy (GTK_WIDGET (current_dialog));
538@@ -368,83 +467,119 @@
539
540 current_dialog = logout_dialog;
541
542- gtk_window_set_title (GTK_WINDOW (logout_dialog), "");
543-
544- logout_dialog->priv->type = type;
545+ vbox = gtk_vbox_new (FALSE, 12);
546+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog))), vbox,
547+ FALSE, FALSE, 0);
548+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
549+ gtk_widget_show (vbox);
550
551 icon_name = NULL;
552- primary_text = NULL;
553+ title = NULL;
554
555 switch (type) {
556 case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
557 icon_name = GSM_ICON_LOGOUT;
558- primary_text = _("Log out of this system now?");
559+ title = _("Log Out of the Session");
560
561 logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
562
563- if (gsm_logout_supports_switch_user (logout_dialog)) {
564- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
565+
566+ gsm_logout_append_tile (vbox, GSM_LOGOUT_RESPONSE_LOGOUT,
567+ GSM_ICON_LOGOUT, _("_Log Out"),
568+ _("Ends your session and logs you "
569+ "out."));
570+
571+ tile = gsm_logout_append_tile (vbox,
572+ GSM_LOGOUT_RESPONSE_SWITCH_USER,
573+ GSM_ICON_SWITCH,
574 _("_Switch User"),
575- GSM_LOGOUT_RESPONSE_SWITCH_USER);
576+ _("Suspends your session, "
577+ "allowing another user to "
578+ "log in and use the "
579+ "computer."));
580+ if (!gsm_logout_supports_switch_user (logout_dialog)) {
581+ gtk_widget_set_sensitive (tile, FALSE);
582 }
583
584- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
585- GTK_STOCK_CANCEL,
586- GTK_RESPONSE_CANCEL);
587-
588- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
589- _("_Log Out"),
590- GSM_LOGOUT_RESPONSE_LOGOUT);
591-
592 break;
593 case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
594 icon_name = GSM_ICON_SHUTDOWN;
595- primary_text = _("Shut down this system now?");
596+ title = _("Shut Down the Computer");
597
598 logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
599
600- if (gsm_logout_supports_system_suspend (logout_dialog)) {
601- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
602- _("S_uspend"),
603- GSM_LOGOUT_RESPONSE_SLEEP);
604+ tile = gsm_logout_append_tile (vbox,
605+ GSM_LOGOUT_RESPONSE_SHUTDOWN,
606+ GSM_ICON_SHUTDOWN,
607+ _("_Shut Down"),
608+ _("Ends your session and turns "
609+ "off the computer."));
610+ if (!gsm_logout_supports_shutdown (logout_dialog)) {
611+ gtk_widget_set_sensitive (tile, FALSE);
612+ /* If shutdown is not available, let's just fallback
613+ * on cancel as the default action. We could fallback
614+ * on reboot first, then suspend and then hibernate
615+ * but it's not that useful, really */
616+ logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
617 }
618
619- if (gsm_logout_supports_system_hibernate (logout_dialog)) {
620- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
621- _("_Hibernate"),
622- GSM_LOGOUT_RESPONSE_HIBERNATE);
623+ tile = gsm_logout_append_tile (vbox,
624+ GSM_LOGOUT_RESPONSE_REBOOT,
625+ GSM_ICON_REBOOT, _("_Restart"),
626+ _("Ends your session and "
627+ "restarts the computer."));
628+ if (!gsm_logout_supports_reboot (logout_dialog)) {
629+ gtk_widget_set_sensitive (tile, FALSE);
630 }
631
632- if (gsm_logout_supports_reboot (logout_dialog)) {
633- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
634- _("_Restart"),
635- GSM_LOGOUT_RESPONSE_REBOOT);
636+ /* We don't set those options insensitive if they are no
637+ * supported (like we do for shutdown/restart) since some
638+ * hardware just don't support suspend/hibernate. So we
639+ * don't show those options in this case. */
640+ if (gsm_logout_supports_system_suspend (logout_dialog)) {
641+ gsm_logout_append_tile (vbox,
642+ GSM_LOGOUT_RESPONSE_SLEEP,
643+ GSM_ICON_SLEEP, _("S_uspend"),
644+ _("Suspends your session "
645+ "quickly, using minimal "
646+ "power while the computer "
647+ "stands by."));
648 }
649
650- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
651- GTK_STOCK_CANCEL,
652- GTK_RESPONSE_CANCEL);
653-
654- if (gsm_logout_supports_shutdown (logout_dialog)) {
655- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
656- _("_Shut Down"),
657- GSM_LOGOUT_RESPONSE_SHUTDOWN);
658+ if (gsm_logout_supports_system_hibernate (logout_dialog)) {
659+ gsm_logout_append_tile (vbox,
660+ GSM_LOGOUT_RESPONSE_HIBERNATE,
661+ GSM_ICON_HIBERNATE,
662+ _("_Hibernate"),
663+ _("Suspends your session, "
664+ "using no power until the "
665+ "computer is restarted."));
666 }
667+
668 break;
669 default:
670 g_assert_not_reached ();
671 }
672
673- dialog_image = gtk_message_dialog_get_image (GTK_MESSAGE_DIALOG (logout_dialog));
674+ logout_dialog->priv->info_label = gtk_label_new ("");
675+ gtk_label_set_line_wrap (GTK_LABEL (logout_dialog->priv->info_label),
676+ TRUE);
677+ gtk_box_pack_start (GTK_BOX (vbox), logout_dialog->priv->info_label,
678+ TRUE, TRUE, 0);
679+ gtk_widget_show (logout_dialog->priv->info_label);
680
681- gtk_image_set_from_icon_name (GTK_IMAGE (dialog_image),
682- icon_name, GTK_ICON_SIZE_DIALOG);
683 gtk_window_set_icon_name (GTK_WINDOW (logout_dialog), icon_name);
684- gtk_window_set_position (GTK_WINDOW (logout_dialog), GTK_WIN_POS_CENTER_ALWAYS);
685- gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (logout_dialog), primary_text);
686+ gtk_window_set_title (GTK_WINDOW (logout_dialog), title);
687+ gtk_window_set_position (GTK_WINDOW (logout_dialog),
688+ GTK_WIN_POS_CENTER_ALWAYS);
689
690 gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
691 logout_dialog->priv->default_response);
692+ /* Note that focus is on the widget for the default response by default
693+ * (since they're the first widget, except when it's Cancel */
694+ if (logout_dialog->priv->default_response == GTK_RESPONSE_CANCEL)
695+ gtk_window_set_focus (GTK_WINDOW (logout_dialog),
696+ logout_dialog->priv->cancel_button);
697
698 gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
699
7000
=== modified file 'debian/patches/95_dbus_request_shutdown.patch'
--- debian/patches/95_dbus_request_shutdown.patch 2013-06-08 23:25:03 +0000
+++ debian/patches/95_dbus_request_shutdown.patch 2014-10-31 04:52:33 +0000
@@ -2,11 +2,9 @@
2other applications to shutdown or reboot the machine via the session manager2other applications to shutdown or reboot the machine via the session manager
3Author: Chris Coulson <chrisccoulson@ubuntu.com>3Author: Chris Coulson <chrisccoulson@ubuntu.com>
44
5Index: gnome-session-3.7.3/gnome-session/gsm-manager.c5--- a/gnome-session/gsm-manager.c
6===================================================================6+++ b/gnome-session/gsm-manager.c
7--- gnome-session-3.7.3.orig/gnome-session/gsm-manager.c 2013-01-07 12:51:02.026999067 +13007@@ -3116,6 +3116,48 @@
8+++ gnome-session-3.7.3/gnome-session/gsm-manager.c 2013-01-07 12:51:02.022999066 +1300
9@@ -3664,6 +3664,48 @@
10 }8 }
11 9
12 gboolean10 gboolean
@@ -52,14 +50,12 @@
52+}50+}
53+51+
54+gboolean52+gboolean
55 gsm_manager_shutdown (GsmManager *manager,53 gsm_manager_shutdown (GsmManager *manager,
56 GError **error)54 DBusGMethodInvocation *context)
57 {55 {
58Index: gnome-session-3.7.3/gnome-session/gsm-manager.h56--- a/gnome-session/gsm-manager.h
59===================================================================57+++ b/gnome-session/gsm-manager.h
60--- gnome-session-3.7.3.orig/gnome-session/gsm-manager.h 2013-01-07 12:51:02.026999067 +130058@@ -159,7 +159,10 @@
61+++ gnome-session-3.7.3/gnome-session/gsm-manager.h 2013-01-07 12:51:02.022999066 +1300
62@@ -160,7 +160,10 @@
63 guint flags,59 guint flags,
64 gboolean *is_inhibited,60 gboolean *is_inhibited,
65 GError *error);61 GError *error);
@@ -69,13 +65,11 @@
69+gboolean gsm_manager_request_reboot (GsmManager *manager,65+gboolean gsm_manager_request_reboot (GsmManager *manager,
70+ GError **error); 66+ GError **error);
71 gboolean gsm_manager_shutdown (GsmManager *manager,67 gboolean gsm_manager_shutdown (GsmManager *manager,
72 GError **error);68 DBusGMethodInvocation *context);
73 gboolean gsm_manager_reboot (GsmManager *manager,69 gboolean gsm_manager_reboot (GsmManager *manager,
74Index: gnome-session-3.7.3/gnome-session/org.gnome.SessionManager.xml70--- a/gnome-session/org.gnome.SessionManager.xml
75===================================================================71+++ b/gnome-session/org.gnome.SessionManager.xml
76--- gnome-session-3.7.3.orig/gnome-session/org.gnome.SessionManager.xml 2013-01-07 12:51:02.026999067 +130072@@ -348,6 +348,23 @@
77+++ gnome-session-3.7.3/gnome-session/org.gnome.SessionManager.xml 2013-01-07 12:51:02.022999066 +1300
78@@ -346,6 +346,23 @@
79 </doc:doc>73 </doc:doc>
80 </method>74 </method>
81 75
8276
=== removed file 'debian/patches/git_fix_wrong_unref_call.patch'
--- debian/patches/git_fix_wrong_unref_call.patch 2013-10-11 13:45:07 +0000
+++ debian/patches/git_fix_wrong_unref_call.patch 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
1Subject: shell: unref correct proxy on destroy
2
3gsm-shell.c tries to automatically clear it's reference to the
4EndSessionDialog proxy when the proxy is destroyed.
5
6It accidentally unrefs the wrong object though. This commit
7fixes that by changing the open coded unref+nullify to g_clear_object
8
9I believe this will address this crasher:
10
11https://retrace.fedoraproject.org/faf/problems/1214348/
12
13https://bugzilla.gnome.org/show_bug.cgi?id=709221
14---
15diff --git a/gnome-session/gsm-shell.c b/gnome-session/gsm-shell.c
16index 450ca40..1c7f053 100644
17--- a/gnome-session/gsm-shell.c
18+++ b/gnome-session/gsm-shell.c
19@@ -534,11 +534,7 @@ static void
20 on_end_session_dialog_proxy_destroyed (DBusGProxy *proxy,
21 GsmShell *shell)
22 {
23- /* FIXME - is this right? */
24- if (shell->priv->end_session_dialog_proxy != NULL) {
25- g_object_unref (shell->priv->proxy);
26- shell->priv->end_session_dialog_proxy = NULL;
27- }
28+ g_clear_object (&shell->priv->end_session_dialog_proxy);
29 }
30
31 static gboolean
32
330
=== added file 'debian/patches/revert_remove_gnome_session_properties.patch'
--- debian/patches/revert_remove_gnome_session_properties.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/revert_remove_gnome_session_properties.patch 2014-10-31 04:52:33 +0000
@@ -0,0 +1,3992 @@
1From 172a7377d00be077c96e9951941c070d491b0b4b Mon Sep 17 00:00:00 2001
2From: Tim Lunn <tim@feathertop.org>
3Date: Fri, 31 Oct 2014 09:23:49 +1100
4Subject: [PATCH] Revert "Remove gnome-session-properties"
5
6This reverts commit ea285af9962313ee2675fff27d3a852bb61e936a.
7---
8 Makefile.am | 1 +
9 capplet/Makefile.am | 31 +
10 capplet/gsm-app-dialog.c | 540 +++++++++++++
11 capplet/gsm-app-dialog.h | 66 ++
12 capplet/gsm-properties-dialog.c | 774 +++++++++++++++++++
13 capplet/gsm-properties-dialog.h | 57 ++
14 capplet/gsp-app-manager.c | 593 ++++++++++++++
15 capplet/gsp-app-manager.h | 81 ++
16 capplet/gsp-app.c | 1102 +++++++++++++++++++++++++++
17 capplet/gsp-app.h | 108 +++
18 capplet/gsp-keyfile.c | 201 +++++
19 capplet/gsp-keyfile.h | 65 ++
20 capplet/main.c | 108 +++
21 configure.ac | 2 +
22 data/Makefile.am | 6 +
23 data/gnome-session-properties.desktop.in.in | 15 +
24 doc/man/Makefile.am | 1 +
25 doc/man/gnome-session-properties.1 | 24 +
26 po/POTFILES.in | 5 +
27 19 files changed, 3780 insertions(+)
28 create mode 100644 capplet/Makefile.am
29 create mode 100644 capplet/gsm-app-dialog.c
30 create mode 100644 capplet/gsm-app-dialog.h
31 create mode 100644 capplet/gsm-properties-dialog.c
32 create mode 100644 capplet/gsm-properties-dialog.h
33 create mode 100644 capplet/gsp-app-manager.c
34 create mode 100644 capplet/gsp-app-manager.h
35 create mode 100644 capplet/gsp-app.c
36 create mode 100644 capplet/gsp-app.h
37 create mode 100644 capplet/gsp-keyfile.c
38 create mode 100644 capplet/gsp-keyfile.h
39 create mode 100644 capplet/main.c
40 create mode 100644 data/gnome-session-properties.desktop.in.in
41 create mode 100644 doc/man/gnome-session-properties.1
42
43Index: gnome-session/Makefile.am
44===================================================================
45--- gnome-session.orig/Makefile.am
46+++ gnome-session/Makefile.am
47@@ -1,5 +1,6 @@
48 SUBDIRS = \
49 gnome-session \
50+ capplet \
51 tools \
52 data \
53 doc \
54Index: gnome-session/capplet/Makefile.am
55===================================================================
56--- /dev/null
57+++ gnome-session/capplet/Makefile.am
58@@ -0,0 +1,31 @@
59+bin_PROGRAMS = gnome-session-properties
60+
61+AM_CPPFLAGS = \
62+ $(SESSION_PROPERTIES_CFLAGS) \
63+ $(GCONF_CFLAGS) \
64+ -I$(top_srcdir)/gnome-session \
65+ -DLOCALE_DIR=\""$(datadir)/locale"\" \
66+ -DGTKBUILDER_DIR=\""$(pkgdatadir)"\" \
67+ $(DISABLE_DEPRECATED_CFLAGS)
68+
69+AM_CFLAGS = $(WARN_CFLAGS)
70+
71+gnome_session_properties_SOURCES = \
72+ main.c \
73+ gsm-properties-dialog.h \
74+ gsm-properties-dialog.c \
75+ gsm-app-dialog.h \
76+ gsm-app-dialog.c \
77+ gsp-app.h \
78+ gsp-app.c \
79+ gsp-app-manager.h \
80+ gsp-app-manager.c \
81+ gsp-keyfile.h \
82+ gsp-keyfile.c
83+
84+gnome_session_properties_LDADD = \
85+ $(SESSION_PROPERTIES_LIBS) \
86+ $(top_builddir)/gnome-session/libgsmutil.la \
87+ $(GCONF_LIBS)
88+
89+-include $(top_srcdir)/git.mk
90Index: gnome-session/capplet/gsm-app-dialog.c
91===================================================================
92--- /dev/null
93+++ gnome-session/capplet/gsm-app-dialog.c
94@@ -0,0 +1,540 @@
95+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
96+ *
97+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
98+ *
99+ * This program is free software; you can redistribute it and/or modify
100+ * it under the terms of the GNU General Public License as published by
101+ * the Free Software Foundation; either version 2 of the License, or
102+ * (at your option) any later version.
103+ *
104+ * This program is distributed in the hope that it will be useful,
105+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
106+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107+ * GNU General Public License for more details.
108+ *
109+ * You should have received a copy of the GNU General Public License
110+ * along with this program; if not, write to the Free Software
111+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
112+ *
113+ */
114+
115+#include "config.h"
116+
117+#include <glib.h>
118+#include <glib/gi18n.h>
119+#include <gtk/gtk.h>
120+
121+#include "gsm-util.h"
122+
123+#include "gsm-app-dialog.h"
124+
125+#define GTKBUILDER_FILE "session-properties.ui"
126+
127+#define CAPPLET_NAME_ENTRY_WIDGET_NAME "session_properties_name_entry"
128+#define CAPPLET_COMMAND_ENTRY_WIDGET_NAME "session_properties_command_entry"
129+#define CAPPLET_COMMENT_ENTRY_WIDGET_NAME "session_properties_comment_entry"
130+#define CAPPLET_BROWSE_WIDGET_NAME "session_properties_browse_button"
131+
132+
133+#define GSM_APP_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_APP_DIALOG, GsmAppDialogPrivate))
134+
135+struct GsmAppDialogPrivate
136+{
137+ GtkWidget *name_entry;
138+ GtkWidget *command_entry;
139+ GtkWidget *comment_entry;
140+ GtkWidget *browse_button;
141+ char *name;
142+ char *command;
143+ char *comment;
144+};
145+
146+static void gsm_app_dialog_class_init (GsmAppDialogClass *klass);
147+static void gsm_app_dialog_init (GsmAppDialog *app_dialog);
148+static void gsm_app_dialog_finalize (GObject *object);
149+
150+enum {
151+ PROP_0,
152+ PROP_NAME,
153+ PROP_COMMAND,
154+ PROP_COMMENT
155+};
156+
157+G_DEFINE_TYPE (GsmAppDialog, gsm_app_dialog, GTK_TYPE_DIALOG)
158+
159+static char *
160+make_exec_uri (const char *exec)
161+{
162+ GString *str;
163+ const char *c;
164+
165+ if (exec == NULL) {
166+ return g_strdup ("");
167+ }
168+
169+ if (strchr (exec, ' ') == NULL) {
170+ return g_strdup (exec);
171+ }
172+
173+ str = g_string_new_len (NULL, strlen (exec));
174+
175+ str = g_string_append_c (str, '"');
176+ for (c = exec; *c != '\0'; c++) {
177+ /* FIXME: GKeyFile will add an additional backslach so we'll
178+ * end up with toto\\" instead of toto\"
179+ * We could use g_key_file_set_value(), but then we don't
180+ * benefit from the other escaping that glib is doing...
181+ */
182+ if (*c == '"') {
183+ str = g_string_append (str, "\\\"");
184+ } else {
185+ str = g_string_append_c (str, *c);
186+ }
187+ }
188+ str = g_string_append_c (str, '"');
189+
190+ return g_string_free (str, FALSE);
191+}
192+
193+static void
194+on_browse_button_clicked (GtkWidget *widget,
195+ GsmAppDialog *dialog)
196+{
197+ GtkWidget *chooser;
198+ int response;
199+
200+ chooser = gtk_file_chooser_dialog_new ("",
201+ GTK_WINDOW (dialog),
202+ GTK_FILE_CHOOSER_ACTION_OPEN,
203+ GTK_STOCK_CANCEL,
204+ GTK_RESPONSE_CANCEL,
205+ GTK_STOCK_OPEN,
206+ GTK_RESPONSE_ACCEPT,
207+ NULL);
208+
209+ gtk_window_set_transient_for (GTK_WINDOW (chooser),
210+ GTK_WINDOW (dialog));
211+
212+ gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
213+
214+ gtk_window_set_title (GTK_WINDOW (chooser), _("Select Command"));
215+
216+ gtk_widget_show (chooser);
217+
218+ response = gtk_dialog_run (GTK_DIALOG (chooser));
219+
220+ if (response == GTK_RESPONSE_ACCEPT) {
221+ char *text;
222+ char *uri;
223+
224+ text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
225+
226+ uri = make_exec_uri (text);
227+
228+ g_free (text);
229+
230+ gtk_entry_set_text (GTK_ENTRY (dialog->priv->command_entry), uri);
231+
232+ g_free (uri);
233+ }
234+
235+ gtk_widget_destroy (chooser);
236+}
237+
238+static void
239+on_entry_activate (GtkEntry *entry,
240+ GsmAppDialog *dialog)
241+{
242+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
243+}
244+
245+static void
246+setup_dialog (GsmAppDialog *dialog)
247+{
248+ GtkWidget *content_area;
249+ GtkWidget *widget;
250+ GtkBuilder *xml;
251+ GError *error;
252+
253+ xml = gtk_builder_new ();
254+ gtk_builder_set_translation_domain (xml, GETTEXT_PACKAGE);
255+
256+ error = NULL;
257+ if (!gtk_builder_add_from_file (xml,
258+ GTKBUILDER_DIR "/" GTKBUILDER_FILE,
259+ &error)) {
260+ if (error) {
261+ g_warning ("Could not load capplet UI file: %s",
262+ error->message);
263+ g_error_free (error);
264+ } else {
265+ g_warning ("Could not load capplet UI file.");
266+ }
267+ }
268+
269+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
270+ widget = GTK_WIDGET (gtk_builder_get_object (xml, "main-table"));
271+ gtk_container_add (GTK_CONTAINER (content_area), widget);
272+
273+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
274+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
275+
276+ g_object_set (dialog,
277+ "allow-shrink", FALSE,
278+ "allow-grow", FALSE,
279+ NULL);
280+
281+ gtk_dialog_add_button (GTK_DIALOG (dialog),
282+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
283+
284+ if (dialog->priv->name == NULL
285+ && dialog->priv->command == NULL
286+ && dialog->priv->comment == NULL) {
287+ gtk_window_set_title (GTK_WINDOW (dialog), _("Add Startup Program"));
288+ gtk_dialog_add_button (GTK_DIALOG (dialog),
289+ GTK_STOCK_ADD, GTK_RESPONSE_OK);
290+ } else {
291+ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Startup Program"));
292+ gtk_dialog_add_button (GTK_DIALOG (dialog),
293+ GTK_STOCK_SAVE, GTK_RESPONSE_OK);
294+ }
295+
296+ dialog->priv->name_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_NAME_ENTRY_WIDGET_NAME));
297+ g_signal_connect (dialog->priv->name_entry,
298+ "activate",
299+ G_CALLBACK (on_entry_activate),
300+ dialog);
301+ if (dialog->priv->name != NULL) {
302+ gtk_entry_set_text (GTK_ENTRY (dialog->priv->name_entry), dialog->priv->name);
303+ }
304+
305+ dialog->priv->browse_button = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_BROWSE_WIDGET_NAME));
306+ g_signal_connect (dialog->priv->browse_button,
307+ "clicked",
308+ G_CALLBACK (on_browse_button_clicked),
309+ dialog);
310+
311+ dialog->priv->command_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMAND_ENTRY_WIDGET_NAME));
312+ g_signal_connect (dialog->priv->command_entry,
313+ "activate",
314+ G_CALLBACK (on_entry_activate),
315+ dialog);
316+ if (dialog->priv->command != NULL) {
317+ gtk_entry_set_text (GTK_ENTRY (dialog->priv->command_entry), dialog->priv->command);
318+ }
319+
320+ dialog->priv->comment_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMENT_ENTRY_WIDGET_NAME));
321+ g_signal_connect (dialog->priv->comment_entry,
322+ "activate",
323+ G_CALLBACK (on_entry_activate),
324+ dialog);
325+ if (dialog->priv->comment != NULL) {
326+ gtk_entry_set_text (GTK_ENTRY (dialog->priv->comment_entry), dialog->priv->comment);
327+ }
328+
329+ if (xml != NULL) {
330+ g_object_unref (xml);
331+ }
332+}
333+
334+static GObject *
335+gsm_app_dialog_constructor (GType type,
336+ guint n_construct_app,
337+ GObjectConstructParam *construct_app)
338+{
339+ GsmAppDialog *dialog;
340+
341+ dialog = GSM_APP_DIALOG (G_OBJECT_CLASS (gsm_app_dialog_parent_class)->constructor (type,
342+ n_construct_app,
343+ construct_app));
344+
345+ setup_dialog (dialog);
346+
347+ gtk_widget_show_all (GTK_WIDGET (dialog));
348+
349+ return G_OBJECT (dialog);
350+}
351+
352+static void
353+gsm_app_dialog_dispose (GObject *object)
354+{
355+ GsmAppDialog *dialog;
356+
357+ g_return_if_fail (object != NULL);
358+ g_return_if_fail (GSM_IS_APP_DIALOG (object));
359+
360+ dialog = GSM_APP_DIALOG (object);
361+
362+ g_free (dialog->priv->name);
363+ dialog->priv->name = NULL;
364+ g_free (dialog->priv->command);
365+ dialog->priv->command = NULL;
366+ g_free (dialog->priv->comment);
367+ dialog->priv->comment = NULL;
368+
369+ G_OBJECT_CLASS (gsm_app_dialog_parent_class)->dispose (object);
370+}
371+
372+static void
373+gsm_app_dialog_set_name (GsmAppDialog *dialog,
374+ const char *name)
375+{
376+ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
377+
378+ g_free (dialog->priv->name);
379+
380+ dialog->priv->name = g_strdup (name);
381+ g_object_notify (G_OBJECT (dialog), "name");
382+}
383+
384+static void
385+gsm_app_dialog_set_command (GsmAppDialog *dialog,
386+ const char *name)
387+{
388+ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
389+
390+ g_free (dialog->priv->command);
391+
392+ dialog->priv->command = g_strdup (name);
393+ g_object_notify (G_OBJECT (dialog), "command");
394+}
395+
396+static void
397+gsm_app_dialog_set_comment (GsmAppDialog *dialog,
398+ const char *name)
399+{
400+ g_return_if_fail (GSM_IS_APP_DIALOG (dialog));
401+
402+ g_free (dialog->priv->comment);
403+
404+ dialog->priv->comment = g_strdup (name);
405+ g_object_notify (G_OBJECT (dialog), "comment");
406+}
407+
408+const char *
409+gsm_app_dialog_get_name (GsmAppDialog *dialog)
410+{
411+ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
412+ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->name_entry));
413+}
414+
415+const char *
416+gsm_app_dialog_get_command (GsmAppDialog *dialog)
417+{
418+ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
419+ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->command_entry));
420+}
421+
422+const char *
423+gsm_app_dialog_get_comment (GsmAppDialog *dialog)
424+{
425+ g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL);
426+ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->comment_entry));
427+}
428+
429+static void
430+gsm_app_dialog_set_property (GObject *object,
431+ guint prop_id,
432+ const GValue *value,
433+ GParamSpec *pspec)
434+{
435+ GsmAppDialog *dialog = GSM_APP_DIALOG (object);
436+
437+ switch (prop_id) {
438+ case PROP_NAME:
439+ gsm_app_dialog_set_name (dialog, g_value_get_string (value));
440+ break;
441+ case PROP_COMMAND:
442+ gsm_app_dialog_set_command (dialog, g_value_get_string (value));
443+ break;
444+ case PROP_COMMENT:
445+ gsm_app_dialog_set_comment (dialog, g_value_get_string (value));
446+ break;
447+ default:
448+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
449+ break;
450+ }
451+}
452+
453+static void
454+gsm_app_dialog_get_property (GObject *object,
455+ guint prop_id,
456+ GValue *value,
457+ GParamSpec *pspec)
458+{
459+ GsmAppDialog *dialog = GSM_APP_DIALOG (object);
460+
461+ switch (prop_id) {
462+ case PROP_NAME:
463+ g_value_set_string (value, dialog->priv->name);
464+ break;
465+ case PROP_COMMAND:
466+ g_value_set_string (value, dialog->priv->command);
467+ break;
468+ case PROP_COMMENT:
469+ g_value_set_string (value, dialog->priv->comment);
470+ break;
471+ default:
472+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
473+ break;
474+ }
475+}
476+
477+static void
478+gsm_app_dialog_class_init (GsmAppDialogClass *klass)
479+{
480+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
481+
482+ object_class->get_property = gsm_app_dialog_get_property;
483+ object_class->set_property = gsm_app_dialog_set_property;
484+ object_class->constructor = gsm_app_dialog_constructor;
485+ object_class->dispose = gsm_app_dialog_dispose;
486+ object_class->finalize = gsm_app_dialog_finalize;
487+
488+ g_object_class_install_property (object_class,
489+ PROP_NAME,
490+ g_param_spec_string ("name",
491+ "name",
492+ "name",
493+ NULL,
494+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
495+ g_object_class_install_property (object_class,
496+ PROP_COMMAND,
497+ g_param_spec_string ("command",
498+ "command",
499+ "command",
500+ NULL,
501+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
502+ g_object_class_install_property (object_class,
503+ PROP_COMMENT,
504+ g_param_spec_string ("comment",
505+ "comment",
506+ "comment",
507+ NULL,
508+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
509+
510+ g_type_class_add_private (klass, sizeof (GsmAppDialogPrivate));
511+}
512+
513+static void
514+gsm_app_dialog_init (GsmAppDialog *dialog)
515+{
516+
517+ dialog->priv = GSM_APP_DIALOG_GET_PRIVATE (dialog);
518+}
519+
520+static void
521+gsm_app_dialog_finalize (GObject *object)
522+{
523+ GsmAppDialog *dialog;
524+
525+ g_return_if_fail (object != NULL);
526+ g_return_if_fail (GSM_IS_APP_DIALOG (object));
527+
528+ dialog = GSM_APP_DIALOG (object);
529+
530+ g_return_if_fail (dialog->priv != NULL);
531+
532+ G_OBJECT_CLASS (gsm_app_dialog_parent_class)->finalize (object);
533+}
534+
535+GtkWidget *
536+gsm_app_dialog_new (const char *name,
537+ const char *command,
538+ const char *comment)
539+{
540+ GObject *object;
541+
542+ object = g_object_new (GSM_TYPE_APP_DIALOG,
543+ "name", name,
544+ "command", command,
545+ "comment", comment,
546+ NULL);
547+
548+ return GTK_WIDGET (object);
549+}
550+
551+gboolean
552+gsm_app_dialog_run (GsmAppDialog *dialog,
553+ char **name_p,
554+ char **command_p,
555+ char **comment_p)
556+{
557+ gboolean retval;
558+
559+ retval = FALSE;
560+
561+ while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
562+ const char *name;
563+ const char *exec;
564+ const char *comment;
565+ const char *error_msg;
566+ GError *error;
567+ char **argv;
568+ int argc;
569+
570+ name = gsm_app_dialog_get_name (GSM_APP_DIALOG (dialog));
571+ exec = gsm_app_dialog_get_command (GSM_APP_DIALOG (dialog));
572+ comment = gsm_app_dialog_get_comment (GSM_APP_DIALOG (dialog));
573+
574+ error = NULL;
575+ error_msg = NULL;
576+
577+ if (gsm_util_text_is_blank (exec)) {
578+ error_msg = _("The startup command cannot be empty");
579+ } else {
580+ if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
581+ if (error != NULL) {
582+ error_msg = error->message;
583+ } else {
584+ error_msg = _("The startup command is not valid");
585+ }
586+ }
587+ }
588+
589+ if (error_msg != NULL) {
590+ GtkWidget *msgbox;
591+
592+ msgbox = gtk_message_dialog_new (GTK_WINDOW (dialog),
593+ GTK_DIALOG_MODAL,
594+ GTK_MESSAGE_ERROR,
595+ GTK_BUTTONS_CLOSE,
596+ "%s", error_msg);
597+
598+ if (error != NULL) {
599+ g_error_free (error);
600+ }
601+
602+ gtk_dialog_run (GTK_DIALOG (msgbox));
603+
604+ gtk_widget_destroy (msgbox);
605+
606+ continue;
607+ }
608+
609+ if (gsm_util_text_is_blank (name)) {
610+ name = argv[0];
611+ }
612+
613+ if (name_p) {
614+ *name_p = g_strdup (name);
615+ }
616+
617+ g_strfreev (argv);
618+
619+ if (command_p) {
620+ *command_p = g_strdup (exec);
621+ }
622+
623+ if (comment_p) {
624+ *comment_p = g_strdup (comment);
625+ }
626+
627+ retval = TRUE;
628+ break;
629+ }
630+
631+ gtk_widget_destroy (GTK_WIDGET (dialog));
632+
633+ return retval;
634+}
635Index: gnome-session/capplet/gsm-app-dialog.h
636===================================================================
637--- /dev/null
638+++ gnome-session/capplet/gsm-app-dialog.h
639@@ -0,0 +1,66 @@
640+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
641+ *
642+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
643+ *
644+ * This program is free software; you can redistribute it and/or modify
645+ * it under the terms of the GNU General Public License as published by
646+ * the Free Software Foundation; either version 2 of the License, or
647+ * (at your option) any later version.
648+ *
649+ * This program is distributed in the hope that it will be useful,
650+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
651+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
652+ * GNU General Public License for more details.
653+ *
654+ * You should have received a copy of the GNU General Public License
655+ * along with this program; if not, write to the Free Software
656+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
657+ *
658+ */
659+
660+#ifndef __GSM_APP_DIALOG_H
661+#define __GSM_APP_DIALOG_H
662+
663+#include <glib-object.h>
664+#include <gtk/gtk.h>
665+
666+G_BEGIN_DECLS
667+
668+#define GSM_TYPE_APP_DIALOG (gsm_app_dialog_get_type ())
669+#define GSM_APP_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_APP_DIALOG, GsmAppDialog))
670+#define GSM_APP_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_APP_DIALOG, GsmAppDialogClass))
671+#define GSM_IS_APP_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_APP_DIALOG))
672+#define GSM_IS_APP_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_APP_DIALOG))
673+#define GSM_APP_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_APP_DIALOG, GsmAppDialogClass))
674+
675+typedef struct GsmAppDialogPrivate GsmAppDialogPrivate;
676+
677+typedef struct
678+{
679+ GtkDialog parent;
680+ GsmAppDialogPrivate *priv;
681+} GsmAppDialog;
682+
683+typedef struct
684+{
685+ GtkDialogClass parent_class;
686+} GsmAppDialogClass;
687+
688+GType gsm_app_dialog_get_type (void);
689+
690+GtkWidget * gsm_app_dialog_new (const char *name,
691+ const char *command,
692+ const char *comment);
693+
694+gboolean gsm_app_dialog_run (GsmAppDialog *dialog,
695+ char **name_p,
696+ char **command_p,
697+ char **comment_p);
698+
699+const char * gsm_app_dialog_get_name (GsmAppDialog *dialog);
700+const char * gsm_app_dialog_get_command (GsmAppDialog *dialog);
701+const char * gsm_app_dialog_get_comment (GsmAppDialog *dialog);
702+
703+G_END_DECLS
704+
705+#endif /* __GSM_APP_DIALOG_H */
706Index: gnome-session/capplet/gsm-properties-dialog.c
707===================================================================
708--- /dev/null
709+++ gnome-session/capplet/gsm-properties-dialog.c
710@@ -0,0 +1,774 @@
711+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
712+ *
713+ * Copyright (C) 1999 Free Software Foundation, Inc.
714+ * Copyright (C) 2007 Vincent Untz.
715+ * Copyright (C) 2008 Lucas Rocha.
716+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
717+ *
718+ * This program is free software; you can redistribute it and/or modify
719+ * it under the terms of the GNU General Public License as published by
720+ * the Free Software Foundation; either version 2 of the License, or
721+ * (at your option) any later version.
722+ *
723+ * This program is distributed in the hope that it will be useful,
724+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
725+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
726+ * GNU General Public License for more details.
727+ *
728+ * You should have received a copy of the GNU General Public License
729+ * along with this program; if not, write to the Free Software
730+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
731+ *
732+ */
733+
734+#include "config.h"
735+
736+#include <glib.h>
737+#include <glib/gi18n.h>
738+#include <gtk/gtk.h>
739+
740+#include "gsm-properties-dialog.h"
741+#include "gsm-app-dialog.h"
742+#include "gsm-util.h"
743+#include "gsp-app.h"
744+#include "gsp-app-manager.h"
745+
746+#define GSM_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogPrivate))
747+
748+#define GTKBUILDER_FILE "session-properties.ui"
749+
750+#define CAPPLET_TREEVIEW_WIDGET_NAME "session_properties_treeview"
751+#define CAPPLET_ADD_WIDGET_NAME "session_properties_add_button"
752+#define CAPPLET_DELETE_WIDGET_NAME "session_properties_delete_button"
753+#define CAPPLET_EDIT_WIDGET_NAME "session_properties_edit_button"
754+#define CAPPLET_SAVE_WIDGET_NAME "session_properties_save_button"
755+#define CAPPLET_REMEMBER_WIDGET_NAME "session_properties_remember_toggle"
756+
757+#define STARTUP_APP_ICON "system-run"
758+
759+#define SPC_SETTINGS_SCHEMA "org.gnome.SessionManager"
760+#define SPC_SETTINGS_AUTOSAVE_KEY "auto-save-session"
761+
762+struct GsmPropertiesDialogPrivate
763+{
764+ GtkBuilder *xml;
765+ GtkListStore *list_store;
766+ GtkTreeModel *tree_filter;
767+
768+ GtkTreeView *treeview;
769+ GtkWidget *add_button;
770+ GtkWidget *delete_button;
771+ GtkWidget *edit_button;
772+
773+ GSettings *settings;
774+
775+ GspAppManager *manager;
776+};
777+
778+enum {
779+ STORE_COL_VISIBLE = 0,
780+ STORE_COL_ENABLED,
781+ STORE_COL_GICON,
782+ STORE_COL_DESCRIPTION,
783+ STORE_COL_APP,
784+ STORE_COL_SEARCH,
785+ NUMBER_OF_COLUMNS
786+};
787+
788+static void gsm_properties_dialog_class_init (GsmPropertiesDialogClass *klass);
789+static void gsm_properties_dialog_init (GsmPropertiesDialog *properties_dialog);
790+static void gsm_properties_dialog_finalize (GObject *object);
791+
792+G_DEFINE_TYPE (GsmPropertiesDialog, gsm_properties_dialog, GTK_TYPE_DIALOG)
793+
794+static gboolean
795+find_by_app (GtkTreeModel *model,
796+ GtkTreeIter *iter,
797+ GspApp *app)
798+{
799+ GspApp *iter_app = NULL;
800+
801+ if (!gtk_tree_model_get_iter_first (model, iter)) {
802+ return FALSE;
803+ }
804+
805+ do {
806+ gtk_tree_model_get (model, iter,
807+ STORE_COL_APP, &iter_app,
808+ -1);
809+
810+ if (iter_app == app) {
811+ g_object_unref (iter_app);
812+ return TRUE;
813+ }
814+ } while (gtk_tree_model_iter_next (model, iter));
815+
816+ return FALSE;
817+}
818+
819+static void
820+_fill_iter_from_app (GtkListStore *list_store,
821+ GtkTreeIter *iter,
822+ GspApp *app)
823+{
824+ gboolean hidden;
825+ gboolean display;
826+ gboolean enabled;
827+ gboolean shown;
828+ GIcon *icon;
829+ const char *description;
830+ const char *app_name;
831+
832+ hidden = gsp_app_get_hidden (app);
833+ display = gsp_app_get_display (app);
834+ enabled = gsp_app_get_enabled (app);
835+ shown = gsp_app_get_shown (app);
836+ icon = gsp_app_get_icon (app);
837+ description = gsp_app_get_description (app);
838+ app_name = gsp_app_get_name (app);
839+
840+ if (G_IS_THEMED_ICON (icon)) {
841+ GtkIconTheme *theme;
842+ const char * const *icon_names;
843+
844+ theme = gtk_icon_theme_get_default ();
845+ icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon));
846+ if (icon_names[0] == NULL ||
847+ !gtk_icon_theme_has_icon (theme, icon_names[0])) {
848+ g_object_unref (icon);
849+ icon = NULL;
850+ }
851+ } else if (G_IS_FILE_ICON (icon)) {
852+ GFile *iconfile;
853+
854+ iconfile = g_file_icon_get_file (G_FILE_ICON (icon));
855+ if (!g_file_query_exists (iconfile, NULL)) {
856+ g_object_unref (icon);
857+ icon = NULL;
858+ }
859+ }
860+
861+ if (icon == NULL) {
862+ icon = g_themed_icon_new (STARTUP_APP_ICON);
863+ }
864+
865+ gtk_list_store_set (list_store, iter,
866+ STORE_COL_VISIBLE, !hidden && shown && display,
867+ STORE_COL_ENABLED, enabled,
868+ STORE_COL_GICON, icon,
869+ STORE_COL_DESCRIPTION, description,
870+ STORE_COL_APP, app,
871+ STORE_COL_SEARCH, app_name,
872+ -1);
873+ g_object_unref (icon);
874+}
875+
876+static void
877+_app_changed (GsmPropertiesDialog *dialog,
878+ GspApp *app)
879+{
880+ GtkTreeIter iter;
881+
882+ if (!find_by_app (GTK_TREE_MODEL (dialog->priv->list_store),
883+ &iter, app)) {
884+ return;
885+ }
886+
887+ _fill_iter_from_app (dialog->priv->list_store, &iter, app);
888+}
889+
890+static void
891+append_app (GsmPropertiesDialog *dialog,
892+ GspApp *app)
893+{
894+ GtkTreeIter iter;
895+
896+ gtk_list_store_append (dialog->priv->list_store, &iter);
897+ _fill_iter_from_app (dialog->priv->list_store, &iter, app);
898+
899+ g_signal_connect_swapped (app, "changed",
900+ G_CALLBACK (_app_changed), dialog);
901+}
902+
903+static void
904+_app_added (GsmPropertiesDialog *dialog,
905+ GspApp *app,
906+ GspAppManager *manager)
907+{
908+ append_app (dialog, app);
909+}
910+
911+static void
912+_app_removed (GsmPropertiesDialog *dialog,
913+ GspApp *app,
914+ GspAppManager *manager)
915+{
916+ GtkTreeIter iter;
917+
918+ if (!find_by_app (GTK_TREE_MODEL (dialog->priv->list_store),
919+ &iter, app)) {
920+ return;
921+ }
922+
923+ g_signal_handlers_disconnect_by_func (app,
924+ _app_changed,
925+ dialog);
926+ gtk_list_store_remove (dialog->priv->list_store, &iter);
927+}
928+
929+static void
930+populate_model (GsmPropertiesDialog *dialog)
931+{
932+ GSList *apps;
933+ GSList *l;
934+
935+ apps = gsp_app_manager_get_apps (dialog->priv->manager);
936+ for (l = apps; l != NULL; l = l->next) {
937+ append_app (dialog, GSP_APP (l->data));
938+ }
939+ g_slist_free (apps);
940+}
941+
942+static void
943+on_selection_changed (GtkTreeSelection *selection,
944+ GsmPropertiesDialog *dialog)
945+{
946+ gboolean sel;
947+
948+ sel = gtk_tree_selection_get_selected (selection, NULL, NULL);
949+
950+ gtk_widget_set_sensitive (dialog->priv->edit_button, sel);
951+ gtk_widget_set_sensitive (dialog->priv->delete_button, sel);
952+}
953+
954+static void
955+on_startup_enabled_toggled (GtkCellRendererToggle *cell_renderer,
956+ char *path,
957+ GsmPropertiesDialog *dialog)
958+{
959+ GtkTreeIter iter;
960+ GspApp *app;
961+ gboolean active;
962+
963+ if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (dialog->priv->tree_filter),
964+ &iter, path)) {
965+ return;
966+ }
967+
968+ app = NULL;
969+ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
970+ &iter,
971+ STORE_COL_APP, &app,
972+ -1);
973+
974+ active = gtk_cell_renderer_toggle_get_active (cell_renderer);
975+ active = !active;
976+
977+ if (app) {
978+ gsp_app_set_enabled (app, active);
979+ g_object_unref (app);
980+ }
981+}
982+
983+static void
984+on_drag_data_received (GtkWidget *widget,
985+ GdkDragContext *drag_context,
986+ gint x,
987+ gint y,
988+ GtkSelectionData *data,
989+ guint info,
990+ guint time,
991+ GsmPropertiesDialog *dialog)
992+{
993+ gboolean dnd_success;
994+
995+ dnd_success = FALSE;
996+
997+ if (data != NULL) {
998+ char **filenames;
999+ int i;
1000+
1001+ filenames = gtk_selection_data_get_uris (data);
1002+
1003+ for (i = 0; filenames[i] && filenames[i][0]; i++) {
1004+ /* Return success if at least one file succeeded */
1005+ gboolean file_success;
1006+ file_success = gsp_app_copy_desktop_file (filenames[i]);
1007+ dnd_success = dnd_success || file_success;
1008+ }
1009+
1010+ g_strfreev (filenames);
1011+ }
1012+
1013+ gtk_drag_finish (drag_context, dnd_success, FALSE, time);
1014+ g_signal_stop_emission_by_name (widget, "drag_data_received");
1015+}
1016+
1017+static void
1018+on_drag_begin (GtkWidget *widget,
1019+ GdkDragContext *context,
1020+ GsmPropertiesDialog *dialog)
1021+{
1022+ GtkTreePath *path;
1023+ GtkTreeIter iter;
1024+ GspApp *app;
1025+
1026+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (widget), &path, NULL);
1027+ gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->tree_filter),
1028+ &iter, path);
1029+ gtk_tree_path_free (path);
1030+
1031+ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
1032+ &iter,
1033+ STORE_COL_APP, &app,
1034+ -1);
1035+
1036+ if (app) {
1037+ g_object_set_data_full (G_OBJECT (context), "gsp-app",
1038+ g_object_ref (app), g_object_unref);
1039+ g_object_unref (app);
1040+ }
1041+
1042+}
1043+
1044+static void
1045+on_drag_data_get (GtkWidget *widget,
1046+ GdkDragContext *context,
1047+ GtkSelectionData *selection_data,
1048+ guint info,
1049+ guint time,
1050+ GsmPropertiesDialog *dialog)
1051+{
1052+ GspApp *app;
1053+
1054+ app = g_object_get_data (G_OBJECT (context), "gsp-app");
1055+ if (app) {
1056+ const char *uris[2];
1057+ char *uri;
1058+
1059+ uri = g_filename_to_uri (gsp_app_get_path (app), NULL, NULL);
1060+
1061+ uris[0] = uri;
1062+ uris[1] = NULL;
1063+ gtk_selection_data_set_uris (selection_data, (char **) uris);
1064+
1065+ g_free (uri);
1066+ }
1067+}
1068+
1069+static void
1070+on_add_app_clicked (GtkWidget *widget,
1071+ GsmPropertiesDialog *dialog)
1072+{
1073+ GtkWidget *add_dialog;
1074+ char *name;
1075+ char *exec;
1076+ char *comment;
1077+
1078+ add_dialog = gsm_app_dialog_new (NULL, NULL, NULL);
1079+ gtk_window_set_transient_for (GTK_WINDOW (add_dialog),
1080+ GTK_WINDOW (dialog));
1081+
1082+ if (gsm_app_dialog_run (GSM_APP_DIALOG (add_dialog),
1083+ &name, &exec, &comment)) {
1084+ gsp_app_create (name, comment, exec);
1085+ g_free (name);
1086+ g_free (exec);
1087+ g_free (comment);
1088+ }
1089+}
1090+
1091+static void
1092+on_delete_app_clicked (GtkWidget *widget,
1093+ GsmPropertiesDialog *dialog)
1094+{
1095+ GtkTreeSelection *selection;
1096+ GtkTreeIter iter;
1097+ GspApp *app;
1098+
1099+ selection = gtk_tree_view_get_selection (dialog->priv->treeview);
1100+
1101+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
1102+ return;
1103+ }
1104+
1105+ app = NULL;
1106+ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
1107+ &iter,
1108+ STORE_COL_APP, &app,
1109+ -1);
1110+
1111+ if (app) {
1112+ gsp_app_delete (app);
1113+ g_object_unref (app);
1114+ }
1115+}
1116+
1117+static void
1118+on_edit_app_clicked (GtkWidget *widget,
1119+ GsmPropertiesDialog *dialog)
1120+{
1121+ GtkTreeSelection *selection;
1122+ GtkTreeIter iter;
1123+ GspApp *app;
1124+
1125+ selection = gtk_tree_view_get_selection (dialog->priv->treeview);
1126+
1127+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
1128+ return;
1129+ }
1130+
1131+ app = NULL;
1132+ gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->tree_filter),
1133+ &iter,
1134+ STORE_COL_APP, &app,
1135+ -1);
1136+
1137+ if (app) {
1138+ GtkWidget *edit_dialog;
1139+ char *name;
1140+ char *exec;
1141+ char *comment;
1142+
1143+ edit_dialog = gsm_app_dialog_new (gsp_app_get_name (app),
1144+ gsp_app_get_exec (app),
1145+ gsp_app_get_comment (app));
1146+ gtk_window_set_transient_for (GTK_WINDOW (edit_dialog),
1147+ GTK_WINDOW (dialog));
1148+
1149+ if (gsm_app_dialog_run (GSM_APP_DIALOG (edit_dialog),
1150+ &name, &exec, &comment)) {
1151+ gsp_app_update (app, name, comment, exec);
1152+ g_free (name);
1153+ g_free (exec);
1154+ g_free (comment);
1155+ }
1156+
1157+ g_object_unref (app);
1158+ }
1159+}
1160+
1161+static void
1162+on_row_activated (GtkTreeView *tree_view,
1163+ GtkTreePath *path,
1164+ GtkTreeViewColumn *column,
1165+ GsmPropertiesDialog *dialog)
1166+{
1167+ on_edit_app_clicked (NULL, dialog);
1168+}
1169+
1170+static void
1171+on_save_session_clicked (GtkWidget *widget,
1172+ GsmPropertiesDialog *dialog)
1173+{
1174+ g_debug ("Session saving is not implemented yet!");
1175+}
1176+
1177+static void
1178+setup_dialog (GsmPropertiesDialog *dialog)
1179+{
1180+ GtkTreeView *treeview;
1181+ GtkWidget *button;
1182+ GtkTreeModel *tree_filter;
1183+ GtkTreeViewColumn *column;
1184+ GtkCellRenderer *renderer;
1185+ GtkTreeSelection *selection;
1186+ GtkTargetList *targetlist;
1187+
1188+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
1189+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
1190+ NULL);
1191+
1192+ dialog->priv->list_store = gtk_list_store_new (NUMBER_OF_COLUMNS,
1193+ G_TYPE_BOOLEAN,
1194+ G_TYPE_BOOLEAN,
1195+ G_TYPE_ICON,
1196+ G_TYPE_STRING,
1197+ G_TYPE_OBJECT,
1198+ G_TYPE_STRING);
1199+ tree_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (dialog->priv->list_store),
1200+ NULL);
1201+ g_object_unref (dialog->priv->list_store);
1202+ dialog->priv->tree_filter = tree_filter;
1203+
1204+ gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (tree_filter),
1205+ STORE_COL_VISIBLE);
1206+
1207+ treeview = GTK_TREE_VIEW (gtk_builder_get_object (dialog->priv->xml,
1208+ CAPPLET_TREEVIEW_WIDGET_NAME));
1209+ dialog->priv->treeview = treeview;
1210+
1211+ gtk_tree_view_set_model (treeview, tree_filter);
1212+ g_object_unref (tree_filter);
1213+
1214+ gtk_tree_view_set_headers_visible (treeview, FALSE);
1215+ g_signal_connect (treeview,
1216+ "row-activated",
1217+ G_CALLBACK (on_row_activated),
1218+ dialog);
1219+
1220+ selection = gtk_tree_view_get_selection (treeview);
1221+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
1222+ g_signal_connect (selection,
1223+ "changed",
1224+ G_CALLBACK (on_selection_changed),
1225+ dialog);
1226+
1227+ /* CHECKBOX COLUMN */
1228+ renderer = gtk_cell_renderer_toggle_new ();
1229+ column = gtk_tree_view_column_new_with_attributes (_("Enabled"),
1230+ renderer,
1231+ "active", STORE_COL_ENABLED,
1232+ NULL);
1233+ gtk_tree_view_append_column (treeview, column);
1234+ g_signal_connect (renderer,
1235+ "toggled",
1236+ G_CALLBACK (on_startup_enabled_toggled),
1237+ dialog);
1238+
1239+ /* ICON COLUMN */
1240+ renderer = gtk_cell_renderer_pixbuf_new ();
1241+ column = gtk_tree_view_column_new_with_attributes (_("Icon"),
1242+ renderer,
1243+ "gicon", STORE_COL_GICON,
1244+ "sensitive", STORE_COL_ENABLED,
1245+ NULL);
1246+ g_object_set (renderer,
1247+ "stock-size", GSM_PROPERTIES_ICON_SIZE,
1248+ NULL);
1249+ gtk_tree_view_append_column (treeview, column);
1250+
1251+ /* NAME COLUMN */
1252+ renderer = gtk_cell_renderer_text_new ();
1253+ column = gtk_tree_view_column_new_with_attributes (_("Program"),
1254+ renderer,
1255+ "markup", STORE_COL_DESCRIPTION,
1256+ "sensitive", STORE_COL_ENABLED,
1257+ NULL);
1258+ g_object_set (renderer,
1259+ "ellipsize", PANGO_ELLIPSIZE_END,
1260+ NULL);
1261+ gtk_tree_view_append_column (treeview, column);
1262+
1263+
1264+ gtk_tree_view_column_set_sort_column_id (column, STORE_COL_DESCRIPTION);
1265+ gtk_tree_view_set_search_column (treeview, STORE_COL_SEARCH);
1266+ gtk_tree_view_set_rules_hint (treeview, TRUE);
1267+
1268+ gtk_tree_view_enable_model_drag_source (treeview,
1269+ GDK_BUTTON1_MASK|GDK_BUTTON2_MASK,
1270+ NULL, 0,
1271+ GDK_ACTION_COPY);
1272+ gtk_drag_source_add_uri_targets (GTK_WIDGET (treeview));
1273+
1274+ gtk_drag_dest_set (GTK_WIDGET (treeview),
1275+ GTK_DEST_DEFAULT_ALL,
1276+ NULL, 0,
1277+ GDK_ACTION_COPY);
1278+
1279+ gtk_drag_dest_add_uri_targets (GTK_WIDGET (treeview));
1280+ /* we don't want to accept drags coming from this widget */
1281+ targetlist = gtk_drag_dest_get_target_list (GTK_WIDGET (treeview));
1282+ if (targetlist != NULL) {
1283+ GtkTargetEntry *targets;
1284+ gint n_targets;
1285+ gint i;
1286+
1287+ targets = gtk_target_table_new_from_list (targetlist, &n_targets);
1288+ for (i = 0; i < n_targets; i++)
1289+ targets[i].flags = GTK_TARGET_OTHER_WIDGET;
1290+
1291+ targetlist = gtk_target_list_new (targets, n_targets);
1292+ gtk_drag_dest_set_target_list (GTK_WIDGET (treeview), targetlist);
1293+ gtk_target_list_unref (targetlist);
1294+
1295+ gtk_target_table_free (targets, n_targets);
1296+ }
1297+
1298+ g_signal_connect (treeview, "drag_begin",
1299+ G_CALLBACK (on_drag_begin),
1300+ dialog);
1301+ g_signal_connect (treeview, "drag_data_get",
1302+ G_CALLBACK (on_drag_data_get),
1303+ dialog);
1304+ g_signal_connect (treeview, "drag_data_received",
1305+ G_CALLBACK (on_drag_data_received),
1306+ dialog);
1307+
1308+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dialog->priv->list_store),
1309+ STORE_COL_DESCRIPTION,
1310+ GTK_SORT_ASCENDING);
1311+
1312+
1313+ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1314+ CAPPLET_ADD_WIDGET_NAME));
1315+ dialog->priv->add_button = button;
1316+ g_signal_connect (button,
1317+ "clicked",
1318+ G_CALLBACK (on_add_app_clicked),
1319+ dialog);
1320+
1321+ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1322+ CAPPLET_DELETE_WIDGET_NAME));
1323+ dialog->priv->delete_button = button;
1324+ g_signal_connect (button,
1325+ "clicked",
1326+ G_CALLBACK (on_delete_app_clicked),
1327+ dialog);
1328+
1329+ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1330+ CAPPLET_EDIT_WIDGET_NAME));
1331+ dialog->priv->edit_button = button;
1332+ g_signal_connect (button,
1333+ "clicked",
1334+ G_CALLBACK (on_edit_app_clicked),
1335+ dialog);
1336+
1337+ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1338+ CAPPLET_REMEMBER_WIDGET_NAME));
1339+ g_settings_bind (dialog->priv->settings, SPC_SETTINGS_AUTOSAVE_KEY,
1340+ button, "active", G_SETTINGS_BIND_DEFAULT);
1341+
1342+ button = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1343+ CAPPLET_SAVE_WIDGET_NAME));
1344+ g_signal_connect (button,
1345+ "clicked",
1346+ G_CALLBACK (on_save_session_clicked),
1347+ dialog);
1348+
1349+ dialog->priv->manager = gsp_app_manager_get ();
1350+ gsp_app_manager_fill (dialog->priv->manager);
1351+ g_signal_connect_swapped (dialog->priv->manager, "added",
1352+ G_CALLBACK (_app_added), dialog);
1353+ g_signal_connect_swapped (dialog->priv->manager, "removed",
1354+ G_CALLBACK (_app_removed), dialog);
1355+
1356+ populate_model (dialog);
1357+}
1358+
1359+static GObject *
1360+gsm_properties_dialog_constructor (GType type,
1361+ guint n_construct_properties,
1362+ GObjectConstructParam *construct_properties)
1363+{
1364+ GsmPropertiesDialog *dialog;
1365+
1366+ dialog = GSM_PROPERTIES_DIALOG (G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->constructor (type,
1367+ n_construct_properties,
1368+ construct_properties));
1369+
1370+ setup_dialog (dialog);
1371+
1372+ gtk_widget_show (GTK_WIDGET (dialog));
1373+
1374+ return G_OBJECT (dialog);
1375+}
1376+
1377+static void
1378+gsm_properties_dialog_dispose (GObject *object)
1379+{
1380+ GsmPropertiesDialog *dialog;
1381+
1382+ g_return_if_fail (object != NULL);
1383+ g_return_if_fail (GSM_IS_PROPERTIES_DIALOG (object));
1384+
1385+ dialog = GSM_PROPERTIES_DIALOG (object);
1386+
1387+ if (dialog->priv->xml != NULL) {
1388+ g_object_unref (dialog->priv->xml);
1389+ dialog->priv->xml = NULL;
1390+ }
1391+
1392+ if (dialog->priv->settings != NULL) {
1393+ g_object_unref (dialog->priv->settings);
1394+ dialog->priv->settings = NULL;
1395+ }
1396+
1397+ G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->dispose (object);
1398+
1399+ /* it's important to do this after chaining to the parent dispose
1400+ * method because we want to make sure the treeview has been disposed
1401+ * and removed all its references to GspApp objects */
1402+ if (dialog->priv->manager != NULL) {
1403+ g_object_unref (dialog->priv->manager);
1404+ dialog->priv->manager = NULL;
1405+ }
1406+}
1407+
1408+static void
1409+gsm_properties_dialog_class_init (GsmPropertiesDialogClass *klass)
1410+{
1411+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1412+
1413+ object_class->constructor = gsm_properties_dialog_constructor;
1414+ object_class->dispose = gsm_properties_dialog_dispose;
1415+ object_class->finalize = gsm_properties_dialog_finalize;
1416+
1417+ g_type_class_add_private (klass, sizeof (GsmPropertiesDialogPrivate));
1418+}
1419+
1420+static void
1421+gsm_properties_dialog_init (GsmPropertiesDialog *dialog)
1422+{
1423+ GtkWidget *content_area;
1424+ GtkWidget *widget;
1425+ GError *error;
1426+
1427+ dialog->priv = GSM_PROPERTIES_DIALOG_GET_PRIVATE (dialog);
1428+
1429+ dialog->priv->settings = g_settings_new (SPC_SETTINGS_SCHEMA);
1430+
1431+ dialog->priv->xml = gtk_builder_new ();
1432+ gtk_builder_set_translation_domain (dialog->priv->xml, GETTEXT_PACKAGE);
1433+
1434+ error = NULL;
1435+ if (!gtk_builder_add_from_file (dialog->priv->xml,
1436+ GTKBUILDER_DIR "/" GTKBUILDER_FILE,
1437+ &error)) {
1438+ if (error) {
1439+ g_warning ("Could not load capplet UI file: %s",
1440+ error->message);
1441+ g_error_free (error);
1442+ } else {
1443+ g_warning ("Could not load capplet UI file.");
1444+ }
1445+ }
1446+
1447+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
1448+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
1449+ "main-notebook"));
1450+ gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
1451+
1452+ gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 450);
1453+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
1454+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
1455+ gtk_box_set_spacing (GTK_BOX (content_area), 2);
1456+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
1457+ gtk_window_set_title (GTK_WINDOW (dialog), _("Startup Applications Preferences"));
1458+}
1459+
1460+static void
1461+gsm_properties_dialog_finalize (GObject *object)
1462+{
1463+ GsmPropertiesDialog *dialog;
1464+
1465+ g_return_if_fail (object != NULL);
1466+ g_return_if_fail (GSM_IS_PROPERTIES_DIALOG (object));
1467+
1468+ dialog = GSM_PROPERTIES_DIALOG (object);
1469+
1470+ g_return_if_fail (dialog->priv != NULL);
1471+
1472+ G_OBJECT_CLASS (gsm_properties_dialog_parent_class)->finalize (object);
1473+}
1474+
1475+GtkWidget *
1476+gsm_properties_dialog_new (void)
1477+{
1478+ GObject *object;
1479+
1480+ object = g_object_new (GSM_TYPE_PROPERTIES_DIALOG,
1481+ NULL);
1482+
1483+ return GTK_WIDGET (object);
1484+}
1485Index: gnome-session/capplet/gsm-properties-dialog.h
1486===================================================================
1487--- /dev/null
1488+++ gnome-session/capplet/gsm-properties-dialog.h
1489@@ -0,0 +1,57 @@
1490+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1491+ *
1492+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
1493+ *
1494+ * This program is free software; you can redistribute it and/or modify
1495+ * it under the terms of the GNU General Public License as published by
1496+ * the Free Software Foundation; either version 2 of the License, or
1497+ * (at your option) any later version.
1498+ *
1499+ * This program is distributed in the hope that it will be useful,
1500+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1501+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1502+ * GNU General Public License for more details.
1503+ *
1504+ * You should have received a copy of the GNU General Public License
1505+ * along with this program; if not, write to the Free Software
1506+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1507+ *
1508+ */
1509+
1510+#ifndef __GSM_PROPERTIES_DIALOG_H
1511+#define __GSM_PROPERTIES_DIALOG_H
1512+
1513+#include <glib-object.h>
1514+#include <gtk/gtk.h>
1515+
1516+G_BEGIN_DECLS
1517+
1518+#define GSM_TYPE_PROPERTIES_DIALOG (gsm_properties_dialog_get_type ())
1519+#define GSM_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialog))
1520+#define GSM_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogClass))
1521+#define GSM_IS_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_PROPERTIES_DIALOG))
1522+#define GSM_IS_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_PROPERTIES_DIALOG))
1523+#define GSM_PROPERTIES_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogClass))
1524+
1525+typedef struct GsmPropertiesDialogPrivate GsmPropertiesDialogPrivate;
1526+
1527+typedef struct
1528+{
1529+ GtkDialog parent;
1530+ GsmPropertiesDialogPrivate *priv;
1531+} GsmPropertiesDialog;
1532+
1533+typedef struct
1534+{
1535+ GtkDialogClass parent_class;
1536+} GsmPropertiesDialogClass;
1537+
1538+GType gsm_properties_dialog_get_type (void);
1539+
1540+GtkWidget * gsm_properties_dialog_new (void);
1541+
1542+#define GSM_PROPERTIES_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
1543+
1544+G_END_DECLS
1545+
1546+#endif /* __GSM_PROPERTIES_DIALOG_H */
1547Index: gnome-session/capplet/gsp-app-manager.c
1548===================================================================
1549--- /dev/null
1550+++ gnome-session/capplet/gsp-app-manager.c
1551@@ -0,0 +1,593 @@
1552+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1553+ *
1554+ * Copyright (C) 1999 Free Software Foundation, Inc.
1555+ * Copyright (C) 2007, 2009 Vincent Untz.
1556+ * Copyright (C) 2008 Lucas Rocha.
1557+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
1558+ *
1559+ * This program is free software; you can redistribute it and/or modify
1560+ * it under the terms of the GNU General Public License as published by
1561+ * the Free Software Foundation; either version 2 of the License, or
1562+ * (at your option) any later version.
1563+ *
1564+ * This program is distributed in the hope that it will be useful,
1565+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1566+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1567+ * GNU General Public License for more details.
1568+ *
1569+ * You should have received a copy of the GNU General Public License
1570+ * along with this program; if not, write to the Free Software
1571+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1572+ *
1573+ */
1574+
1575+#include <string.h>
1576+
1577+#include "gsm-util.h"
1578+#include "gsp-app.h"
1579+
1580+#include "gsp-app-manager.h"
1581+
1582+static GspAppManager *manager = NULL;
1583+
1584+typedef struct {
1585+ char *dir;
1586+ int index;
1587+ GFileMonitor *monitor;
1588+} GspXdgDir;
1589+
1590+struct _GspAppManagerPrivate {
1591+ GSList *apps;
1592+ GSList *dirs;
1593+};
1594+
1595+#define GSP_APP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSP_TYPE_APP_MANAGER, GspAppManagerPrivate))
1596+
1597+
1598+enum {
1599+ ADDED,
1600+ REMOVED,
1601+ LAST_SIGNAL
1602+};
1603+
1604+static guint gsp_app_manager_signals[LAST_SIGNAL] = { 0 };
1605+
1606+
1607+G_DEFINE_TYPE (GspAppManager, gsp_app_manager, G_TYPE_OBJECT)
1608+
1609+static void gsp_app_manager_dispose (GObject *object);
1610+static void gsp_app_manager_finalize (GObject *object);
1611+static void _gsp_app_manager_app_unref (GspApp *app,
1612+ GspAppManager *manager);
1613+static void _gsp_app_manager_app_removed (GspAppManager *manager,
1614+ GspApp *app);
1615+
1616+static GspXdgDir *
1617+_gsp_xdg_dir_new (const char *dir,
1618+ int index)
1619+{
1620+ GspXdgDir *xdgdir;
1621+
1622+ xdgdir = g_slice_new (GspXdgDir);
1623+
1624+ xdgdir->dir = g_strdup (dir);
1625+ xdgdir->index = index;
1626+ xdgdir->monitor = NULL;
1627+
1628+ return xdgdir;
1629+}
1630+
1631+static void
1632+_gsp_xdg_dir_free (GspXdgDir *xdgdir)
1633+{
1634+ if (xdgdir->dir) {
1635+ g_free (xdgdir->dir);
1636+ xdgdir->dir = NULL;
1637+ }
1638+
1639+ if (xdgdir->monitor) {
1640+ g_file_monitor_cancel (xdgdir->monitor);
1641+ g_object_unref (xdgdir->monitor);
1642+ xdgdir->monitor = NULL;
1643+ }
1644+
1645+ g_slice_free (GspXdgDir, xdgdir);
1646+}
1647+
1648+static void
1649+gsp_app_manager_class_init (GspAppManagerClass *class)
1650+{
1651+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
1652+
1653+ gobject_class->dispose = gsp_app_manager_dispose;
1654+ gobject_class->finalize = gsp_app_manager_finalize;
1655+
1656+ gsp_app_manager_signals[ADDED] =
1657+ g_signal_new ("added",
1658+ G_TYPE_FROM_CLASS (gobject_class),
1659+ G_SIGNAL_RUN_LAST,
1660+ G_STRUCT_OFFSET (GspAppManagerClass,
1661+ added),
1662+ NULL,
1663+ NULL,
1664+ g_cclosure_marshal_VOID__OBJECT,
1665+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
1666+
1667+ gsp_app_manager_signals[REMOVED] =
1668+ g_signal_new ("removed",
1669+ G_TYPE_FROM_CLASS (gobject_class),
1670+ G_SIGNAL_RUN_LAST,
1671+ G_STRUCT_OFFSET (GspAppManagerClass,
1672+ removed),
1673+ NULL,
1674+ NULL,
1675+ g_cclosure_marshal_VOID__OBJECT,
1676+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
1677+
1678+ g_type_class_add_private (class, sizeof (GspAppManagerPrivate));
1679+}
1680+
1681+static void
1682+gsp_app_manager_init (GspAppManager *manager)
1683+{
1684+ manager->priv = GSP_APP_MANAGER_GET_PRIVATE (manager);
1685+
1686+ memset (manager->priv, 0, sizeof (GspAppManagerPrivate));
1687+}
1688+
1689+static void
1690+gsp_app_manager_dispose (GObject *object)
1691+{
1692+ GspAppManager *manager;
1693+
1694+ g_return_if_fail (object != NULL);
1695+ g_return_if_fail (GSP_IS_APP_MANAGER (object));
1696+
1697+ manager = GSP_APP_MANAGER (object);
1698+
1699+ /* we unref GspApp objects in dispose since they might need to
1700+ * reference us during their dispose/finalize */
1701+ g_slist_foreach (manager->priv->apps,
1702+ (GFunc) _gsp_app_manager_app_unref, manager);
1703+ g_slist_free (manager->priv->apps);
1704+ manager->priv->apps = NULL;
1705+
1706+ G_OBJECT_CLASS (gsp_app_manager_parent_class)->dispose (object);
1707+}
1708+
1709+static void
1710+gsp_app_manager_finalize (GObject *object)
1711+{
1712+ GspAppManager *manager;
1713+
1714+ g_return_if_fail (object != NULL);
1715+ g_return_if_fail (GSP_IS_APP_MANAGER (object));
1716+
1717+ manager = GSP_APP_MANAGER (object);
1718+
1719+ g_slist_foreach (manager->priv->dirs,
1720+ (GFunc) _gsp_xdg_dir_free, NULL);
1721+ g_slist_free (manager->priv->dirs);
1722+ manager->priv->dirs = NULL;
1723+
1724+ G_OBJECT_CLASS (gsp_app_manager_parent_class)->finalize (object);
1725+
1726+ manager = NULL;
1727+}
1728+
1729+static void
1730+_gsp_app_manager_emit_added (GspAppManager *manager,
1731+ GspApp *app)
1732+{
1733+ g_signal_emit (G_OBJECT (manager), gsp_app_manager_signals[ADDED],
1734+ 0, app);
1735+}
1736+
1737+static void
1738+_gsp_app_manager_emit_removed (GspAppManager *manager,
1739+ GspApp *app)
1740+{
1741+ g_signal_emit (G_OBJECT (manager), gsp_app_manager_signals[REMOVED],
1742+ 0, app);
1743+}
1744+
1745+/*
1746+ * Directories
1747+ */
1748+
1749+static int
1750+gsp_app_manager_get_dir_index (GspAppManager *manager,
1751+ const char *dir)
1752+{
1753+ GSList *l;
1754+ GspXdgDir *xdgdir;
1755+
1756+ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), -1);
1757+ g_return_val_if_fail (dir != NULL, -1);
1758+
1759+ for (l = manager->priv->dirs; l != NULL; l = l->next) {
1760+ xdgdir = l->data;
1761+ if (strcmp (dir, xdgdir->dir) == 0) {
1762+ return xdgdir->index;
1763+ }
1764+ }
1765+
1766+ return -1;
1767+}
1768+
1769+const char *
1770+gsp_app_manager_get_dir (GspAppManager *manager,
1771+ unsigned int index)
1772+{
1773+ GSList *l;
1774+ GspXdgDir *xdgdir;
1775+
1776+ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
1777+
1778+ for (l = manager->priv->dirs; l != NULL; l = l->next) {
1779+ xdgdir = l->data;
1780+ if (index == xdgdir->index) {
1781+ return xdgdir->dir;
1782+ }
1783+ }
1784+
1785+ return NULL;
1786+}
1787+
1788+static int
1789+_gsp_app_manager_find_dir_with_basename (GspAppManager *manager,
1790+ const char *basename,
1791+ int minimum_index)
1792+{
1793+ GSList *l;
1794+ GspXdgDir *xdgdir;
1795+ char *path;
1796+ GKeyFile *keyfile;
1797+ int result = -1;
1798+
1799+ path = NULL;
1800+ keyfile = g_key_file_new ();
1801+
1802+ for (l = manager->priv->dirs; l != NULL; l = l->next) {
1803+ xdgdir = l->data;
1804+
1805+ if (xdgdir->index <= minimum_index) {
1806+ continue;
1807+ }
1808+
1809+ g_free (path);
1810+ path = g_build_filename (xdgdir->dir, basename, NULL);
1811+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
1812+ continue;
1813+ }
1814+
1815+ if (!g_key_file_load_from_file (keyfile, path,
1816+ G_KEY_FILE_NONE, NULL)) {
1817+ continue;
1818+ }
1819+
1820+ /* the file exists and is readable */
1821+ if (result == -1) {
1822+ result = xdgdir->index;
1823+ } else {
1824+ result = MIN (result, xdgdir->index);
1825+ }
1826+ }
1827+
1828+ g_key_file_free (keyfile);
1829+ g_free (path);
1830+
1831+ return result;
1832+}
1833+
1834+static void
1835+_gsp_app_manager_handle_delete (GspAppManager *manager,
1836+ GspApp *app,
1837+ const char *basename,
1838+ int index)
1839+{
1840+ unsigned int position;
1841+ unsigned int system_position;
1842+
1843+ position = gsp_app_get_xdg_position (app);
1844+ system_position = gsp_app_get_xdg_system_position (app);
1845+
1846+ if (system_position < index) {
1847+ /* it got deleted, but we don't even care about it */
1848+ return;
1849+ }
1850+
1851+ if (index < position) {
1852+ /* it got deleted, but in a position earlier than the current
1853+ * one. This happens when the user file was changed and became
1854+ * identical to the system file; in this case, the user file is
1855+ * simply removed. */
1856+ g_assert (index == 0);
1857+ return;
1858+ }
1859+
1860+ if (position == index &&
1861+ (system_position == index || system_position == G_MAXUINT)) {
1862+ /* the file used by the user was deleted, and there's no other
1863+ * file in system directories. So it really got deleted. */
1864+ _gsp_app_manager_app_removed (manager, app);
1865+ return;
1866+ }
1867+
1868+ if (system_position == index) {
1869+ /* then we know that position != index; we just hae to tell
1870+ * GspApp if there's still a system directory containing this
1871+ * basename */
1872+ int new_system;
1873+
1874+ new_system = _gsp_app_manager_find_dir_with_basename (manager,
1875+ basename,
1876+ index);
1877+ if (new_system < 0) {
1878+ gsp_app_set_xdg_system_position (app, G_MAXUINT);
1879+ } else {
1880+ gsp_app_set_xdg_system_position (app, new_system);
1881+ }
1882+
1883+ return;
1884+ }
1885+
1886+ if (position == index) {
1887+ /* then we know that system_position != G_MAXUINT; we need to
1888+ * tell GspApp to change position to system_position */
1889+ const char *dir;
1890+
1891+ dir = gsp_app_manager_get_dir (manager, system_position);
1892+ if (dir) {
1893+ char *path;
1894+
1895+ path = g_build_filename (dir, basename, NULL);
1896+ gsp_app_reload_at (app, path,
1897+ (unsigned int) system_position);
1898+ g_free (path);
1899+ } else {
1900+ _gsp_app_manager_app_removed (manager, app);
1901+ }
1902+
1903+ return;
1904+ }
1905+
1906+ g_assert_not_reached ();
1907+}
1908+
1909+static gboolean
1910+gsp_app_manager_xdg_dir_monitor (GFileMonitor *monitor,
1911+ GFile *child,
1912+ GFile *other_file,
1913+ GFileMonitorEvent flags,
1914+ gpointer data)
1915+{
1916+ GspAppManager *manager;
1917+ GspApp *old_app;
1918+ GspApp *app;
1919+ GFile *parent;
1920+ char *basename;
1921+ char *dir;
1922+ char *path;
1923+ int index;
1924+
1925+ manager = GSP_APP_MANAGER (data);
1926+
1927+ basename = g_file_get_basename (child);
1928+ if (!g_str_has_suffix (basename, ".desktop")) {
1929+ /* not a desktop file, we can ignore */
1930+ g_free (basename);
1931+ return TRUE;
1932+ }
1933+ old_app = gsp_app_manager_find_app_with_basename (manager, basename);
1934+
1935+ parent = g_file_get_parent (child);
1936+ dir = g_file_get_path (parent);
1937+ g_object_unref (parent);
1938+
1939+ index = gsp_app_manager_get_dir_index (manager, dir);
1940+ if (index < 0) {
1941+ /* not a directory we know; should never happen, though */
1942+ g_free (dir);
1943+ return TRUE;
1944+ }
1945+
1946+ path = g_file_get_path (child);
1947+
1948+ switch (flags) {
1949+ case G_FILE_MONITOR_EVENT_CHANGED:
1950+ case G_FILE_MONITOR_EVENT_CREATED:
1951+ /* we just do as if it was a new file: GspApp is clever enough
1952+ * to do the right thing */
1953+ app = gsp_app_new (path, (unsigned int) index);
1954+
1955+ /* we didn't have this app before, so add it */
1956+ if (old_app == NULL && app != NULL) {
1957+ gsp_app_manager_add (manager, app);
1958+ g_object_unref (app);
1959+ }
1960+ /* else: it was just updated, GspApp took care of
1961+ * sending the event */
1962+ break;
1963+ case G_FILE_MONITOR_EVENT_DELETED:
1964+ if (!old_app) {
1965+ /* it got deleted, but we don't know about it, so
1966+ * nothing to do */
1967+ break;
1968+ }
1969+
1970+ _gsp_app_manager_handle_delete (manager, old_app,
1971+ basename, index);
1972+ break;
1973+ default:
1974+ break;
1975+ }
1976+
1977+ g_free (path);
1978+ g_free (dir);
1979+ g_free (basename);
1980+
1981+ return TRUE;
1982+}
1983+
1984+/*
1985+ * Initialization
1986+ */
1987+
1988+static void
1989+_gsp_app_manager_fill_from_dir (GspAppManager *manager,
1990+ GspXdgDir *xdgdir)
1991+{
1992+ GFile *file;
1993+ GDir *dir;
1994+ const char *name;
1995+
1996+ file = g_file_new_for_path (xdgdir->dir);
1997+ xdgdir->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE,
1998+ NULL, NULL);
1999+ g_object_unref (file);
2000+
2001+ if (xdgdir->monitor) {
2002+ g_signal_connect (xdgdir->monitor, "changed",
2003+ G_CALLBACK (gsp_app_manager_xdg_dir_monitor),
2004+ manager);
2005+ }
2006+
2007+ dir = g_dir_open (xdgdir->dir, 0, NULL);
2008+ if (!dir) {
2009+ return;
2010+ }
2011+
2012+ while ((name = g_dir_read_name (dir))) {
2013+ GspApp *app;
2014+ char *desktop_file_path;
2015+
2016+ if (!g_str_has_suffix (name, ".desktop")) {
2017+ continue;
2018+ }
2019+
2020+ desktop_file_path = g_build_filename (xdgdir->dir, name, NULL);
2021+ app = gsp_app_new (desktop_file_path, xdgdir->index);
2022+
2023+ if (app != NULL) {
2024+ gsp_app_manager_add (manager, app);
2025+ g_object_unref (app);
2026+ }
2027+
2028+ g_free (desktop_file_path);
2029+ }
2030+
2031+ g_dir_close (dir);
2032+}
2033+
2034+void
2035+gsp_app_manager_fill (GspAppManager *manager)
2036+{
2037+ char **autostart_dirs;
2038+ int i;
2039+
2040+ if (manager->priv->apps != NULL)
2041+ return;
2042+
2043+ autostart_dirs = gsm_util_get_autostart_dirs ();
2044+ /* we always assume that the first directory is the user one */
2045+ g_assert (g_str_has_prefix (autostart_dirs[0],
2046+ g_get_user_config_dir ()));
2047+
2048+ for (i = 0; autostart_dirs[i] != NULL; i++) {
2049+ GspXdgDir *xdgdir;
2050+
2051+ if (gsp_app_manager_get_dir_index (manager,
2052+ autostart_dirs[i]) >= 0) {
2053+ continue;
2054+ }
2055+
2056+ xdgdir = _gsp_xdg_dir_new (autostart_dirs[i], i);
2057+ manager->priv->dirs = g_slist_prepend (manager->priv->dirs,
2058+ xdgdir);
2059+
2060+ _gsp_app_manager_fill_from_dir (manager, xdgdir);
2061+ }
2062+
2063+ g_strfreev (autostart_dirs);
2064+}
2065+
2066+/*
2067+ * App handling
2068+ */
2069+
2070+static void
2071+_gsp_app_manager_app_unref (GspApp *app,
2072+ GspAppManager *manager)
2073+{
2074+ g_signal_handlers_disconnect_by_func (app,
2075+ _gsp_app_manager_app_removed,
2076+ manager);
2077+ g_object_unref (app);
2078+}
2079+
2080+static void
2081+_gsp_app_manager_app_removed (GspAppManager *manager,
2082+ GspApp *app)
2083+{
2084+ _gsp_app_manager_emit_removed (manager, app);
2085+ manager->priv->apps = g_slist_remove (manager->priv->apps, app);
2086+ _gsp_app_manager_app_unref (app, manager);
2087+}
2088+
2089+void
2090+gsp_app_manager_add (GspAppManager *manager,
2091+ GspApp *app)
2092+{
2093+ g_return_if_fail (GSP_IS_APP_MANAGER (manager));
2094+ g_return_if_fail (GSP_IS_APP (app));
2095+
2096+ manager->priv->apps = g_slist_prepend (manager->priv->apps,
2097+ g_object_ref (app));
2098+ g_signal_connect_swapped (app, "removed",
2099+ G_CALLBACK (_gsp_app_manager_app_removed),
2100+ manager);
2101+ _gsp_app_manager_emit_added (manager, app);
2102+}
2103+
2104+GspApp *
2105+gsp_app_manager_find_app_with_basename (GspAppManager *manager,
2106+ const char *basename)
2107+{
2108+ GSList *l;
2109+ GspApp *app;
2110+
2111+ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
2112+ g_return_val_if_fail (basename != NULL, NULL);
2113+
2114+ for (l = manager->priv->apps; l != NULL; l = l->next) {
2115+ app = GSP_APP (l->data);
2116+ if (strcmp (basename, gsp_app_get_basename (app)) == 0)
2117+ return app;
2118+ }
2119+
2120+ return NULL;
2121+}
2122+
2123+/*
2124+ * Singleton
2125+ */
2126+
2127+GspAppManager *
2128+gsp_app_manager_get (void)
2129+{
2130+ if (manager == NULL) {
2131+ manager = g_object_new (GSP_TYPE_APP_MANAGER, NULL);
2132+ return manager;
2133+ } else {
2134+ return g_object_ref (manager);
2135+ }
2136+}
2137+
2138+GSList *
2139+gsp_app_manager_get_apps (GspAppManager *manager)
2140+{
2141+ g_return_val_if_fail (GSP_IS_APP_MANAGER (manager), NULL);
2142+
2143+ return g_slist_copy (manager->priv->apps);
2144+}
2145Index: gnome-session/capplet/gsp-app-manager.h
2146===================================================================
2147--- /dev/null
2148+++ gnome-session/capplet/gsp-app-manager.h
2149@@ -0,0 +1,81 @@
2150+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2151+ *
2152+ * Copyright (C) 1999 Free Software Foundation, Inc.
2153+ * Copyright (C) 2007, 2009 Vincent Untz.
2154+ * Copyright (C) 2008 Lucas Rocha.
2155+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
2156+ *
2157+ * This program is free software; you can redistribute it and/or modify
2158+ * it under the terms of the GNU General Public License as published by
2159+ * the Free Software Foundation; either version 2 of the License, or
2160+ * (at your option) any later version.
2161+ *
2162+ * This program is distributed in the hope that it will be useful,
2163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2165+ * GNU General Public License for more details.
2166+ *
2167+ * You should have received a copy of the GNU General Public License
2168+ * along with this program; if not, write to the Free Software
2169+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2170+ *
2171+ */
2172+
2173+#ifndef __GSP_APP_MANAGER_H
2174+#define __GSP_APP_MANAGER_H
2175+
2176+#include <glib-object.h>
2177+
2178+#include <gsp-app.h>
2179+
2180+G_BEGIN_DECLS
2181+
2182+#define GSP_TYPE_APP_MANAGER (gsp_app_manager_get_type ())
2183+#define GSP_APP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSP_TYPE_APP_MANAGER, GspAppManager))
2184+#define GSP_APP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSP_TYPE_APP_MANAGER, GspAppManagerClass))
2185+#define GSP_IS_APP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSP_TYPE_APP_MANAGER))
2186+#define GSP_IS_APP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSP_TYPE_APP_MANAGER))
2187+#define GSP_APP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSP_TYPE_APP_MANAGER, GspAppManagerClass))
2188+
2189+typedef struct _GspAppManager GspAppManager;
2190+typedef struct _GspAppManagerClass GspAppManagerClass;
2191+
2192+typedef struct _GspAppManagerPrivate GspAppManagerPrivate;
2193+
2194+struct _GspAppManagerClass
2195+{
2196+ GObjectClass parent_class;
2197+
2198+ void (* added) (GspAppManager *manager,
2199+ GspApp *app);
2200+ void (* removed) (GspAppManager *manager,
2201+ GspApp *app);
2202+};
2203+
2204+struct _GspAppManager
2205+{
2206+ GObject parent_instance;
2207+
2208+ GspAppManagerPrivate *priv;
2209+};
2210+
2211+GType gsp_app_manager_get_type (void);
2212+
2213+GspAppManager *gsp_app_manager_get (void);
2214+
2215+void gsp_app_manager_fill (GspAppManager *manager);
2216+
2217+GSList *gsp_app_manager_get_apps (GspAppManager *manager);
2218+
2219+GspApp *gsp_app_manager_find_app_with_basename (GspAppManager *manager,
2220+ const char *basename);
2221+
2222+const char *gsp_app_manager_get_dir (GspAppManager *manager,
2223+ unsigned int index);
2224+
2225+void gsp_app_manager_add (GspAppManager *manager,
2226+ GspApp *app);
2227+
2228+G_END_DECLS
2229+
2230+#endif /* __GSP_APP_MANAGER_H */
2231Index: gnome-session/capplet/gsp-app.c
2232===================================================================
2233--- /dev/null
2234+++ gnome-session/capplet/gsp-app.c
2235@@ -0,0 +1,1129 @@
2236+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2237+ *
2238+ * Copyright (C) 1999 Free Software Foundation, Inc.
2239+ * Copyright (C) 2007, 2009 Vincent Untz.
2240+ * Copyright (C) 2008 Lucas Rocha.
2241+ * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
2242+ *
2243+ * This program is free software; you can redistribute it and/or modify
2244+ * it under the terms of the GNU General Public License as published by
2245+ * the Free Software Foundation; either version 2 of the License, or
2246+ * (at your option) any later version.
2247+ *
2248+ * This program is distributed in the hope that it will be useful,
2249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2251+ * GNU General Public License for more details.
2252+ *
2253+ * You should have received a copy of the GNU General Public License
2254+ * along with this program; if not, write to the Free Software
2255+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2256+ *
2257+ */
2258+
2259+#ifdef HAVE_CONFIG_H
2260+#include <config.h>
2261+#endif
2262+
2263+#include <string.h>
2264+#include <sys/stat.h>
2265+
2266+#include <glib/gi18n.h>
2267+#include <glib/gstdio.h>
2268+
2269+#include "gsm-app-dialog.h"
2270+#include "gsm-properties-dialog.h"
2271+#include "gsm-util.h"
2272+#include "gsp-app-manager.h"
2273+#include "gsp-keyfile.h"
2274+
2275+#include "gsp-app.h"
2276+
2277+#define GSP_APP_SAVE_DELAY 2
2278+
2279+#define GSP_ASP_SAVE_MASK_HIDDEN 0x0001
2280+#define GSP_ASP_SAVE_MASK_ENABLED 0x0002
2281+#define GSP_ASP_SAVE_MASK_NAME 0x0004
2282+#define GSP_ASP_SAVE_MASK_EXEC 0x0008
2283+#define GSP_ASP_SAVE_MASK_COMMENT 0x0010
2284+#define GSP_ASP_SAVE_MASK_NO_DISPLAY 0x0020
2285+#define GSP_ASP_SAVE_MASK_ALL 0xffff
2286+
2287+struct _GspAppPrivate {
2288+ char *basename;
2289+ char *path;
2290+
2291+ gboolean hidden;
2292+ gboolean no_display;
2293+ gboolean enabled;
2294+ gboolean shown;
2295+
2296+ char *name;
2297+ char *exec;
2298+ char *comment;
2299+ char *icon;
2300+
2301+ GIcon *gicon;
2302+ char *description;
2303+
2304+ /* position of the directory in the XDG environment variable */
2305+ unsigned int xdg_position;
2306+ /* position of the first system directory in the XDG env var containing
2307+ * this autostart app too (G_MAXUINT means none) */
2308+ unsigned int xdg_system_position;
2309+
2310+ unsigned int save_timeout;
2311+ /* mask of what has changed */
2312+ unsigned int save_mask;
2313+ /* path that contains the original file that needs to be saved */
2314+ char *old_system_path;
2315+ /* after writing to file, we skip the next file monitor event of type
2316+ * CHANGED */
2317+ gboolean skip_next_monitor_event;
2318+};
2319+
2320+#define GSP_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSP_TYPE_APP, GspAppPrivate))
2321+
2322+
2323+enum {
2324+ CHANGED,
2325+ REMOVED,
2326+ LAST_SIGNAL
2327+};
2328+
2329+static guint gsp_app_signals[LAST_SIGNAL] = { 0 };
2330+
2331+
2332+G_DEFINE_TYPE (GspApp, gsp_app, G_TYPE_OBJECT)
2333+
2334+static void gsp_app_dispose (GObject *object);
2335+static void gsp_app_finalize (GObject *object);
2336+static gboolean _gsp_app_save (gpointer data);
2337+
2338+
2339+static gboolean
2340+_gsp_str_equal (const char *a,
2341+ const char *b)
2342+{
2343+ if (g_strcmp0 (a, b) == 0) {
2344+ return TRUE;
2345+ }
2346+
2347+ if (a && !b && a[0] == '\0') {
2348+ return TRUE;
2349+ }
2350+
2351+ if (b && !a && b[0] == '\0') {
2352+ return TRUE;
2353+ }
2354+
2355+ return FALSE;
2356+}
2357+
2358+
2359+static void
2360+gsp_app_class_init (GspAppClass *class)
2361+{
2362+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
2363+
2364+ gobject_class->dispose = gsp_app_dispose;
2365+ gobject_class->finalize = gsp_app_finalize;
2366+
2367+ gsp_app_signals[CHANGED] =
2368+ g_signal_new ("changed",
2369+ G_TYPE_FROM_CLASS (gobject_class),
2370+ G_SIGNAL_RUN_LAST,
2371+ G_STRUCT_OFFSET (GspAppClass,
2372+ changed),
2373+ NULL,
2374+ NULL,
2375+ g_cclosure_marshal_VOID__VOID,
2376+ G_TYPE_NONE, 0);
2377+
2378+ gsp_app_signals[REMOVED] =
2379+ g_signal_new ("removed",
2380+ G_TYPE_FROM_CLASS (gobject_class),
2381+ G_SIGNAL_RUN_LAST,
2382+ G_STRUCT_OFFSET (GspAppClass,
2383+ removed),
2384+ NULL,
2385+ NULL,
2386+ g_cclosure_marshal_VOID__VOID,
2387+ G_TYPE_NONE, 0);
2388+
2389+ g_type_class_add_private (class, sizeof (GspAppPrivate));
2390+}
2391+
2392+static void
2393+gsp_app_init (GspApp *app)
2394+{
2395+ app->priv = GSP_APP_GET_PRIVATE (app);
2396+
2397+ memset (app->priv, 0, sizeof (GspAppPrivate));
2398+ app->priv->xdg_position = G_MAXUINT;
2399+ app->priv->xdg_system_position = G_MAXUINT;
2400+}
2401+
2402+static void
2403+_gsp_app_free_reusable_data (GspApp *app)
2404+{
2405+ if (app->priv->path) {
2406+ g_free (app->priv->path);
2407+ app->priv->path = NULL;
2408+ }
2409+
2410+ if (app->priv->name) {
2411+ g_free (app->priv->name);
2412+ app->priv->name = NULL;
2413+ }
2414+
2415+ if (app->priv->exec) {
2416+ g_free (app->priv->exec);
2417+ app->priv->exec = NULL;
2418+ }
2419+
2420+ if (app->priv->comment) {
2421+ g_free (app->priv->comment);
2422+ app->priv->comment = NULL;
2423+ }
2424+
2425+ if (app->priv->icon) {
2426+ g_free (app->priv->icon);
2427+ app->priv->icon = NULL;
2428+ }
2429+
2430+ if (app->priv->gicon) {
2431+ g_object_unref (app->priv->gicon);
2432+ app->priv->gicon = NULL;
2433+ }
2434+
2435+ if (app->priv->description) {
2436+ g_free (app->priv->description);
2437+ app->priv->description = NULL;
2438+ }
2439+
2440+ if (app->priv->old_system_path) {
2441+ g_free (app->priv->old_system_path);
2442+ app->priv->old_system_path = NULL;
2443+ }
2444+}
2445+
2446+static void
2447+gsp_app_dispose (GObject *object)
2448+{
2449+ GspApp *app;
2450+
2451+ g_return_if_fail (object != NULL);
2452+ g_return_if_fail (GSP_IS_APP (object));
2453+
2454+ app = GSP_APP (object);
2455+
2456+ /* we save in dispose since we might need to reference GspAppManager */
2457+ if (app->priv->save_timeout) {
2458+ g_source_remove (app->priv->save_timeout);
2459+ app->priv->save_timeout = 0;
2460+
2461+ /* save now */
2462+ _gsp_app_save (app);
2463+ }
2464+
2465+ G_OBJECT_CLASS (gsp_app_parent_class)->dispose (object);
2466+}
2467+
2468+static void
2469+gsp_app_finalize (GObject *object)
2470+{
2471+ GspApp *app;
2472+
2473+ g_return_if_fail (object != NULL);
2474+ g_return_if_fail (GSP_IS_APP (object));
2475+
2476+ app = GSP_APP (object);
2477+
2478+ if (app->priv->basename) {
2479+ g_free (app->priv->basename);
2480+ app->priv->basename = NULL;
2481+ }
2482+
2483+ _gsp_app_free_reusable_data (app);
2484+
2485+ G_OBJECT_CLASS (gsp_app_parent_class)->finalize (object);
2486+}
2487+
2488+static void
2489+_gsp_app_emit_changed (GspApp *app)
2490+{
2491+ g_signal_emit (G_OBJECT (app), gsp_app_signals[CHANGED], 0);
2492+}
2493+
2494+static void
2495+_gsp_app_emit_removed (GspApp *app)
2496+{
2497+ g_signal_emit (G_OBJECT (app), gsp_app_signals[REMOVED], 0);
2498+}
2499+
2500+static void
2501+_gsp_app_update_description (GspApp *app)
2502+{
2503+ const char *primary;
2504+ const char *secondary;
2505+
2506+ if (!gsm_util_text_is_blank (app->priv->name)) {
2507+ primary = app->priv->name;
2508+ } else if (!gsm_util_text_is_blank (app->priv->exec)) {
2509+ primary = app->priv->exec;
2510+ } else {
2511+ primary = _("No name");
2512+ }
2513+
2514+ if (!gsm_util_text_is_blank (app->priv->comment)) {
2515+ secondary = app->priv->comment;
2516+ } else {
2517+ secondary = _("No description");
2518+ }
2519+
2520+ g_free (app->priv->description);
2521+ app->priv->description = g_markup_printf_escaped ("<b>%s</b>\n%s",
2522+ primary,
2523+ secondary);
2524+}
2525+
2526+/*
2527+ * Saving
2528+ */
2529+
2530+static void
2531+_gsp_ensure_user_autostart_dir (void)
2532+{
2533+ char *dir;
2534+
2535+ dir = g_build_filename (g_get_user_config_dir (), "autostart", NULL);
2536+ g_mkdir_with_parents (dir, S_IRWXU);
2537+
2538+ g_free (dir);
2539+}
2540+
2541+static char *
2542+_gsp_get_current_desktop ()
2543+{
2544+ static char *current_desktop = NULL;
2545+
2546+ /* Support XDG_CURRENT_DESKTOP environment variable; this can be used
2547+ * to abuse gnome-session in non-GNOME desktops. */
2548+ if (!current_desktop) {
2549+ const char *desktop;
2550+
2551+ desktop = g_getenv ("XDG_CURRENT_DESKTOP");
2552+
2553+ /* Note: if XDG_CURRENT_DESKTOP is set but empty, do as if it
2554+ * was not set */
2555+ if (!desktop || desktop[0] == '\0')
2556+ current_desktop = g_strdup ("GNOME");
2557+ else
2558+ current_desktop = g_strdup (desktop);
2559+ }
2560+
2561+ /* Using "*" means skipping desktop-related checks */
2562+ if (g_strcmp0 (current_desktop, "*") == 0)
2563+ return NULL;
2564+
2565+ return current_desktop;
2566+}
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: