aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xutil/fluxbox-generate_menu.in382
1 files changed, 361 insertions, 21 deletions
diff --git a/util/fluxbox-generate_menu.in b/util/fluxbox-generate_menu.in
index 26e89b1..dbd6cb0 100755
--- a/util/fluxbox-generate_menu.in
+++ b/util/fluxbox-generate_menu.in
@@ -48,10 +48,11 @@ WHOAMI=`whoami`
48[ "$WHOAMI" = root ] && PATH=/bin:/usr/bin/:/usr/local/bin:/usr/X11R6/bin 48[ "$WHOAMI" = root ] && PATH=/bin:/usr/bin/:/usr/local/bin:/usr/X11R6/bin
49 49
50# Check for Imlib2-support 50# Check for Imlib2-support
51if ( fluxbox -info 2> /dev/null | grep -- -IMLIB ); then 51if fluxbox -info 2> /dev/null | grep -q "^IMLIB"; then
52 PNG_ICONS="no" 52 PNG_ICONS="yes"
53else 53else
54 PNG_ICONS="yes" 54 # better assume to assume "no"
55 PNG_ICONS="no"
55fi 56fi
56 57
57# Functions 58# Functions
@@ -59,6 +60,7 @@ display_usage() {
59 cat << EOF 60 cat << EOF
60Usage: fluxbox-generate_menu [-kgrBh] [-t terminal] [-w url] [-b browser] 61Usage: fluxbox-generate_menu [-kgrBh] [-t terminal] [-w url] [-b browser]
61 [-m menu-title] [-o /path] [-u /path] [-p /path] [-n /path] [-q /path] 62 [-m menu-title] [-o /path] [-u /path] [-p /path] [-n /path] [-q /path]
63 [-d /path ] [-ds] [-i /path] [-is]
62EOF 64EOF
63} 65}
64 66
@@ -73,6 +75,11 @@ Options:
73 -B enable backgrounds menu 75 -B enable backgrounds menu
74 -r Don't remove empty menu-entries; for templates 76 -r Don't remove empty menu-entries; for templates
75 77
78 -d path(s) to search for *.desktop files
79 -ds wider search for *.desktop files (takes more time)
80 -i path(s) to search for icons
81 -is wider search for icons (worth the extra time)
82
76 -t Favourite terminal 83 -t Favourite terminal
77 -w Homepage for console-browsers. Default is fluxbox.org 84 -w Homepage for console-browsers. Default is fluxbox.org
78 -b Favourite browser 85 -b Favourite browser
@@ -149,25 +156,285 @@ case `uname` in
149 ;; 156 ;;
150esac 157esac
151 158
159convertIcon(){
160 if [ ! -f "$1" ] ; then
161 echo "Icon file not found: $1" >&2
162 return 1
163 fi
164
165 if [ "$1" == "$2" ]; then
166 $ECHO "Files are in the same location: $1 == $2" >&2
167 # not really an error; just nothing to do.
168 return 0;
169 fi
170
171 local BASENAME="${1##*/}"
172
173 # make sure it is an icon by checking if it has an extension
174 if [ "$BASENAME" == "${BASENAME%%.*}" ]; then
175 $ECHO "File $1 does not have a filename extention." >&2
176 return 1;
177 fi
178
179 # don't have to convert xpm files
180 case "$1" in
181 *.xpm)
182 echo "$1"
183 return 0;
184 ;;
185 esac
186
187 # may not have to convert png if imlib is enabled
188 if [ "$PNG_ICONS" == "yes" ]; then
189 case "$1" in
190 *.png)
191 echo "$1"
192 return 0;
193 ;;
194 esac
195 fi
196
197 # convert all others icons and save it as xpm format under directory $2
198 entry_icon="$2/${BASENAME%.*}.xpm"
199 if [ -f "${entry_icon}" ]; then
200 : echo "File exists. To overwrite, type: convert \"$1\" \"$entry_icon\"" >&2
201 else
202 if which convert &> /dev/null; then
203 convert "$1" "$entry_icon"
204 # echo convert "$1" , "$entry_icon" >> $ICONMAPPING
205 else
206 echo "Please install ImageMagick's convert utility" >&2
207 fi
208 fi
209 echo "$entry_icon"
210}
211
212removePath(){
213 execname="$1"
214 local progname=${execname%% *}
215 # separate program name and its parameters
216 if [ "$progname" == "$execname" ]; then
217 # no params
218 # remove path from only program name
219 execname="${progname##*/}"
220 else
221 local params=${execname#* }
222 # remove path from only program name
223 execname="${progname##*/} $params"
224 fi
225 echo $execname
226}
227
228doSearchLoop(){
229 for ICONPATH in "$@"; do
230 #$ECHO ": $ICONPATH" >> $ICONMAPPING
231 [ -d "$ICONPATH" ] || continue
232 #echo -n "."
233 # $ECHO ":: $ICONPATH/$temp_icon" >> $ICONMAPPING
234 if [ -f "$ICONPATH/$temp_icon" ]; then
235 echo "$ICONPATH/$temp_icon"
236 return 0;
237 else # try different extensions;
238 # remove extension
239 iconNOext=${temp_icon%%.*}
240 [ -d "$ICONPATH" ] && for ICONEXT in .xpm .png .gif ; do
241 #$ECHO "::: $ICONPATH/$iconNOext$ICONEXT" >> $ICONMAPPING
242 if [ -f "$ICONPATH/$iconNOext$ICONEXT" ]; then
243 echo "$ICONPATH/$iconNOext$ICONEXT"
244 return 0;
245 fi
246 done
247 fi
248 done
249 #echo "done"
250 return 1
251}
252
253doSearch(){
254 # remove '(' from '(fluxbox ...) | ...'
255 local execname="${1//(}"
256 local temp_icon="$2"
257 $ECHO "# Searching for icon $temp_icon for $execname" >> $ICONMAPPING
258
259 # check in $ICONMAPPING before searching directories
260 entry_icon=`grep -m 1 "^\"${execname}\"" $ICONMAPPING | grep -o '<.*>'`
261 if [ "$entry_icon" ]; then
262 entry_icon=${entry_icon//<}
263 entry_icon=${entry_icon//>}
264 echo $entry_icon
265 return 0;
266 fi
267 # echo "$ICONMAPPING for $execname: $entry_icon"
268
269 # the following paths include a user-defined variable, listing paths to search for icons
270 # echo -n "for $temp_icon"
271 eval doSearchLoop $USER_ICONPATHS \
272 "$FB_ICONDIR" \
273 "/usr/share/${execname%% *}" \
274 ${OTHER_ICONPATHS} \
275
276
277}
278
279searchForIcon(){
280 # remove '&' and everything after it
281 entry_exec="${1%%&*}"
282 entry_icon="$2"
283 $ECHO "searchForIcon \"$entry_exec\" \"$entry_icon\"" >&2
284
285 # get the basename and parameters of entry_exec -- no path
286 entry_exec=`removePath "${entry_exec}"`
287 [ -z "$entry_exec" ] && { echo "Exec is NULL $1 with icon $2"; return 1; }
288
289 # search for specified icon if it does not exists
290 if [ "$entry_icon" ] && [ "$entry_exec" != "$entry_icon" ] && [ ! -f "$entry_icon" ]; then
291 # to search for icon in other paths,
292 # get basename
293 local temp_icon="${entry_icon##*/}"
294 # remove parameters
295 temp_icon=${temp_icon#* }
296 # clear entry_icon until temp_icon is found
297 unset entry_icon
298
299 if [ ! -f "$entry_icon" ]; then
300 entry_icon=`doSearch "$entry_exec" "$temp_icon"`
301 fi
302 fi
303
304 # remove parameters
305 local execname=${entry_exec%% *}
306
307 # echo "search for icon named $execname.{xpm,png,gif}"
308 if [ ! -f "$entry_icon" ]; then
309 entry_icon=`doSearch "$entry_exec" "$execname"`
310 fi
311
312 # ----------- done with search ------------
313
314 # convert icon file, if needed
315 if [ -f "$entry_icon" ] && [ "yes$ConvertIfNecessary" ]; then
316 entry_icon=`convertIcon "$entry_icon" "$HOME/.fluxbox/icons"`
317 # echo ":::: $entry_icon"
318 fi
319
320 # remove path to icon; just get basename
321 local icon_base=${entry_icon##*/}
322 # remove extension
323 icon_base=${icon_base%%.*}
324 # echo "^.${entry_exec}.[[:space:]]*<.*/${icon_base}\....>"
325 if [ -f "$entry_icon" ]; then
326 # if icon exists and entry does not already exists, add it
327 if ! grep -q -m 1 "^.${entry_exec}.[[:space:]]*<.*/${icon_base}\....>" $ICONMAPPING 2> /dev/null; then
328 echo -e "\"${entry_exec}\" \t <${entry_icon}>" >> $ICONMAPPING
329 else
330 $ECHO "# mapping already exists for ${entry_exec}" >> $ICONMAPPING
331 fi
332 else
333 echo "# No icon file found for $entry_exec" >> $ICONMAPPING
334 fi
335}
336
337toSingleLine(){ echo "$@"; }
338createIconMapping(){
339 $ECHO "# creating `date`" >> $ICONMAPPING
340 $ECHO "# using desktop files in $@" >> $ICONMAPPING
341 $ECHO "# searching for icons in `eval toSingleLine $OTHER_ICONPATHS`" >> $ICONMAPPING
342 # need to determine when to use .fluxbox/icons/$execname.xpm over those listed in iconmapping
343 for DIR in "$@" ; do
344 if [ -d "$DIR" ]; then
345 echo "# ------- Looking in $DIR" >> $ICONMAPPING
346 find "$DIR" -type f -name "*.desktop" | while read DESKTOP_FILE; do
347 # echo $DESKTOP_FILE;
348 #entry_name=`grep -m 1 '^[ ]*Name=' $DESKTOP_FILE`
349 #entry_name=${entry_name##*=}
350 entry_exec=`grep -m 1 '^[ ]*Exec=' "$DESKTOP_FILE"`
351 entry_exec=${entry_exec##*=}
352 entry_exec=${entry_exec//\"}
353 if [ -z "$entry_exec" ]; then
354 entry_exec=${DESKTOP_FILE%%.desktop*}
355 fi
356
357 entry_icon=`grep -m 1 '^[ ]*Icon=' "$DESKTOP_FILE"`
358 entry_icon=${entry_icon##*=}
359
360 # echo "--- $entry_exec $entry_icon"
361 case "$entry_icon" in
362 "" | mime_empty | no_icon )
363 : echo "no icon for $entry_exec"
364 ;;
365 *)
366 searchForIcon "$entry_exec" "$entry_icon"
367 ;;
368 esac
369 done
370 else
371 $ECHO not exists: $DIR >&2
372 fi
373 done
374 $ECHO "# done `date`" >> $ICONMAPPING
375}
376
377lookupIcon() {
378 if [ ! -f $ICONMAPPING ]; then
379 echo "!!! Icon map file not found: $ICONMAPPING" >&2
380 return 1
381 fi
382
383 local execname=$1
384 shift
385 [ "$1" ] && echo "!! Ignoring extra paramters: $*" >&2
386
387 [ -z "$execname" ] && { echo "execname is NULL; cannot lookup"; return 1; }
388 execname=`removePath "$execname"`
389
390
391 #echo "grepping ${execname}"
392 iconString=`grep -m 1 "^\"${execname}\"" $ICONMAPPING | grep -o '<.*>'`
393 $ECHO "lookupIcon $execname, $iconString" >&2
394
395 if [ -z "$iconString" ] ; then
396 iconString=`grep -m 1 "^\"${execname%% *}" $ICONMAPPING | grep -o '<.*>'`
397 fi
398
399 if [ -z "$iconString" ] && [ -z "$PARSING_DESKTOP" ] ; then
400 #$ECHO "lookupIcon: Searching ... should only be needed for icons not gotten from *.desktop (manual-created ones): $execname" >&2
401 searchForIcon "$execname" "$execname"
402 [ "$entry_icon" ] && iconString="<$entry_icon>"
403 fi
404
405 # [ "$iconString" ] && echo " Found icon for $execname: $iconString" >&2
406 echo $iconString
407}
408
152append() { 409append() {
153 if [ -z "${INSTALL}" ]; then 410 if [ -z "${INSTALL}" ]; then
154 echo -n " $*" >> ${MENUFILENAME} 411 local iconString="`echo $* | grep -o '<.*>'`"
155 execname="`echo $*|cut -d\( -f2|cut -d\) -f1`" 412 if [ -z "$iconString" ]; then
156 if [ "${PNG_ICONS}" = "no" ]; then 413 echo -n " $* " >> ${MENUFILENAME}
157 if [ -r "${HOME}/.fluxbox/icons/$execname.xpm" ]; then 414 # get the program name between '{}' from parameters
158 echo "<${HOME}/.fluxbox/icons/$execname.xpm>" >> ${MENUFILENAME} 415 local execname=$*
159 else 416 execname=${execname#*\{}
160 echo >> ${MENUFILENAME} 417 execname=${execname%%\}*}
161 fi 418 # if execname hasn't changed from original $*, then no '{...}' was given
162 else 419 if [ "$execname" != "$*" ]; then
163 if [ -r "${HOME}/.fluxbox/icons/$execname.png" ]; then 420 case "$execname" in
164 echo "<${HOME}/.fluxbox/icons/$execname.png>" >> ${MENUFILENAME} 421 $DEFAULT_TERM*)
165 elif [ -r "${HOME}/.fluxbox/icons/$execname.xpm" ]; then 422 # remove quotes
166 echo "<${HOME}/.fluxbox/icons/$execname.xpm>" >> ${MENUFILENAME} 423 execname=${execname//\"}
167 else 424 # remove "$DEFAULT_TERM -e "
168 echo >> ${MENUFILENAME} 425 # needed in case calling another program (e.g., vi) via "xterm -e"
169 fi 426 execname=${execname##*$DEFAULT_TERM -e }
170 fi 427 ;;
428 esac
429 # echo -$execname-
430 # lookup execname in icon map file
431 iconString=`lookupIcon "$execname"`
432 #[ "$iconString" ] || echo "No icon found for $execname"
433 fi
434 echo "${iconString}" >> ${MENUFILENAME}
435 else
436 echo " $*" >> ${MENUFILENAME}
437 fi
171 else 438 else
172 echo " $*" >> ${MENUFILENAME} 439 echo " $*" >> ${MENUFILENAME}
173 fi 440 fi
@@ -244,6 +511,8 @@ normal_find() {
244} 511}
245 512
246clean_up() { 513clean_up() {
514[ -f "$ICONMAPPING" ] && rm -f "$ICONMAPPING"
515
247# Some magic to clean up empty menus 516# Some magic to clean up empty menus
248rm -f ${MENUFILENAME}.tmp 517rm -f ${MENUFILENAME}.tmp
249touch ${MENUFILENAME}.tmp 518touch ${MENUFILENAME}.tmp
@@ -903,6 +1172,32 @@ while [ $# -gt 0 ]; do
903 -B) BACKGROUNDMENUITEM=yes; shift;; 1172 -B) BACKGROUNDMENUITEM=yes; shift;;
904 -k) KDEMENU=yes; shift;; 1173 -k) KDEMENU=yes; shift;;
905 -g) GNOMEMENU=yes; shift;; 1174 -g) GNOMEMENU=yes; shift;;
1175 -is) OTHER_ICONPATHS="
1176 /usr{,/local}/share{,/xclass}/{icons,pixmaps}
1177 /usr{,/local}/share/icons/mini
1178 /usr{,/local}/share/icons/{default.kde,hicolor}/16x16/*
1179 "
1180 shift;;
1181 -ds) OTHER_DESKTOP_PATHS="
1182 /usr/share/mimelnk
1183 /usr/share/applications
1184 /usr/share/xsessions
1185 /usr/share/services
1186 "
1187 # /usr/share/apps \
1188 shift;;
1189 -i) USER_ICONPATHS=${2};
1190 #needs testing
1191 for aPath in $2; do
1192 testoption di $1 $aPath;
1193 done
1194 shift 2;;
1195 -d) USER_DESKTOP_PATHS=${2};
1196 #needs testing
1197 for aPath in $2; do
1198 testoption di $1 $aPath;
1199 done
1200 shift 2;;
906 -t) MY_TERM=${2}; testoption ex $1 $2; shift 2;; 1201 -t) MY_TERM=${2}; testoption ex $1 $2; shift 2;;
907 -b) MY_BROWSER=${2}; testoption ex $1 $2; shift 2;; 1202 -b) MY_BROWSER=${2}; testoption ex $1 $2; shift 2;;
908 -o) MENUFILENAME=${2}; shift 2; CHECKINIT=NO ;; 1203 -o) MENUFILENAME=${2}; shift 2; CHECKINIT=NO ;;
@@ -976,6 +1271,45 @@ for KDE_PREFIX in "${KDE_PREFIX}" /usr/local /usr/X11R6 /usr /opt "${PREFIX}"; d
976 fi 1271 fi
977done 1272done
978 1273
1274if [ -z "${INSTALL}" ]; then
1275 [ -z "$ECHO" ] && ECHO=": echo" # for debugging
1276 FB_ICONDIR="$HOME/.fluxbox/icons"
1277 [ -d "$FB_ICONDIR" ] || mkdir "$FB_ICONDIR"
1278 ICONMAPPING="$HOME/.fluxbox/iconmapping"
1279
1280 if [ "$GNOMEMENU" ] ; then
1281 OTHER_DESKTOP_PATHS="\"$HOME/.gnome/apps\" \"${GNOME_PREFIX}/share/gnome/apps\" $OTHER_DESKTOP_PATHS"
1282 #[ "OTHER_ICONPATHS" ] && OTHER_ICONPATHS=
1283 fi
1284 if [ "$KDEMENU" ] ; then
1285 OTHER_DESKTOP_PATHS="\"$HOME/.kde/share/applnk\" \"${KDE_PREFIX}/share/applnk\" $OTHER_DESKTOP_PATHS"
1286 [ "OTHER_ICONPATHS" ] && OTHER_ICONPATHS="\"$HOME\"/.kde/share/icons/{,*} $OTHER_ICONPATHS"
1287 fi
1288 [ "$GNOMEMENU$KDEMENU" ] && OTHER_DESKTOP_PATHS="\"$ETCAPPLNK\" $OTHER_DESKTOP_PATHS"
1289
1290 checkDirs(){
1291 local CHECKED_DIRS=""
1292 for DIR in "$@"; do
1293 if [ -d "$DIR" ]; then
1294 # todo: should check if there are duplicates
1295 CHECKED_DIRS="$CHECKED_DIRS \"$DIR\""
1296 fi
1297 done
1298 echo $CHECKED_DIRS
1299 }
1300
1301 OTHER_ICONPATHS=`eval checkDirs $OTHER_ICONPATHS`
1302 OTHER_DESKTOP_PATHS=`eval checkDirs $OTHER_DESKTOP_PATHS`
1303
1304 $ECHO "Using USER_DESKTOP_PATHS=\"$USER_DESKTOP_PATHS\" and USER_ICONPATHS=\"$USER_ICONPATHS\""
1305 $ECHO "Using OTHER_ICONPATHS=$OTHER_ICONPATHS"
1306 $ECHO "Using OTHER_DESKTOP_PATHS=$OTHER_DESKTOP_PATHS"
1307 $ECHO "Calling function: createIconMapping"
1308
1309 eval createIconMapping $USER_DESKTOP_PATHS $OTHER_DESKTOP_PATHS
1310 $ECHO "Done createIconMapping."
1311fi
1312
979# directory for the backgrounds 1313# directory for the backgrounds
980if [ -z "$BACKGROUND_DIRS" ]; then 1314if [ -z "$BACKGROUND_DIRS" ]; then
981 BACKGROUND_DIRS="${HOME}/.fluxbox/backgrounds/:${PREFIX}/share/fluxbox/backgrounds/" 1315 BACKGROUND_DIRS="${HOME}/.fluxbox/backgrounds/:${PREFIX}/share/fluxbox/backgrounds/"
@@ -1215,6 +1549,7 @@ append_menu_end
1215 1549
1216# We'll only use this once 1550# We'll only use this once
1217ETCAPPLNK=/etc/X11/applnk 1551ETCAPPLNK=/etc/X11/applnk
1552PARSING_DESKTOP="true"
1218# gnome menu 1553# gnome menu
1219if [ "${GNOMEMENU}" ]; then 1554if [ "${GNOMEMENU}" ]; then
1220 append_submenu "${GNOMEMENUTEXT}" 1555 append_submenu "${GNOMEMENUTEXT}"
@@ -1230,6 +1565,7 @@ if [ -d "${KDE_PREFIX}/share/applnk/" -a "${KDEMENU}" ]; then
1230 append_menu_end 1565 append_menu_end
1231 unset ETCAPPLNK 1566 unset ETCAPPLNK
1232fi 1567fi
1568unset PARSING_DESKTOP
1233 1569
1234#User menu 1570#User menu
1235if [ -r "${USERMENU}" ]; then 1571if [ -r "${USERMENU}" ]; then
@@ -1333,6 +1669,10 @@ if [ ! "${REMOVE}" ]; then
1333 clean_up 1669 clean_up
1334fi 1670fi
1335 1671
1672# escapes any parentheses in menu label
1673# e.g., "[exec] (konqueror (web))" becomes "[exec] (konqueror (web\))"
1674sed -i 's/(\(.*\)(\(.*\)))/(\1 (\2\\))/' $MENUFILENAME
1675
1336if [ -z "$INSTALL" ]; then 1676if [ -z "$INSTALL" ]; then
1337 if [ -z "$CHECKINIT" ]; then 1677 if [ -z "$CHECKINIT" ]; then
1338 INITMENUFILENAME=`awk '/menuFile/ {print $2}' $HOME/.fluxbox/init` 1678 INITMENUFILENAME=`awk '/menuFile/ {print $2}' $HOME/.fluxbox/init`