dev-python/cryptography: Bump to 2.8
[gentoo.git] / eclass / desktop.eclass
1 # Copyright 1999-2018 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: desktop.eclass
5 # @MAINTAINER:
6 # base-system@gentoo.org
7 # @BLURB: support for desktop files, menus, and icons
8
9 if [[ -z ${_DESKTOP_ECLASS} ]]; then
10 _DESKTOP_ECLASS=1
11
12 # @FUNCTION: make_desktop_entry
13 # @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
14 # @DESCRIPTION:
15 # Make a .desktop file.
16 #
17 # @CODE
18 # binary:   what command does the app run with ?
19 # name:     the name that will show up in the menu
20 # icon:     the icon to use in the menu entry
21 #           this can be relative (to /usr/share/pixmaps) or
22 #           a full path to an icon
23 # type:     what kind of application is this?
24 #           for categories:
25 #           https://specifications.freedesktop.org/menu-spec/latest/apa.html
26 #           if unset, function tries to guess from package's category
27 # fields:       extra fields to append to the desktop file; a printf string
28 # @CODE
29 make_desktop_entry() {
30         [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
31
32         local exec=${1}
33         local name=${2:-${PN}}
34         local icon=${3:-${PN}}
35         local type=${4}
36         local fields=${5}
37
38         if [[ -z ${type} ]] ; then
39                 local catmaj=${CATEGORY%%-*}
40                 local catmin=${CATEGORY##*-}
41                 case ${catmaj} in
42                         app)
43                                 case ${catmin} in
44                                         accessibility) type="Utility;Accessibility";;
45                                         admin)         type=System;;
46                                         antivirus)     type=System;;
47                                         arch)          type="Utility;Archiving";;
48                                         backup)        type="Utility;Archiving";;
49                                         cdr)           type="AudioVideo;DiscBurning";;
50                                         dicts)         type="Office;Dictionary";;
51                                         doc)           type=Documentation;;
52                                         editors)       type="Utility;TextEditor";;
53                                         emacs)         type="Development;TextEditor";;
54                                         emulation)     type="System;Emulator";;
55                                         laptop)        type="Settings;HardwareSettings";;
56                                         office)        type=Office;;
57                                         pda)           type="Office;PDA";;
58                                         vim)           type="Development;TextEditor";;
59                                         xemacs)        type="Development;TextEditor";;
60                                 esac
61                                 ;;
62
63                         dev)
64                                 type="Development"
65                                 ;;
66
67                         games)
68                                 case ${catmin} in
69                                         action|fps) type=ActionGame;;
70                                         arcade)     type=ArcadeGame;;
71                                         board)      type=BoardGame;;
72                                         emulation)  type=Emulator;;
73                                         kids)       type=KidsGame;;
74                                         puzzle)     type=LogicGame;;
75                                         roguelike)  type=RolePlaying;;
76                                         rpg)        type=RolePlaying;;
77                                         simulation) type=Simulation;;
78                                         sports)     type=SportsGame;;
79                                         strategy)   type=StrategyGame;;
80                                 esac
81                                 type="Game;${type}"
82                                 ;;
83
84                         gnome)
85                                 type="Gnome;GTK"
86                                 ;;
87
88                         kde)
89                                 type="KDE;Qt"
90                                 ;;
91
92                         mail)
93                                 type="Network;Email"
94                                 ;;
95
96                         media)
97                                 case ${catmin} in
98                                         gfx)
99                                                 type=Graphics
100                                                 ;;
101                                         *)
102                                                 case ${catmin} in
103                                                         radio) type=Tuner;;
104                                                         sound) type=Audio;;
105                                                         tv)    type=TV;;
106                                                         video) type=Video;;
107                                                 esac
108                                                 type="AudioVideo;${type}"
109                                                 ;;
110                                 esac
111                                 ;;
112
113                         net)
114                                 case ${catmin} in
115                                         dialup) type=Dialup;;
116                                         ftp)    type=FileTransfer;;
117                                         im)     type=InstantMessaging;;
118                                         irc)    type=IRCClient;;
119                                         mail)   type=Email;;
120                                         news)   type=News;;
121                                         nntp)   type=News;;
122                                         p2p)    type=FileTransfer;;
123                                         voip)   type=Telephony;;
124                                 esac
125                                 type="Network;${type}"
126                                 ;;
127
128                         sci)
129                                 case ${catmin} in
130                                         astro*)  type=Astronomy;;
131                                         bio*)    type=Biology;;
132                                         calc*)   type=Calculator;;
133                                         chem*)   type=Chemistry;;
134                                         elec*)   type=Electronics;;
135                                         geo*)    type=Geology;;
136                                         math*)   type=Math;;
137                                         physics) type=Physics;;
138                                         visual*) type=DataVisualization;;
139                                 esac
140                                 type="Education;Science;${type}"
141                                 ;;
142
143                         sys)
144                                 type="System"
145                                 ;;
146
147                         www)
148                                 case ${catmin} in
149                                         client) type=WebBrowser;;
150                                 esac
151                                 type="Network;${type}"
152                                 ;;
153
154                         *)
155                                 type=
156                                 ;;
157                 esac
158         fi
159         local slot=${SLOT%/*}
160         if [[ ${slot} == "0" ]] ; then
161                 local desktop_name="${PN}"
162         else
163                 local desktop_name="${PN}-${slot}"
164         fi
165         local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
166         #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
167
168         # Don't append another ";" when a valid category value is provided.
169         type=${type%;}${type:+;}
170
171         if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
172                 ewarn "As described in the Icon Theme Specification, icon file extensions are not"
173                 ewarn "allowed in .desktop files if the value is not an absolute path."
174                 icon=${icon%.*}
175         fi
176
177         cat <<-EOF > "${desktop}" || die
178         [Desktop Entry]
179         Name=${name}
180         Type=Application
181         Comment=${DESCRIPTION}
182         Exec=${exec}
183         TryExec=${exec%% *}
184         Icon=${icon}
185         Categories=${type}
186         EOF
187
188         if [[ ${fields:-=} != *=* ]] ; then
189                 # 5th arg used to be value to Path=
190                 ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
191                 fields="Path=${fields}"
192         fi
193         if [[ -n ${fields} ]]; then
194                 printf '%b\n' "${fields}" >> "${desktop}" || die
195         fi
196
197         (
198                 # wrap the env here so that the 'insinto' call
199                 # doesn't corrupt the env of the caller
200                 insopts -m 0644
201                 insinto /usr/share/applications
202                 doins "${desktop}"
203         ) || die "installing desktop file failed"
204 }
205
206 # @FUNCTION: make_session_desktop
207 # @USAGE: <title> <command> [command args...]
208 # @DESCRIPTION:
209 # Make a GDM/KDM Session file.  The title is the file to execute to start the
210 # Window Manager.  The command is the name of the Window Manager.
211 #
212 # You can set the name of the file via the ${wm} variable.
213 make_session_desktop() {
214         [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
215         [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
216
217         local title=$1
218         local command=$2
219         local desktop=${T}/${wm:-${PN}}.desktop
220         shift 2
221
222         cat <<-EOF > "${desktop}" || die
223         [Desktop Entry]
224         Name=${title}
225         Comment=This session logs you into ${title}
226         Exec=${command} $*
227         TryExec=${command}
228         Type=XSession
229         EOF
230
231         (
232         # wrap the env here so that the 'insinto' call
233         # doesn't corrupt the env of the caller
234         insopts -m 0644
235         insinto /usr/share/xsessions
236         doins "${desktop}"
237         )
238 }
239
240 # @FUNCTION: domenu
241 # @USAGE: <menus>
242 # @DESCRIPTION:
243 # Install the list of .desktop menu files into the appropriate directory
244 # (/usr/share/applications).
245 domenu() {
246         (
247         # wrap the env here so that the 'insinto' call
248         # doesn't corrupt the env of the caller
249         local i ret=0
250         insopts -m 0644
251         insinto /usr/share/applications
252         for i in "$@" ; do
253                 if [[ -d ${i} ]] ; then
254                         doins "${i}"/*.desktop
255                         ((ret|=$?))
256                 else
257                         doins "${i}"
258                         ((ret|=$?))
259                 fi
260         done
261         exit ${ret}
262         )
263 }
264
265 # @FUNCTION: newmenu
266 # @USAGE: <menu> <newname>
267 # @DESCRIPTION:
268 # Like all other new* functions, install the specified menu as newname.
269 newmenu() {
270         (
271         # wrap the env here so that the 'insinto' call
272         # doesn't corrupt the env of the caller
273         insopts -m 0644
274         insinto /usr/share/applications
275         newins "$@"
276         )
277 }
278
279 # @FUNCTION: _iconins
280 # @INTERNAL
281 # @DESCRIPTION:
282 # function for use in doicon and newicon
283 _iconins() {
284         (
285         # wrap the env here so that the 'insinto' call
286         # doesn't corrupt the env of the caller
287         insopts -m 0644
288         local funcname=$1; shift
289         local size dir
290         local context=apps
291         local theme=hicolor
292
293         while [[ $# -gt 0 ]] ; do
294                 case $1 in
295                 -s|--size)
296                         if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
297                                 size=${2%%x*}
298                         else
299                                 size=${2}
300                         fi
301                         case ${size} in
302                         16|22|24|32|36|48|64|72|96|128|192|256|512)
303                                 size=${size}x${size};;
304                         scalable)
305                                 ;;
306                         *)
307                                 eerror "${size} is an unsupported icon size!"
308                                 exit 1;;
309                         esac
310                         shift 2;;
311                 -t|--theme)
312                         theme=${2}
313                         shift 2;;
314                 -c|--context)
315                         context=${2}
316                         shift 2;;
317                 *)
318                         if [[ -z ${size} ]] ; then
319                                 insinto /usr/share/pixmaps
320                         else
321                                 insinto /usr/share/icons/${theme}/${size}/${context}
322                         fi
323
324                         if [[ ${funcname} == doicon ]] ; then
325                                 if [[ -f $1 ]] ; then
326                                         doins "${1}"
327                                 elif [[ -d $1 ]] ; then
328                                         shopt -s nullglob
329                                         doins "${1}"/*.{png,svg}
330                                         shopt -u nullglob
331                                 else
332                                         eerror "${1} is not a valid file/directory!"
333                                         exit 1
334                                 fi
335                         else
336                                 break
337                         fi
338                         shift 1;;
339                 esac
340         done
341         if [[ ${funcname} == newicon ]] ; then
342                 newins "$@"
343         fi
344         ) || die
345 }
346
347 # @FUNCTION: doicon
348 # @USAGE: [options] <icons>
349 # @DESCRIPTION:
350 # Install icon into the icon directory /usr/share/icons or into
351 # /usr/share/pixmaps if "--size" is not set.
352 # This is useful in conjunction with creating desktop/menu files.
353 #
354 # @CODE
355 #  options:
356 #  -s, --size
357 #    !!! must specify to install into /usr/share/icons/... !!!
358 #    size of the icon, like 48 or 48x48
359 #    supported icon sizes are:
360 #    16 22 24 32 36 48 64 72 96 128 192 256 512 scalable
361 #  -c, --context
362 #    defaults to "apps"
363 #  -t, --theme
364 #    defaults to "hicolor"
365 #
366 # icons: list of icons
367 #
368 # example 1: doicon foobar.png fuqbar.svg suckbar.png
369 # results in: insinto /usr/share/pixmaps
370 #             doins foobar.png fuqbar.svg suckbar.png
371 #
372 # example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
373 # results in: insinto /usr/share/icons/hicolor/48x48/apps
374 #             doins foobar.png fuqbar.png blobbar.png
375 # @CODE
376 doicon() {
377         _iconins ${FUNCNAME} "$@"
378 }
379
380 # @FUNCTION: newicon
381 # @USAGE: [options] <icon> <newname>
382 # @DESCRIPTION:
383 # Like doicon, install the specified icon as newname.
384 #
385 # @CODE
386 # example 1: newicon foobar.png NEWNAME.png
387 # results in: insinto /usr/share/pixmaps
388 #             newins foobar.png NEWNAME.png
389 #
390 # example 2: newicon -s 48 foobar.png NEWNAME.png
391 # results in: insinto /usr/share/icons/hicolor/48x48/apps
392 #             newins foobar.png NEWNAME.png
393 # @CODE
394 newicon() {
395         _iconins ${FUNCNAME} "$@"
396 }
397
398 fi