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
=== modified file 'bindings/Makefile.am'
--- bindings/Makefile.am 2012-06-10 07:32:04 +0000
+++ bindings/Makefile.am 2020-04-08 18:54:42 +0000
@@ -1,10 +1,7 @@
1SUBDIRS =
2
1if USE_GTK33if USE_GTK3
2SUBDIRS = \4SUBDIRS += vala
3 vala
4else
5SUBDIRS = \
6 python \
7 vala
8endif5endif
96
10if HAS_MONO7if HAS_MONO
118
=== removed directory 'bindings/python'
=== removed file 'bindings/python/Makefile.am'
=== removed file 'bindings/python/__init__.py'
=== removed file 'bindings/python/appindicator-arg-types.py'
=== removed file 'bindings/python/appindicator.defs'
=== removed file 'bindings/python/appindicator.override.in'
=== removed file 'bindings/python/appindicatormodule.c'
=== modified file 'configure.ac'
--- configure.ac 2013-01-29 17:50:13 +0000
+++ configure.ac 2020-04-08 18:54:42 +0000
@@ -44,7 +44,6 @@
44GTK3_REQUIRED_VERSION=2.9144GTK3_REQUIRED_VERSION=2.91
45GLIB_REQUIRED_VERSION=2.35.445GLIB_REQUIRED_VERSION=2.35.4
46GIO_REQUIRED_VERSION=2.2646GIO_REQUIRED_VERSION=2.26
47INDICATOR_REQUIRED_VERSION=0.4.93
48DBUSMENUGTK_REQUIRED_VERSION=0.5.9047DBUSMENUGTK_REQUIRED_VERSION=0.5.90
49DBUS_GLIB_REQUIRED_VERSION=0.8248DBUS_GLIB_REQUIRED_VERSION=0.82
5049
@@ -56,16 +55,16 @@
56AS_IF([test "x$with_gtk" = x3],55AS_IF([test "x$with_gtk" = x3],
57 [PKG_CHECK_MODULES(LIBRARY, gtk+-3.0 >= $GTK3_REQUIRED_VERSION56 [PKG_CHECK_MODULES(LIBRARY, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
58 glib-2.0 >= $GLIB_REQUIRED_VERSION57 glib-2.0 >= $GLIB_REQUIRED_VERSION
58 gio-unix-2.0
59 gio-2.0 >= $GIO_REQUIRED_VERSION59 gio-2.0 >= $GIO_REQUIRED_VERSION
60 indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION
61 dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)60 dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
62 AC_DEFINE(HAVE_GTK3, 1, [whether gtk3 is available])61 AC_DEFINE(HAVE_GTK3, 1, [whether gtk3 is available])
63 ],62 ],
64 [test "x$with_gtk" = x2],63 [test "x$with_gtk" = x2],
65 [PKG_CHECK_MODULES(LIBRARY, gtk+-2.0 >= $GTK_REQUIRED_VERSION64 [PKG_CHECK_MODULES(LIBRARY, gtk+-2.0 >= $GTK_REQUIRED_VERSION
66 glib-2.0 >= $GLIB_REQUIRED_VERSION65 glib-2.0 >= $GLIB_REQUIRED_VERSION
66 gio-unix-2.0
67 gio-2.0 >= $GIO_REQUIRED_VERSION67 gio-2.0 >= $GIO_REQUIRED_VERSION
68 indicator-0.4 >= $INDICATOR_REQUIRED_VERSION
69 dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)68 dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
70 ],69 ],
71 [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])]70 [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])]
@@ -121,7 +120,7 @@
121 RUNTIME=mono120 RUNTIME=mono
122 fi121 fi
123122
124 AC_PATH_PROG(CSC, gmcs, no)123 AC_PATH_PROG(CSC, mono-csc, no)
125 LIB_PREFIX=.so124 LIB_PREFIX=.so
126 LIB_SUFFIX=125 LIB_SUFFIX=
127fi126fi
@@ -181,33 +180,6 @@
181with_localinstall="no"180with_localinstall="no"
182AC_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)181AC_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)
183182
184###########################
185# Python
186###########################
187
188PYGTK_REQUIRED=2.14.0
189PYGOBJECT_REQUIRED=0.22
190
191AM_PATH_PYTHON(2.3.5)
192AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
193
194PKG_CHECK_MODULES(APPINDICATOR_PYTHON,
195 [
196 pygtk-2.0 >= $PYGTK_REQUIRED
197 gtk+-2.0 >= $GTK_REQUIRED_VERSION
198 pygobject-2.0 >= $PYGOBJECT_REQUIRED
199 ])
200
201AC_MSG_CHECKING(for pygtk defs)
202PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
203AC_SUBST(PYGTK_DEFSDIR)
204AC_MSG_RESULT($PYGTK_DEFSDIR)
205
206AC_MSG_CHECKING(for pygtk codegen)
207PYGTK_CODEGEN="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/codegen.py"
208AC_SUBST(PYGTK_CODEGEN)
209AC_MSG_RESULT($PYGTK_CODEGEN)
210
211#########################183#########################
212# Check if build tests184# Check if build tests
213#########################185#########################
@@ -239,8 +211,6 @@
239src/appindicator-0.1.pc211src/appindicator-0.1.pc
240src/appindicator3-0.1.pc212src/appindicator3-0.1.pc
241bindings/Makefile213bindings/Makefile
242bindings/python/Makefile
243bindings/python/appindicator.override
244bindings/vala/Makefile214bindings/vala/Makefile
245bindings/vala/examples/Makefile215bindings/vala/examples/Makefile
246tests/Makefile216tests/Makefile
247217
=== modified file 'debian/changelog'
--- debian/changelog 2016-09-05 18:32:14 +0000
+++ debian/changelog 2020-04-08 18:54:42 +0000
@@ -1,3 +1,91 @@
1libappindicator (12.10.1+18.04.20180322.1-0ubuntu7) UNRELEASED; urgency=medium
2
3 [ Paul G ]
4 * app-indicator: Don't pass unexpected parameter to signal emissions
5 (LP: #1867996)
6
7 [ Ash Holland ]
8 * app-indicator: Only check for item numbers when iterating array
9 (LP: #1867996)
10
11 -- Marco Trevisan (Treviño) <marco@ubuntu.com> Wed, 08 Apr 2020 17:55:12 +0200
12
13libappindicator (12.10.1+18.04.20180322.1-0ubuntu6) focal; urgency=medium
14
15 * Disable mono on riscv64 too.
16
17 -- William Grant <wgrant@ubuntu.com> Mon, 06 Apr 2020 18:15:21 +1000
18
19libappindicator (12.10.1+18.04.20180322.1-0ubuntu5) focal; urgency=medium
20
21 * configure.ac: require gio-unix-2.0, it's need for gdesktopappinfo
22 which was added in one of the recent uploads
23
24 [ Jeremy Bicha ]
25 * Drop python-appindicator and gir1.2-appindicator-0.1 packages
26 (LP: #1740637)
27
28 -- Sebastien Bacher <seb128@ubuntu.com> Tue, 17 Dec 2019 15:36:01 +0100
29
30libappindicator (12.10.1+18.04.20180322.1-0ubuntu4) eoan; urgency=medium
31
32 * Don't build with -Werror.
33 * Drop hard coded dependency on multiarch-support.
34
35 -- Matthias Klose <doko@ubuntu.com> Sun, 01 Sep 2019 05:58:07 +0200
36
37libappindicator (12.10.1+18.04.20180322.1-0ubuntu2) disco; urgency=medium
38
39 * Vendorize indicator-desktop-shortcuts (convenience wrapper around
40 gdesktopappinfo) from libindicator project, to drop the dependency on
41 libindicator as none of the rest of it is used.
42
43 -- Dimitri John Ledkov <xnox@ubuntu.com> Thu, 21 Feb 2019 00:40:40 +0100
44
45libappindicator (12.10.1+18.04.20180322.1-0ubuntu1) bionic; urgency=medium
46
47 [ Unit 193 ]
48 * Have -dev package depend on libgtk2.0-dev or libgk-3-dev according
49 to its pkgconfig file (LP: #1757574) (LP: #1757574)
50
51 -- Jeremy Bicha <jbicha@ubuntu.com> Thu, 22 Mar 2018 01:16:11 +0000
52
53libappindicator (12.10.1+18.04.20180320-0ubuntu1) bionic; urgency=medium
54
55 [ Olivier Tilloy ]
56 * Fix build failures on bionic, (LP: #1757121)
57
58 -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 20 Mar 2018 12:48:14 +0000
59
60libappindicator (12.10.1+17.04.20170215-0ubuntu2) artful; urgency=medium
61
62 * debian/control:
63 - Downgrade libappindicator* recommending the indicator-application
64 service to suggests. Only some sessions wants it, while we still
65 link against the lib in multiple apps.
66
67 -- Didier Roche <didrocks@ubuntu.com> Wed, 19 Jul 2017 13:28:58 +0200
68
69libappindicator (12.10.1+17.04.20170215-0ubuntu1) zesty; urgency=medium
70
71 * app-indicator: don't append the snap prefix if the icon is saved in
72 a well known readable path
73
74 -- Marco Trevisan (Treviño) <mail@3v1n0.net> Wed, 15 Feb 2017 14:16:09 +0000
75
76libappindicator (12.10.1+17.04.20170213-0ubuntu1) zesty; urgency=medium
77
78 * AppIndicator: don't emit label cahanges when guide is still empty
79
80 -- Marco Trevisan (Treviño) <mail@3v1n0.net> Mon, 13 Feb 2017 17:16:38 +0000
81
82libappindicator (12.10.1+17.04.20161129-0ubuntu1) zesty; urgency=medium
83
84 * AppIndicator: fix icon and theme paths when running in $SNAP
85 environment (LP: #1600136)
86
87 -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 29 Nov 2016 18:04:06 +0000
88
1libappindicator (12.10.1+16.10.20160905-0ubuntu1) yakkety; urgency=medium89libappindicator (12.10.1+16.10.20160905-0ubuntu1) yakkety; urgency=medium
290
3 [ Alberts Muktupāvels ]91 [ Alberts Muktupāvels ]
492
=== modified file 'debian/control'
--- debian/control 2013-12-19 14:37:54 +0000
+++ debian/control 2020-04-08 18:54:42 +0000
@@ -1,31 +1,27 @@
1Source: libappindicator1Source: libappindicator
2Section: gnome2Section: gnome
3Priority: optional3Priority: optional
4XS-Python-Version: all
5Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>4Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
6Build-Depends: debhelper (>= 9),5Build-Depends: debhelper (>= 9),
7 dh-autoreconf,6 dh-autoreconf,
8 python-all-dev,
9 at-spi2-core,7 at-spi2-core,
10 cli-common-dev (>= 0.5.7) [!arm64 !ppc64el],8 cli-common-dev (>= 0.5.7) [!arm64 !ppc64el !riscv64],
9 gnome-common,
11 gobject-introspection,10 gobject-introspection,
12 intltool,11 intltool,
13 gtk-doc-tools,12 gtk-doc-tools,
14 libxml2-utils,13 libxml2-utils,
15 libnunit-cil-dev [!arm64 !ppc64el],14 libnunit-cil-dev [!arm64 !ppc64el !riscv64],
16 dbus-test-runner,15 dbus-test-runner,
17 xvfb,16 xvfb,
18 valac,17 valac,
19 mono-devel (>= 2.4.3) [!arm64 !ppc64el],18 mono-devel (>= 2.4.3) [!arm64 !ppc64el !riscv64],
20 libglib2.0-dev (>= 2.35.4),19 libglib2.0-dev (>= 2.35.4),
21 libgtk-3-dev (>= 2.91.3),20 libgtk-3-dev (>= 2.91.3),
22 libgtk2.0-dev (>= 2.12.0),21 libgtk2.0-dev (>= 2.12.0),
23 python-gtk2-dev,22 gtk-sharp2-gapi [!arm64 !ppc64el !riscv64],
24 gtk-sharp2-gapi [!arm64 !ppc64el],23 libgtk2.0-cil-dev [!arm64 !ppc64el !riscv64],
25 libgtk2.0-cil-dev [!arm64 !ppc64el],
26 libdbus-glib-1-dev (>= 0.82),24 libdbus-glib-1-dev (>= 0.82),
27 libindicator-dev (>= 0.3.90),
28 libindicator3-dev (>= 0.3.90),
29 libdbusmenu-glib-dev (>= 0.5.90),25 libdbusmenu-glib-dev (>= 0.5.90),
30 libdbusmenu-gtk-dev (>= 0.5.90),26 libdbusmenu-gtk-dev (>= 0.5.90),
31 libdbusmenu-gtk3-dev (>= 0.5.90),27 libdbusmenu-gtk3-dev (>= 0.5.90),
@@ -35,54 +31,29 @@
35# If you aren't a member of ~indicator-applet-developers but need to upload31# If you aren't a member of ~indicator-applet-developers but need to upload
36# packaging changes, just go ahead. ~indicator-applet-developers will notice32# packaging changes, just go ahead. ~indicator-applet-developers will notice
37# and sync up the code again.33# and sync up the code again.
38Vcs-Bzr: https://code.launchpad.net/~indicator-applet-developers/libappindicator/trunk.13.0434Vcs-Bzr: https://code.launchpad.net/~indicator-applet-developers/libappindicator/trunk.16.10
39Vcs-Browser: https://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk.13.04/files35Vcs-Browser: https://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk.16.10/files
40
41Package: python-appindicator
42Section: python
43Architecture: any
44XB-Python-Version: ${python:Versions}
45Depends: ${shlibs:Depends},
46 ${misc:Depends},
47 ${python:Depends},
48 libappindicator1 (= ${binary:Version}),
49 python-gobject,
50Provides: ${python:Provides},
51Description: Python bindings for libappindicator
52 This package provides Python bindings so that you can use libappindicator from
53 a Python program.
5436
55Package: libappindicator137Package: libappindicator1
56Section: libs38Section: libs
57Architecture: any39Architecture: any
58Pre-Depends: multiarch-support,
59Depends: ${shlibs:Depends},40Depends: ${shlibs:Depends},
60 ${misc:Depends},41 ${misc:Depends},
61Recommends: indicator-application (>= 0.2.93),42Suggests: indicator-application (>= 0.2.93),
62Description: Application Indicators43Description: Application Indicators
63 A library and indicator to take menus from applications and place them in44 A library and indicator to take menus from applications and place them in
64 the panel.45 the panel.
65 .46 .
66 This package contains shared libraries to be used by applications.47 This package contains shared libraries to be used by applications.
6748
68Package: gir1.2-appindicator-0.1
69Section: introspection
70Architecture: any
71Depends: ${misc:Depends},
72 ${gir:Depends},
73Description: Typelib files for libappindicator1.
74 .
75 This package can be used by other packages using the GIRepository format
76 to generate dynamic bindings.
77
78Package: libappindicator-dev49Package: libappindicator-dev
79Section: libdevel50Section: libdevel
80Architecture: any51Architecture: any
81Depends: ${shlibs:Depends},52Depends: ${shlibs:Depends},
82 ${misc:Depends},53 ${misc:Depends},
83 gir1.2-appindicator-0.1 (= ${binary:Version}),
84 libdbusmenu-glib-dev (>= 0.1.8),54 libdbusmenu-glib-dev (>= 0.1.8),
85 libdbus-glib-1-dev (>= 0.76),55 libdbus-glib-1-dev (>= 0.76),
56 libgtk2.0-dev,
86 libappindicator1 (= ${binary:Version}),57 libappindicator1 (= ${binary:Version}),
87Description: Application Indicators58Description: Application Indicators
88 A library and indicator to take menus from applications and place them in59 A library and indicator to take menus from applications and place them in
@@ -103,10 +74,9 @@
103Package: libappindicator3-174Package: libappindicator3-1
104Section: libs75Section: libs
105Architecture: any76Architecture: any
106Pre-Depends: multiarch-support,
107Depends: ${shlibs:Depends},77Depends: ${shlibs:Depends},
108 ${misc:Depends},78 ${misc:Depends},
109Recommends: indicator-application (>= 0.2.93),79Suggests: indicator-application (>= 0.2.93),
110Description: Application Indicators80Description: Application Indicators
111 A library and indicator to take menus from applications and place them in81 A library and indicator to take menus from applications and place them in
112 the panel.82 the panel.
@@ -121,6 +91,7 @@
121 gir1.2-appindicator3-0.1 (= ${binary:Version}),91 gir1.2-appindicator3-0.1 (= ${binary:Version}),
122 libdbusmenu-glib-dev (>= 0.1.8),92 libdbusmenu-glib-dev (>= 0.1.8),
123 libdbus-glib-1-dev (>= 0.76),93 libdbus-glib-1-dev (>= 0.76),
94 libgtk-3-dev,
124 libappindicator3-1 (= ${binary:Version}),95 libappindicator3-1 (= ${binary:Version}),
125Description: Application Indicators96Description: Application Indicators
126 A library and indicator to take menus from applications and place them in97 A library and indicator to take menus from applications and place them in
12798
=== removed file 'debian/gir1.2-appindicator-0.1.install'
=== modified file 'debian/libappindicator-dev.install'
--- debian/libappindicator-dev.install 2012-11-27 02:18:17 +0000
+++ debian/libappindicator-dev.install 2020-04-08 18:54:42 +0000
@@ -1,5 +1,3 @@
1usr/include/libappindicator-0.1/*1usr/include/libappindicator-0.1/*
2usr/lib/*/libappindicator.so2usr/lib/*/libappindicator.so
3usr/lib/*/pkgconfig/appindicator-0.1.pc3usr/lib/*/pkgconfig/appindicator-0.1.pc
4usr/share/gir-1.0/AppIndicator-0.1.gir
5usr/share/vala/vapi/appindicator-0.1.vapi
64
=== removed file 'debian/python-appindicator.install'
=== modified file 'debian/rules' (properties changed: +x to -x)
--- debian/rules 2013-12-19 14:37:54 +0000
+++ debian/rules 2020-04-08 18:54:42 +0000
@@ -1,13 +1,12 @@
1#!/usr/bin/make -f1#!/usr/bin/make -f
22
3FLAVORS = gtk2 gtk33FLAVORS = gtk2 gtk3
4PY_VERSIONS = $(shell pyversions --requested debian/control)
5API_VERSION = 0.14API_VERSION = 0.1
65
7DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)6DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
87
9CONFIGURE_COMMON_FLAGS = --disable-scrollkeeper --enable-introspection8CONFIGURE_COMMON_FLAGS = --disable-scrollkeeper --enable-introspection
10ifneq (,$(filter $(DEB_HOST_ARCH),arm64 ppc64el))9ifneq (,$(filter $(DEB_HOST_ARCH),arm64 ppc64el riscv64))
11 CONFIGURE_COMMON_FLAGS += --disable-mono-test10 CONFIGURE_COMMON_FLAGS += --disable-mono-test
12else11else
13 dh_extra_args = ,cli12 dh_extra_args = ,cli
@@ -15,14 +14,12 @@
15CONFIGURE_FLAGS_gtk2 = --with-gtk=2 --enable-gtk-doc14CONFIGURE_FLAGS_gtk2 = --with-gtk=2 --enable-gtk-doc
16CONFIGURE_FLAGS_gtk3 = --with-gtk=3 --enable-gtk-doc=no15CONFIGURE_FLAGS_gtk3 = --with-gtk=3 --enable-gtk-doc=no
1716
18export CSC=/usr/bin/mono-csc
19
20export DPKG_GENSYMBOLS_CHECK_LEVEL = 417export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
2118
22CFLAGS += -fPIC19CFLAGS += -fPIC
2320
24%:21%:
25 dh $@ --with autoreconf,python2,gir$(dh_extra_args)22 dh $@ --with autoreconf,gir$(dh_extra_args)
2623
27override_dh_autoreconf:24override_dh_autoreconf:
28 NOCONFIGURE=1 dh_autoreconf ./autogen.sh25 NOCONFIGURE=1 dh_autoreconf ./autogen.sh
@@ -32,24 +29,16 @@
32doconfigure-%:29doconfigure-%:
33 dh_auto_configure --builddirectory=build/$* -- $(CONFIGURE_FLAGS_$*) $(CONFIGURE_COMMON_FLAGS)30 dh_auto_configure --builddirectory=build/$* -- $(CONFIGURE_FLAGS_$*) $(CONFIGURE_COMMON_FLAGS)
3431
35doconfigure-gtk2: $(PY_VERSIONS:%=doconfiguregtk2-%)
36 # GTK2 flavor configure was run on a per-python-version basis.
37
38doconfiguregtk2-%:32doconfiguregtk2-%:
39 PYTHON=`which $*` \33 dh_auto_configure --builddirectory=build/gtk2 -- $(CONFIGURE_FLAGS_gtk2) $(CONFIGURE_COMMON_FLAGS)
40 dh_auto_configure --builddirectory=build/gtk2 -- $(CONFIGURE_FLAGS_gtk2) $(CONFIGURE_COMMON_FLAGS)
4134
42override_dh_auto_build: $(FLAVORS:%=dobuild-%)35override_dh_auto_build: $(FLAVORS:%=dobuild-%)
4336
44dobuild-%:37dobuild-%:
45 dh_auto_build --builddirectory=build/$*38 dh_auto_build --builddirectory=build/$*
4639
47dobuild-gtk2: $(PY_VERSIONS:%=dobuildgtk2-%)
48 # GTK2 flavor build was run on a per-python-version basis.
49
50dobuildgtk2-%:40dobuildgtk2-%:
51 PYTHON=`which $*` \41 dh_auto_build --builddirectory=build/gtk2
52 dh_auto_build --builddirectory=build/gtk2
5342
54override_dh_auto_install: $(FLAVORS:%=doinstall-%)43override_dh_auto_install: $(FLAVORS:%=doinstall-%)
5544
@@ -61,9 +50,7 @@
61 find debian/tmp -name \*.a -exec rm {} \;50 find debian/tmp -name \*.a -exec rm {} \;
62 rm -rf debian/tmp/*/usr/lib/mono51 rm -rf debian/tmp/*/usr/lib/mono
63 rm -rf debian/tmp/*/usr/share/vala/vapi/appindicator*-0.1.deps52 rm -rf debian/tmp/*/usr/share/vala/vapi/appindicator*-0.1.deps
64 dh_install -ppython-appindicator --fail-missing --sourcedir=debian/tmp/gtk2
65 dh_install -plibappindicator1 --fail-missing --sourcedir=debian/tmp/gtk253 dh_install -plibappindicator1 --fail-missing --sourcedir=debian/tmp/gtk2
66 dh_install -pgir1.2-appindicator-0.1 --fail-missing --sourcedir=debian/tmp/gtk2
67 dh_install -plibappindicator-dev --fail-missing --sourcedir=debian/tmp/gtk254 dh_install -plibappindicator-dev --fail-missing --sourcedir=debian/tmp/gtk2
68 dh_install -plibappindicator-doc --fail-missing --sourcedir=debian/tmp/gtk255 dh_install -plibappindicator-doc --fail-missing --sourcedir=debian/tmp/gtk2
69 dh_install -plibappindicator3-1 --fail-missing --sourcedir=debian/tmp/gtk356 dh_install -plibappindicator3-1 --fail-missing --sourcedir=debian/tmp/gtk3
@@ -77,15 +64,10 @@
77dotest-%:64dotest-%:
78 dh_auto_test --builddirectory=build/$* --65 dh_auto_test --builddirectory=build/$* --
7966
80
81dotest-gtk2: $(PY_VERSIONS:%=dotestgtk2-%)
82 # GTK2 flavor test was run on a per-python-version basis.
83
84dotestgtk2-%:67dotestgtk2-%:
85 ps -ef68 ps -ef
86 env69 env
87 PYTHON=`which $*` \70 dh_auto_test --builddirectory=build/gtk2 --
88 dh_auto_test --builddirectory=build/gtk2 --
8971
90override_dh_auto_clean:72override_dh_auto_clean:
91 dh_auto_clean73 dh_auto_clean
9274
=== modified file 'docs/reference/Makefile.am'
--- docs/reference/Makefile.am 2013-06-08 04:26:37 +0000
+++ docs/reference/Makefile.am 2020-04-08 18:54:42 +0000
@@ -33,7 +33,7 @@
33DOC_SOURCE_DIR=$(top_srcdir)/src33DOC_SOURCE_DIR=$(top_srcdir)/src
3434
35# Extra options to pass to gtkdoc-scangobj. Not normally needed.35# Extra options to pass to gtkdoc-scangobj. Not normally needed.
36SCANGOBJ_OPTIONS=--nogtkinit --type-init-func="g_type_init()"36SCANGOBJ_OPTIONS=--type-init-func="g_type_init()"
3737
38# Extra options to supply to gtkdoc-scan.38# Extra options to supply to gtkdoc-scan.
39# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"39# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
4040
=== modified file 'example/simple-client-vala.vala'
--- example/simple-client-vala.vala 2012-03-21 18:02:41 +0000
+++ example/simple-client-vala.vala 2020-04-08 18:54:42 +0000
@@ -104,7 +104,7 @@
104 print(@"Got scroll event! delta: $delta, direction: $direction\n");104 print(@"Got scroll event! delta: $delta, direction: $direction\n");
105 });105 });
106106
107 Timeout.add_seconds(1, () => {107 GLib.Timeout.add_seconds(1, () => {
108 percentage = (percentage + 1) % 100;108 percentage = (percentage + 1) % 100;
109 if (can_haz_label) {109 if (can_haz_label) {
110 ci.set_label(@"$(percentage+1)%", "");110 ci.set_label(@"$(percentage+1)%", "");
111111
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2013-12-19 14:37:54 +0000
+++ src/Makefile.am 2020-04-08 18:54:42 +0000
@@ -62,6 +62,8 @@
62 dbus-shared.h \62 dbus-shared.h \
63 generate-id.h \63 generate-id.h \
64 generate-id.c \64 generate-id.c \
65 indicator-desktop-shortcuts.c \
66 indicator-desktop-shortcuts.h \
65 gen-notification-item.xml.h \67 gen-notification-item.xml.h \
66 gen-notification-item.xml.c \68 gen-notification-item.xml.c \
67 gen-notification-watcher.xml.h \69 gen-notification-watcher.xml.h \
@@ -71,12 +73,12 @@
71 $(COVERAGE_LDFLAGS) \73 $(COVERAGE_LDFLAGS) \
72 -version-info 1:0:0 \74 -version-info 1:0:0 \
73 -no-undefined \75 -no-undefined \
74 -export-symbols-regex "^[^_d].*"76 -export-symbols-regex "^app_indicator_.*"
7577
76libappindicator_la_CFLAGS = \78libappindicator_la_CFLAGS = \
77 $(LIBRARY_CFLAGS) \79 $(LIBRARY_CFLAGS) \
78 $(COVERAGE_CFLAGS) \80 $(COVERAGE_CFLAGS) \
79 -Wall -Werror -Wno-error=deprecated-declarations \81 -Wall -Wno-error=deprecated-declarations \
80 -DG_LOG_DOMAIN=\"libappindicator\"82 -DG_LOG_DOMAIN=\"libappindicator\"
8183
82libappindicator_la_LIBADD = \84libappindicator_la_LIBADD = \
@@ -153,29 +155,23 @@
153 $(addprefix $(srcdir)/,app-indicator.c) \155 $(addprefix $(srcdir)/,app-indicator.c) \
154 $(addprefix $(srcdir)/,$(libappindicator_headers))156 $(addprefix $(srcdir)/,$(libappindicator_headers))
155157
156AppIndicator$(VER)-0.1.gir: libappindicator$(VER).la158AppIndicator3-0.1.gir: libappindicator3.la
157159
158AppIndicator_0_1_gir_INCLUDES = \160AppIndicator3_0_1_gir_INCLUDES = \
159 GObject-2.0 \161 GObject-2.0 \
160 $(GTKGIR)162 $(GTKGIR)
161AppIndicator_0_1_gir_CFLAGS = $(LIBRARY_CFLAGS) -I$(srcdir) -I$(top_builddir)/src163AppIndicator3_0_1_gir_CFLAGS = $(LIBRARY_CFLAGS) -I$(srcdir) -I$(top_builddir)/src
162AppIndicator_0_1_gir_LIBS = libappindicator$(VER).la164AppIndicator3_0_1_gir_LIBS = libappindicator3.la
163AppIndicator_0_1_gir_FILES = $(introspection_sources)165AppIndicator3_0_1_gir_FILES = $(introspection_sources)
164# AppIndicator_0_1_gir_NAMESPACE = AppIndicator
165
166AppIndicator3_0_1_gir_INCLUDES = $(AppIndicator_0_1_gir_INCLUDES)
167AppIndicator3_0_1_gir_CFLAGS = $(AppIndicator_0_1_gir_CFLAGS)
168AppIndicator3_0_1_gir_LIBS = $(AppIndicator_0_1_gir_LIBS)
169AppIndicator3_0_1_gir_FILES = $(AppIndicator_0_1_gir_FILES)
170# AppIndicator3_0_1_gir_NAMESPACE = AppIndicator166# AppIndicator3_0_1_gir_NAMESPACE = AppIndicator
171167
172INTROSPECTION_GIRS += AppIndicator$(VER)-0.1.gir168INTROSPECTION_GIRS += AppIndicator3-0.1.gir
173169
174AppIndicator$(VER)-0.1.metadata: AppIndicator$(VER)-0.1.gir170AppIndicator3-0.1.metadata: AppIndicator3-0.1.gir
175 cp -f $(srcdir)/$@.in $@171 cp -f $(srcdir)/$@.in $@
176172
177BUILT_SOURCES += AppIndicator$(VER)-0.1.metadata173BUILT_SOURCES += AppIndicator3-0.1.metadata
178CLEANFILES += AppIndicator$(VER)-0.1.metadata174CLEANFILES += AppIndicator3-0.1.metadata
179175
180girdir = $(datadir)/gir-1.0176girdir = $(datadir)/gir-1.0
181gir_DATA = $(INTROSPECTION_GIRS)177gir_DATA = $(INTROSPECTION_GIRS)
182178
=== modified file 'src/app-indicator.c'
--- src/app-indicator.c 2015-07-02 17:03:37 +0000
+++ src/app-indicator.c 2020-04-08 18:54:42 +0000
@@ -36,7 +36,9 @@
36#include <libdbusmenu-gtk/client.h>36#include <libdbusmenu-gtk/client.h>
37#include <libdbusmenu-gtk/parser.h>37#include <libdbusmenu-gtk/parser.h>
3838
39#include <libindicator/indicator-desktop-shortcuts.h>39#include "indicator-desktop-shortcuts.h"
40
41#include <stdlib.h>
4042
41#include "app-indicator.h"43#include "app-indicator.h"
42#include "app-indicator-enum-types.h"44#include "app-indicator-enum-types.h"
@@ -71,8 +73,11 @@
71 AppIndicatorCategory category;73 AppIndicatorCategory category;
72 AppIndicatorStatus status;74 AppIndicatorStatus status;
73 gchar *icon_name;75 gchar *icon_name;
76 gchar *absolute_icon_name;
74 gchar *attention_icon_name;77 gchar *attention_icon_name;
78 gchar *absolute_attention_icon_name;
75 gchar *icon_theme_path;79 gchar *icon_theme_path;
80 gchar *absolute_icon_theme_path;
76 DbusmenuServer *menuservice;81 DbusmenuServer *menuservice;
77 GtkWidget *menu;82 GtkWidget *menu;
78 GtkWidget *sec_activate_target;83 GtkWidget *sec_activate_target;
@@ -190,6 +195,8 @@
190static void status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data);195static void status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data);
191static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);196static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);
192static gchar * append_panel_icon_suffix (const gchar * icon_name);197static gchar * append_panel_icon_suffix (const gchar * icon_name);
198static gchar * get_real_theme_path (AppIndicator * self);
199static gchar * append_snap_prefix (const gchar * path);
193static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);200static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);
194static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);201static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);
195static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);202static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);
@@ -389,7 +396,7 @@
389 "An additional place to look for icon names that may be installed by the application.",396 "An additional place to look for icon names that may be installed by the application.",
390 NULL,397 NULL,
391 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));398 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
392 399
393 /**400 /**
394 * AppIndicator:connected:401 * AppIndicator:connected:
395 * 402 *
@@ -501,7 +508,7 @@
501 G_STRUCT_OFFSET (AppIndicatorClass, new_icon),508 G_STRUCT_OFFSET (AppIndicatorClass, new_icon),
502 NULL, NULL,509 NULL, NULL,
503 g_cclosure_marshal_VOID__VOID,510 g_cclosure_marshal_VOID__VOID,
504 G_TYPE_NONE, 0, G_TYPE_NONE);511 G_TYPE_NONE, 0);
505512
506 /**513 /**
507 * AppIndicator::new-attention-icon:514 * AppIndicator::new-attention-icon:
@@ -515,7 +522,7 @@
515 G_STRUCT_OFFSET (AppIndicatorClass, new_attention_icon),522 G_STRUCT_OFFSET (AppIndicatorClass, new_attention_icon),
516 NULL, NULL,523 NULL, NULL,
517 g_cclosure_marshal_VOID__VOID,524 g_cclosure_marshal_VOID__VOID,
518 G_TYPE_NONE, 0, G_TYPE_NONE);525 G_TYPE_NONE, 0);
519526
520 /**527 /**
521 * AppIndicator::new-status:528 * AppIndicator::new-status:
@@ -563,7 +570,7 @@
563 G_STRUCT_OFFSET (AppIndicatorClass, connection_changed),570 G_STRUCT_OFFSET (AppIndicatorClass, connection_changed),
564 NULL, NULL,571 NULL, NULL,
565 g_cclosure_marshal_VOID__BOOLEAN,572 g_cclosure_marshal_VOID__BOOLEAN,
566 G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE);573 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
567574
568 /**575 /**
569 * AppIndicator::new-icon-theme-path:576 * AppIndicator::new-icon-theme-path:
@@ -640,6 +647,7 @@
640app_indicator_init (AppIndicator *self)647app_indicator_init (AppIndicator *self)
641{648{
642 AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self);649 AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self);
650 self->priv = priv;
643651
644 priv->id = NULL;652 priv->id = NULL;
645 priv->clean_id = NULL;653 priv->clean_id = NULL;
@@ -648,6 +656,7 @@
648 priv->icon_name = NULL;656 priv->icon_name = NULL;
649 priv->attention_icon_name = NULL;657 priv->attention_icon_name = NULL;
650 priv->icon_theme_path = NULL;658 priv->icon_theme_path = NULL;
659 priv->absolute_icon_theme_path = get_real_theme_path (self);
651 priv->menu = NULL;660 priv->menu = NULL;
652 priv->menuservice = NULL;661 priv->menuservice = NULL;
653 priv->ordering_index = 0;662 priv->ordering_index = 0;
@@ -676,8 +685,6 @@
676 (GBusNameVanishedCallback) name_vanished_handler,685 (GBusNameVanishedCallback) name_vanished_handler,
677 self, NULL);686 self, NULL);
678687
679 self->priv = priv;
680
681 /* Start getting the session bus */688 /* Start getting the session bus */
682 g_object_ref(self); /* ref for the bus creation callback */689 g_object_ref(self); /* ref for the bus creation callback */
683 g_bus_get(G_BUS_TYPE_SESSION, NULL, bus_creation, self);690 g_bus_get(G_BUS_TYPE_SESSION, NULL, bus_creation, self);
@@ -794,16 +801,31 @@
794 priv->icon_name = NULL;801 priv->icon_name = NULL;
795 }802 }
796803
804 if (priv->absolute_icon_name != NULL) {
805 g_free(priv->absolute_icon_name);
806 priv->absolute_icon_name = NULL;
807 }
808
797 if (priv->attention_icon_name != NULL) {809 if (priv->attention_icon_name != NULL) {
798 g_free(priv->attention_icon_name);810 g_free(priv->attention_icon_name);
799 priv->attention_icon_name = NULL;811 priv->attention_icon_name = NULL;
800 }812 }
801813
814 if (priv->absolute_attention_icon_name != NULL) {
815 g_free(priv->absolute_attention_icon_name);
816 priv->absolute_attention_icon_name = NULL;
817 }
818
802 if (priv->icon_theme_path != NULL) {819 if (priv->icon_theme_path != NULL) {
803 g_free(priv->icon_theme_path);820 g_free(priv->icon_theme_path);
804 priv->icon_theme_path = NULL;821 priv->icon_theme_path = NULL;
805 }822 }
806 823
824 if (priv->absolute_icon_theme_path != NULL) {
825 g_free(priv->absolute_icon_theme_path);
826 priv->absolute_icon_theme_path = NULL;
827 }
828
807 if (priv->title != NULL) {829 if (priv->title != NULL) {
808 g_free(priv->title);830 g_free(priv->title);
809 priv->title = NULL;831 priv->title = NULL;
@@ -976,6 +998,11 @@
976 gchar * oldguide = priv->label_guide;998 gchar * oldguide = priv->label_guide;
977 priv->label_guide = g_value_dup_string(value);999 priv->label_guide = g_value_dup_string(value);
9781000
1001 if (priv->label_guide != NULL && priv->label_guide[0] == '\0') {
1002 g_free(priv->label_guide);
1003 priv->label_guide = NULL;
1004 }
1005
979 if (g_strcmp0(oldguide, priv->label_guide) != 0) {1006 if (g_strcmp0(oldguide, priv->label_guide) != 0) {
980 signal_label_change(APP_INDICATOR(object));1007 signal_label_change(APP_INDICATOR(object));
981 }1008 }
@@ -1188,8 +1215,14 @@
1188 enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (APP_INDICATOR_TYPE_INDICATOR_STATUS), priv->status);1215 enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (APP_INDICATOR_TYPE_INDICATOR_STATUS), priv->status);
1189 return g_variant_new_string(enum_value->value_nick ? enum_value->value_nick : "");1216 return g_variant_new_string(enum_value->value_nick ? enum_value->value_nick : "");
1190 } else if (g_strcmp0(property, "IconName") == 0) {1217 } else if (g_strcmp0(property, "IconName") == 0) {
1218 if (priv->absolute_icon_name) {
1219 return g_variant_new_string(priv->absolute_icon_name);
1220 }
1191 return g_variant_new_string(priv->icon_name ? priv->icon_name : "");1221 return g_variant_new_string(priv->icon_name ? priv->icon_name : "");
1192 } else if (g_strcmp0(property, "AttentionIconName") == 0) {1222 } else if (g_strcmp0(property, "AttentionIconName") == 0) {
1223 if (priv->absolute_attention_icon_name) {
1224 return g_variant_new_string(priv->absolute_attention_icon_name);
1225 }
1193 return g_variant_new_string(priv->attention_icon_name ? priv->attention_icon_name : "");1226 return g_variant_new_string(priv->attention_icon_name ? priv->attention_icon_name : "");
1194 } else if (g_strcmp0(property, "Title") == 0) {1227 } else if (g_strcmp0(property, "Title") == 0) {
1195 const gchar * output = NULL;1228 const gchar * output = NULL;
@@ -1205,6 +1238,9 @@
1205 }1238 }
1206 return g_variant_new_string(output);1239 return g_variant_new_string(output);
1207 } else if (g_strcmp0(property, "IconThemePath") == 0) {1240 } else if (g_strcmp0(property, "IconThemePath") == 0) {
1241 if (priv->absolute_icon_theme_path) {
1242 return g_variant_new_string(priv->absolute_icon_theme_path);
1243 }
1208 return g_variant_new_string(priv->icon_theme_path ? priv->icon_theme_path : "");1244 return g_variant_new_string(priv->icon_theme_path ? priv->icon_theme_path : "");
1209 } else if (g_strcmp0(property, "Menu") == 0) {1245 } else if (g_strcmp0(property, "Menu") == 0) {
1210 if (priv->menuservice != NULL) {1246 if (priv->menuservice != NULL) {
@@ -1244,7 +1280,7 @@
1244 gchar * guide = priv->label_guide != NULL ? priv->label_guide : "";1280 gchar * guide = priv->label_guide != NULL ? priv->label_guide : "";
12451281
1246 g_signal_emit(G_OBJECT(self), signals[NEW_LABEL], 0,1282 g_signal_emit(G_OBJECT(self), signals[NEW_LABEL], 0,
1247 label, guide, TRUE);1283 label, guide);
1248 if (priv->dbus_registration != 0 && priv->connection != NULL) {1284 if (priv->dbus_registration != 0 && priv->connection != NULL) {
1249 GError * error = NULL;1285 GError * error = NULL;
12501286
@@ -1460,7 +1496,7 @@
1460static void1496static void
1461theme_changed_cb (GtkIconTheme * theme, gpointer user_data)1497theme_changed_cb (GtkIconTheme * theme, gpointer user_data)
1462{1498{
1463 g_signal_emit (user_data, signals[NEW_ICON], 0, TRUE);1499 g_signal_emit (user_data, signals[NEW_ICON], 0);
14641500
1465 AppIndicator * self = (AppIndicator *)user_data;1501 AppIndicator * self = (AppIndicator *)user_data;
1466 AppIndicatorPrivate *priv = self->priv;1502 AppIndicatorPrivate *priv = self->priv;
@@ -1571,19 +1607,23 @@
15711607
1572 /* add the icon_theme_path once if needed */1608 /* add the icon_theme_path once if needed */
1573 GtkIconTheme *icon_theme = gtk_icon_theme_get_default();1609 GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
1574 if (self->priv->icon_theme_path != NULL) {1610 const gchar *theme_path = self->priv->absolute_icon_theme_path ?
1611 self->priv->absolute_icon_theme_path :
1612 self->priv->icon_theme_path;
1613
1614 if (theme_path != NULL) {
1575 gchar **path;1615 gchar **path;
1576 gint n_elements, i;1616 gint n_elements, i;
1577 gboolean found=FALSE;1617 gboolean found=FALSE;
1578 gtk_icon_theme_get_search_path(icon_theme, &path, &n_elements);1618 gtk_icon_theme_get_search_path(icon_theme, &path, &n_elements);
1579 for (i=0; i< n_elements || path[i] == NULL; i++) {1619 for (i=0; i< n_elements; i++) {
1580 if(g_strcmp0(path[i], self->priv->icon_theme_path) == 0) {1620 if(g_strcmp0(path[i], theme_path) == 0) {
1581 found=TRUE;1621 found=TRUE;
1582 break;1622 break;
1583 }1623 }
1584 }1624 }
1585 if(!found) {1625 if(!found) {
1586 gtk_icon_theme_append_search_path(icon_theme, self->priv->icon_theme_path);1626 gtk_icon_theme_append_search_path(icon_theme, theme_path);
1587 }1627 }
1588 g_strfreev (path);1628 g_strfreev (path);
1589 }1629 }
@@ -1607,8 +1647,12 @@
1607 };1647 };
16081648
1609 if (icon_name != NULL) {1649 if (icon_name != NULL) {
1650 gchar *snapped_icon = append_snap_prefix(icon_name);
1651
1610 if (g_file_test(icon_name, G_FILE_TEST_EXISTS)) {1652 if (g_file_test(icon_name, G_FILE_TEST_EXISTS)) {
1611 gtk_status_icon_set_from_file(icon, icon_name);1653 gtk_status_icon_set_from_file(icon, icon_name);
1654 } else if (snapped_icon && g_file_test(snapped_icon, G_FILE_TEST_EXISTS)) {
1655 gtk_status_icon_set_from_file(icon, snapped_icon);
1612 } else {1656 } else {
1613 gchar *longname = append_panel_icon_suffix(icon_name);1657 gchar *longname = append_panel_icon_suffix(icon_name);
16141658
@@ -1620,6 +1664,8 @@
16201664
1621 g_free(longname);1665 g_free(longname);
1622 }1666 }
1667
1668 g_free(snapped_icon);
1623 }1669 }
16241670
1625 return;1671 return;
@@ -1633,7 +1679,7 @@
1633 GtkMenu * menu = app_indicator_get_menu(APP_INDICATOR(data));1679 GtkMenu * menu = app_indicator_get_menu(APP_INDICATOR(data));
1634 if (menu == NULL)1680 if (menu == NULL)
1635 return;1681 return;
1636 1682
1637 gtk_menu_popup(menu,1683 gtk_menu_popup(menu,
1638 NULL, /* Parent Menu */1684 NULL, /* Parent Menu */
1639 NULL, /* Parent item */1685 NULL, /* Parent item */
@@ -1681,7 +1727,7 @@
1681 long_name = g_strdup (icon_name);1727 long_name = g_strdup (icon_name);
1682 }1728 }
16831729
1684 return long_name; 1730 return long_name;
1685}1731}
16861732
1687static gboolean1733static gboolean
@@ -1858,6 +1904,14 @@
1858 if (g_strcmp0 (self->priv->attention_icon_name, icon_name) != 0) {1904 if (g_strcmp0 (self->priv->attention_icon_name, icon_name) != 0) {
1859 g_free (self->priv->attention_icon_name);1905 g_free (self->priv->attention_icon_name);
1860 self->priv->attention_icon_name = g_strdup (icon_name);1906 self->priv->attention_icon_name = g_strdup (icon_name);
1907
1908 g_free(self->priv->absolute_attention_icon_name);
1909 self->priv->absolute_attention_icon_name = NULL;
1910
1911 if (icon_name && icon_name[0] == '/') {
1912 self->priv->absolute_attention_icon_name = append_snap_prefix (icon_name);
1913 }
1914
1861 changed = TRUE;1915 changed = TRUE;
1862 }1916 }
18631917
@@ -1868,7 +1922,7 @@
1868 }1922 }
18691923
1870 if (changed) {1924 if (changed) {
1871 g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0, TRUE);1925 g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0);
18721926
1873 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {1927 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
1874 GError * error = NULL;1928 GError * error = NULL;
@@ -1933,6 +1987,14 @@
1933 }1987 }
19341988
1935 self->priv->icon_name = g_strdup(icon_name);1989 self->priv->icon_name = g_strdup(icon_name);
1990
1991 g_free(self->priv->absolute_icon_name);
1992 self->priv->absolute_icon_name = NULL;
1993
1994 if (icon_name && icon_name[0] == '/') {
1995 self->priv->absolute_icon_name = append_snap_prefix (icon_name);
1996 }
1997
1936 changed = TRUE;1998 changed = TRUE;
1937 }1999 }
19382000
@@ -1946,7 +2008,7 @@
1946 }2008 }
19472009
1948 if (changed) {2010 if (changed) {
1949 g_signal_emit (self, signals[NEW_ICON], 0, TRUE);2011 g_signal_emit (self, signals[NEW_ICON], 0);
19502012
1951 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {2013 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
1952 GError * error = NULL;2014 GError * error = NULL;
@@ -1994,6 +2056,66 @@
1994 return;2056 return;
1995}2057}
19962058
2059static const gchar *
2060get_snap_prefix ()
2061{
2062 const gchar *snap = g_getenv ("SNAP");
2063 return (snap && *snap != '\0') ? snap : NULL;
2064}
2065
2066static gchar *
2067append_snap_prefix (const gchar *path)
2068{
2069 gint i;
2070 gchar real_path[PATH_MAX];
2071 const gchar *snap = get_snap_prefix ();
2072
2073 if (snap != NULL && path != NULL) {
2074 if (realpath (path, real_path) != NULL) {
2075 path = real_path;
2076 }
2077
2078 if (g_str_has_prefix (path, "/tmp/")) {
2079 g_warning ("Using '/tmp' paths in SNAP environment will lead to unreadable resources");
2080 return NULL;
2081 }
2082
2083 if (g_str_has_prefix (path, snap) ||
2084 g_str_has_prefix (path, g_get_home_dir ()) ||
2085 g_str_has_prefix (path, g_get_user_cache_dir ()) ||
2086 g_str_has_prefix (path, g_get_user_config_dir ()) ||
2087 g_str_has_prefix (path, g_get_user_data_dir ()) ||
2088 g_str_has_prefix (path, g_get_user_runtime_dir ())) {
2089 return g_strdup (path);
2090 }
2091
2092 for (i = 0; i < G_USER_N_DIRECTORIES; ++ i) {
2093 if (g_str_has_prefix (path, g_get_user_special_dir (i))) {
2094 return g_strdup (path);
2095 }
2096 }
2097
2098 return g_build_path (G_DIR_SEPARATOR_S, snap, path, NULL);
2099 }
2100
2101 return NULL;
2102}
2103
2104static gchar *
2105get_real_theme_path (AppIndicator * self)
2106{
2107 const gchar *theme_path = self->priv->icon_theme_path;
2108 gchar *snapped_path = append_snap_prefix (theme_path);
2109
2110 if (snapped_path != NULL) {
2111 return snapped_path;
2112 } else if (get_snap_prefix ()) {
2113 return g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), "icons", NULL);
2114 }
2115
2116 return NULL;
2117}
2118
1997/**2119/**
1998 * app_indicator_set_icon_theme_path:2120 * app_indicator_set_icon_theme_path:
1999 * @self: The #AppIndicator object to use2121 * @self: The #AppIndicator object to use
@@ -2012,9 +2134,15 @@
20122134
2013 self->priv->icon_theme_path = g_strdup(icon_theme_path);2135 self->priv->icon_theme_path = g_strdup(icon_theme_path);
20142136
2015 g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path, TRUE);2137 g_free (self->priv->absolute_icon_theme_path);
2138 self->priv->absolute_icon_theme_path = get_real_theme_path (self);
2139
2140 g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path);
20162141
2017 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {2142 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
2143 const gchar *theme_path = self->priv->absolute_icon_theme_path ?
2144 self->priv->absolute_icon_theme_path :
2145 self->priv->icon_theme_path;
2018 GError * error = NULL;2146 GError * error = NULL;
20192147
2020 g_dbus_connection_emit_signal(self->priv->connection,2148 g_dbus_connection_emit_signal(self->priv->connection,
@@ -2022,7 +2150,7 @@
2022 self->priv->path,2150 self->priv->path,
2023 NOTIFICATION_ITEM_DBUS_IFACE,2151 NOTIFICATION_ITEM_DBUS_IFACE,
2024 "NewIconThemePath",2152 "NewIconThemePath",
2025 g_variant_new("(s)", self->priv->icon_theme_path),2153 g_variant_new("(s)", theme_path ? theme_path : ""),
2026 &error);2154 &error);
20272155
2028 if (error != NULL) {2156 if (error != NULL) {
@@ -2160,7 +2288,7 @@
21602288
2161 g_return_if_fail (GTK_IS_WIDGET (menuitem));2289 g_return_if_fail (GTK_IS_WIDGET (menuitem));
21622290
2163 priv->sec_activate_target = g_object_ref(G_OBJECT(menuitem));2291 priv->sec_activate_target = g_object_ref(menuitem);
2164 priv->sec_activate_enabled = widget_is_menu_child(self, menuitem);2292 priv->sec_activate_enabled = widget_is_menu_child(self, menuitem);
2165 g_signal_connect(menuitem, "parent-set", G_CALLBACK(sec_activate_target_parent_changed), self);2293 g_signal_connect(menuitem, "parent-set", G_CALLBACK(sec_activate_target_parent_changed), self);
2166}2294}
21672295
=== added file 'src/indicator-desktop-shortcuts.c'
--- src/indicator-desktop-shortcuts.c 1970-01-01 00:00:00 +0000
+++ src/indicator-desktop-shortcuts.c 2020-04-08 18:54:42 +0000
@@ -0,0 +1,705 @@
1/*
2A small file to parse through the actions that are available
3in the desktop file and making those easily usable.
4
5Copyright 2010 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <gio/gdesktopappinfo.h>
29#include "indicator-desktop-shortcuts.h"
30
31#define ACTIONS_KEY "Actions"
32#define ACTION_GROUP_PREFIX "Desktop Action"
33
34#define OLD_GROUP_SUFFIX "Shortcut Group"
35#define OLD_SHORTCUTS_KEY "X-Ayatana-Desktop-Shortcuts"
36#define OLD_ENVIRON_KEY "TargetEnvironment"
37
38#define PROP_DESKTOP_FILE_S "desktop-file"
39#define PROP_IDENTITY_S "identity"
40
41typedef enum _actions_t actions_t;
42enum _actions_t {
43 ACTIONS_NONE,
44 ACTIONS_XAYATANA,
45 ACTIONS_DESKTOP_SPEC
46};
47
48typedef struct _IndicatorDesktopShortcutsPrivate IndicatorDesktopShortcutsPrivate;
49struct _IndicatorDesktopShortcutsPrivate {
50 actions_t actions;
51 GKeyFile * keyfile;
52 gchar * identity;
53 GArray * nicks;
54 gchar * domain;
55};
56
57enum {
58 PROP_0,
59 PROP_DESKTOP_FILE,
60 PROP_IDENTITY
61};
62
63#define INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(o) \
64 (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsPrivate))
65
66static void indicator_desktop_shortcuts_class_init (IndicatorDesktopShortcutsClass *klass);
67static void indicator_desktop_shortcuts_init (IndicatorDesktopShortcuts *self);
68static void indicator_desktop_shortcuts_dispose (GObject *object);
69static void indicator_desktop_shortcuts_finalize (GObject *object);
70static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
71static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
72static void parse_keyfile (IndicatorDesktopShortcuts * ids);
73static gboolean should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gboolean should_have_target);
74
75G_DEFINE_TYPE (IndicatorDesktopShortcuts, indicator_desktop_shortcuts, G_TYPE_OBJECT);
76
77/* Build up the class */
78static void
79indicator_desktop_shortcuts_class_init (IndicatorDesktopShortcutsClass *klass)
80{
81 GObjectClass *object_class = G_OBJECT_CLASS (klass);
82
83 g_type_class_add_private (klass, sizeof (IndicatorDesktopShortcutsPrivate));
84
85 object_class->dispose = indicator_desktop_shortcuts_dispose;
86 object_class->finalize = indicator_desktop_shortcuts_finalize;
87
88 /* Property funcs */
89 object_class->set_property = set_property;
90 object_class->get_property = get_property;
91
92 g_object_class_install_property(object_class, PROP_DESKTOP_FILE,
93 g_param_spec_string(PROP_DESKTOP_FILE_S,
94 "The path of the desktop file to read",
95 "A path to a desktop file that we'll look for shortcuts in.",
96 NULL,
97 G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
98 g_object_class_install_property(object_class, PROP_IDENTITY,
99 g_param_spec_string(PROP_IDENTITY_S,
100 "The string that represents the identity that we're acting as.",
101 "Used to process ShowIn and NotShownIn fields of the desktop shortcust to get the proper list.",
102 NULL,
103 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
104
105 return;
106}
107
108/* Initialize instance data */
109static void
110indicator_desktop_shortcuts_init (IndicatorDesktopShortcuts *self)
111{
112 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(self);
113
114 priv->keyfile = NULL;
115 priv->identity = NULL;
116 priv->domain = NULL;
117 priv->nicks = g_array_new(TRUE, TRUE, sizeof(gchar *));
118 priv->actions = ACTIONS_NONE;
119
120 return;
121}
122
123/* Clear object references */
124static void
125indicator_desktop_shortcuts_dispose (GObject *object)
126{
127 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
128
129 if (priv->keyfile) {
130 g_key_file_free(priv->keyfile);
131 priv->keyfile = NULL;
132 }
133
134 G_OBJECT_CLASS (indicator_desktop_shortcuts_parent_class)->dispose (object);
135 return;
136}
137
138/* Free all memory */
139static void
140indicator_desktop_shortcuts_finalize (GObject *object)
141{
142 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
143
144 if (priv->identity != NULL) {
145 g_free(priv->identity);
146 priv->identity = NULL;
147 }
148
149 if (priv->domain != NULL) {
150 g_free(priv->domain);
151 priv->domain = NULL;
152 }
153
154 if (priv->nicks != NULL) {
155 gint i;
156 for (i = 0; i < priv->nicks->len; i++) {
157 gchar * nick = g_array_index(priv->nicks, gchar *, i);
158 g_free(nick);
159 }
160 g_array_free(priv->nicks, TRUE);
161 priv->nicks = NULL;
162 }
163
164 G_OBJECT_CLASS (indicator_desktop_shortcuts_parent_class)->finalize (object);
165 return;
166}
167
168/* Sets one of the two properties we have, only at construction though */
169static void
170set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
171{
172 g_return_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(object));
173 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
174
175 switch(prop_id) {
176 case PROP_DESKTOP_FILE: {
177 if (priv->keyfile != NULL) {
178 g_key_file_free(priv->keyfile);
179 priv->keyfile = NULL;
180 priv->actions = ACTIONS_NONE;
181 }
182
183 GError * error = NULL;
184 GKeyFile * keyfile = g_key_file_new();
185 g_key_file_load_from_file(keyfile, g_value_get_string(value), G_KEY_FILE_NONE, &error);
186
187 if (error != NULL) {
188 g_warning("Unable to load keyfile from file '%s': %s", g_value_get_string(value), error->message);
189 g_error_free(error);
190 g_key_file_free(keyfile);
191 break;
192 }
193
194 /* Always prefer the desktop spec if we can get it */
195 if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, ACTIONS_KEY, NULL)) {
196 priv->actions = ACTIONS_DESKTOP_SPEC;
197 }
198
199 /* But fallback if we can't */
200 if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, OLD_SHORTCUTS_KEY, NULL)) {
201 priv->actions = ACTIONS_XAYATANA;
202 g_warning("Desktop file '%s' is using a deprecated format for its actions that will be dropped soon.", g_value_get_string(value));
203 }
204
205 if (priv->actions == ACTIONS_NONE) {
206 g_key_file_free(keyfile);
207 break;
208 }
209
210 priv->keyfile = keyfile;
211 parse_keyfile(INDICATOR_DESKTOP_SHORTCUTS(object));
212 break;
213 }
214 case PROP_IDENTITY:
215 if (priv->identity != NULL) {
216 g_warning("Identity already set to '%s' and trying to set it to '%s'.", priv->identity, g_value_get_string(value));
217 return;
218 }
219 priv->identity = g_value_dup_string(value);
220 parse_keyfile(INDICATOR_DESKTOP_SHORTCUTS(object));
221 break;
222 /* *********************** */
223 default:
224 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
225 break;
226 }
227
228 return;
229}
230
231/* Gets either the desktop file our the identity. */
232static void
233get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
234{
235 g_return_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(object));
236 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(object);
237
238 switch(prop_id) {
239 case PROP_IDENTITY:
240 g_value_set_string(value, priv->identity);
241 break;
242 /* *********************** */
243 default:
244 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
245 break;
246 }
247
248 return;
249}
250
251/* Checks to see if we can, and if we can it goes through
252 and parses the keyfile entries. */
253static void
254parse_keyfile (IndicatorDesktopShortcuts * ids)
255{
256 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
257
258 if (priv->keyfile == NULL) {
259 return;
260 }
261
262 if (priv->identity == NULL) {
263 return;
264 }
265
266 /* Remove a previous translation domain if we had one
267 from a previously parsed file. */
268 if (priv->domain != NULL) {
269 g_free(priv->domain);
270 priv->domain = NULL;
271 }
272
273 /* Check to see if there is a custom translation domain that
274 we should take into account. */
275 if (priv->domain == NULL &&
276 g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL)) {
277 priv->domain = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
278 }
279
280 if (priv->domain == NULL &&
281 g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL)) {
282 priv->domain = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL);
283 }
284
285 /* We need to figure out what we're looking for and what we want to
286 look for in the rest of the file */
287 const gchar * list_name = NULL;
288 const gchar * group_format = NULL;
289 gboolean should_have_target = FALSE;
290
291 switch (priv->actions) {
292 case ACTIONS_NONE:
293 /* None, let's just get outta here */
294 return;
295 case ACTIONS_XAYATANA:
296 list_name = OLD_SHORTCUTS_KEY;
297 group_format = "%s " OLD_GROUP_SUFFIX;
298 should_have_target = TRUE;
299 break;
300 case ACTIONS_DESKTOP_SPEC:
301 list_name = ACTIONS_KEY;
302 group_format = ACTION_GROUP_PREFIX " %s";
303 should_have_target = FALSE;
304 break;
305 default:
306 g_assert_not_reached();
307 return;
308 }
309
310 /* Okay, we've got everything we need. Let's get it on! */
311 gint i;
312 gsize num_nicks = 0;
313 gchar ** nicks = g_key_file_get_string_list(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, list_name, &num_nicks, NULL);
314
315 /* If there is an error from get_string_list num_nicks should still
316 be zero, so this loop will drop out. */
317 for (i = 0; i < num_nicks; i++) {
318 /* g_debug("Looking at group nick %s", nicks[i]); */
319 gchar * groupname = g_strdup_printf(group_format, nicks[i]);
320 if (!g_key_file_has_group(priv->keyfile, groupname)) {
321 g_warning("Unable to find group '%s'", groupname);
322 g_free(groupname);
323 continue;
324 }
325
326 if (!should_show(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, priv->identity, FALSE)) {
327 g_free(groupname);
328 continue;
329 }
330
331 if (!should_show(priv->keyfile, groupname, priv->identity, should_have_target)) {
332 g_free(groupname);
333 continue;
334 }
335
336 gchar * nickalloc = g_strdup(nicks[i]);
337 g_array_append_val(priv->nicks, nickalloc);
338 g_free(groupname);
339 }
340
341 if (nicks != NULL) {
342 g_strfreev(nicks);
343 }
344
345 return;
346}
347
348/* Checks the ONLY_SHOW_IN and NOT_SHOW_IN keys for a group to
349 see if we should be showing ourselves. */
350static gboolean
351should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gboolean should_have_target)
352{
353 if (should_have_target && g_key_file_has_key(keyfile, group, OLD_ENVIRON_KEY, NULL)) {
354 /* If we've got this key, we're going to return here and not
355 process the deprecated keys. */
356 gint j;
357 gsize num_env = 0;
358 gchar ** envs = g_key_file_get_string_list(keyfile, group, OLD_ENVIRON_KEY, &num_env, NULL);
359
360 for (j = 0; j < num_env; j++) {
361 if (g_strcmp0(envs[j], identity) == 0) {
362 break;
363 }
364 }
365
366 if (envs != NULL) {
367 g_strfreev(envs);
368 }
369
370 if (j == num_env) {
371 return FALSE;
372 }
373 return TRUE;
374 }
375
376 /* If there is a list of OnlyShowIn entries we need to check
377 to see if we're in that list. If not, we drop this nick */
378 if (g_key_file_has_key(keyfile, group, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, NULL)) {
379 gint j;
380 gsize num_only = 0;
381 gchar ** onlies = g_key_file_get_string_list(keyfile, group, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, &num_only, NULL);
382
383 for (j = 0; j < num_only; j++) {
384 if (g_strcmp0(onlies[j], identity) == 0) {
385 break;
386 }
387 }
388
389 if (onlies != NULL) {
390 g_strfreev(onlies);
391 }
392
393 if (j == num_only) {
394 return FALSE;
395 }
396 }
397
398 /* If there is a NotShowIn entry we need to make sure that we're
399 not in that list. If we are, we need to drop out. */
400 if (g_key_file_has_key(keyfile, group, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL)) {
401 gint j;
402 gsize num_not = 0;
403 gchar ** nots = g_key_file_get_string_list(keyfile, group, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, &num_not, NULL);
404
405 for (j = 0; j < num_not; j++) {
406 if (g_strcmp0(nots[j], identity) == 0) {
407 break;
408 }
409 }
410
411 if (nots != NULL) {
412 g_strfreev(nots);
413 }
414
415 if (j != num_not) {
416 return FALSE;
417 }
418 }
419
420 return TRUE;
421}
422
423/* Looks through the nicks to see if this one is in the list,
424 and thus valid to use. */
425static gboolean
426is_valid_nick (gchar ** list, const gchar * nick)
427{
428 if (*list == NULL)
429 return FALSE;
430 /* g_debug("Checking Nick: %s", list[0]); */
431 if (g_strcmp0(list[0], nick) == 0)
432 return TRUE;
433 return is_valid_nick(&list[1], nick);
434}
435
436/* API */
437
438/**
439 indicator_desktop_shortcuts_new:
440 @file: The desktop file that would be opened to
441 find the actions.
442 @identity: This is a string that represents the identity
443 that should be used in searching those actions. It
444 relates to the ShowIn and NotShownIn properties.
445
446 This function creates the basic object. It involves opening
447 the file and parsing it. It could potentially block on IO. At
448 the end of the day you'll have a fully functional object.
449
450 Return value: A new #IndicatorDesktopShortcuts object.
451*/
452IndicatorDesktopShortcuts *
453indicator_desktop_shortcuts_new (const gchar * file, const gchar * identity)
454{
455 GObject * obj = g_object_new(INDICATOR_TYPE_DESKTOP_SHORTCUTS,
456 PROP_DESKTOP_FILE_S, file,
457 PROP_IDENTITY_S, identity,
458 NULL);
459 return INDICATOR_DESKTOP_SHORTCUTS(obj);
460}
461
462/**
463 indicator_desktop_shortcuts_get_nicks:
464 @ids: The #IndicatorDesktopShortcuts object to look in
465
466 Give you the list of commands that are available for this desktop
467 file given the identity that was passed in at creation. This will
468 filter out the various items in the desktop file. These nicks can
469 then be used as keys for working with the desktop file.
470
471 Return value: A #NULL terminated list of strings. This memory
472 is managed by the @ids object.
473*/
474const gchar **
475indicator_desktop_shortcuts_get_nicks (IndicatorDesktopShortcuts * ids)
476{
477 g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), NULL);
478 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
479 return (const gchar **)priv->nicks->data;
480}
481
482/**
483 indicator_desktop_shortcuts_nick_get_name:
484 @ids: The #IndicatorDesktopShortcuts object to look in
485 @nick: Which command that we're referencing.
486
487 This function looks in a desktop file for a nick to find the
488 user visible name for that shortcut. The @nick parameter
489 should be gotten from #indicator_desktop_shortcuts_get_nicks
490 though it's not required that the exact memory location
491 be the same.
492
493 Return value: A user visible string for the shortcut or
494 #NULL on error.
495*/
496gchar *
497indicator_desktop_shortcuts_nick_get_name (IndicatorDesktopShortcuts * ids, const gchar * nick)
498{
499 g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), NULL);
500 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
501
502 g_return_val_if_fail(priv->actions != ACTIONS_NONE, NULL);
503 g_return_val_if_fail(priv->keyfile != NULL, NULL);
504 g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), NULL);
505
506 const gchar * group_format = NULL;
507
508 switch (priv->actions) {
509 case ACTIONS_XAYATANA:
510 group_format = "%s " OLD_GROUP_SUFFIX;
511 break;
512 case ACTIONS_DESKTOP_SPEC:
513 group_format = ACTION_GROUP_PREFIX " %s";
514 break;
515 default:
516 g_assert_not_reached();
517 return NULL;
518 }
519
520 gchar * groupheader = g_strdup_printf(group_format, nick);
521 if (!g_key_file_has_group(priv->keyfile, groupheader)) {
522 g_warning("The group for nick '%s' doesn't exist anymore.", nick);
523 g_free(groupheader);
524 return NULL;
525 }
526
527 if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_NAME, NULL)) {
528 g_warning("No name available for nick '%s'", nick);
529 g_free(groupheader);
530 return NULL;
531 }
532
533 gchar * name = NULL;
534 gchar * keyvalue = g_key_file_get_string(priv->keyfile,
535 groupheader,
536 G_KEY_FILE_DESKTOP_KEY_NAME,
537 NULL);
538 gchar * localeval = g_key_file_get_locale_string(priv->keyfile,
539 groupheader,
540 G_KEY_FILE_DESKTOP_KEY_NAME,
541 NULL,
542 NULL);
543 g_free(groupheader);
544
545 if (priv->domain != NULL && g_strcmp0(keyvalue, localeval) == 0) {
546 name = g_strdup(g_dgettext(priv->domain, keyvalue));
547 g_free(localeval);
548 } else {
549 name = localeval;
550 }
551
552 g_free(keyvalue);
553
554 return name;
555}
556
557/**
558 indicator_desktop_shortcuts_nick_exec_with_context:
559 @ids: The #IndicatorDesktopShortcuts object to look in
560 @nick: Which command that we're referencing.
561 @launch_context: The #GAppLaunchContext to use for launching the shortcut
562
563 Here we take a @nick and try and execute the action that is
564 associated with it. The @nick parameter should be gotten
565 from #indicator_desktop_shortcuts_get_nicks though it's not
566 required that the exact memory location be the same.
567
568 Return value: #TRUE on success or #FALSE on error.
569*/
570gboolean
571indicator_desktop_shortcuts_nick_exec_with_context (IndicatorDesktopShortcuts * ids, const gchar * nick, GAppLaunchContext * launch_context)
572{
573 GError * error = NULL;
574 gchar * current_dir = NULL;
575
576 g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), FALSE);
577 IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
578
579 g_return_val_if_fail(priv->actions != ACTIONS_NONE, FALSE);
580 g_return_val_if_fail(priv->keyfile != NULL, FALSE);
581 g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), FALSE);
582
583 const gchar * group_format = NULL;
584
585 switch (priv->actions) {
586 case ACTIONS_XAYATANA:
587 group_format = "%s " OLD_GROUP_SUFFIX;
588 break;
589 case ACTIONS_DESKTOP_SPEC:
590 group_format = ACTION_GROUP_PREFIX " %s";
591 break;
592 default:
593 g_assert_not_reached();
594 return FALSE;
595 }
596
597 gchar * groupheader = g_strdup_printf(group_format, nick);
598 if (!g_key_file_has_group(priv->keyfile, groupheader)) {
599 g_warning("The group for nick '%s' doesn't exist anymore.", nick);
600 g_free(groupheader);
601 return FALSE;
602 }
603
604 if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_NAME, NULL)) {
605 g_warning("No name available for nick '%s'", nick);
606 g_free(groupheader);
607 return FALSE;
608 }
609
610 if (!g_key_file_has_key(priv->keyfile, groupheader, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL)) {
611 g_warning("No exec available for nick '%s'", nick);
612 g_free(groupheader);
613 return FALSE;
614 }
615
616 /* If possible move to the proper launch path */
617 gchar * path = g_key_file_get_string(priv->keyfile, groupheader,
618 G_KEY_FILE_DESKTOP_KEY_PATH, NULL);
619
620 if (path && *path != '\0') {
621 current_dir = g_get_current_dir();
622
623 if (chdir(path) < 0) {
624 g_warning("Impossible to run action '%s' from path '%s'", nick, path);
625 g_free(current_dir);
626 g_free(groupheader);
627 g_free(path);
628 return FALSE;
629 }
630 }
631
632 /* Grab the name and the exec entries out of our current group */
633 gchar * name = g_key_file_get_locale_string(priv->keyfile,
634 groupheader,
635 G_KEY_FILE_DESKTOP_KEY_NAME,
636 NULL,
637 NULL);
638
639 gchar * exec = g_key_file_get_locale_string(priv->keyfile,
640 groupheader,
641 G_KEY_FILE_DESKTOP_KEY_EXEC,
642 NULL,
643 NULL);
644
645 GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE;
646
647 if (launch_context) {
648 flags |= G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION;
649 }
650
651 GAppInfo * appinfo = g_app_info_create_from_commandline(exec, name, flags, &error);
652 g_free(groupheader);
653 g_free(path);
654 g_free(name);
655 g_free(exec);
656
657 if (error != NULL) {
658 g_warning("Unable to build Command line App info: %s", error->message);
659 g_free(current_dir);
660 g_error_free(error);
661 return FALSE;
662 }
663
664 if (appinfo == NULL) {
665 g_warning("Unable to build Command line App info (unknown)");
666 g_free(current_dir);
667 return FALSE;
668 }
669
670 gboolean launched = g_app_info_launch(appinfo, NULL, launch_context, &error);
671
672 if (current_dir && chdir(current_dir) < 0)
673 g_warning("Impossible to switch back to default work dir");
674
675
676 if (error != NULL) {
677 g_warning("Unable to launch file from nick '%s': %s", nick, error->message);
678 g_clear_error(&error);
679 }
680
681 g_free(current_dir);
682 g_object_unref(appinfo);
683
684 return launched;
685}
686
687/**
688 indicator_desktop_shortcuts_nick_exec:
689 @ids: The #IndicatorDesktopShortcuts object to look in
690 @nick: Which command that we're referencing.
691
692 Here we take a @nick and try and execute the action that is
693 associated with it. The @nick parameter should be gotten
694 from #indicator_desktop_shortcuts_get_nicks though it's not
695 required that the exact memory location be the same.
696 This function is deprecated and shouldn't be used in newly
697 written code.
698
699 Return value: #TRUE on success or #FALSE on error.
700*/
701gboolean
702indicator_desktop_shortcuts_nick_exec (IndicatorDesktopShortcuts * ids, const gchar * nick)
703{
704 return indicator_desktop_shortcuts_nick_exec_with_context (ids, nick, NULL);
705}
0706
=== added file 'src/indicator-desktop-shortcuts.h'
--- src/indicator-desktop-shortcuts.h 1970-01-01 00:00:00 +0000
+++ src/indicator-desktop-shortcuts.h 2020-04-08 18:54:42 +0000
@@ -0,0 +1,80 @@
1/*
2A small file to parse through the actions that are available
3in the desktop file and making those easily usable.
4
5Copyright 2010 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifndef __INDICATOR_DESKTOP_SHORTCUTS_H__
25#define __INDICATOR_DESKTOP_SHORTCUTS_H__
26
27#include <gio/gio.h>
28#include <glib.h>
29#include <glib-object.h>
30
31G_BEGIN_DECLS
32
33#define INDICATOR_TYPE_DESKTOP_SHORTCUTS (indicator_desktop_shortcuts_get_type ())
34#define INDICATOR_DESKTOP_SHORTCUTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcuts))
35#define INDICATOR_DESKTOP_SHORTCUTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsClass))
36#define INDICATOR_IS_DESKTOP_SHORTCUTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS))
37#define INDICATOR_IS_DESKTOP_SHORTCUTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_TYPE_DESKTOP_SHORTCUTS))
38#define INDICATOR_DESKTOP_SHORTCUTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_TYPE_DESKTOP_SHORTCUTS, IndicatorDesktopShortcutsClass))
39
40typedef struct _IndicatorDesktopShortcuts IndicatorDesktopShortcuts;
41typedef struct _IndicatorDesktopShortcutsClass IndicatorDesktopShortcutsClass;
42
43/**
44 IndicatorDesktopShortcutsClass:
45 @parent_class: Space for #GObjectClass
46
47 The vtable for our precious #IndicatorDesktopShortcutsClass.
48*/
49struct _IndicatorDesktopShortcutsClass {
50 GObjectClass parent_class;
51};
52
53/**
54 IndicatorDesktopShortcuts:
55 @parent: The parent data from #GObject
56
57 The public data for an instance of the class
58 #IndicatorDesktopShortcuts.
59*/
60struct _IndicatorDesktopShortcuts {
61 GObject parent;
62};
63
64GType indicator_desktop_shortcuts_get_type (void);
65IndicatorDesktopShortcuts * indicator_desktop_shortcuts_new (const gchar * file,
66 const gchar * identity);
67const gchar ** indicator_desktop_shortcuts_get_nicks (IndicatorDesktopShortcuts * ids);
68gchar * indicator_desktop_shortcuts_nick_get_name (IndicatorDesktopShortcuts * ids,
69 const gchar * nick);
70gboolean indicator_desktop_shortcuts_nick_exec_with_context (IndicatorDesktopShortcuts * ids,
71 const gchar * nick,
72 GAppLaunchContext * launch_context);
73
74GLIB_DEPRECATED_FOR(indicator_desktop_shortcuts_nick_exec_with_context)
75gboolean indicator_desktop_shortcuts_nick_exec (IndicatorDesktopShortcuts * ids,
76 const gchar * nick);
77
78G_END_DECLS
79
80#endif
081
=== modified file 'tests/Makefile.am'
--- tests/Makefile.am 2013-12-19 14:37:54 +0000
+++ tests/Makefile.am 2020-04-08 18:54:42 +0000
@@ -32,7 +32,7 @@
32test_libappindicator_CFLAGS = \32test_libappindicator_CFLAGS = \
33 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \33 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
34 -DSRCDIR="\"$(srcdir)\"" \34 -DSRCDIR="\"$(srcdir)\"" \
35 -Wall -Werror -Wno-error=deprecated-declarations \35 -Wall -Wno-error=deprecated-declarations \
36 -I$(top_srcdir)/src36 -I$(top_srcdir)/src
3737
38test_libappindicator_LDADD = \38test_libappindicator_LDADD = \
@@ -49,7 +49,7 @@
4949
50test_libappindicator_dbus_client_CFLAGS = \50test_libappindicator_dbus_client_CFLAGS = \
51 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \51 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
52 -Wall -Werror -Wno-error=deprecated-declarations \52 -Wall -Wno-error=deprecated-declarations \
53 -I$(top_srcdir)/src53 -I$(top_srcdir)/src
5454
55test_libappindicator_dbus_client_LDADD = \55test_libappindicator_dbus_client_LDADD = \
@@ -66,7 +66,7 @@
6666
67test_libappindicator_dbus_server_CFLAGS = \67test_libappindicator_dbus_server_CFLAGS = \
68 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \68 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
69 -Wall -Werror -Wno-error=deprecated-declarations \69 -Wall -Wno-error=deprecated-declarations \
70 -I$(top_srcdir)/src70 -I$(top_srcdir)/src
7171
72test_libappindicator_dbus_server_LDADD = \72test_libappindicator_dbus_server_LDADD = \
@@ -83,7 +83,7 @@
8383
84test_libappindicator_status_client_CFLAGS = \84test_libappindicator_status_client_CFLAGS = \
85 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \85 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
86 -Wall -Werror -Wno-error=deprecated-declarations \86 -Wall -Wno-error=deprecated-declarations \
87 -I$(top_srcdir)/src87 -I$(top_srcdir)/src
8888
89test_libappindicator_status_client_LDADD = \89test_libappindicator_status_client_LDADD = \
@@ -100,7 +100,7 @@
100100
101test_libappindicator_status_server_CFLAGS = \101test_libappindicator_status_server_CFLAGS = \
102 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \102 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
103 -Wall -Werror -Wno-error=deprecated-declarations \103 -Wall -Wno-error=deprecated-declarations \
104 -I$(top_srcdir)/src104 -I$(top_srcdir)/src
105105
106test_libappindicator_status_server_LDADD = \106test_libappindicator_status_server_LDADD = \
@@ -116,7 +116,7 @@
116116
117test_libappindicator_fallback_watcher_CFLAGS = \117test_libappindicator_fallback_watcher_CFLAGS = \
118 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \118 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
119 -Wall -Werror -Wno-error=deprecated-declarations \119 -Wall -Wno-error=deprecated-declarations \
120 -I$(top_srcdir)/src120 -I$(top_srcdir)/src
121121
122test_libappindicator_fallback_watcher_LDADD = \122test_libappindicator_fallback_watcher_LDADD = \
@@ -128,7 +128,7 @@
128128
129test_libappindicator_fallback_item_CFLAGS = \129test_libappindicator_fallback_item_CFLAGS = \
130 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \130 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
131 -Wall -Werror -Wno-error=deprecated-declarations \131 -Wall -Wno-error=deprecated-declarations \
132 -I$(top_srcdir)/src132 -I$(top_srcdir)/src
133133
134test_libappindicator_fallback_item_LDADD = \134test_libappindicator_fallback_item_LDADD = \
@@ -198,7 +198,7 @@
198198
199test_simple_app_CFLAGS = \199test_simple_app_CFLAGS = \
200 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \200 $(TESTDEPS_CFLAGS) $(LIBRARY_CFLAGS) \
201 -Wall -Werror -Wno-error=deprecated-declarations \201 -Wall -Wno-error=deprecated-declarations \
202 -I$(top_srcdir)/src202 -I$(top_srcdir)/src
203203
204test_simple_app_LDADD = \204test_simple_app_LDADD = \

Subscribers

People subscribed via source and target branches