Merge lp:~3v1n0/libappindicator/discord-indicator-crash-fix into lp:libappindicator/16.10
- discord-indicator-crash-fix
- Merge into trunk.16.10
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 |
Related bugs: |
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.
Commit message
Description of the change
Marco Trevisan (Treviño) (3v1n0) : | # |
- 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
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 = \ |