You are not logged in.

#51 2021-02-20 06:44:06

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

ohnonot wrote:

Oh, xdg-mime can also do this. Interesting, I'll have to check that out.
It's a shell script itself, so chances are good I can figure the mechanism out.

I've just been looking some more at xdg-open and xdg-mime. xdg-open in fact calls xdg-mime in its "generic" mode (no desktop detected) but xdg-mime looks buggy to me. The info_gnome() function - called if it detects an XFCE desktop - exits with success even if none of gio, gvfs-info or gnomevs-info are present. roll
( Ah, it's a known bug: https://bugs.debian.org/cgi-bin/bugrepo … bug=838120 )
info_generic() looks for mimetype and falls back to file - so we're back where we started...

There is 'mimetype' from libfile-mimeinfo-perl which seems more complicated (and slower) than 'file --mime-type' but I haven't reasearched enough to have an opinion on which is better.

Try clearing your recntly-used.xbel, then open an executable shell script straight from geany (not from the filemanager). Does it show up as "application/octet-stream" now?

No, it's still "application/x-shellscript"

johnraff wrote:

It's not foolproof though. I've got a couple of dead entries in my current menu, which ought to be debugged...

My script drops non-readable (non-existing) files.

It's not because the file is unreadable. It's a problem with the BL script dropping a needed option in one case (meld). In another case, if Thunderbird saves an attachment as a .png file which I haven't yet opened in an image viewer, then the only application stored in *.xbel is Thunderbird, so clicking the menu item sends it to Tbird which offers to send it as an attachment in an email. Fair enough, but perhaps not what most users would want.

Maybe the simple mime-type based approach is the best...

Also, other people have created openbox-recent pipemenus, I should research before re-inventing.

I haven't yet found any that weren't based on the (somewhat hacky) shell script in the OB wiki. If you find one, please post a link!


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#52 2021-02-20 08:22:08

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

sleekmason wrote:

Now in a terminal I get:

sleekmason@ai:~$ pipe-recent-files
<openbox_pipe_menu>

Me too.

Line 61:

[ -r "$recentfile" ] || echo "<item label=\"No data to process\" /></openbox_pipe_menu>" && exit 1

This exits right away. That possible error usually gets picked up by shellcheck, but not this time for some reason. Anyway, this allows the script to run:

[ -r "$recentfile" ] || { echo "<item label=\"No data to process\" /></openbox_pipe_menu>" && exit 1 ;}

---
Now I've looked at the code, this rearrangement makes debugging easier, from line 111:

    # finally print out this recent item
    echo "<item label=\"$label\" icon=\"$icon\">
    <action name=\"Execute\">
        <command>
            <![CDATA[xdg-open '${file[i]}']]>
        </command>
    </action>
</item>"

---
And I found that issue with meld that our lua script also suffers from. After doing a file comparison, meld puts a recent-********.meldcmp file (in ~/.local/share/meld/) which appears in the recent files menu. Meld can redo the comparison if run as 'meld --comparison-file <filepath>' and that command is written into recently-used.xbel like this:

<bookmark:application name="Meld" exec="&apos;/usr/bin/meld --comparison-file %u&apos;" modified="2021-02-20T07:51:20Z" count="2"/>

Running 'xdg-open <filepath>' doesn't work. (My script gets it.  angel )


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#53 2021-02-20 13:39:57

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

johnraff wrote:

Try clearing your recntly-used.xbel, then open an executable shell script straight from geany (not from the filemanager). Does it show up as "application/octet-stream" now?

No, it's still "application/x-shellscript"

OK, then my geany is different from yours. I wonder why. I'm on version 1.37.1.
"application/octet-stream" seems to be a fancy way of saying "I have no clue what this file is".
---

sleekmason wrote:

Now in a terminal I get:

sleekmason@ai:~$ pipe-recent-files
<openbox_pipe_menu>

Sorry for that, I must have pushed before saving the file.
It should be working now.
---
I almost completely rewrote the script.
Openbox can use SVG graphics, yes?
In that case there's no need to convert anything - the previous 'mkicon()' function is now 'findicon()' and simply returns a suitable mimetype icon with some clever file system traversing (no 'find').
There's also no need to provide icon theme paths (although you still can), 'findicon()' finds the current theme, reads the Inherits, and searches there.
All this is happening so fast that no caching is required.

[ I also added a function that replaces the stupid octet-stream mimetype with something more useful, as discovered by 'gio' (part of glib2, or rather libglib2.0-bin on Debian). If you don't have that problem you might not need it. In any case, 'gio' is an optional dependency and installing libglib2.0-bin might fix weird icons. ]

The script now almost completely gets its information from recently-used.xbel with xmlstarlet, and sorts by recently used - the last item in the file is not always the most recently used!
It also opens the entry with the application defined in recently-used.xbel, and not 'xdg-open'.

I must say I'm very happy with the result. There's still some room for improvement of course.
But feel free to use and reuse this.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#54 2021-02-20 13:56:15

sleekmason
zoom
From: Ozarks
Registered: 2018-05-22
Posts: 510
Website

Re: [Solved] Icons in pipe menus

@ohnonot, Closer!  Your newest script opens the menu, but without the icons.

The line johnraff provided made the earlier version work as expected(afaik).

*Edit The 'clear recents' icon is there.

*Edit 2- The icon for "downloads" is "unknown" in the first script. Everything else looks groovy.

Last edited by sleekmason (2021-02-20 14:25:42)

Offline

#55 2021-02-20 18:11:15

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

What exactly is "downloads"? AFAIK recently-used.xbel does not store folders, only files.
So beyond that, all icons are good?

If there's any sort of problem with icons, you need to look at your icon theme's index.theme - sometimes the Inherits are messed up or plain missing, in that case you can provide a chain of icon themes to search on the command line.

If you think it will help me debug, you can always provide the output of the script.
The '-d' option will give a little additional info.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#56 2021-02-20 19:56:11

sleekmason
zoom
From: Ozarks
Registered: 2018-05-22
Posts: 510
Website

Re: [Solved] Icons in pipe menus

ohnonot wrote:

What exactly is "downloads"? AFAIK recently-used.xbel does not store folders, only files.
So beyond that, all icons are good?

If there's any sort of problem with icons, you need to look at your icon theme's index.theme - sometimes the Inherits are messed up or plain missing, in that case you can provide a chain of icon themes to search on the command line.

If you think it will help me debug, you can always provide the output of the script.
The '-d' option will give a little additional info.

Super sorry about that. I made a mistake. Not downloads, but ISO files in downloads.
Matters not a bit, and easy enough to change if need be. Also couldn't reproduce!

Really digging the separate icons. Well done:)

Edit* Everything is Awesome:) Forgot to change themes! <-- then looked at the script and saw it shouldn't be necessary to add gnome anymore. - See below.
Edit 2* Really fast as well.
edit 3* Ha! Very nice:) just saying.

Edit 4* Found an issue. - None of the "named" Gnome Colors work.  Gnome-brave, gnome-wise etc..  Gnome, and Papirus work wonderfully.

Heres -d while in gnome-brave:

sleekmason@ai:~$ pipe-recent-files -d
<openbox_pipe_menu>
/usr/local/bin/pipe-recent-files: line 165: type: gio: not found
0	/home/sleekmason/Pictures/wallpapers/Ice.jpg
0	jpeg
0	firefox-esr "/home/sleekmason/Pictures/wallpapers/Ice.jpg"
1	/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg
1	jpeg
1	thunderbird "/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg"
2	/home/sleekmason/Bin/gpg
2	x-shellscript
2	geany "/home/sleekmason/Bin/gpg"
3	/home/sleekmason/packages_list.txt
3	plain
3	mousepad "/home/sleekmason/packages_list.txt"
########################
########################
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
<item label="~/Pictures/wallpapers/Ice.jpg " icon=""><action name="Execute"><command><![CDATA[firefox-esr "/home/sleekmason/Pictures/wallpapers/Ice.jpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
<item label="~/Pictures/wallpapers/IMG__20210220__112137.jpg " icon=""><action name="Execute"><command><![CDATA[thunderbird "/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
<item label="~/Bin/gpg " icon=""><action name="Execute"><command><![CDATA[geany "/home/sleekmason/Bin/gpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
<item label="~/packages__list.txt " icon=""><action name="Execute"><command><![CDATA[mousepad "/home/sleekmason/packages_list.txt"]]></command></action></item>
Icon lookup @ /usr/share/icons/gnome-brave
Icon lookup @ /usr/share/icons/gnome-colors-common
<separator /><item icon="/usr/share/icons/gnome-colors-common/22x22/actions/edit-delete.png" label="Clear Recents"><action name="Execute"><prompt>Really delete ~/.local/share/recently-used.xbel?</prompt><command><![CDATA["/usr/local/bin/pipe-recent-files" -c]]></command></action></item></openbox_pipe_menu>
sleekmason@ai:~$ 

Here is the same with epapirus activated;

sleekmason@ai:~$ pipe-recent-files -d
<openbox_pipe_menu>
/usr/local/bin/pipe-recent-files: line 165: type: gio: not found
0	/home/sleekmason/Pictures/wallpapers/Ice.jpg
0	jpeg
0	firefox-esr "/home/sleekmason/Pictures/wallpapers/Ice.jpg"
1	/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg
1	jpeg
1	thunderbird "/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg"
2	/home/sleekmason/Bin/gpg
2	x-shellscript
2	geany "/home/sleekmason/Bin/gpg"
3	/home/sleekmason/packages_list.txt
3	plain
3	mousepad "/home/sleekmason/packages_list.txt"
########################
########################
Icon lookup @ /usr/share/icons/ePapirus
<item label="~/Pictures/wallpapers/Ice.jpg " icon="/usr/share/icons/ePapirus/22x22/mimetypes/image-jpeg.svg"><action name="Execute"><command><![CDATA[firefox-esr "/home/sleekmason/Pictures/wallpapers/Ice.jpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/ePapirus
<item label="~/Pictures/wallpapers/IMG__20210220__112137.jpg " icon="/usr/share/icons/ePapirus/22x22/mimetypes/image-jpeg.svg"><action name="Execute"><command><![CDATA[thunderbird "/home/sleekmason/Pictures/wallpapers/IMG_20210220_112137.jpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/ePapirus
<item label="~/Bin/gpg " icon="/usr/share/icons/ePapirus/22x22/mimetypes/application-x-shellscript.svg"><action name="Execute"><command><![CDATA[geany "/home/sleekmason/Bin/gpg"]]></command></action></item>
Icon lookup @ /usr/share/icons/ePapirus
<item label="~/packages__list.txt " icon="/usr/share/icons/ePapirus/22x22/mimetypes/text-plain.svg"><action name="Execute"><command><![CDATA[mousepad "/home/sleekmason/packages_list.txt"]]></command></action></item>
Icon lookup @ /usr/share/icons/ePapirus
<separator /><item icon="/usr/share/icons/ePapirus/22x22/actions/delete.svg" label="Clear Recents"><action name="Execute"><prompt>Really delete ~/.local/share/recently-used.xbel?</prompt><command><![CDATA["/usr/local/bin/pipe-recent-files" -c]]></command></action></item></openbox_pipe_menu>
sleekmason@ai:~$ 

Last edited by sleekmason (2021-02-20 22:50:09)

Offline

#57 2021-02-21 05:39:20

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

sleekmason wrote:

Edit 4* Found an issue. - None of the "named" Gnome Colors work.  Gnome-brave, gnome-wise etc..  Gnome, and Papirus work wonderfully.

Thank you for the output.
I think you got bit by this:

ohnonot wrote:

If there's any sort of problem with icons, you need to look at your icon theme's index.theme - sometimes the Inherits are messed up or plain missing, in that case you can provide a chain of icon themes to search on the command line.

So that would be /usr/share/icons/gnome-*/index.theme I guess.
This is often a problem with the icon themes themselves and how they're packaged - the Inherits should be dependencies but aren't. In other cases the designers seem to be suffering delusions of grandeur when they don't supply any Inherits at all, supposedly thinking their theme is perfect.
So it's not the recent script's "fault", but I provided a fallback mechanism just for such cases. Read the code.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#58 2021-02-21 08:27:00

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

ohnonot wrote:
johnraff wrote:

Try clearing your recntly-used.xbel, then open an executable shell script straight from geany (not from the filemanager). Does it show up as "application/octet-stream" now?

No, it's still "application/x-shellscript"

OK, then my geany is different from yours. I wonder why. I'm on version 1.37.1.
"application/octet-stream" seems to be a fancy way of saying "I have no clue what this file is".

On Buster, I've got geany 1.33. I do get the octet mimetypes sometimes, but not as often as you seem to. "No clue" seems to be about right though - instead of trying to cope, you could just use some generic icon in those cases?

johnraff wrote:

Xmlstarlet is very powerful and versatile - I'm  using it in a snippet I wrote years ago, but am now fired up to play with it some more...

ohnonot wrote:

I almost completely rewrote the script.
...
The script now almost completely gets its information from recently-used.xbel with xmlstarlet, and sorts by recently used - the last item in the file is not always the most recently used!
It also opens the entry with the application defined in recently-used.xbel, and not 'xdg-open'.

While I was playing around with xmlstarlet you totally GOT it. cool
That's the perfect invocation to extract the info needed. Great job.
I'll stash that snippet of code away for further use.

---
I've been running your script and do have a few suggestions though - of course it's up to you whether to apply any of them...

Small stuff first:
*) A -h/--help option?
*) An option to display the filename only, not the full path?
*) An option not to display icons? I know icons are a major feature here, but I think it's a solid recent files menu without them too.
*) The icons look a bit squashed together in my menu. I'd like a bit of padding round them.
Dn5XfYSt.png
*) There is quite a lot of output on STDERR which will spam out ~/.xsession-errors with meaningless messages. Create a debug() function (turned on when $debug=1) to replace echo in those places?
*) Shellcheck on line #99: "recent-files-ohnonot.sh:99:5: warning: Invalid flags are not handled. Add a *) case. [SC2220]"
*) Grep is pretty fast, and 'read -r line file' can be slow - are you sure that G() function gives you a speed advantage?
*) In several places you chek if an array is empty like this: '[[ "$array" == "" ]] &&...' By default bash will assume you mean the first element, so it works OK, but it would feel cleaner to do [[ "${array[0]}" = "" ]] or [[ -z "${array[0]}" ]] or [[ ${#array[@]} -eq 0 ]]...
*) You go through the array of parsed xml data twice - can it not all be done in one go? I don't know if that would make any significant difference to running time, though.

*)
And the big one: escaping special characters. You only handle %20 for spaces, but there are many many more, and if any of them remain in the file path as-is then things you do later get broken. Apart from quotes, apostrophes etc there's the whole world of unicode. As it is your script can't handle files with Japanese names. (But see the tweaked version in the screenshot has one.) Instead of trying to do each one in bash (there are hundreds, if not thousands) in the past I used a perl snippet to decode everything:

var=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0]);' "$var" )

In my tweaked version of your script I applied that to each array element in turn, and because perl is so fast it doesn't make it intolerably slow, but still perceptably so. It would be more efficient to run it only once over the whole menu as a single string - maybe that could be done right at the end if you collected all the items in a variable instead of echoing them when they're generated.

I hit some other fiddly issues with quoting and escaping for xml.
I've got a folder full of files with difficult names for testing menus like this. One such file is

/home/john/text/oddnames/"new folder"/It's called "conkyrc-caption", "so?"

Yes that's its name, and the regular tools like thunar and geany can all handle it. For your script to do the same I had to escape some xml special characters, and escape single quotes as '\'', otherwise some files don't appear in the menu, or don't open correctly when clicked.

Here's the tweaked version. (This contains none of the above smaller suggestions, just the quoting/escaping.) All I can say is that it works, but it could easily do with some optimization. smile

#!/bin/bash

# Openbox pipemenu to create a list of recent files with icons
# (if you don't care about icons this will be a waste of resources)
# also see: forums.bunsenlabs.org/viewtopic.php?pid=111438#p111438

### Dependencies:
# - xmlstarlet                  parsing recentfile
### Optional:
# - gio (glib2, libglib2.0-bin) redefine useless mimetypes

# Options:
# -r str  Recentfile to parse (default: $HOME/.local/share/recently-used.xbel)
# -c      Clear the recentfile
#
# -d      Output a little more to stderr
# -s str  Comma-separated list of icon sizes to consider. Default 22,24,32
# -t str  Comma-separated list of Icon theme names to consider. No default.
#         Example: "Tela,Papirus,Paper"
# -m int  maximum number of results to display

# If the user didn't define iconthemes, we extract the current one from
# gtk3's settings.ini and append the "Inherits" found in that theme's index.theme.
# Warning: many icon themes have messy Inherits - if the result is less than
# desirable, one can override the whole Icon theme chain with the '-' option.

max=20 # maximum number of recent files
# Comma-separated list of Desired icon sizes.
# Choose something that is actually found in icon themes.
isizes=22,24,32
debug=0
recentfile="$HOME/.local/share/recently-used.xbel"
gtksettingsfile="${XDG_CONFIG_HOME-"$HOME/.config"}/gtk-3.0/settings.ini"

G() {
    # simplistic grep replacement
    # only works on files, only the first match is assigned to a variable
    # $1: query
    # $2: file
    # $3: variable to use
    while read -r line; do
        [[ "$line" == *"$1"* ]] && declare -g "$3"="$line" && return
    done <"$2"
}
# This function will return exactly one icon for a mimetype
findicon() {
    mime="$1"
    queries="${2-"mimetypes,mimes"}" # comma-separated list of icon type subfolders

    shopt -s nullglob # required to recognize empty results

    # If the user didn't define iconthemes, we extract the current one from
    # gtk3's settings.ini and append the "Inherits" found in that theme's index.theme.
    if [[ "$iconthemes" == "" ]]; then
        G gtk-icon-theme-name "$gtksettingsfile" iconthemes
        iconthemes="${iconthemes##*=}"
        iconthemes="${iconthemes#*\"}"
        iconthemes="${iconthemes%\"*}"
        for path in "$HOME/.local/share/icons" "/usr/share/icons"; do
            path="$path/$iconthemes/index.theme"
            [ -r "$path" ] && break
        done
        G 'Inherits=' "$path" inherits
        iconthemes="${iconthemes},${inherits#*=}"
    fi

    src_icon=""
    for theme in ${iconthemes//,/ }; do
        for path in "$HOME/.local/share/icons" "/usr/share/icons"; do
            path="$path/$theme"
            [ -d "$path" ] || continue
            echo "Icon lookup @ $path" >&2
            for isize in ${isizes//,/ }; do
                for dir1 in "$isize" "${isize}x$isize" scalable; do
                    for dir2 in ${queries//,/ }; do
                        for dir in "$dir1/$dir2" "$dir2/$dir1"; do
                            [ -d "$path/$dir" ] || continue
                            for src_icon in "$path/$dir/$mime".???; do [ -r "$src_icon" ] && break 7; done
                            for src_icon in "$path/$dir/"*"-$mime".???; do [ -r "$src_icon" ] && break 7; done
                        done
                    done
                done
            done
        done
    done
    # no results? OK, no icon then, and return 1 == error
    [[ "$src_icon" == "" ]] && return 1
    echo "$src_icon"
}
pipe_exit() {
    echo "<item label=\"$*\" /></openbox_pipe_menu>"
    exit 1
}
######################### MAIN ###############################

echo "<openbox_pipe_menu>"

while getopts "dcs:t:m:r:g:" opt; do
    case $opt in
        d)  debug=1
        ;;
        c)
            cat <<EOF > "$recentfile"
<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0"
      xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
      xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
</xbel>
EOF
        exit
        ;;
        s) isizes="$OPTARG"
        ;;
        t)  # a comma-separated list of icon theme names to search for mimetype icons
            # overrides automatic detection
            iconthemes="$OPTARG"
        ;;
        m)  [[ "$OPTARG" =~ [0-9]+ ]] && (( OPTARG >= 0 )) && (( OPTARG <= 65535 )) || pipe_exit "Option -${opt}: invalid number $OPTARG"
            max="$OPTARG"
        ;;
        r)  [ -r "$OPTARG" ] || pipe_exit "Option -${opt}: Cannot read $OPTARG"
            recentfile="$OPTARG"
        ;;
        g)  [ -r "$OPTARG" ] || pipe_exit "Option -${opt}: Cannot read $OPTARG"
            gtksettingsfile="$OPTARG"
        ;;
    esac
done

# quick dependency check
for dep in xmlstarlet; do
    type "$dep" >/dev/null || exit 1
done

# Use an Xpath expression to collect all
# 1) file:///...
# 2) mime-type
# 3) application
# elements, sorted by last modified date. Read into array and limit to $max elements.
mapfile -n "$((max*3))" -t array <<<"$(xmlstarlet sel -t -m "/xbel/bookmark" -s D:T:U '@modified' \
-v '@href' -n \
-v 'info/metadata/mime:mime-type/@type' -n \
-v 'info/metadata/bookmark:applications/bookmark:application[last()]/@exec' -n "$recentfile")"
[[ "$array" == "" ]] && pipe_exit "No file data to process"

mimetypestofix=()
j=0
# Converting file:/// elements to proper unix paths:
for ((i=0;i<${#array[@]};i++)); do
    # file path
    array[i]="${array[i]#*file://}"
    #array[i]="${array[i]%\"*}"
    array[i]=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0]);' "${array[i]}" )
    #array[i]="${array[i]//%20/ }"
    ((i++))
    # mime-type - keep only the part after the /
    array[i]="${array[i]#*/}"
    # if the mime-type is the useless octet-stream, collect files to re-test with gio:
    if [[ "${array[i]}" == "octet-stream" ]]; then
        mimetypestofix[$((j++))]="${array[$((i-1))]}"
    fi
    ((i++))
    # command to open file
    # remove enclosing single quotes
    array[i]="${array[i]#\'}"
    array[i]="${array[i]%\'}"
    filepath="${array[$((i-2))]}"
    # escaping single quotes is tricky
    filepath="${filepath//\'/\'\\\'\'}"
    # replace %u with quoted file path
    array[i]="${array[i]//%u/\'${filepath}\'}"
done

mimetypesfixed=()
if type gio >/dev/null && [[ "$mimetypestofix" != "" ]]; then
    # We need to fix the stupid octet-stream mimetype.
    # to get only the last line of the gio output for each file we use mapfile with
    # a callback function, see: wiki.bash-hackers.org/commands/builtin/mapfile#the_callback
    mtf() { mimetypesfixed[$(($1/5))]="${2##*/}"; }
    mapfile -t -c 5 -C 'mtf ' <<<"$(gio info -a standard::content-type "${mimetypestofix[@]}")"
fi
if [[ "$debug" == 1 ]]; then
    for ((i=0;i<${#array[@]};i++)); do
        echo -e "$((i/3))\t${array[i]}"
    done
    echo "########################"
    for ((i=0;i<${#mimetypestofix[@]};i++)); do
        echo -e "$((i))\t${mimetypestofix[i]}"
    done
    echo "########################"
    for ((i=0;i<${#mimetypesfixed[@]};i++)); do
        echo -e "$((i))\t${mimetypesfixed[i]}"
    done
fi >&2

# go through the array 3 lines at a time, and output openbox pipemenu stuff:
for ((i=0,j=0;i<${#array[@]};i+=3)); do
    # 1st line: the file path
    # 2nd line: the mimetype
    # 3rd line: the command to execute

    # 1. the file - skip if unreadable
    [ -r "${array[i]}" ] || continue
    array[i]="${array[i]//\'/&apos;}"
    array[i]="${array[i]//\"/&quot;}"
    array[i]="${array[i]//</&lt;}"
    array[i]="${array[i]//>/&gt;}"
    # label of the menu entry - openbox-specific
    label="${array[i]/$HOME/\~}"
    label="${label//_/__}"

    # 2. The mimetype
    type="${array[$((i+1))]}"
    if [[ "$mimetypesfixed" != "" ]]; then
        echo "unfixed $type" >&2
        [[ "$type" == "octet-stream" ]] && type="${mimetypesfixed[$((j++))]}"
        echo "fixed   $type" >&2
    fi
    # find a suitable icon
    icon="$(findicon "$type" || findicon unknown)"

    # 3. the command
    cmd="${array[$((i+2))]}"
 
    # finally print out the recent item
    echo "<item label=\"$label \" icon=\"$icon\">
    <action name=\"Execute\">
        <command>
            <![CDATA[$cmd]]>
        </command>
    </action>
</item>"
done

# close up the pipemenu, with one last entry to remove $recentfile and a suitable "delete" icon
icon="$(findicon delete actions)"
echo "<separator /><item icon=\"$icon\" label=\"Clear Recents\"><action name=\"Execute\"><prompt>Really delete ${recentfile//$HOME/\~}?</prompt><command><![CDATA[\"$0\" -c]]></command></action></item></openbox_pipe_menu>"

Last edited by johnraff (2021-02-21 13:15:38)


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#59 2021-02-21 13:18:13

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

^Added a couple more suggestions.

BTW as to what is writing to recently-used.xbel, I guess the most likely suspect would be a GTK library?


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#60 2021-02-21 14:48:28

sleekmason
zoom
From: Ozarks
Registered: 2018-05-22
Posts: 510
Website

Re: [Solved] Icons in pipe menus

Where and how to do this?

My original super duper code was 18 lines long.  This is 238, and we are way past my knowledge level.

Right now, gnome-colors do not work. *Edit Nevermind, I'm an idiot.  Finally figured it out.

I do not know how to fix this or I would. 

I don't mind doing debugging, but please don't leave me stranded without a direct example.

Edit* Yes, You did.
I see here:
# -t str  Comma-separated list of Icon theme names to consider. No default.
#         Example: "Tela,Papirus,Paper"

But this does not make any sense to me.  Where do I put this line in the script? How does it begin? (-t str)? 
*Edit All makes sense now.

For instance, for the icon size, I can see

isizes=22,24,32

So I have at least something to reference.

Sorry if I am being dense here.  I can build a house from the ground up, everything included.  But I will never be able to code like you guys do.  *Edit - yep being dense.

Honestly? It bothers me to no end that I can't just seem to "grab" it. It really seems simple on the face, and then "by degrees" more difficulty just a short ways in.  Time consuming to learn I would think. Somehow I get the idea that just taking a class isn't going to suddenly wise me up.

Edit*  ^ I just want to get to the point I don't waste hours, when all I have to do is change the concept of how I think of something.

And, You guys rock. Period.

Last edited by sleekmason (2021-02-21 22:15:20)

Offline

#61 2021-02-21 16:02:55

damo
....moderator....
Registered: 2015-08-20
Posts: 6,529

Re: [Solved] Icons in pipe menus

sleekmason wrote:

Where and how to do this?
...
I see here:
# -t str  Comma-separated list of Icon theme names to consider. No default.
#         Example: "Tela,Papirus,Paper"

But this does not make any sense to me.  Where do I put this line in the script? How does it begin? (-t str)?
....

It looks like it is a script parameter, so run it with eg

scriptname -t Papirus,Paper

or maybe

scriptname -t "Papirus,Paper"

Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#62 2021-02-21 17:01:48

sleekmason
zoom
From: Ozarks
Registered: 2018-05-22
Posts: 510
Website

Re: [Solved] Icons in pipe menus

damo wrote:
sleekmason wrote:

Where and how to do this?
...
I see here:
# -t str  Comma-separated list of Icon theme names to consider. No default.
#         Example: "Tela,Papirus,Paper"

But this does not make any sense to me.  Where do I put this line in the script? How does it begin? (-t str)?
....

It looks like it is a script parameter, so run it with eg

scriptname -t Papirus,Paper

or maybe

scriptname -t "Papirus,Paper"

I actually got that far:) 
*Edit - The rather obvious answer is to use the gnome icons, not to use the gnome-brave icons.

pipe-recent-files -t "gnome-brave"

Should just be:

pipe-recent-files -t "gnome"

Last edited by sleekmason (2021-02-21 22:12:07)

Offline

#63 2021-02-21 22:00:50

sleekmason
zoom
From: Ozarks
Registered: 2018-05-22
Posts: 510
Website

Re: [Solved] Icons in pipe menus

Okay! Got it. Sorry for all the mess.

Why I was trying to use gnome-brave instead of just assigning icons from gnome, I will never know.

Last edited by sleekmason (2021-02-21 22:16:04)

Offline

#64 2021-02-22 09:56:31

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

@johnraff: thanks for pointing out de/encoding problems.
I am working on that now; it might be possible without additional depenencies.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#65 2021-02-22 10:08:40

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

^The problem is when you come to all the unicode characters. Unless there's some algorithm, you'll never be able to code each conversion separately without using some external library, I think. But perl is pretty much a given - it wouldn't require any extra dependencies. But there are surely alternatives - the perl code is just something I found long ago that does the job reasonably quickly.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#66 2021-02-22 17:03:53

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

I don't have a problem with unicode characters: https://dt.iki.fi/stuff/forums/bunsen/recent-pipe.png
Unless you mean something else?

When I said "dependencies" I actually meant "external programs that slow the script down".
Even half a dozen bash string manipulations must be faster than a single perl command.
So after you pointed the shortcomings out to me, I made more changes - first I need to completely decode the file:/// string to turn it into a unix path:

str="${str//&amp;/&}"
str="${str//&apos;/\'}"
str="${str//&quot;/\"}"
str="${str//&lt;/<}"
str="${str//&gt;/>}"
# decode url encoding - unix.stackexchange.com/a/187256
LC_ALL=C str="$(printf "%b" "${str//%/\\x}")"

But then I need to partly re-encode it to make it suitable for the Openbox menu label:

# encode for XML
label="${label//&/&amp;}"
label="${label//\'/&apos;}"
label="${label//\"/&quot;}"
label="${label//</&lt;}"
label="${label//>/&gt;}"
label="${label//_/__}"

That bothers me because I'm not sure if I thought of everything now...

Anyhow, much more changes, making it more robust (I hope), configurable, precise and faster.
Even so, it's gotten to the point where I'm getting lost in the code.

The license is GPL3, so feel free to use it everybody.
https://notabug.org/ohnonot/stuff/src/master/recent

___________________________________________________________

BTW, what you wrote about grep being faster than read... where are you getting this from?
I did some testing:

time for ((i=0;i<10000;i++)); do grep -q gtk-icon-theme-name ~/.config/gtk-3.0/settings.ini ; done

real    0m20.079s
user    0m18.023s
sys     0m2.550s

real    0m20.074s
user    0m18.031s
sys     0m2.529s

export LC_ALL=C; time for ((i=0;i<10000;i++)); do grep -q gtk-icon-theme-name ~/.config/gtk-3.0/settings.ini ; done

real    0m7.293s
user    0m6.052s
sys     0m1.744s

real    0m7.401s
user    0m5.970s
sys     0m1.919s

time for ((i=0;i<10000;i++)); do while read -r line; do [[ "$line" == gtk-icon-theme-name ]] && var=happy; done < ~/.config/gtk-3.0/settings.ini ; done

real    0m2.170s
user    0m2.009s
sys     0m0.159s

real    0m2.164s
user    0m1.985s
sys     0m0.177s

export LC_ALL=C; time for ((i=0;i<10000;i++)); do while read -r line; do [[ "$line" == gtk-icon-theme-name ]] && var=happy; done < ~/.config/gtk-3.0/settings.ini ; done

real    0m1.897s
user    0m1.700s
sys     0m0.195s

real    0m1.864s
user    0m1.686s
sys     0m0.177s

Interesting results. I wonder why LC_ALL=C makes it so much faster.
But still, builtin read rules.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#67 2021-02-22 17:37:46

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

johnraff wrote:

*) The icons look a bit squashed together in my menu. I'd like a bit of padding round them.

Openbox resizes the icons to fit the height of the element, which is in turn defined by the font size. I think there's no way to influence this.

Now I just noticed that the script mangles double quotes again.  Damn. Fixed it, with your version of the script!

Last edited by ohnonot (2021-02-22 18:12:41)


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#68 2021-02-23 07:28:03

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

Wow, you've been working hard on this! Just ran it through all the options and everything works. All my trickily named files came through unscathed - you've got the pesky quoting issues sorted. Running time is quite low considering all the icon work (-I option roughly halves it, though it remains marginally slower than our lua script) and the cached symlinks directory is a neat idea. The ordering of items is an improvement on the current BL script because you've got xmlstarlet ordering them by modification time. cool

---
OK I'm now reduced to picking at peripheral issues:

ohnonot wrote:

I don't have a problem with unicode characters: https://dt.iki.fi/stuff/forums/bunsen/recent-pipe.png
Unless you mean something else?

No, you have the Japanese characters displaying OK there - but this is something you've added since yesterdays post I think?

...to completely decode the file:/// string to turn it into a unix path:

str="${str//&amp;/&}"
str="${str//&apos;/\'}"
str="${str//&quot;/\"}"
str="${str//&lt;/<}"
str="${str//&gt;/>}"
# decode url encoding - unix.stackexchange.com/a/187256
LC_ALL=C str="$(printf "%b" "${str//%/\\x}")"

I doesn't hurt to play safe, but I don't think there will be any &lt; or &gt; in the file path - any literal < or > will be urlencoded, likewise any % or any other special symbols (made a couple more strangely named files to check). &amp; &apos; and &quot; are certainly found though.

Anyway, nice to discover that printf can handle hex conversions without having to call in an external library like perl or python, however fast they might be. (I subsequently found that even 'echo -e' will do it.)

I need to partly re-encode it to make it suitable for the Openbox menu label:

# encode for XML
label="${label//&/&amp;}"
label="${label//\'/&apos;}"
label="${label//\"/&quot;}"
label="${label//</&lt;}"
label="${label//>/&gt;}"
label="${label//_/__}"

That bothers me because I'm not sure if I thought of everything now...

I think you've got everything. The five basic control characters plus the openbox key accelerator underscore.
These two pages say the same thing:
https://www.liquid-technologies.com/XML … gData.aspx
https://stackoverflow.com/a/1091953/4964251

what you wrote about grep being faster than read... where are you getting this from?

Well, I didn't say exactly that, I said grep was fast and read could be be slow (both true I think), and wondered if it was worth checking if there was a speed advantage. You did that, and yes there is a speed advantage in read. smile
I thought I originally read that reading a file line by line could be slow on Greg Wooledge's Bash Wiki, but I can't find any such comment now. Search the web on the topic, though, and you'll find many people talking about read being slow. Still, it's a built-in so even a fast utility like grep will find it hard to compete I guess. Maybe for huge files?

The debug() function: speed of execution isn't really important at all here, but it is possible to save a bit - checking the $debug flag every time debug() is run - by defining debug() once near the start of the script, for example:

case $debug in
0)
    debug() { :;}
;;
1)
    debug() { echo stuff;}
;;
esac

So normally debug() would do nothing at all.

...it's gotten to the point where I'm getting lost in the code.

Yes it is getting a bit long and tangled. If you were willing to forgo fixing the icon for octet-stream and just use some default icon in that case (does it happen all that often?), then you wouldn't need to build the mimetypestofix and mimetypesfixed arrays, and maybe you could go through the main array just once, not twice. Your call though.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#69 2021-02-23 12:41:36

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

Thanks for your kind feedback.
And thanks for the tip with the debug function! I put it straight into the getopts case/esac. One variable and a few tests less!

I'm very, very annoyed at those messed-up mimetypes in recently-used.xbel, and the part of the script that deals with them. Hackish.
I just tried a live USB of SysRescCD (Arch-based, so not too far from home), Antix (19 iirc), and BL Lithium. I can see the undesirable classifications in all three - i.e. various shellscripts or plain text files are categorized as "application/octet-stream". Examples: ~/.bashrc, /boot/syslinux/syslinux.cfg, those test files with weird characters all get categorized thusly.
Are you sure you can't reproduce this on your installation?

The weirdest thing is that all the while filemanagers (pcmanfm, thunar) recognize and "iconize" these correctly.

Unless I find a solution for this, future versions of the script will just use 'gio' to get the mime-type for all files (actually gio goes one step further and already provides a list of icon-names), if the user chooses to see icons.

It seems the filechoosers of GTK2 and GTK3 are the only thing writing to recently-used.xbel. But I didn't see different results for e.g. viewnior (gtk2) or Firefox (gtk3).


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#70 2021-02-24 02:58:33

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

ohnonot wrote:

I'm very, very annoyed at those messed-up mimetypes in recently-used.xbel, and the part of the script that deals with them. Hackish.
I just tried a live USB of SysRescCD (Arch-based, so not too far from home), Antix (19 iirc), and BL Lithium. I can see the undesirable classifications in all three - i.e. various shellscripts or plain text files are categorized as "application/octet-stream". Examples: ~/.bashrc, /boot/syslinux/syslinux.cfg, those test files with weird characters all get categorized thusly.
Are you sure you can't reproduce this on your installation?

Just checked .bashrc and my recently-used.xbel shows "text/plain". But I opened a Bullseye VM, and sure enough, octet-streams all over the place. neutral So something has happened to the recent GTK libraries I guess. And yes, this is rather annoying.

The weirdest thing is that all the while filemanagers (pcmanfm, thunar) recognize and "iconize" these correctly.

Indeed.

Unless I find a solution for this, future versions of the script will just use 'gio' to get the mime-type for all files (actually gio goes one step further and already provides a list of icon-names), if the user chooses to see icons.

Why not? 'gio info -a standard::icon' seems to provide what you need (gio means a dependency on libglib2.0-bin btw). Running gio once on a whole list of files is definitely faster than doing each entry separately though, and (I haven't looked closely at the icon finding section) it looks as if it might mean a lot of rewriting...


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#71 2021-02-24 07:00:09

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

^ Yes, changing the logic to use gio will require major rewriting - which I already started big_smile

johnraff wrote:

Just checked .bashrc and my recently-used.xbel shows "text/plain". But I opened a Bullseye VM, and sure enough, octet-streams all over the place. neutral So something has happened to the recent GTK libraries I guess. And yes, this is rather annoying.

I just checked again:

  • When I open files with pcmanfm, it doesn't touch recently-used.xbel at all.

  • When I open files from thunar, the files get assigned meaningful mime-types.

  • When I open files from the GTK filechooser (both gtk2 and gtk3), it uses "octet-stream" abundantly.

This behaviour seems consistent across distros & versions.
Can you reproduce that?


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#72 2021-02-24 11:14:01

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

I'll have a look tomorrow.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#73 2021-02-25 05:32:27

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

My version, on Debian Bullseye:

  • When I open files with pcmanfm, the files get assigned meaningful mime-types.

  • When I open files from thunar, the files get assigned meaningful mime-types.

  • When I open files from a terminal command, the files get assigned meaningful mime-types.

  • When I open files from the GTK filechooser (in geany), it uses "octet-stream" most of the time.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#74 2021-02-25 19:46:48

ohnonot
...again
Registered: 2015-09-29
Posts: 5,342
Website

Re: [Solved] Icons in pipe menus

From the terminal, I suppose that's `xdg-open` yes? I get very inconsistent behavior with that, sometimes files aren't added to recently-used.xbel at all, sometimes they are, with "meaningful" mimetypes. Can't (yet) see a pattern.
Pcmanfm seems to add all files with "meaningful" mimetypes (contrary to what I said earlier), but for some reason refuses to add ~/.bashrc. Go figure roll
And for the filechooser our observations seem to match up.

That cinches it for me, a rewrite leaning much more on `gio` is in order.

Thanks for testing, and partly going down this rabbithole with me.

Anyhow, that's already two bugs or at least serious shortcomings for the gtk filechooser.
The AUR has one or two alternative versions of GTK3, one even with a patched filemanager. Let's see if that helps.


Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos

Offline

#75 2021-02-25 23:22:27

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 7,753
Website

Re: [Solved] Icons in pipe menus

On the terminal I just called the opening app directly: 'geany /path/to/file' but the data was added to *.xbel.
Pcmanfm added .bashrc for me.

Good luck with the rewrite!

If you use AUR packages we won't be able to use it here on Debian of course...


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

Board footer

Powered by FluxBB