AppImage / AppImageKit

Package desktop applications as AppImages that run on common Linux-based operating systems, such as RHEL, CentOS, openSUSE, SLED, Ubuntu, Fedora, debian and derivatives. Join #AppImage on irc.libera.chat
http://appimage.org
Other
8.67k stars 554 forks source link

Handle Gtk+ better #906

Open probonopd opened 5 years ago

probonopd commented 5 years ago

Currently we are bundling libgtk-3.so.0 and libgdk-3.so.0 but not the resources (e.g., themes) that go with them.

This results in

bad

when it should be

good

(AppRun:7980): Gtk-WARNING **: 11:40:02.419: Theme parsing error: gtk-contained.css:4322:148: Missing name of pseudo-class

(AppRun:7980): Gtk-WARNING **: 11:40:02.419: Theme parsing error: gtk-contained.css:4367:14: 'min-height' is not a valid property name

(AppRun:7980): Gtk-WARNING **: 11:40:02.420: Theme parsing error: gtk-contained.css:4587:23: No property named '-gtk-icon-transform'

We should either not bundle libgtk-3.so.0 and libgdk-3.so.0, or also bundle the resources (e.g., themes) that go with them.

With something like GTK_EXE_PREFIX=squashfs-root/usr/ GTK_THEME=Adwaita squashfs-root/AppRun it may be possible to load a bundled Gtk+ theme rather than the system's one, which is broken for us most of the time.

More information: https://developer.gnome.org/gtk3/stable/gtk-running.html

probonopd commented 5 years ago

Some experimentation in https://github.com/probonopd/gydl/blob/patch-1/.travis.yml

probonopd commented 5 years ago

People will likely complain that we are not using the system theme.

Hence there should be a check, similar to https://github.com/darealshinji/AppImageKit-checkrt/. If there is a more recent Gtk+ on the system, then use that, along with its theme. If it is not there, then use the bundled one, along with the bundled theme.

TheAssassin commented 5 years ago

Why bundle themes at all? Is there any desktop you know which doesn't ship a compatible theme? KDE does, for instance.

probonopd commented 5 years ago

When we ship a certain libgtk-3.so.0, then we also need to ship a matching theme, since even later themes will not work with earlier libgtk-3.so.0. In other words, we must treat libgtk-3.so.0 and its theme as a unit that needs to be bundled together or not bundled at all.

probonopd commented 5 years ago

Looks we also need to bundle usr/lib/x86_64-linux-gnu/gdk-pixbuf-*/*/loaders/*.so and deploy them correctly (rewrite rpaths, deploy dependencies)... and

  export GTK_EXE_PREFIX="$HERE/usr"
  export GDK_PIXBUF_MODULEDIR="$HERE/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders"
  export GTK_THEME=Adwaita

It's not that others haven't done it before:

https://github.com/aferrero2707/rapid-photo-downloader-appimage/blob/d6a036f00b7fbb0869615450b6793439c49f4674/AppRun-custom#L75-L84

Or isn't it needed aftter all?

https://github.com/aferrero2707/hugin-appimage/blob/2d3cdc3e58151afb0ebf75dd3f27b06a3706be8a/AppRun#L33-L39

probonopd commented 5 years ago

More may be needed:

https://gitlab.gnome.org/GNOME/gtk-mac-bundler/blob/03f78c56905dfda2dcca2e803e22e09d18534533/examples/launcher.sh#L25-36

export XDG_CONFIG_DIRS="$bundle_etc"/xdg
export XDG_DATA_DIRS="$bundle_data"
export GTK_DATA_PREFIX="$bundle_res"
export GTK_EXE_PREFIX="$bundle_res"
export GTK_PATH="$bundle_res"

export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
export PANGO_LIBDIR="$bundle_lib"
export PANGO_SYSCONFDIR="$bundle_etc"

or, for Gtk+ 3:

https://gitlab.gnome.org/GNOME/gtk-mac-bundler/blob/03f78c56905dfda2dcca2e803e22e09d18534533/examples/gtk3-launcher.sh#L26-36

export XDG_CONFIG_DIRS="$bundle_etc"/xdg
export XDG_DATA_DIRS="$bundle_data"
export GTK_DATA_PREFIX="$bundle_res"
export GTK_EXE_PREFIX="$bundle_res"
export GTK_PATH="$bundle_res"

export GTK2_RC_FILES="$bundle_etc/gtk-3.0/gtkrc"
export GTK_IM_MODULE_FILE="$bundle_etc/gtk-3.0/gtk.immodules"
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-3.0/gdk-pixbuf.loaders"
export PANGO_LIBDIR="$bundle_lib"
export PANGO_SYSCONFDIR="$bundle_etc"
probonopd commented 5 years ago

usr/lib/gdk-pixbuf-2.0/loaders.cache is needed but has hardcoded absolute paths.

We can patch them into relative paths, but then cd need to chdir().

Investigate

https://github.com/aferrero2707/gimp-appimage/blob/43b529390697fbfea67cc75aa57c3c35e0910775/appimage-helper-scripts/bundle-gtk2.sh

It seems to do much of what is needed for a Gtk+ linuxdeploy plugin. And it seems to be able to do without chdir(), by having no path at all!

cc @TheAssassin

probonopd commented 5 years ago

Actually... https://docs.appimage.org/packaging-guide/manual.html#bundling-gtk-libraries rocks :+1:

TheAssassin commented 5 years ago

Now, turn it into a linuxdeploy plugin, please.