TheAssassin / AppImageLauncher

Helper application for Linux distributions serving as a kind of "entry point" for running and integrating AppImages
https://assassinate-you.net/tags/appimagelauncher/
MIT License
5.65k stars 265 forks source link

Use Thumbnailers to automatically generate thumbnails for every *.AppImage in any place #387

Open mttbernardini opened 3 years ago

mttbernardini commented 3 years ago

Is your feature request related to a problem? Please describe. Thumbnails get generated only when the AppImage resides in the "common" paths (i.e. ~/Applications), since the process is managed by appimaged. ~Might be related with https://github.com/AppImage/type2-runtime/issues/34~

Describe the solution you'd like File manager functionality can be employed to automatically generate thumbnails for *.AppImage files, instead of implementing the functionality in AppImageLauncher by touching ~/.cache/thumbnails (I read somewhere this is the current method, please correct me if I'm wrong).

Describe alternatives you've considered None.

Additional context

Here's a proof of concept which works under Cinnamon 3.8.8 using Nemo as file manager. It needs proper tweaking (i.e. extracting the icon in a fast way, probably using libappimage instead of relying on the runtime) since this implementation is quite slow and cpu-hungry (since it ~extracts useless stuff from AppImages and~ does maybe unnecessary converts).

  1. Create ~/.local/share/thumbnailers/appimage.thumbnailer
[Thumbnailer Entry]
TryExec=appimage-thumbnailer
Exec=appimage-thumbnailer %i %o %s
MimeType=application/vnd.appimage;application/x-iso9660-appimage;
  1. Create ~/.local/bin/appimage-thumbnailer (or suitable path under $PATH) (updated on 2021/01/10: using trusted runtime and extracting only what's necessary) (updated on 2021/01/12: typo, -size should be -resize)
#!/bin/bash

APPIMAGE="$1"
OUT="$2"
SIZE="$3"

export TARGET_APPIMAGE="$APPIMAGE"

tmpdir="$(mktemp -d)"
pushd "$tmpdir"

icon_path=".DirIcon"

while : ; do
    # appimageruntime is the runtime downloaded directly from AppImageKit
    # to avoid executing an untrusted runtime
    appimageruntime --appimage-extract "$icon_path"
    icon_path="$(readlink "squashfs-root/$icon_path")"
    [ -z "$icon_path"  ] && break
done

convert squashfs-root/.DirIcon -resize "$SIZE" "$OUT"
rm -r squashfs-root

popd

Implementing this in AppImageLauncher would simply require to define the two files system-wise (when installing with the .deb) w/o the need to write any additional logic about hashing or other things.

I hope this helps, thank you for you time!

PS: a similar method could be employed to generate thumbnails of AppDirs (this would be a first step towards making AppDirs first-class citizens, the second being able to run them by double clicking them. I'm trying to work on this second one)

TheAssassin commented 3 years ago

I'm all open for adding a minimal AppImage thumbnailer to AppImageLauncher. AIL already sets up correct MIME integration for its main UI, so we can re-use this for the thumbnailer. We can also employ libappimage for the thumbnail extraction.

What desktops have you tested this on? I suppose this doesn't work on KDE...

mttbernardini commented 3 years ago

I've tested on Cinnamon DE v3.8.8 (a fork of Gnome), so I assume this method works with other Gnome/GTK based DEs. I don't have the chance to test on KDE recently, but by inspecting some other Kthumbnailers (like this one) I think this method doesn't work.

However it seems the adjustements are not dramatic, instead of the .thumbnailer file, KDE requires a .desktop representing a KDE "Service" under /usr/share/kservices5/ with a similar spec. As for the executable, in the example they are using a library instead of a simple executable as in Gnome, I'm not sure if this is the only way.

TheAssassin commented 3 years ago

The main issue I see with this is that we'd have to run libappimage code on basically any file that might be an AppImage. The code hasn't been thoroughly reviewed by many people (mainly me, for most of the code), and we've recently had actual security issues with its desktop integration code. As we "just" run its thumbnailer, the attack surface is relatively low compared to the full desktop integration, but this is still something to be aware of.

I think I will make this an opt-in configuration option for the beginning.

I'm integrating this into ail-cli by the way. We can write a little adapter script like you've done there, which we can then easily rm to disable the feature.

TheAssassin commented 3 years ago

Can you please provide some sample arguments how your script is called? libappimage's thumbnailer doesn't let me (currently) choose the output path of the thumbnail. Perhaps we don't need that, as libappimage is capable of generating that path?

mttbernardini commented 3 years ago

/home/matteo/Applications/AppImageUpdate-x86_64.AppImage /tmp/.gnome_desktop_thumbnail.KTURW0 128 They correspond respectively to %i, %o and %s defined in the .desktop file. I think the thumbnailing pipeline expects the thumbnail to be at the specified path (if libappimage cannot handle this, we could just mv it afterwards), so then it can do the hashing and move it to ~/.cache/thumbnails.

PS: I updated the script with a loop to extract just the icon (and resolve symlinks) and use the trusted runtime downloaded from AppImageKit

TheAssassin commented 3 years ago

Thanks. That means I'll have to rewrite that part. At the moment, it's a bit too tightly coupled anyway there.

mttbernardini commented 3 years ago

@TheAssassin I recently drafted a full-fledged thumbnailer using libappimage, both for GNOME-derived desktop environments and KDE. For now I'm just extracting .DirIcon (if found), no resizing is performed: https://github.com/mttbernardini/appimage-thumbnailer

probonopd commented 2 years ago

fwiw, xapp-thumbnailers has a Python based thumbnailer for squashfs-based type-2 AppImages using unsquashfs that can work (at least) in Caja (MATE), Nautilus (GNOME), Nemo (Cinnamon), PCManFM (LXDE), and Thunar (Xfce).