linuxdeploy-plugin-gtk icon indicating copy to clipboard operation
linuxdeploy-plugin-gtk copied to clipboard

Cannot open images after recent commits

Open qarmin opened this issue 4 years ago • 19 comments

After upgrading version of GTK plugin(from c008df652946408f357f502bab67bfcf6f303b4e to 447f23f3420b2827f6bdfd3f86ff0cb4fce3cf90), I lost ability to open images.

Steps to reproduce:

  • Download Appimages
  • Extract archive(contains few images) - FF.zip
  • Open Appimage
  • Add at the top directory with previously extracted folder
  • Go to similar images tab
  • Search for similar images
  • Try to open by double click image

In 2.1.0 version, image should open in ImageMagick app, but 2.2.0 version doesn't show anything(maybe is a way to open it in default image app?). I doesn't change logic between versions, but 2.2 version should prints when xdg-open fails to open app

https://github.com/qarmin/czkawka/releases/download/2.2.0/linux_czkawka_gui.AppImage https://github.com/qarmin/czkawka/releases/download/2.1.0/linux_czkawka_gui.AppImage

qarmin avatar Jan 11 '21 18:01 qarmin

It works for me, both with 2.1.0 and 2.2.0. Do you think something is missing in XDG_DATA_DIRS export?

You can extract your AppImage with ./linux_czkawka_gui.AppImage --appimage-extract, then edit squashfs-root/apprun-hooks/linuxdeploy-plugin-gtk.sh file and add $HOME/.local/share to XDG_DATA_DIRS. To test, run ./squashfs-root/AppRun.

I don't see any difference.

I'm using Ubuntu 20.04. I tried to reproduce it on different OS, but for now after updating kernel I don't have access to VirtualBox.

Opening folders in default file manager works fine(this is done by double click with Right mouse button)

qarmin avatar Jan 12 '21 10:01 qarmin

Ok, I'm able to reproduce your issue on a Ubuntu VM. When I comment GDK_PIXBUF_MODULE_FILE, it works. All I know for the moment is it concerns EOG only: with other default image viewer, I don't have this issue.

I need to investigate deeper...

Just for the record, I just discovered some Gtk+ related stuff in https://docs.appimage.org/packaging-guide/manual.html#bundling-gtk-libraries. Doubt it helps. Perhaps it should be updated or removed.

TheAssassin avatar Jan 12 '21 13:01 TheAssassin

I also found, that natively installed app allows to open multiple images at once(by double click of left mouse button) but packed with appimage allows to open only one image and entire app freeze until I close ImageMagick app(tested only with 2.1).

In appimage forum I got info that this is not problem with Appimage because problem persists when app is unpacked with --appimage-extract

qarmin avatar Jan 12 '21 13:01 qarmin

The the link between GDK_PIXBUF_MODULE_FILE and this bug is the following:

  • $APPDIR/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.so is called
  • this library depends on libpng16.so.16
  • it crashes somewhere in libpng16.so.16

Full BT: debug.txt

As you can see in BT, libpng16.so.16 is loaded from /lib/x86_64-linux-gnu, while is it available in $APPDIR/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/../../../../. The problem is EOG also depends on libpng16.so.16.

Setting LD_LIBRARY_PATH to $APPDIR/usr/lib definitively solves this problem. So it is like the libpng16.so.16 in Focal is not the same as Xenial...

@TheAssassin Any idea to force libpixbufloader-png.so to load the correct libpng16.so.16 library?

Can you provide a link to the broken AppImage so I can check it out?

TheAssassin avatar Jan 12 '21 20:01 TheAssassin

Links are in first post.

Maybe GDB does not respect RPATH, so forget the BT.

@qarmin Can you test if the issue is related to a problem with shared libraries? Try to replace the following line in squashfs-root/apprun-hooks/linuxdeploy-plugin-gtk.sh:

export LD_LIBRARY_PATH="$GDK_PIXBUF_MODULEDIR:$LD_LIBRARY_PATH"

By this one:

export LD_LIBRARY_PATH="$APPDIR/usr/lib:$GDK_PIXBUF_MODULEDIR:$LD_LIBRARY_PATH"

After change I'm able to open image in ImageMagick(setting any other default app like eye of gnome, still opens ImageMagick)

qarmin avatar Jan 14 '21 07:01 qarmin

Changing default application has been complicated for me too. But I succeed to open an image from your AppImage without any changes, see my screenshot: VirtualBox_focal_17_01_2021_10_54_12 No issue with ImageMagick, but with EOG I am still investigating...

@qarmin can you check the default application for JPEG files, please?

xdg-mime query default image/jpeg

org.gnome.eog.desktop

qarmin avatar Jan 17 '21 10:01 qarmin

Then try to change it to ImageMagick:

xdg-mime default display-im6.q16.desktop image/jpeg

Now jpg opens in image magick and png still shows nothing

qarmin avatar Jan 17 '21 10:01 qarmin

Maybe you need to change default file association for PNG files too.

For me, it is definitively a bug with libpng16.so.16. When I start EOG normally: openat_normal.txt When I start EOG from AppRun: openat_apprun.txt

The problem is our plugin exports environment variables to make binary inside AppImage to work (e.g. czkawka_gui in this case). However, the side effect is sub-processes inherit these environments variables (like EOG) when they shouldn't, because they are outside AppImage.

Maybe we should "whitelist" some applications (like EOG), i.e. unset these environments variables in a custom wrapper. Do you have a better idea or shall I send a PR with such workaround @TheAssassin? I know, this proposal is not elegant...

Following up the question in #12.

But Czkawka is written in Rust, and there is no exec() or something like that in this case. I have no knowledge in Rust, so I have no idea what linuxdeploy should intercept.

Indeed, when tools are linked statically (that includes Rust, Go, ...), a simple exec() wrapper won't be able to sanitize the environment when subprocesses are launched.

A tool like Czkawka could however detect whether it's running in an AppImage and sanitize the environment itself. We could provide such a functionality by providing the same sanitation run in the exec wrapper in a simple tool (could even be a bash script) through which the actual tool is launched by the Gtk+ application. The application path/name would be passed as argv[0].

Unfortunately, it's not easy to work around Gtk+'s limitations here. Qt makes it a lot easier, as almost all settings can also be read from a file called qt.conf next to the binaries. Gtk+ lacks such a feature and requires these crude hacks.

Setting environment variables is always a workaround. It works fine for many applications, but breaks the moment you want to call external tools.

Have you considered just shipping eog, though? Do you launch eog explicitly or is it just the default tool for images (e.g., opened with xdg-open)?

TheAssassin avatar Jan 26 '21 17:01 TheAssassin

Czkawka uses crate https://crates.io/crates/open which just execute native os tool to open things. On Linux it run open, xdg-open, gnome-open or kde-open(don't know which check first)

qarmin avatar Jan 26 '21 17:01 qarmin

@qarmin I think it is easier for you to handle this then on application level rather than expecting miracles from the plugin. I think if we document this properly (e.g., in the README), you should be able to fix the issues as an application author. The cheapest way to implement the workaround is to just unsetenv(...) all the offending variables, most notably LD_LIBRARY_PATH.

I'm not too much into Rust to see whether there's a more elegant solution for this than unsetenv. But this usually works quite well: once the program is loaded, the environment variables typically aren't needed any more, unless you want to call other programs in your AppImage.

I think there's even a need for a separate crate that you can call to do this....

TheAssassin avatar Feb 06 '21 08:02 TheAssassin