Merge lp:~3v1n0/libappindicator/discord-indicator-crash-fix into lp:libappindicator/16.10

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~3v1n0/libappindicator/discord-indicator-crash-fix
Merge into: lp:libappindicator/16.10
Diff against target: 1792 lines (+1068/-153)
13 files modified
bindings/Makefile.am (+3/-6)
configure.ac (+3/-33)
debian/changelog (+88/-0)
debian/control (+12/-41)
debian/libappindicator-dev.install (+0/-2)
debian/rules (+5/-23)
docs/reference/Makefile.am (+1/-1)
example/simple-client-vala.vala (+1/-1)
src/Makefile.am (+13/-17)
src/app-indicator.c (+149/-21)
src/indicator-desktop-shortcuts.c (+705/-0)
src/indicator-desktop-shortcuts.h (+80/-0)
tests/Makefile.am (+8/-8)
To merge this branch: bzr merge lp:~3v1n0/libappindicator/discord-indicator-crash-fix
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Review via email: mp+381930@code.launchpad.net

This proposal has been superseded by a proposal from 2020-04-08.

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :
review: Approve
294. By William Grant

Disable mono on riscv64 too

295. By Paul G <Unknown>

app-indicator: Don't pass unexpected parameter to signal emissions

cleaned up all g_signal_emit and g_signal_new calls so they correspond with
each other and make sense.

No external API changes.

LP: #1867996

296. By Ash Holland <Unknown>

app-indicator: Only check for item numbers when iterating array

297. By Marco Trevisan (Treviño)

Update changelog

Unmerged revisions

297. By Marco Trevisan (Treviño)

Update changelog

296. By Ash Holland <Unknown>

app-indicator: Only check for item numbers when iterating array

295. By Paul G <Unknown>

app-indicator: Don't pass unexpected parameter to signal emissions

cleaned up all g_signal_emit and g_signal_new calls so they correspond with
each other and make sense.

No external API changes.

LP: #1867996

294. By William Grant

Disable mono on riscv64 too

293. By Sebastien Bacher

releasing package libappindicator version 12.10.1+18.04.20180322.1-0ubuntu5

292. By Jeremy Bícha

Drop python-appindicator and gir1.2-appindicator-0.1 packages
(LP: #1740637)

291. By Sebastien Bacher

releasing package libappindicator version 12.10.1+18.04.20180322.1-0ubuntu4

290. By Dimitri John Ledkov

releasing package libappindicator version 12.10.1+18.04.20180322.1-0ubuntu2

289. By Dimitri John Ledkov

Vendorize indicator-desktop-shortcuts (convenience wrapper around
gdesktopappinfo) from libindicator project, to drop the dependency on
libindicator as none of the rest of it is used.

288. By CI Train Bot Account

Releasing 12.10.1+18.04.20180322.1-0ubuntu1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bindings/Makefile.am'
2--- bindings/Makefile.am 2012-06-10 07:32:04 +0000
3+++ bindings/Makefile.am 2020-04-08 18:54:42 +0000
4@@ -1,10 +1,7 @@
5+SUBDIRS =
6+
7 if USE_GTK3
8-SUBDIRS = \
9- vala
10-else
11-SUBDIRS = \
12- python \
13- vala
14+SUBDIRS += vala
15 endif
16
17 if HAS_MONO
18
19=== removed directory 'bindings/python'
20=== removed file 'bindings/python/Makefile.am'
21=== removed file 'bindings/python/__init__.py'
22=== removed file 'bindings/python/appindicator-arg-types.py'
23=== removed file 'bindings/python/appindicator.defs'
24=== removed file 'bindings/python/appindicator.override.in'
25=== removed file 'bindings/python/appindicatormodule.c'
26=== modified file 'configure.ac'
27--- configure.ac 2013-01-29 17:50:13 +0000
28+++ configure.ac 2020-04-08 18:54:42 +0000
29@@ -44,7 +44,6 @@
30 GTK3_REQUIRED_VERSION=2.91
31 GLIB_REQUIRED_VERSION=2.35.4
32 GIO_REQUIRED_VERSION=2.26
33-INDICATOR_REQUIRED_VERSION=0.4.93
34 DBUSMENUGTK_REQUIRED_VERSION=0.5.90
35 DBUS_GLIB_REQUIRED_VERSION=0.82
36
37@@ -56,16 +55,16 @@
38 AS_IF([test "x$with_gtk" = x3],
39 [PKG_CHECK_MODULES(LIBRARY, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
40 glib-2.0 >= $GLIB_REQUIRED_VERSION
41+ gio-unix-2.0
42 gio-2.0 >= $GIO_REQUIRED_VERSION
43- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION
44 dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
45 AC_DEFINE(HAVE_GTK3, 1, [whether gtk3 is available])
46 ],
47 [test "x$with_gtk" = x2],
48 [PKG_CHECK_MODULES(LIBRARY, gtk+-2.0 >= $GTK_REQUIRED_VERSION
49 glib-2.0 >= $GLIB_REQUIRED_VERSION
50+ gio-unix-2.0
51 gio-2.0 >= $GIO_REQUIRED_VERSION
52- indicator-0.4 >= $INDICATOR_REQUIRED_VERSION
53 dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
54 ],
55 [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])]
56@@ -121,7 +120,7 @@
57 RUNTIME=mono
58 fi
59
60- AC_PATH_PROG(CSC, gmcs, no)
61+ AC_PATH_PROG(CSC, mono-csc, no)
62 LIB_PREFIX=.so
63 LIB_SUFFIX=
64 fi
65@@ -181,33 +180,6 @@
66 with_localinstall="no"
67 AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all of the files localy instead of system directories (for distcheck)]), with_localinstall=$enableval, with_localinstall=no)
68
69-###########################
70-# Python
71-###########################
72-
73-PYGTK_REQUIRED=2.14.0
74-PYGOBJECT_REQUIRED=0.22
75-
76-AM_PATH_PYTHON(2.3.5)
77-AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
78-
79-PKG_CHECK_MODULES(APPINDICATOR_PYTHON,
80- [
81- pygtk-2.0 >= $PYGTK_REQUIRED
82- gtk+-2.0 >= $GTK_REQUIRED_VERSION
83- pygobject-2.0 >= $PYGOBJECT_REQUIRED
84- ])
85-
86-AC_MSG_CHECKING(for pygtk defs)
87-PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
88-AC_SUBST(PYGTK_DEFSDIR)
89-AC_MSG_RESULT($PYGTK_DEFSDIR)
90-
91-AC_MSG_CHECKING(for pygtk codegen)
92-PYGTK_CODEGEN="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/codegen.py"
93-AC_SUBST(PYGTK_CODEGEN)
94-AC_MSG_RESULT($PYGTK_CODEGEN)
95-
96 #########################
97 # Check if build tests
98 #########################
99@@ -239,8 +211,6 @@
100 src/appindicator-0.1.pc
101 src/appindicator3-0.1.pc
102 bindings/Makefile
103-bindings/python/Makefile
104-bindings/python/appindicator.override
105 bindings/vala/Makefile
106 bindings/vala/examples/Makefile
107 tests/Makefile
108
109=== modified file 'debian/changelog'
110--- debian/changelog 2016-09-05 18:32:14 +0000
111+++ debian/changelog 2020-04-08 18:54:42 +0000
112@@ -1,3 +1,91 @@
113+libappindicator (12.10.1+18.04.20180322.1-0ubuntu7) UNRELEASED; urgency=medium
114+
115+ [ Paul G ]
116+ * app-indicator: Don't pass unexpected parameter to signal emissions
117+ (LP: #1867996)
118+
119+ [ Ash Holland ]
120+ * app-indicator: Only check for item numbers when iterating array
121+ (LP: #1867996)
122+
123+ -- Marco Trevisan (Treviño) <marco@ubuntu.com> Wed, 08 Apr 2020 17:55:12 +0200
124+
125+libappindicator (12.10.1+18.04.20180322.1-0ubuntu6) focal; urgency=medium
126+
127+ * Disable mono on riscv64 too.
128+
129+ -- William Grant <wgrant@ubuntu.com> Mon, 06 Apr 2020 18:15:21 +1000
130+
131+libappindicator (12.10.1+18.04.20180322.1-0ubuntu5) focal; urgency=medium
132+
133+ * configure.ac: require gio-unix-2.0, it's need for gdesktopappinfo
134+ which was added in one of the recent uploads
135+
136+ [ Jeremy Bicha ]
137+ * Drop python-appindicator and gir1.2-appindicator-0.1 packages
138+ (LP: #1740637)
139+
140+ -- Sebastien Bacher <seb128@ubuntu.com> Tue, 17 Dec 2019 15:36:01 +0100
141+
142+libappindicator (12.10.1+18.04.20180322.1-0ubuntu4) eoan; urgency=medium
143+
144+ * Don't build with -Werror.
145+ * Drop hard coded dependency on multiarch-support.
146+
147+ -- Matthias Klose <doko@ubuntu.com> Sun, 01 Sep 2019 05:58:07 +0200
148+
149+libappindicator (12.10.1+18.04.20180322.1-0ubuntu2) disco; urgency=medium
150+
151+ * Vendorize indicator-desktop-shortcuts (convenience wrapper around
152+ gdesktopappinfo) from libindicator project, to drop the dependency on
153+ libindicator as none of the rest of it is used.
154+
155+ -- Dimitri John Ledkov <xnox@ubuntu.com> Thu, 21 Feb 2019 00:40:40 +0100
156+
157+libappindicator (12.10.1+18.04.20180322.1-0ubuntu1) bionic; urgency=medium
158+
159+ [ Unit 193 ]
160+ * Have -dev package depend on libgtk2.0-dev or libgk-3-dev according
161+ to its pkgconfig file (LP: #1757574) (LP: #1757574)
162+
163+ -- Jeremy Bicha <jbicha@ubuntu.com> Thu, 22 Mar 2018 01:16:11 +0000
164+
165+libappindicator (12.10.1+18.04.20180320-0ubuntu1) bionic; urgency=medium
166+
167+ [ Olivier Tilloy ]
168+ * Fix build failures on bionic, (LP: #1757121)
169+
170+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 20 Mar 2018 12:48:14 +0000
171+
172+libappindicator (12.10.1+17.04.20170215-0ubuntu2) artful; urgency=medium
173+
174+ * debian/control:
175+ - Downgrade libappindicator* recommending the indicator-application
176+ service to suggests. Only some sessions wants it, while we still
177+ link against the lib in multiple apps.
178+
179+ -- Didier Roche <didrocks@ubuntu.com> Wed, 19 Jul 2017 13:28:58 +0200
180+
181+libappindicator (12.10.1+17.04.20170215-0ubuntu1) zesty; urgency=medium
182+
183+ * app-indicator: don't append the snap prefix if the icon is saved in
184+ a well known readable path
185+
186+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Wed, 15 Feb 2017 14:16:09 +0000
187+
188+libappindicator (12.10.1+17.04.20170213-0ubuntu1) zesty; urgency=medium
189+
190+ * AppIndicator: don't emit label cahanges when guide is still empty
191+
192+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Mon, 13 Feb 2017 17:16:38 +0000
193+
194+libappindicator (12.10.1+17.04.20161129-0ubuntu1) zesty; urgency=medium
195+
196+ * AppIndicator: fix icon and theme paths when running in $SNAP
197+ environment (LP: #1600136)
198+
199+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 29 Nov 2016 18:04:06 +0000
200+
201 libappindicator (12.10.1+16.10.20160905-0ubuntu1) yakkety; urgency=medium
202
203 [ Alberts Muktupāvels ]
204
205=== modified file 'debian/control'
206--- debian/control 2013-12-19 14:37:54 +0000
207+++ debian/control 2020-04-08 18:54:42 +0000
208@@ -1,31 +1,27 @@
209 Source: libappindicator
210 Section: gnome
211 Priority: optional
212-XS-Python-Version: all
213 Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
214 Build-Depends: debhelper (>= 9),
215 dh-autoreconf,
216- python-all-dev,
217 at-spi2-core,
218- cli-common-dev (>= 0.5.7) [!arm64 !ppc64el],
219+ cli-common-dev (>= 0.5.7) [!arm64 !ppc64el !riscv64],
220+ gnome-common,
221 gobject-introspection,
222 intltool,
223 gtk-doc-tools,
224 libxml2-utils,
225- libnunit-cil-dev [!arm64 !ppc64el],
226+ libnunit-cil-dev [!arm64 !ppc64el !riscv64],
227 dbus-test-runner,
228 xvfb,
229 valac,
230- mono-devel (>= 2.4.3) [!arm64 !ppc64el],
231+ mono-devel (>= 2.4.3) [!arm64 !ppc64el !riscv64],
232 libglib2.0-dev (>= 2.35.4),
233 libgtk-3-dev (>= 2.91.3),
234 libgtk2.0-dev (>= 2.12.0),
235- python-gtk2-dev,
236- gtk-sharp2-gapi [!arm64 !ppc64el],
237- libgtk2.0-cil-dev [!arm64 !ppc64el],
238+ gtk-sharp2-gapi [!arm64 !ppc64el !riscv64],
239+ libgtk2.0-cil-dev [!arm64 !ppc64el !riscv64],
240 libdbus-glib-1-dev (>= 0.82),
241- libindicator-dev (>= 0.3.90),
242- libindicator3-dev (>= 0.3.90),
243 libdbusmenu-glib-dev (>= 0.5.90),
244 libdbusmenu-gtk-dev (>= 0.5.90),
245 libdbusmenu-gtk3-dev (>= 0.5.90),
246@@ -35,54 +31,29 @@
247 # If you aren't a member of ~indicator-applet-developers but need to upload
248 # packaging changes, just go ahead. ~indicator-applet-developers will notice
249 # and sync up the code again.
250-Vcs-Bzr: https://code.launchpad.net/~indicator-applet-developers/libappindicator/trunk.13.04
251-Vcs-Browser: https://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk.13.04/files
252-
253-Package: python-appindicator
254-Section: python
255-Architecture: any
256-XB-Python-Version: ${python:Versions}
257-Depends: ${shlibs:Depends},
258- ${misc:Depends},
259- ${python:Depends},
260- libappindicator1 (= ${binary:Version}),
261- python-gobject,
262-Provides: ${python:Provides},
263-Description: Python bindings for libappindicator
264- This package provides Python bindings so that you can use libappindicator from
265- a Python program.
266+Vcs-Bzr: https://code.launchpad.net/~indicator-applet-developers/libappindicator/trunk.16.10
267+Vcs-Browser: https://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk.16.10/files
268
269 Package: libappindicator1
270 Section: libs
271 Architecture: any
272-Pre-Depends: multiarch-support,
273 Depends: ${shlibs:Depends},
274 ${misc:Depends},
275-Recommends: indicator-application (>= 0.2.93),
276+Suggests: indicator-application (>= 0.2.93),
277 Description: Application Indicators
278 A library and indicator to take menus from applications and place them in
279 the panel.
280 .
281 This package contains shared libraries to be used by applications.
282
283-Package: gir1.2-appindicator-0.1
284-Section: introspection
285-Architecture: any
286-Depends: ${misc:Depends},
287- ${gir:Depends},
288-Description: Typelib files for libappindicator1.
289- .
290- This package can be used by other packages using the GIRepository format
291- to generate dynamic bindings.
292-
293 Package: libappindicator-dev
294 Section: libdevel
295 Architecture: any
296 Depends: ${shlibs:Depends},
297 ${misc:Depends},
298- gir1.2-appindicator-0.1 (= ${binary:Version}),
299 libdbusmenu-glib-dev (>= 0.1.8),
300 libdbus-glib-1-dev (>= 0.76),
301+ libgtk2.0-dev,
302 libappindicator1 (= ${binary:Version}),
303 Description: Application Indicators
304 A library and indicator to take menus from applications and place them in
305@@ -103,10 +74,9 @@
306 Package: libappindicator3-1
307 Section: libs
308 Architecture: any
309-Pre-Depends: multiarch-support,
310 Depends: ${shlibs:Depends},
311 ${misc:Depends},
312-Recommends: indicator-application (>= 0.2.93),
313+Suggests: indicator-application (>= 0.2.93),
314 Description: Application Indicators
315 A library and indicator to take menus from applications and place them in
316 the panel.
317@@ -121,6 +91,7 @@
318 gir1.2-appindicator3-0.1 (= ${binary:Version}),
319 libdbusmenu-glib-dev (>= 0.1.8),
320 libdbus-glib-1-dev (>= 0.76),
321+ libgtk-3-dev,
322 libappindicator3-1 (= ${binary:Version}),
323 Description: Application Indicators
324 A library and indicator to take menus from applications and place them in
325
326=== removed file 'debian/gir1.2-appindicator-0.1.install'
327=== modified file 'debian/libappindicator-dev.install'
328--- debian/libappindicator-dev.install 2012-11-27 02:18:17 +0000
329+++ debian/libappindicator-dev.install 2020-04-08 18:54:42 +0000
330@@ -1,5 +1,3 @@
331 usr/include/libappindicator-0.1/*
332 usr/lib/*/libappindicator.so
333 usr/lib/*/pkgconfig/appindicator-0.1.pc
334-usr/share/gir-1.0/AppIndicator-0.1.gir
335-usr/share/vala/vapi/appindicator-0.1.vapi
336
337=== removed file 'debian/python-appindicator.install'
338=== modified file 'debian/rules' (properties changed: +x to -x)
339--- debian/rules 2013-12-19 14:37:54 +0000
340+++ debian/rules 2020-04-08 18:54:42 +0000
341@@ -1,13 +1,12 @@
342 #!/usr/bin/make -f
343
344 FLAVORS = gtk2 gtk3
345-PY_VERSIONS = $(shell pyversions --requested debian/control)
346 API_VERSION = 0.1
347
348 DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
349
350 CONFIGURE_COMMON_FLAGS = --disable-scrollkeeper --enable-introspection
351-ifneq (,$(filter $(DEB_HOST_ARCH),arm64 ppc64el))
352+ifneq (,$(filter $(DEB_HOST_ARCH),arm64 ppc64el riscv64))
353 CONFIGURE_COMMON_FLAGS += --disable-mono-test
354 else
355 dh_extra_args = ,cli
356@@ -15,14 +14,12 @@
357 CONFIGURE_FLAGS_gtk2 = --with-gtk=2 --enable-gtk-doc
358 CONFIGURE_FLAGS_gtk3 = --with-gtk=3 --enable-gtk-doc=no
359
360-export CSC=/usr/bin/mono-csc
361-
362 export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
363
364 CFLAGS += -fPIC
365
366 %:
367- dh $@ --with autoreconf,python2,gir$(dh_extra_args)
368+ dh $@ --with autoreconf,gir$(dh_extra_args)
369
370 override_dh_autoreconf:
371 NOCONFIGURE=1 dh_autoreconf ./autogen.sh
372@@ -32,24 +29,16 @@
373 doconfigure-%:
374 dh_auto_configure --builddirectory=build/$* -- $(CONFIGURE_FLAGS_$*) $(CONFIGURE_COMMON_FLAGS)
375
376-doconfigure-gtk2: $(PY_VERSIONS:%=doconfiguregtk2-%)
377- # GTK2 flavor configure was run on a per-python-version basis.
378-
379 doconfiguregtk2-%:
380- PYTHON=`which $*` \
381- dh_auto_configure --builddirectory=build/gtk2 -- $(CONFIGURE_FLAGS_gtk2) $(CONFIGURE_COMMON_FLAGS)
382+ dh_auto_configure --builddirectory=build/gtk2 -- $(CONFIGURE_FLAGS_gtk2) $(CONFIGURE_COMMON_FLAGS)
383
384 override_dh_auto_build: $(FLAVORS:%=dobuild-%)
385
386 dobuild-%:
387 dh_auto_build --builddirectory=build/$*
388
389-dobuild-gtk2: $(PY_VERSIONS:%=dobuildgtk2-%)
390- # GTK2 flavor build was run on a per-python-version basis.
391-
392 dobuildgtk2-%:
393- PYTHON=`which $*` \
394- dh_auto_build --builddirectory=build/gtk2
395+ dh_auto_build --builddirectory=build/gtk2
396
397 override_dh_auto_install: $(FLAVORS:%=doinstall-%)
398
399@@ -61,9 +50,7 @@
400 find debian/tmp -name \*.a -exec rm {} \;
401 rm -rf debian/tmp/*/usr/lib/mono
402 rm -rf debian/tmp/*/usr/share/vala/vapi/appindicator*-0.1.deps
403- dh_install -ppython-appindicator --fail-missing --sourcedir=debian/tmp/gtk2
404 dh_install -plibappindicator1 --fail-missing --sourcedir=debian/tmp/gtk2
405- dh_install -pgir1.2-appindicator-0.1 --fail-missing --sourcedir=debian/tmp/gtk2
406 dh_install -plibappindicator-dev --fail-missing --sourcedir=debian/tmp/gtk2
407 dh_install -plibappindicator-doc --fail-missing --sourcedir=debian/tmp/gtk2
408 dh_install -plibappindicator3-1 --fail-missing --sourcedir=debian/tmp/gtk3
409@@ -77,15 +64,10 @@
410 dotest-%:
411 dh_auto_test --builddirectory=build/$* --
412
413-
414-dotest-gtk2: $(PY_VERSIONS:%=dotestgtk2-%)
415- # GTK2 flavor test was run on a per-python-version basis.
416-
417 dotestgtk2-%:
418 ps -ef
419 env
420- PYTHON=`which $*` \
421- dh_auto_test --builddirectory=build/gtk2 --
422+ dh_auto_test --builddirectory=build/gtk2 --
423
424 override_dh_auto_clean:
425 dh_auto_clean
426
427=== modified file 'docs/reference/Makefile.am'
428--- docs/reference/Makefile.am 2013-06-08 04:26:37 +0000
429+++ docs/reference/Makefile.am 2020-04-08 18:54:42 +0000
430@@ -33,7 +33,7 @@
431 DOC_SOURCE_DIR=$(top_srcdir)/src
432
433 # Extra options to pass to gtkdoc-scangobj. Not normally needed.
434-SCANGOBJ_OPTIONS=--nogtkinit --type-init-func="g_type_init()"
435+SCANGOBJ_OPTIONS=--type-init-func="g_type_init()"
436
437 # Extra options to supply to gtkdoc-scan.
438 # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
439
440=== modified file 'example/simple-client-vala.vala'
441--- example/simple-client-vala.vala 2012-03-21 18:02:41 +0000
442+++ example/simple-client-vala.vala 2020-04-08 18:54:42 +0000
443@@ -104,7 +104,7 @@
444 print(@"Got scroll event! delta: $delta, direction: $direction\n");
445 });
446
447- Timeout.add_seconds(1, () => {
448+ GLib.Timeout.add_seconds(1, () => {
449 percentage = (percentage + 1) % 100;
450 if (can_haz_label) {
451 ci.set_label(@"$(percentage+1)%", "");
452
453=== modified file 'src/Makefile.am'
454--- src/Makefile.am 2013-12-19 14:37:54 +0000
455+++ src/Makefile.am 2020-04-08 18:54:42 +0000
456@@ -62,6 +62,8 @@
457 dbus-shared.h \
458 generate-id.h \
459 generate-id.c \
460+ indicator-desktop-shortcuts.c \
461+ indicator-desktop-shortcuts.h \
462 gen-notification-item.xml.h \
463 gen-notification-item.xml.c \
464 gen-notification-watcher.xml.h \
465@@ -71,12 +73,12 @@
466 $(COVERAGE_LDFLAGS) \
467 -version-info 1:0:0 \
468 -no-undefined \
469- -export-symbols-regex "^[^_d].*"
470+ -export-symbols-regex "^app_indicator_.*"
471
472 libappindicator_la_CFLAGS = \
473 $(LIBRARY_CFLAGS) \
474 $(COVERAGE_CFLAGS) \
475- -Wall -Werror -Wno-error=deprecated-declarations \
476+ -Wall -Wno-error=deprecated-declarations \
477 -DG_LOG_DOMAIN=\"libappindicator\"
478
479 libappindicator_la_LIBADD = \
480@@ -153,29 +155,23 @@
481 $(addprefix $(srcdir)/,app-indicator.c) \
482 $(addprefix $(srcdir)/,$(libappindicator_headers))
483
484-AppIndicator$(VER)-0.1.gir: libappindicator$(VER).la
485+AppIndicator3-0.1.gir: libappindicator3.la
486
487-AppIndicator_0_1_gir_INCLUDES = \
488+AppIndicator3_0_1_gir_INCLUDES = \
489 GObject-2.0 \
490 $(GTKGIR)
491-AppIndicator_0_1_gir_CFLAGS = $(LIBRARY_CFLAGS) -I$(srcdir) -I$(top_builddir)/src
492-AppIndicator_0_1_gir_LIBS = libappindicator$(VER).la
493-AppIndicator_0_1_gir_FILES = $(introspection_sources)
494-# AppIndicator_0_1_gir_NAMESPACE = AppIndicator
495-
496-AppIndicator3_0_1_gir_INCLUDES = $(AppIndicator_0_1_gir_INCLUDES)
497-AppIndicator3_0_1_gir_CFLAGS = $(AppIndicator_0_1_gir_CFLAGS)
498-AppIndicator3_0_1_gir_LIBS = $(AppIndicator_0_1_gir_LIBS)
499-AppIndicator3_0_1_gir_FILES = $(AppIndicator_0_1_gir_FILES)
500+AppIndicator3_0_1_gir_CFLAGS = $(LIBRARY_CFLAGS) -I$(srcdir) -I$(top_builddir)/src
501+AppIndicator3_0_1_gir_LIBS = libappindicator3.la
502+AppIndicator3_0_1_gir_FILES = $(introspection_sources)
503 # AppIndicator3_0_1_gir_NAMESPACE = AppIndicator
504
505-INTROSPECTION_GIRS += AppIndicator$(VER)-0.1.gir
506+INTROSPECTION_GIRS += AppIndicator3-0.1.gir
507
508-AppIndicator$(VER)-0.1.metadata: AppIndicator$(VER)-0.1.gir
509+AppIndicator3-0.1.metadata: AppIndicator3-0.1.gir
510 cp -f $(srcdir)/$@.in $@
511
512-BUILT_SOURCES += AppIndicator$(VER)-0.1.metadata
513-CLEANFILES += AppIndicator$(VER)-0.1.metadata
514+BUILT_SOURCES += AppIndicator3-0.1.metadata
515+CLEANFILES += AppIndicator3-0.1.metadata
516
517 girdir = $(datadir)/gir-1.0
518 gir_DATA = $(INTROSPECTION_GIRS)
519
520=== modified file 'src/app-indicator.c'
521--- src/app-indicator.c 2015-07-02 17:03:37 +0000
522+++ src/app-indicator.c 2020-04-08 18:54:42 +0000
523@@ -36,7 +36,9 @@
524 #include <libdbusmenu-gtk/client.h>
525 #include <libdbusmenu-gtk/parser.h>
526
527-#include <libindicator/indicator-desktop-shortcuts.h>
528+#include "indicator-desktop-shortcuts.h"
529+
530+#include <stdlib.h>
531
532 #include "app-indicator.h"
533 #include "app-indicator-enum-types.h"
534@@ -71,8 +73,11 @@
535 AppIndicatorCategory category;
536 AppIndicatorStatus status;
537 gchar *icon_name;
538+ gchar *absolute_icon_name;
539 gchar *attention_icon_name;
540+ gchar *absolute_attention_icon_name;
541 gchar *icon_theme_path;
542+ gchar *absolute_icon_theme_path;
543 DbusmenuServer *menuservice;
544 GtkWidget *menu;
545 GtkWidget *sec_activate_target;
546@@ -190,6 +195,8 @@
547 static void status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data);
548 static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);
549 static gchar * append_panel_icon_suffix (const gchar * icon_name);
550+static gchar * get_real_theme_path (AppIndicator * self);
551+static gchar * append_snap_prefix (const gchar * path);
552 static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);
553 static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);
554 static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);
555@@ -389,7 +396,7 @@
556 "An additional place to look for icon names that may be installed by the application.",
557 NULL,
558 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
559-
560+
561 /**
562 * AppIndicator:connected:
563 *
564@@ -501,7 +508,7 @@
565 G_STRUCT_OFFSET (AppIndicatorClass, new_icon),
566 NULL, NULL,
567 g_cclosure_marshal_VOID__VOID,
568- G_TYPE_NONE, 0, G_TYPE_NONE);
569+ G_TYPE_NONE, 0);
570
571 /**
572 * AppIndicator::new-attention-icon:
573@@ -515,7 +522,7 @@
574 G_STRUCT_OFFSET (AppIndicatorClass, new_attention_icon),
575 NULL, NULL,
576 g_cclosure_marshal_VOID__VOID,
577- G_TYPE_NONE, 0, G_TYPE_NONE);
578+ G_TYPE_NONE, 0);
579
580 /**
581 * AppIndicator::new-status:
582@@ -563,7 +570,7 @@
583 G_STRUCT_OFFSET (AppIndicatorClass, connection_changed),
584 NULL, NULL,
585 g_cclosure_marshal_VOID__BOOLEAN,
586- G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE);
587+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
588
589 /**
590 * AppIndicator::new-icon-theme-path:
591@@ -640,6 +647,7 @@
592 app_indicator_init (AppIndicator *self)
593 {
594 AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self);
595+ self->priv = priv;
596
597 priv->id = NULL;
598 priv->clean_id = NULL;
599@@ -648,6 +656,7 @@
600 priv->icon_name = NULL;
601 priv->attention_icon_name = NULL;
602 priv->icon_theme_path = NULL;
603+ priv->absolute_icon_theme_path = get_real_theme_path (self);
604 priv->menu = NULL;
605 priv->menuservice = NULL;
606 priv->ordering_index = 0;
607@@ -676,8 +685,6 @@
608 (GBusNameVanishedCallback) name_vanished_handler,
609 self, NULL);
610
611- self->priv = priv;
612-
613 /* Start getting the session bus */
614 g_object_ref(self); /* ref for the bus creation callback */
615 g_bus_get(G_BUS_TYPE_SESSION, NULL, bus_creation, self);
616@@ -794,16 +801,31 @@
617 priv->icon_name = NULL;
618 }
619
620+ if (priv->absolute_icon_name != NULL) {
621+ g_free(priv->absolute_icon_name);
622+ priv->absolute_icon_name = NULL;
623+ }
624+
625 if (priv->attention_icon_name != NULL) {
626 g_free(priv->attention_icon_name);
627 priv->attention_icon_name = NULL;
628 }
629
630+ if (priv->absolute_attention_icon_name != NULL) {
631+ g_free(priv->absolute_attention_icon_name);
632+ priv->absolute_attention_icon_name = NULL;
633+ }
634+
635 if (priv->icon_theme_path != NULL) {
636 g_free(priv->icon_theme_path);
637 priv->icon_theme_path = NULL;
638 }
639-
640+
641+ if (priv->absolute_icon_theme_path != NULL) {
642+ g_free(priv->absolute_icon_theme_path);
643+ priv->absolute_icon_theme_path = NULL;
644+ }
645+
646 if (priv->title != NULL) {
647 g_free(priv->title);
648 priv->title = NULL;
649@@ -976,6 +998,11 @@
650 gchar * oldguide = priv->label_guide;
651 priv->label_guide = g_value_dup_string(value);
652
653+ if (priv->label_guide != NULL && priv->label_guide[0] == '\0') {
654+ g_free(priv->label_guide);
655+ priv->label_guide = NULL;
656+ }
657+
658 if (g_strcmp0(oldguide, priv->label_guide) != 0) {
659 signal_label_change(APP_INDICATOR(object));
660 }
661@@ -1188,8 +1215,14 @@
662 enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (APP_INDICATOR_TYPE_INDICATOR_STATUS), priv->status);
663 return g_variant_new_string(enum_value->value_nick ? enum_value->value_nick : "");
664 } else if (g_strcmp0(property, "IconName") == 0) {
665+ if (priv->absolute_icon_name) {
666+ return g_variant_new_string(priv->absolute_icon_name);
667+ }
668 return g_variant_new_string(priv->icon_name ? priv->icon_name : "");
669 } else if (g_strcmp0(property, "AttentionIconName") == 0) {
670+ if (priv->absolute_attention_icon_name) {
671+ return g_variant_new_string(priv->absolute_attention_icon_name);
672+ }
673 return g_variant_new_string(priv->attention_icon_name ? priv->attention_icon_name : "");
674 } else if (g_strcmp0(property, "Title") == 0) {
675 const gchar * output = NULL;
676@@ -1205,6 +1238,9 @@
677 }
678 return g_variant_new_string(output);
679 } else if (g_strcmp0(property, "IconThemePath") == 0) {
680+ if (priv->absolute_icon_theme_path) {
681+ return g_variant_new_string(priv->absolute_icon_theme_path);
682+ }
683 return g_variant_new_string(priv->icon_theme_path ? priv->icon_theme_path : "");
684 } else if (g_strcmp0(property, "Menu") == 0) {
685 if (priv->menuservice != NULL) {
686@@ -1244,7 +1280,7 @@
687 gchar * guide = priv->label_guide != NULL ? priv->label_guide : "";
688
689 g_signal_emit(G_OBJECT(self), signals[NEW_LABEL], 0,
690- label, guide, TRUE);
691+ label, guide);
692 if (priv->dbus_registration != 0 && priv->connection != NULL) {
693 GError * error = NULL;
694
695@@ -1460,7 +1496,7 @@
696 static void
697 theme_changed_cb (GtkIconTheme * theme, gpointer user_data)
698 {
699- g_signal_emit (user_data, signals[NEW_ICON], 0, TRUE);
700+ g_signal_emit (user_data, signals[NEW_ICON], 0);
701
702 AppIndicator * self = (AppIndicator *)user_data;
703 AppIndicatorPrivate *priv = self->priv;
704@@ -1571,19 +1607,23 @@
705
706 /* add the icon_theme_path once if needed */
707 GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
708- if (self->priv->icon_theme_path != NULL) {
709+ const gchar *theme_path = self->priv->absolute_icon_theme_path ?
710+ self->priv->absolute_icon_theme_path :
711+ self->priv->icon_theme_path;
712+
713+ if (theme_path != NULL) {
714 gchar **path;
715 gint n_elements, i;
716 gboolean found=FALSE;
717 gtk_icon_theme_get_search_path(icon_theme, &path, &n_elements);
718- for (i=0; i< n_elements || path[i] == NULL; i++) {
719- if(g_strcmp0(path[i], self->priv->icon_theme_path) == 0) {
720+ for (i=0; i< n_elements; i++) {
721+ if(g_strcmp0(path[i], theme_path) == 0) {
722 found=TRUE;
723 break;
724 }
725 }
726 if(!found) {
727- gtk_icon_theme_append_search_path(icon_theme, self->priv->icon_theme_path);
728+ gtk_icon_theme_append_search_path(icon_theme, theme_path);
729 }
730 g_strfreev (path);
731 }
732@@ -1607,8 +1647,12 @@
733 };
734
735 if (icon_name != NULL) {
736+ gchar *snapped_icon = append_snap_prefix(icon_name);
737+
738 if (g_file_test(icon_name, G_FILE_TEST_EXISTS)) {
739 gtk_status_icon_set_from_file(icon, icon_name);
740+ } else if (snapped_icon && g_file_test(snapped_icon, G_FILE_TEST_EXISTS)) {
741+ gtk_status_icon_set_from_file(icon, snapped_icon);
742 } else {
743 gchar *longname = append_panel_icon_suffix(icon_name);
744
745@@ -1620,6 +1664,8 @@
746
747 g_free(longname);
748 }
749+
750+ g_free(snapped_icon);
751 }
752
753 return;
754@@ -1633,7 +1679,7 @@
755 GtkMenu * menu = app_indicator_get_menu(APP_INDICATOR(data));
756 if (menu == NULL)
757 return;
758-
759+
760 gtk_menu_popup(menu,
761 NULL, /* Parent Menu */
762 NULL, /* Parent item */
763@@ -1681,7 +1727,7 @@
764 long_name = g_strdup (icon_name);
765 }
766
767- return long_name;
768+ return long_name;
769 }
770
771 static gboolean
772@@ -1858,6 +1904,14 @@
773 if (g_strcmp0 (self->priv->attention_icon_name, icon_name) != 0) {
774 g_free (self->priv->attention_icon_name);
775 self->priv->attention_icon_name = g_strdup (icon_name);
776+
777+ g_free(self->priv->absolute_attention_icon_name);
778+ self->priv->absolute_attention_icon_name = NULL;
779+
780+ if (icon_name && icon_name[0] == '/') {
781+ self->priv->absolute_attention_icon_name = append_snap_prefix (icon_name);
782+ }
783+
784 changed = TRUE;
785 }
786
787@@ -1868,7 +1922,7 @@
788 }
789
790 if (changed) {
791- g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0, TRUE);
792+ g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0);
793
794 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
795 GError * error = NULL;
796@@ -1933,6 +1987,14 @@
797 }
798
799 self->priv->icon_name = g_strdup(icon_name);
800+
801+ g_free(self->priv->absolute_icon_name);
802+ self->priv->absolute_icon_name = NULL;
803+
804+ if (icon_name && icon_name[0] == '/') {
805+ self->priv->absolute_icon_name = append_snap_prefix (icon_name);
806+ }
807+
808 changed = TRUE;
809 }
810
811@@ -1946,7 +2008,7 @@
812 }
813
814 if (changed) {
815- g_signal_emit (self, signals[NEW_ICON], 0, TRUE);
816+ g_signal_emit (self, signals[NEW_ICON], 0);
817
818 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
819 GError * error = NULL;
820@@ -1994,6 +2056,66 @@
821 return;
822 }
823
824+static const gchar *
825+get_snap_prefix ()
826+{
827+ const gchar *snap = g_getenv ("SNAP");
828+ return (snap && *snap != '\0') ? snap : NULL;
829+}
830+
831+static gchar *
832+append_snap_prefix (const gchar *path)
833+{
834+ gint i;
835+ gchar real_path[PATH_MAX];
836+ const gchar *snap = get_snap_prefix ();
837+
838+ if (snap != NULL && path != NULL) {
839+ if (realpath (path, real_path) != NULL) {
840+ path = real_path;
841+ }
842+
843+ if (g_str_has_prefix (path, "/tmp/")) {
844+ g_warning ("Using '/tmp' paths in SNAP environment will lead to unreadable resources");
845+ return NULL;
846+ }
847+
848+ if (g_str_has_prefix (path, snap) ||
849+ g_str_has_prefix (path, g_get_home_dir ()) ||
850+ g_str_has_prefix (path, g_get_user_cache_dir ()) ||
851+ g_str_has_prefix (path, g_get_user_config_dir ()) ||
852+ g_str_has_prefix (path, g_get_user_data_dir ()) ||
853+ g_str_has_prefix (path, g_get_user_runtime_dir ())) {
854+ return g_strdup (path);
855+ }
856+
857+ for (i = 0; i < G_USER_N_DIRECTORIES; ++ i) {
858+ if (g_str_has_prefix (path, g_get_user_special_dir (i))) {
859+ return g_strdup (path);
860+ }
861+ }
862+
863+ return g_build_path (G_DIR_SEPARATOR_S, snap, path, NULL);
864+ }
865+
866+ return NULL;
867+}
868+
869+static gchar *
870+get_real_theme_path (AppIndicator * self)
871+{
872+ const gchar *theme_path = self->priv->icon_theme_path;
873+ gchar *snapped_path = append_snap_prefix (theme_path);
874+
875+ if (snapped_path != NULL) {
876+ return snapped_path;
877+ } else if (get_snap_prefix ()) {
878+ return g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), "icons", NULL);
879+ }
880+
881+ return NULL;
882+}
883+
884 /**
885 * app_indicator_set_icon_theme_path:
886 * @self: The #AppIndicator object to use
887@@ -2012,9 +2134,15 @@
888
889 self->priv->icon_theme_path = g_strdup(icon_theme_path);
890
891- g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path, TRUE);
892+ g_free (self->priv->absolute_icon_theme_path);
893+ self->priv->absolute_icon_theme_path = get_real_theme_path (self);
894+
895+ g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path);
896
897 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
898+ const gchar *theme_path = self->priv->absolute_icon_theme_path ?
899+ self->priv->absolute_icon_theme_path :
900+ self->priv->icon_theme_path;
901 GError * error = NULL;
902
903 g_dbus_connection_emit_signal(self->priv->connection,
904@@ -2022,7 +2150,7 @@
905 self->priv->path,
906 NOTIFICATION_ITEM_DBUS_IFACE,
907 "NewIconThemePath",
908- g_variant_new("(s)", self->priv->icon_theme_path),
909+ g_variant_new("(s)", theme_path ? theme_path : ""),
910 &error);
911
912 if (error != NULL) {
913@@ -2160,7 +2288,7 @@
914
915 g_return_if_fail (GTK_IS_WIDGET (menuitem));
916
917- priv->sec_activate_target = g_object_ref(G_OBJECT(menuitem));
918+ priv->sec_activate_target = g_object_ref(menuitem);
919 priv->sec_activate_enabled = widget_is_menu_child(self, menuitem);
920 g_signal_connect(menuitem, "parent-set", G_CALLBACK(sec_activate_target_parent_changed), self);
921 }
922
923=== added file 'src/indicator-desktop-shortcuts.c'
924--- src/indicator-desktop-shortcuts.c 1970-01-01 00:00:00 +0000
925+++ src/indicator-desktop-shortcuts.c 2020-04-08 18:54:42 +0000
926@@ -0,0 +1,705 @@
927+/*
928+A small file to parse through the actions that are available
929+in the desktop file and making those easily usable.
930+
931+Copyright 2010 Canonical Ltd.
932+
933+Authors:
934+ Ted Gould <ted@canonical.com>
935+
936+This library is free software; you can redistribute it and/or
937+modify it under the terms of the GNU General Public License
938+version 3.0 as published by the Free Software Foundation.
939+
940+This library is distributed in the hope that it will be useful,
941+but WITHOUT ANY WARRANTY; without even the implied warranty of
942+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
943+GNU General Public License version 3.0 for more details.
944+
945+You should have received a copy of the GNU General Public
946+License along with this library. If not, see
947+<http://www.gnu.org/licenses/>.
948+*/
949+
950+#ifdef HAVE_CONFIG_H
951+#include "config.h"
952+#endif
953+
954+#include <gio/gdesktopappinfo.h>
955+#include "indicator-desktop-shortcuts.h"
956+
957+#define ACTIONS_KEY "Actions"
958+#define ACTION_GROUP_PREFIX "Desktop Action"
959+
960+#define OLD_GROUP_SUFFIX "Shortcut Group"
961+#define OLD_SHORTCUTS_KEY "X-Ayatana-Desktop-Shortcuts"
962+#define OLD_ENVIRON_KEY "TargetEnvironment"
963+
964+#define PROP_DESKTOP_FILE_S "desktop-file"
965+#define PROP_IDENTITY_S "identity"
966+
967+typedef enum _actions_t actions_t;
968+enum _actions_t {
969+ ACTIONS_NONE,
970+ ACTIONS_XAYATANA,
971+ ACTIONS_DESKTOP_SPEC
972+};
973+
974+typedef struct _IndicatorDesktopShortcutsPrivate IndicatorDesktopShortcutsPrivate;
975+struct _IndicatorDesktopShortcutsPrivate {
976+ actions_t actions;
977+ GKeyFile * keyfile;
978+ gchar * identity;
979+ GArray * nicks;
980+ gchar * domain;
981+};
982+
983+enum {
984+ PROP_0,
985+ PROP_DESKTOP_FILE,
986+ PROP_IDENTITY
987+};
988+
989+#define INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(o) \
990+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsPrivate))
991+
992+static void indicator_desktop_shortcuts_class_init (IndicatorDesktopShortcutsClass *klass);
993+static void indicator_desktop_shortcuts_init (IndicatorDesktopShortcuts *self);
994+static void indicator_desktop_shortcuts_dispose (GObject *object);
995+static void indicator_desktop_shortcuts_finalize (GObject *object);
996+static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
997+static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
998+static void parse_keyfile (IndicatorDesktopShortcuts * ids);
999+static gboolean should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gboolean should_have_target);
1000+
1001+G_DEFINE_TYPE (IndicatorDesktopShortcuts, indicator_desktop_shortcuts, G_TYPE_OBJECT);
1002+
1003+/* Build up the class */
1004+static void
1005+indicator_desktop_shortcuts_class_init (IndicatorDesktopShortcutsClass *klass)
1006+{
1007+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1008+
1009+ g_type_class_add_private (klass, sizeof (IndicatorDesktopShortcutsPrivate));
1010+
1011+ object_class->dispose = indicator_desktop_shortcuts_dispose;
1012+ object_class->finalize = indicator_desktop_shortcuts_finalize;
1013+
1014+ /* Property funcs */
1015+ object_class->set_property = set_property;
1016+ object_class->get_property = get_property;
1017+
1018+ g_object_class_install_property(object_class, PROP_DESKTOP_FILE,
1019+ g_param_spec_string(PROP_DESKTOP_FILE_S,
1020+ "The path of the desktop file to read",
1021+ "A path to a desktop file that we'll look for shortcuts in.",
1022+ NULL,
1023+ G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
1024+ g_object_class_install_property(object_class, PROP_IDENTITY,
1025+ g_param_spec_string(PROP_IDENTITY_S,
1026+ "The string that represents the identity that we're acting as.",
1027+ "Used to process ShowIn and NotShownIn fields of the desktop shortcust to get the proper list.",
1028+ NULL,
1029+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
1030+
1031+ return;
1032+}
1033+
1034+/* Initialize instance data */
1035+static void
1036+indicator_desktop_shortcuts_init (IndicatorDesktopShortcuts *self)
1037+{
1038+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(self);
1039+
1040+ priv->keyfile = NULL;
1041+ priv->identity = NULL;
1042+ priv->domain = NULL;
1043+ priv->nicks = g_array_new(TRUE, TRUE, sizeof(gchar *));
1044+ priv->actions = ACTIONS_NONE;
1045+
1046+ return;
1047+}
1048+
1049+/* Clear object references */
1050+static void
1051+indicator_desktop_shortcuts_dispose (GObject *object)
1052+{
1053+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
1054+
1055+ if (priv->keyfile) {
1056+ g_key_file_free(priv->keyfile);
1057+ priv->keyfile = NULL;
1058+ }
1059+
1060+ G_OBJECT_CLASS (indicator_desktop_shortcuts_parent_class)->dispose (object);
1061+ return;
1062+}
1063+
1064+/* Free all memory */
1065+static void
1066+indicator_desktop_shortcuts_finalize (GObject *object)
1067+{
1068+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
1069+
1070+ if (priv->identity != NULL) {
1071+ g_free(priv->identity);
1072+ priv->identity = NULL;
1073+ }
1074+
1075+ if (priv->domain != NULL) {
1076+ g_free(priv->domain);
1077+ priv->domain = NULL;
1078+ }
1079+
1080+ if (priv->nicks != NULL) {
1081+ gint i;
1082+ for (i = 0; i < priv->nicks->len; i++) {
1083+ gchar * nick = g_array_index(priv->nicks, gchar *, i);
1084+ g_free(nick);
1085+ }
1086+ g_array_free(priv->nicks, TRUE);
1087+ priv->nicks = NULL;
1088+ }
1089+
1090+ G_OBJECT_CLASS (indicator_desktop_shortcuts_parent_class)->finalize (object);
1091+ return;
1092+}
1093+
1094+/* Sets one of the two properties we have, only at construction though */
1095+static void
1096+set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
1097+{
1098+ g_return_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(object));
1099+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
1100+
1101+ switch(prop_id) {
1102+ case PROP_DESKTOP_FILE: {
1103+ if (priv->keyfile != NULL) {
1104+ g_key_file_free(priv->keyfile);
1105+ priv->keyfile = NULL;
1106+ priv->actions = ACTIONS_NONE;
1107+ }
1108+
1109+ GError * error = NULL;
1110+ GKeyFile * keyfile = g_key_file_new();
1111+ g_key_file_load_from_file(keyfile, g_value_get_string(value), G_KEY_FILE_NONE, &error);
1112+
1113+ if (error != NULL) {
1114+ g_warning("Unable to load keyfile from file '%s': %s", g_value_get_string(value), error->message);
1115+ g_error_free(error);
1116+ g_key_file_free(keyfile);
1117+ break;
1118+ }
1119+
1120+ /* Always prefer the desktop spec if we can get it */
1121+ if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, ACTIONS_KEY, NULL)) {
1122+ priv->actions = ACTIONS_DESKTOP_SPEC;
1123+ }
1124+
1125+ /* But fallback if we can't */
1126+ if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, OLD_SHORTCUTS_KEY, NULL)) {
1127+ priv->actions = ACTIONS_XAYATANA;
1128+ g_warning("Desktop file '%s' is using a deprecated format for its actions that will be dropped soon.", g_value_get_string(value));
1129+ }
1130+
1131+ if (priv->actions == ACTIONS_NONE) {
1132+ g_key_file_free(keyfile);
1133+ break;
1134+ }
1135+
1136+ priv->keyfile = keyfile;
1137+ parse_keyfile(INDICATOR_DESKTOP_SHORTCUTS(object));
1138+ break;
1139+ }
1140+ case PROP_IDENTITY:
1141+ if (priv->identity != NULL) {
1142+ g_warning("Identity already set to '%s' and trying to set it to '%s'.", priv->identity, g_value_get_string(value));
1143+ return;
1144+ }
1145+ priv->identity = g_value_dup_string(value);
1146+ parse_keyfile(INDICATOR_DESKTOP_SHORTCUTS(object));
1147+ break;
1148+ /* *********************** */
1149+ default:
1150+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1151+ break;
1152+ }
1153+
1154+ return;
1155+}
1156+
1157+/* Gets either the desktop file our the identity. */
1158+static void
1159+get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
1160+{
1161+ g_return_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(object));
1162+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
1163+
1164+ switch(prop_id) {
1165+ case PROP_IDENTITY:
1166+ g_value_set_string(value, priv->identity);
1167+ break;
1168+ /* *********************** */
1169+ default:
1170+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1171+ break;
1172+ }
1173+
1174+ return;
1175+}
1176+
1177+/* Checks to see if we can, and if we can it goes through
1178+ and parses the keyfile entries. */
1179+static void
1180+parse_keyfile (IndicatorDesktopShortcuts * ids)
1181+{
1182+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
1183+
1184+ if (priv->keyfile == NULL) {
1185+ return;
1186+ }
1187+
1188+ if (priv->identity == NULL) {
1189+ return;
1190+ }
1191+
1192+ /* Remove a previous translation domain if we had one
1193+ from a previously parsed file. */
1194+ if (priv->domain != NULL) {
1195+ g_free(priv->domain);
1196+ priv->domain = NULL;
1197+ }
1198+
1199+ /* Check to see if there is a custom translation domain that
1200+ we should take into account. */
1201+ if (priv->domain == NULL &&
1202+ g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL)) {
1203+ priv->domain = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
1204+ }
1205+
1206+ if (priv->domain == NULL &&
1207+ g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL)) {
1208+ priv->domain = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL);
1209+ }
1210+
1211+ /* We need to figure out what we're looking for and what we want to
1212+ look for in the rest of the file */
1213+ const gchar * list_name = NULL;
1214+ const gchar * group_format = NULL;
1215+ gboolean should_have_target = FALSE;
1216+
1217+ switch (priv->actions) {
1218+ case ACTIONS_NONE:
1219+ /* None, let's just get outta here */
1220+ return;
1221+ case ACTIONS_XAYATANA:
1222+ list_name = OLD_SHORTCUTS_KEY;
1223+ group_format = "%s " OLD_GROUP_SUFFIX;
1224+ should_have_target = TRUE;
1225+ break;
1226+ case ACTIONS_DESKTOP_SPEC:
1227+ list_name = ACTIONS_KEY;
1228+ group_format = ACTION_GROUP_PREFIX " %s";
1229+ should_have_target = FALSE;
1230+ break;
1231+ default:
1232+ g_assert_not_reached();
1233+ return;
1234+ }
1235+
1236+ /* Okay, we've got everything we need. Let's get it on! */
1237+ gint i;
1238+ gsize num_nicks = 0;
1239+ gchar ** nicks = g_key_file_get_string_list(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, list_name, &num_nicks, NULL);
1240+
1241+ /* If there is an error from get_string_list num_nicks should still
1242+ be zero, so this loop will drop out. */
1243+ for (i = 0; i < num_nicks; i++) {
1244+ /* g_debug("Looking at group nick %s", nicks[i]); */
1245+ gchar * groupname = g_strdup_printf(group_format, nicks[i]);
1246+ if (!g_key_file_has_group(priv->keyfile, groupname)) {
1247+ g_warning("Unable to find group '%s'", groupname);
1248+ g_free(groupname);
1249+ continue;
1250+ }
1251+
1252+ if (!should_show(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, priv->identity, FALSE)) {
1253+ g_free(groupname);
1254+ continue;
1255+ }
1256+
1257+ if (!should_show(priv->keyfile, groupname, priv->identity, should_have_target)) {
1258+ g_free(groupname);
1259+ continue;
1260+ }
1261+
1262+ gchar * nickalloc = g_strdup(nicks[i]);
1263+ g_array_append_val(priv->nicks, nickalloc);
1264+ g_free(groupname);
1265+ }
1266+
1267+ if (nicks != NULL) {
1268+ g_strfreev(nicks);
1269+ }
1270+
1271+ return;
1272+}
1273+
1274+/* Checks the ONLY_SHOW_IN and NOT_SHOW_IN keys for a group to
1275+ see if we should be showing ourselves. */
1276+static gboolean
1277+should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gboolean should_have_target)
1278+{
1279+ if (should_have_target && g_key_file_has_key(keyfile, group, OLD_ENVIRON_KEY, NULL)) {
1280+ /* If we've got this key, we're going to return here and not
1281+ process the deprecated keys. */
1282+ gint j;
1283+ gsize num_env = 0;
1284+ gchar ** envs = g_key_file_get_string_list(keyfile, group, OLD_ENVIRON_KEY, &num_env, NULL);
1285+
1286+ for (j = 0; j < num_env; j++) {
1287+ if (g_strcmp0(envs[j], identity) == 0) {
1288+ break;
1289+ }
1290+ }
1291+
1292+ if (envs != NULL) {
1293+ g_strfreev(envs);
1294+ }
1295+
1296+ if (j == num_env) {
1297+ return FALSE;
1298+ }
1299+ return TRUE;
1300+ }
1301+
1302+ /* If there is a list of OnlyShowIn entries we need to check
1303+ to see if we're in that list. If not, we drop this nick */
1304+ if (g_key_file_has_key(keyfile, group, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, NULL)) {
1305+ gint j;
1306+ gsize num_only = 0;
1307+ gchar ** onlies = g_key_file_get_string_list(keyfile, group, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, &num_only, NULL);
1308+
1309+ for (j = 0; j < num_only; j++) {
1310+ if (g_strcmp0(onlies[j], identity) == 0) {
1311+ break;
1312+ }
1313+ }
1314+
1315+ if (onlies != NULL) {
1316+ g_strfreev(onlies);
1317+ }
1318+
1319+ if (j == num_only) {
1320+ return FALSE;
1321+ }
1322+ }
1323+
1324+ /* If there is a NotShowIn entry we need to make sure that we're
1325+ not in that list. If we are, we need to drop out. */
1326+ if (g_key_file_has_key(keyfile, group, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL)) {
1327+ gint j;
1328+ gsize num_not = 0;
1329+ gchar ** nots = g_key_file_get_string_list(keyfile, group, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, &num_not, NULL);
1330+
1331+ for (j = 0; j < num_not; j++) {
1332+ if (g_strcmp0(nots[j], identity) == 0) {
1333+ break;
1334+ }
1335+ }
1336+
1337+ if (nots != NULL) {
1338+ g_strfreev(nots);
1339+ }
1340+
1341+ if (j != num_not) {
1342+ return FALSE;
1343+ }
1344+ }
1345+
1346+ return TRUE;
1347+}
1348+
1349+/* Looks through the nicks to see if this one is in the list,
1350+ and thus valid to use. */
1351+static gboolean
1352+is_valid_nick (gchar ** list, const gchar * nick)
1353+{
1354+ if (*list == NULL)
1355+ return FALSE;
1356+ /* g_debug("Checking Nick: %s", list[0]); */
1357+ if (g_strcmp0(list[0], nick) == 0)
1358+ return TRUE;
1359+ return is_valid_nick(&list[1], nick);
1360+}
1361+
1362+/* API */
1363+
1364+/**
1365+ indicator_desktop_shortcuts_new:
1366+ @file: The desktop file that would be opened to
1367+ find the actions.
1368+ @identity: This is a string that represents the identity
1369+ that should be used in searching those actions. It
1370+ relates to the ShowIn and NotShownIn properties.
1371+
1372+ This function creates the basic object. It involves opening
1373+ the file and parsing it. It could potentially block on IO. At
1374+ the end of the day you'll have a fully functional object.
1375+
1376+ Return value: A new #IndicatorDesktopShortcuts object.
1377+*/
1378+IndicatorDesktopShortcuts *
1379+indicator_desktop_shortcuts_new (const gchar * file, const gchar * identity)
1380+{
1381+ GObject * obj = g_object_new(INDICATOR_TYPE_DESKTOP_SHORTCUTS,
1382+ PROP_DESKTOP_FILE_S, file,
1383+ PROP_IDENTITY_S, identity,
1384+ NULL);
1385+ return INDICATOR_DESKTOP_SHORTCUTS(obj);
1386+}
1387+
1388+/**
1389+ indicator_desktop_shortcuts_get_nicks:
1390+ @ids: The #IndicatorDesktopShortcuts object to look in
1391+
1392+ Give you the list of commands that are available for this desktop
1393+ file given the identity that was passed in at creation. This will
1394+ filter out the various items in the desktop file. These nicks can
1395+ then be used as keys for working with the desktop file.
1396+
1397+ Return value: A #NULL terminated list of strings. This memory
1398+ is managed by the @ids object.
1399+*/
1400+const gchar **
1401+indicator_desktop_shortcuts_get_nicks (IndicatorDesktopShortcuts * ids)
1402+{
1403+ g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), NULL);
1404+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
1405+ return (const gchar **)priv->nicks->data;
1406+}
1407+
1408+/**
1409+ indicator_desktop_shortcuts_nick_get_name:
1410+ @ids: The #IndicatorDesktopShortcuts object to look in
1411+ @nick: Which command that we're referencing.
1412+
1413+ This function looks in a desktop file for a nick to find the
1414+ user visible name for that shortcut. The @nick parameter
1415+ should be gotten from #indicator_desktop_shortcuts_get_nicks
1416+ though it's not required that the exact memory location
1417+ be the same.
1418+
1419+ Return value: A user visible string for the shortcut or
1420+ #NULL on error.
1421+*/
1422+gchar *
1423+indicator_desktop_shortcuts_nick_get_name (IndicatorDesktopShortcuts * ids, const gchar * nick)
1424+{
1425+ g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), NULL);
1426+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
1427+
1428+ g_return_val_if_fail(priv->actions != ACTIONS_NONE, NULL);
1429+ g_return_val_if_fail(priv->keyfile != NULL, NULL);
1430+ g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), NULL);
1431+
1432+ const gchar * group_format = NULL;
1433+
1434+ switch (priv->actions) {
1435+ case ACTIONS_XAYATANA:
1436+ group_format = "%s " OLD_GROUP_SUFFIX;
1437+ break;
1438+ case ACTIONS_DESKTOP_SPEC:
1439+ group_format = ACTION_GROUP_PREFIX " %s";
1440+ break;
1441+ default:
1442+ g_assert_not_reached();
1443+ return NULL;
1444+ }
1445+
1446+ gchar * groupheader = g_strdup_printf(group_format, nick);
1447+ if (!g_key_file_has_group(priv->keyfile, groupheader)) {
1448+ g_warning("The group for nick '%s' doesn't exist anymore.", nick);
1449+ g_free(groupheader);
1450+ return NULL;
1451+ }
1452+
1453+ if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_NAME, NULL)) {
1454+ g_warning("No name available for nick '%s'", nick);
1455+ g_free(groupheader);
1456+ return NULL;
1457+ }
1458+
1459+ gchar * name = NULL;
1460+ gchar * keyvalue = g_key_file_get_string(priv->keyfile,
1461+ groupheader,
1462+ G_KEY_FILE_DESKTOP_KEY_NAME,
1463+ NULL);
1464+ gchar * localeval = g_key_file_get_locale_string(priv->keyfile,
1465+ groupheader,
1466+ G_KEY_FILE_DESKTOP_KEY_NAME,
1467+ NULL,
1468+ NULL);
1469+ g_free(groupheader);
1470+
1471+ if (priv->domain != NULL && g_strcmp0(keyvalue, localeval) == 0) {
1472+ name = g_strdup(g_dgettext(priv->domain, keyvalue));
1473+ g_free(localeval);
1474+ } else {
1475+ name = localeval;
1476+ }
1477+
1478+ g_free(keyvalue);
1479+
1480+ return name;
1481+}
1482+
1483+/**
1484+ indicator_desktop_shortcuts_nick_exec_with_context:
1485+ @ids: The #IndicatorDesktopShortcuts object to look in
1486+ @nick: Which command that we're referencing.
1487+ @launch_context: The #GAppLaunchContext to use for launching the shortcut
1488+
1489+ Here we take a @nick and try and execute the action that is
1490+ associated with it. The @nick parameter should be gotten
1491+ from #indicator_desktop_shortcuts_get_nicks though it's not
1492+ required that the exact memory location be the same.
1493+
1494+ Return value: #TRUE on success or #FALSE on error.
1495+*/
1496+gboolean
1497+indicator_desktop_shortcuts_nick_exec_with_context (IndicatorDesktopShortcuts * ids, const gchar * nick, GAppLaunchContext * launch_context)
1498+{
1499+ GError * error = NULL;
1500+ gchar * current_dir = NULL;
1501+
1502+ g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), FALSE);
1503+ IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
1504+
1505+ g_return_val_if_fail(priv->actions != ACTIONS_NONE, FALSE);
1506+ g_return_val_if_fail(priv->keyfile != NULL, FALSE);
1507+ g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), FALSE);
1508+
1509+ const gchar * group_format = NULL;
1510+
1511+ switch (priv->actions) {
1512+ case ACTIONS_XAYATANA:
1513+ group_format = "%s " OLD_GROUP_SUFFIX;
1514+ break;
1515+ case ACTIONS_DESKTOP_SPEC:
1516+ group_format = ACTION_GROUP_PREFIX " %s";
1517+ break;
1518+ default:
1519+ g_assert_not_reached();
1520+ return FALSE;
1521+ }
1522+
1523+ gchar * groupheader = g_strdup_printf(group_format, nick);
1524+ if (!g_key_file_has_group(priv->keyfile, groupheader)) {
1525+ g_warning("The group for nick '%s' doesn't exist anymore.", nick);
1526+ g_free(groupheader);
1527+ return FALSE;
1528+ }
1529+
1530+ if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_NAME, NULL)) {
1531+ g_warning("No name available for nick '%s'", nick);
1532+ g_free(groupheader);
1533+ return FALSE;
1534+ }
1535+
1536+ if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL)) {
1537+ g_warning("No exec available for nick '%s'", nick);
1538+ g_free(groupheader);
1539+ return FALSE;
1540+ }
1541+
1542+ /* If possible move to the proper launch path */
1543+ gchar * path = g_key_file_get_string(priv->keyfile, groupheader,
1544+ G_KEY_FILE_DESKTOP_KEY_PATH, NULL);
1545+
1546+ if (path && *path != '\0') {
1547+ current_dir = g_get_current_dir();
1548+
1549+ if (chdir(path) < 0) {
1550+ g_warning("Impossible to run action '%s' from path '%s'", nick, path);
1551+ g_free(current_dir);
1552+ g_free(groupheader);
1553+ g_free(path);
1554+ return FALSE;
1555+ }
1556+ }
1557+
1558+ /* Grab the name and the exec entries out of our current group */
1559+ gchar * name = g_key_file_get_locale_string(priv->keyfile,
1560+ groupheader,
1561+ G_KEY_FILE_DESKTOP_KEY_NAME,
1562+ NULL,
1563+ NULL);
1564+
1565+ gchar * exec = g_key_file_get_locale_string(priv->keyfile,
1566+ groupheader,
1567+ G_KEY_FILE_DESKTOP_KEY_EXEC,
1568+ NULL,
1569+ NULL);
1570+
1571+ GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE;
1572+
1573+ if (launch_context) {
1574+ flags |= G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION;
1575+ }
1576+
1577+ GAppInfo * appinfo = g_app_info_create_from_commandline(exec, name, flags, &error);
1578+ g_free(groupheader);
1579+ g_free(path);
1580+ g_free(name);
1581+ g_free(exec);
1582+
1583+ if (error != NULL) {
1584+ g_warning("Unable to build Command line App info: %s", error->message);
1585+ g_free(current_dir);
1586+ g_error_free(error);
1587+ return FALSE;
1588+ }
1589+
1590+ if (appinfo == NULL) {
1591+ g_warning("Unable to build Command line App info (unknown)");
1592+ g_free(current_dir);
1593+ return FALSE;
1594+ }
1595+
1596+ gboolean launched = g_app_info_launch(appinfo, NULL, launch_context, &error);
1597+
1598+ if (current_dir && chdir(current_dir) < 0)
1599+ g_warning("Impossible to switch back to default work dir");
1600+
1601+
1602+ if (error != NULL) {
1603+ g_warning("Unable to launch file from nick '%s': %s", nick, error->message);
1604+ g_clear_error(&error);
1605+ }
1606+
1607+ g_free(current_dir);
1608+ g_object_unref(appinfo);
1609+
1610+ return launched;
1611+}
1612+
1613+/**
1614+ indicator_desktop_shortcuts_nick_exec:
1615+ @ids: The #IndicatorDesktopShortcuts object to look in
1616+ @nick: Which command that we're referencing.
1617+
1618+ Here we take a @nick and try and execute the action that is
1619+ associated with it. The @nick parameter should be gotten
1620+ from #indicator_desktop_shortcuts_get_nicks though it's not
1621+ required that the exact memory location be the same.
1622+ This function is deprecated and shouldn't be used in newly
1623+ written code.
1624+
1625+ Return value: #TRUE on success or #FALSE on error.
1626+*/
1627+gboolean
1628+indicator_desktop_shortcuts_nick_exec (IndicatorDesktopShortcuts * ids, const gchar * nick)
1629+{
1630+ return indicator_desktop_shortcuts_nick_exec_with_context (ids, nick, NULL);
1631+}
1632
1633=== added file 'src/indicator-desktop-shortcuts.h'
1634--- src/indicator-desktop-shortcuts.h 1970-01-01 00:00:00 +0000
1635+++ src/indicator-desktop-shortcuts.h 2020-04-08 18:54:42 +0000
1636@@ -0,0 +1,80 @@
1637+/*
1638+A small file to parse through the actions that are available
1639+in the desktop file and making those easily usable.
1640+
1641+Copyright 2010 Canonical Ltd.
1642+
1643+Authors:
1644+ Ted Gould <ted@canonical.com>
1645+
1646+This library is free software; you can redistribute it and/or
1647+modify it under the terms of the GNU General Public License
1648+version 3.0 as published by the Free Software Foundation.
1649+
1650+This library is distributed in the hope that it will be useful,
1651+but WITHOUT ANY WARRANTY; without even the implied warranty of
1652+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1653+GNU General Public License version 3.0 for more details.
1654+
1655+You should have received a copy of the GNU General Public
1656+License along with this library. If not, see
1657+<http://www.gnu.org/licenses/>.
1658+*/
1659+
1660+#ifndef __INDICATOR_DESKTOP_SHORTCUTS_H__
1661+#define __INDICATOR_DESKTOP_SHORTCUTS_H__
1662+
1663+#include <gio/gio.h>
1664+#include <glib.h>
1665+#include <glib-object.h>
1666+
1667+G_BEGIN_DECLS
1668+
1669+#define INDICATOR_TYPE_DESKTOP_SHORTCUTS (indicator_desktop_shortcuts_get_type ())
1670+#define INDICATOR_DESKTOP_SHORTCUTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcuts))
1671+#define INDICATOR_DESKTOP_SHORTCUTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsClass))
1672+#define INDICATOR_IS_DESKTOP_SHORTCUTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS))
1673+#define INDICATOR_IS_DESKTOP_SHORTCUTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_TYPE_DESKTOP_SHORTCUTS))
1674+#define INDICATOR_DESKTOP_SHORTCUTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsClass))
1675+
1676+typedef struct _IndicatorDesktopShortcuts IndicatorDesktopShortcuts;
1677+typedef struct _IndicatorDesktopShortcutsClass IndicatorDesktopShortcutsClass;
1678+
1679+/**
1680+ IndicatorDesktopShortcutsClass:
1681+ @parent_class: Space for #GObjectClass
1682+
1683+ The vtable for our precious #IndicatorDesktopShortcutsClass.
1684+*/
1685+struct _IndicatorDesktopShortcutsClass {
1686+ GObjectClass parent_class;
1687+};
1688+
1689+/**
1690+ IndicatorDesktopShortcuts:
1691+ @parent: The parent data from #GObject
1692+
1693+ The public data for an instance of the class
1694+ #IndicatorDesktopShortcuts.
1695+*/
1696+struct _IndicatorDesktopShortcuts {
1697+ GObject parent;
1698+};
1699+
1700+GType indicator_desktop_shortcuts_get_type (void);
1701+IndicatorDesktopShortcuts * indicator_desktop_shortcuts_new (const gchar * file,
1702+ const gchar * identity);
1703+const gchar ** indicator_desktop_shortcuts_get_nicks (IndicatorDesktopShortcuts * ids);
1704+gchar * indicator_desktop_shortcuts_nick_get_name (IndicatorDesktopShortcuts * ids,
1705+ const gchar * nick);
1706+gboolean indicator_desktop_shortcuts_nick_exec_with_context (IndicatorDesktopShortcuts * ids,
1707+ const gchar * nick,
1708+ GAppLaunchContext * launch_context);
1709+
1710+GLIB_DEPRECATED_FOR(indicator_desktop_shortcuts_nick_exec_with_context)
1711+gboolean indicator_desktop_shortcuts_nick_exec (IndicatorDesktopShortcuts * ids,
1712+ const gchar * nick);
1713+
1714+G_END_DECLS
1715+
1716+#endif
1717
1718=== modified file 'tests/Makefile.am'
1719--- tests/Makefile.am 2013-12-19 14:37:54 +0000
1720+++ tests/Makefile.am 2020-04-08 18:54:42 +0000
1721@@ -32,7 +32,7 @@
1722 test_libappindicator_CFLAGS = \
1723 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1724 -DSRCDIR="\"$(srcdir)\"" \
1725- -Wall -Werror -Wno-error=deprecated-declarations \
1726+ -Wall -Wno-error=deprecated-declarations \
1727 -I$(top_srcdir)/src
1728
1729 test_libappindicator_LDADD = \
1730@@ -49,7 +49,7 @@
1731
1732 test_libappindicator_dbus_client_CFLAGS = \
1733 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1734- -Wall -Werror -Wno-error=deprecated-declarations \
1735+ -Wall -Wno-error=deprecated-declarations \
1736 -I$(top_srcdir)/src
1737
1738 test_libappindicator_dbus_client_LDADD = \
1739@@ -66,7 +66,7 @@
1740
1741 test_libappindicator_dbus_server_CFLAGS = \
1742 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1743- -Wall -Werror -Wno-error=deprecated-declarations \
1744+ -Wall -Wno-error=deprecated-declarations \
1745 -I$(top_srcdir)/src
1746
1747 test_libappindicator_dbus_server_LDADD = \
1748@@ -83,7 +83,7 @@
1749
1750 test_libappindicator_status_client_CFLAGS = \
1751 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1752- -Wall -Werror -Wno-error=deprecated-declarations \
1753+ -Wall -Wno-error=deprecated-declarations \
1754 -I$(top_srcdir)/src
1755
1756 test_libappindicator_status_client_LDADD = \
1757@@ -100,7 +100,7 @@
1758
1759 test_libappindicator_status_server_CFLAGS = \
1760 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1761- -Wall -Werror -Wno-error=deprecated-declarations \
1762+ -Wall -Wno-error=deprecated-declarations \
1763 -I$(top_srcdir)/src
1764
1765 test_libappindicator_status_server_LDADD = \
1766@@ -116,7 +116,7 @@
1767
1768 test_libappindicator_fallback_watcher_CFLAGS = \
1769 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1770- -Wall -Werror -Wno-error=deprecated-declarations \
1771+ -Wall -Wno-error=deprecated-declarations \
1772 -I$(top_srcdir)/src
1773
1774 test_libappindicator_fallback_watcher_LDADD = \
1775@@ -128,7 +128,7 @@
1776
1777 test_libappindicator_fallback_item_CFLAGS = \
1778 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1779- -Wall -Werror -Wno-error=deprecated-declarations \
1780+ -Wall -Wno-error=deprecated-declarations \
1781 -I$(top_srcdir)/src
1782
1783 test_libappindicator_fallback_item_LDADD = \
1784@@ -198,7 +198,7 @@
1785
1786 test_simple_app_CFLAGS = \
1787 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
1788- -Wall -Werror -Wno-error=deprecated-declarations \
1789+ -Wall -Wno-error=deprecated-declarations \
1790 -I$(top_srcdir)/src
1791
1792 test_simple_app_LDADD = \

Subscribers

People subscribed via source and target branches