AppImage/AppImageKit

Invoking the browser from an AppImage

bengtmartensson opened this issue · 17 comments

Probono and myself have tried to get my program IrScrutinizer to run as AppImage, see bengtmartensson/IrScrutinizer#65 and https://bintray.com/probono/AppImages/IrScrutinizer/view#files. The only problem remaining is that the browser invocation is not working. IrScrutinizer uses Java Desktop for this (http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#browse%28java.net.URI%29) but this is not cast in iron. Something in the environment is not "right" for firing up/connecting to the system browser, and an IOException is thrown. I have tried other ways to invoke "the browser", but not found anything that works.

Moreover, this appears not to be just my problem: the AppImage version of subsurface appears to have exactly the same problem: invoking the browser (Help -> About -> Website) is also not working! Tried both the version on appimage.org and the version at subsurface-divelog.org.

For the record, I am using Fedora21 64bit (Yes, I know, obsolete :-)) Cinnamon desktop (Gnome dialect), with Firefox as standard browser.

Does xdg-open work? Has always worked for me from within AppImages

Yes, I would also suggest to execute xdg-open http://....
I don't see why it could matter whether you are inside or outside an AppImage to do this.

I guess (not a Java programmer though!) that in Java this might be Runtime.getRuntime().exec("xdg-open http://...");

I have not been able to get xdg-open to work either. My gut-feeling is that it is a library loading problem.

Does the browser invocation on subsurface (as described in my first post) work for other people?

Yes, Help -> About -> Website works fine for me using the Subsurface AppImage from the Subsurface website's download page. Possibly some issue with your particular OS? Can you try using e.g., an Ubuntu Live CD?

Solved!! It turned out that the AppImage set XDG_DATA_DIRS to something that is nonsensical for invoking things like xdg-open: it did not find the standard user configuration files, since setting XDG_DATA_DIRS tells "the programs" to look there instead. The magical word is to

 unset XDG_DATA_DIRS

I still think that this is a real problem with AppImage (and subsurface), but unsetting seems good enough for me, at least for the moment.

I was too laze to try with a live CD :-).

Thanks @bengtmartensson for finding out the cause. I am closing this ticket since you have a workaround but I have opened the more generic #132 to keep track of the topic, in case others run into it too.

I have a similar problem where calling xdg-open from an app in an AppImage fails.

In my app, /usr/bin/xdg-open is called via QProcess starting it. Starting it through QDesktopServices causes the same error, but I tried it more directly via QProcess.

The error message I get is:

kde-open5: /tmp/.mount_UjnHns/usr/lib64/libQt5Core.so.5: version `Qt_5.9' not found (required by kde-open5)
kde-open5: /tmp/.mount_UjnHns/usr/lib64/libQt5Core.so.5: version `Qt_5.9' not found (required by /usr/lib64/libKF5KIOWidgets.so.5)
kde-open5: /tmp/.mount_UjnHns/usr/lib64/libQt5Core.so.5: version `Qt_5.9' not found (required by /usr/lib64/libKF5KIOCore.so.5)
kde-open5: /tmp/.mount_UjnHns/usr/lib64/libQt5Core.so.5: version `Qt_5.9' not found (required by /usr/lib64/libKF5JobWidgets.so.5)

Since I am running a KDE 5 desktop, xdg-open decides to call kde-open5 from the host system. That seems to not be able to link to the host system Qt libs, but the ones from the AppImage which are not from the right version.

I am not sure what is the best way to solve this. Maybe starting xdg-open through a script that explicitely sets the LD_LIBRARY_PATH to the host pathes? Pulling kde-open5 into the AppImage does not solve the problem as other users will have other DEs and xdg-open will use other tools than kde-open5, which is intended.

Thoughts?

Not 100% sure this is applicable in your case @dragotin but according to https://github.com/AppImage/AppImageKit/wiki/Creating-AppImages#environment-variables:

By default, AppRun sets some variables such as LD_LIBRARY_PATH before executing the payload application. While this is sufficient in most cases, it may lead to issues if the payload application launches other applications that reside in the base system, that is, outside of the AppImage. KDevelop is an example of such an application. In these cases, the appimage-exec-wrapper library can be used together with the AppImage distribution mechanism. Place the library somewhere in your AppImage and point LD_PRELOAD to it before launching your application. Whenever your application invokes a child process through execv() or execve(), this wrapper will intercept the call and see if the child process lies outside of the bundled appdir. If it does, the wrapper will attempt to undo any changes done to environment variables before launching the process, since you probably did not intend to launch it with e.g. the LD_LIBRARY_PATH you previously set for your application. linuxdeployqt, on the other hand, does entirely without setting LD_LIBRARY_PATH by setting the RPATH in libraries and executables relative to $ORIGIN.

The question is, does your AppImage use AppRun, and could you get rid of this legacy thingy by using linuxdeployqt instead? I mean, without additional information, like a link to the AppImage or build recipe, or at least a name, we're just guessing wildly here.

Yes, I do use linuxdeployqt. I am building in OBS, this is the receipe: https://build.opensuse.org/package/view_file/home:kfreitag:Kraft/kraft-appimage/appimage.yml?expand=1 Thanks!

@dragotin on OBS it isn't guaranteed that AppRun isn't used despite linuxdeployqt (you can combine both, so OBS might use it anyway, but linuxdeployqt actually obsoletes AppRun). Extract your AppImage using --appimage-extract, and check whether the AppRun file in there is either a binary (hint that it's AppRun.c) or it's a symlink to the binary (then it's probably linuxdeployqt only).

To Do: ask @adrianschroeter whether OBS copies in an AppRun.c binary even if a linuxdeployqt generated symlink is there already.

@TheAssassin AppRun is a binary file in my squashfs.

This is the script I use in OBS:

script:
  - cp $BUILD_APPDIR/usr/share/icons/hicolor/scalable/apps/kraft.svg .
  - linuxdeployqt $BUILD_APPDIR/usr/share/applications/kraft.desktop -bundle-non-qt-libs -verbose=2 || true 
  - linuxdeployqt $BUILD_APPDIR/usr/share/applications/kraft.desktop -bundle-non-qt-libs -verbose=2 || true       

linuxdeployqt is run twice because @adrianschroeter said that it is needed in OBS

@dragotin can you delete AppRun and replace it with a relative symlink to the main executable of your application? See what happens then.

Normally an AppRun executable should not be needed if the AppDir/AppImage was prepared using linuxdeployqt.

@dragotin can you delete AppRun and replace it with a relative symlink to the main executable of your application? See what happens then.

Locally, after build on OBS, he means.

@probonopd my question was meant to verify it's an actual bug in OBS. OBS is actually overwriting existing AppRun scripts, that's not a good idea (should only copy in AppRun if there isn't one already). We should file a bug in the OBS bug tracker.

linuxdeployqt is run twice because @adrianschroeter said that it is needed in OBS

@dragotin sure, that's not limited to OBS, currently it's a necessity to do that unfortunately. Don't worry, it's neither your fault nor ours. In this case, I'd blame OBS.

Having to run it twice is entirely my fault: probonopd/linuxdeployqt#25. PRs welcome!

Probono and myself have tried to get my program IrScrutinizer to run as AppImage, see bengtmartensson/IrScrutinizer#65 and https://bintray.com/probono/AppImages/IrScrutinizer/view#files. The only problem remaining is that the browser invocation is not working. IrScrutinizer uses Java Desktop for this (http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#browse%28java.net.URI%29) but this is not cast in iron. Something in the environment is not "right" for firing up/connecting to the system browser, and an IOException is thrown. I have tried other ways to invoke "the browser", but not found anything that works.

Moreover, this appears not to be just my problem: the AppImage version of subsurface appears to have exactly the same problem: invoking the browser (Help -> About -> Website) is also not working! Tried both the version on appimage.org and the version at subsurface-divelog.org.

For the record, I am using Fedora21 64bit (Yes, I know, obsolete :-)) Cinnamon desktop (Gnome dialect), with Firefox as standard browser.

Just solved it.

Create a [Appname.desktop] file first remember this is the same as creating Desktop entries but for the sake of the issue here just create it in the same folder, Next, we will edit it using any editor or terminal and the content be like

#!/usr/bin/env xdg-open

[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=Figma
Exec=/home/firedrake/figma-linux-0.7.1.AppImage %u
Icon=signal-desktop
MimeType=x-scheme-handler/figma;

Very simple --> ICON be anything you want; Name: anything you want; Exec is the key; The LOC of the image file and obviously after making it executable and test that it's running and then adding the %u at the end then save it,
I tried making a URI handler but didn't work for me, this was the best way I have come through. Try it.

and then you can easily export it to the

ln -s /var/lib/snapd/desktop/applications/Figma.desktop **/home/firedrake/.local/share/applications**
--------------------------------------------------------------------------------
/var/lib/snapd/desktop/applications/Figma.desktop    -----> **my app location**

/home/firedrake/.local/share/applications ---> Desktop entry location

Now, after creating and able to launch the app using desktop entry now time to work at grabbing the TOKEN,
#Note: Desktop entry should be in the Application folder by now,
Next, There in the same folder you will find a mimeinfo.cache file
Edit using your Editor and then create a new entry for the URI handler (i.e Fallback to the app)
in my case, I created this.

x-scheme-handler/figma=Figma.desktop;

x-scheme-handler ----> this is just systemwide code, but figma is the focus here, when you see the error of xdg-open cannot find the specified location. you'll see figma:.......................SECRET ..and something......... Yes we grabbed that figma handle and forwarding it to the Figma.desktop and as you know Figma.desktop contains the Figma %u tag it'll grab it and Voila!
it works

OS: Kali Linux.

using these little lines have fun.