wk GTK list find blog view edit

Setup Gtk3 theme



$ cat ~/.config/gtk-3.0/settings.ini
$ cat /etc/gtk-3.0/settings.ini
[Settings]
gtk-application-prefer-dark-theme=true
gtk-theme-name=Adwaita
gtk-icon-theme-name=gnome
gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
gtk-font-name=Ubuntu 10

$ cat ~/.config/gtk-3.0/gtk.css
.menu {
  border-style: solid;
  border: 1px solid black;
  border-top: 0px;
  padding: 2px;
}




$ cat /etc/gtk-2.0/gtkrc
gtk-theme-name = "Clearlooks"
gtk-icon-theme-name = "gnome"


Portable GTK



GTK+ is a Free and portable widget toolkit written in C with support for bindings in lot of scripting languages.

GTK+ is based on GLib, GObject and other technologies, which are high level abstractions on top of C to provide data serialization, object models, introspection, threads, signalling and many other goods in a clean and portable way.

The complexity to use GObject libraries in C can be simplified by using Vala ( http://vala-project.org ) and on top of Vala there's a project named GtkAML which provides a container-oriented description programming that simplifies even more the design and development of applications using Gtk+.

GTK+ is a toolkit used mostly on OpenSource operating systems. This is probably a good thing.. unless you are trying to distribute binaries of your program you end up with these problems:

 * The ABI changes between big version number changes of the libraries.
 * You end up packaging all the gtk,png|jpeg,pango,glib,x11 dependencies.
 * You create a shellscript that depending on the uname and lsb_release or etc/issue you load some or other libraries
 * GTK themes are not always respected in this situation
 * Some proprietary graphics drivers are linked to X libraries, so you can't distribute them
 * Your binary package size has grown to 40 or 50MB when your application is just 400KB
 * (place here your problems)

Actually, GTK+-2.0 is stable and the development happens in GTK+-3.0, so most of those problems will be just fixed by having an up-to-date system and using old enought libraries when building your application.

 * In my experience, using the older LTS Ubuntu is a good option, so GNOME libraries have some sort of backward compatibility, and applications compiled against old (not ancient) versions of GTK will continue working on future libs.

Many proprietary projects switched to QT because of those problems, they provide a good commercial support.. but personally I prefer GTK, C and a community based development.

After many experiments and projects I end up having an almost simple environment for building portable binary GTK applications for Linux (BSD should be the same), Windows and OSX.

The good point of OSX and Windows is that they have more stable ABI (binary compatibility), so you don't have to care about different versions of OSX of different versions of Windows... In Linux, every distro can have their own drivers hacking X11 libs, different system libraries, etc... which tends to be problematic for distributing binary apps.

Vala/GtkON


When crosscompiling, is better to use Vala and GtkAML compilers natively. As long as they generate C code, you can use them from your own system installation. Only CC environment must be changed in order to specify the mingw32, ARM or whatever crosscompiler.

http://vala-project.org

http://code.google.com/p/gtkaml/

Windows


The easiest way to compile for Windows is to use mingw32 from any POSIX friendly OS (GNU/Linux, ..)

Linux and *BSD have faster implementations of fork() than Windows. This results in pretty slow compilation times on this system. This is where mingw32 and crosscompilation enters the scene.

I took the Iki's w32 blobs for gtk,png,jpeg,glib,... and prepare a single tarball with an example Vala program and a Makefile as an example:

  http://nopcode.org/p/b/w32gtk-2.20.tar.gz

To distribute your application just package your exe with all the required .dll files. Windows will find the library dependencies in the current directory.

OSX


To compile standalone GTK applications on OSX you need to install the GTK+ from ports.

By using the following lines, you'll get a Quartz based GTK+-2.0.

Good things about gtk-quartz:
  - Startup is faster
  - Application is integrated in OSX
  - Not depending on compile-time X11 libraries
  - Less dependencies result in smaller .dmg

The bad things:
  - Some glitches (missing redraws of damaged areas) appear sometimes.

To compile gtk on quartz follow this steps:

# port install cairo +quartz+no_x11
# port install pango +quartz+no_x11
# port install gtk2 +quartz+no_x11


At the moment of writing this tutorial Gtk3 is already packaged but IMHO is still not stable enought on OSX, so i'll write my experiences with gtk3 on osx and w32.

Once you get the libraries installed in /opt/local with the ports system you need to create the structure of your .app which looks like this:


YourApp.app/
  Contents/
  Info.plist
  PkgInfo
  Resources/
  YourApp.icns
  bin/
  lib/
  ...
  MacOS/
  YourApp*


The PkgInfo file just contains a string. feel free to put whatever you like or copy it from somewhere else.

The Info.plist is an XML that points to the binary name, mimetypes supported, icon, package description and other stuff. Mine looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Ragui</string>
<key>CFBundleIconFile</key>
<string>Ragui.icns</string>
<key>CFBundleIdentifier</key>
<string>org.radare.Ragui</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Ragui</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.1</string>
<key>CFBundleSignature</key>
<string>Ragui</string>
<key>CFBundleVersion</key>
<string>0.1</string>
<key>NSHumanReadableCopyright</key>
<string> 2011 The LockLabs Team</string>
</dict>
</plist>


The shellscript that setups the environment to get the libraries from the Resources directory looks like this:

#!/bin/sh
R2DIR=$(dirname "$0")/..
export DYLD_LIBRARY_PATH="${R2DIR}/lib"
exec ${R2DIR}/bin/ragui.bin


You can get a copy of this dmg here:

  http://lolcathost.org/b/ragui-0.1b.dmg

Now you need to copy the libraries from /opt/local to your .app package.. so I wrote this makefile target


BIN=YourProgram
BINDIST=bindist
copyosxlibs:
  for a in `otool -L src/YourProgram | grep -v libr|grep -v :| awk '{print $$1}'| grep -v System` ; do \
  cp $$a ${BINDIST}/lib ; \
  done
  cp /opt/local/bin/pango-querymodules ${BINDIST}/bin
  cp /opt/local/lib/libiconv.2.dylib ${BINDIST}/lib
  cp /opt/local/lib/libpixman-1.0.dylib ${BINDIST}/lib
  mkdir -p ${BINDIST}/lib/pango/${PANGOVERSION}/modules
  cp /opt/local/lib/pango/${PANGOVERSION}/modules/*.so \
  ${BINDIST}/lib/pango/${PANGOVERSION}/modules


To create the DMG just use the [b]hdiutil[/b] program:

$ hdiutil create -fs HFS+ -srcfolder YourProgram.app -volname YourProgram.app YourProgram.dmg


To create the icon for your application you need to create a 128x128 PNG image and use the [b]FastIcns[/b] application to create a .icns file.

Place your .icns file inside the Resources directory and then just reference your .icns file in the PkgInfo XML like this:

<key>CFBundleIconFile</key>
  <string>Ragui.icns</string>


At some point I will write a set of scripts to do all this job automatically.. but until then.. just hack it up in your own way :)

Setting up fonts



If your GTK app is rendering rectangles instead of fonts you will have to setup the pango modules. To do this in a position-independent way.. you have to create a startup script that setups LD_LIBRARY_PATH (linux,bsd) or DYLD_LIBRARY_PATH (osx) and run the following script:

$ export TMPDIR=$(mkstemp)
$ pango-querymodules $TMPDIR/lib/pango/1.6.0/modules/*.so > pango.modules
$ printf "[Pango]\nModuleFiles=$TMPDIR/etc/pango.rc


In order to run your application just setup the PANGO_RC_FILE environment variable:

PANGO_RC_FILE=${TMPDIR}/pango.rc


Configure the theme


To embed a GTK theme in the application you need to do the following steps:

  * embed engine module (libclearlooks.so)
  * embed theme directory (share/themes/*)
  * embed gdk pixbuf modules. (to open jpg, png files..)
  * generate gdk-pixbuf-query-loaders
  * generate gtkrc with fixed paths
  * setup some environment vars (GTK_PATHS, XDG_DATA_DIRS, ...)

Check out the makefile here:

  http://lolcathost.org/b/Makefile.ragui

To start the app you need to setup the environment and create some RC files at startup. See this startup file as an example:

  http://lolcathost.org/b/ragui.sh

# Force GTK Theme
force_gtk_theme() {
  GDK_PIXBUF_MODULE_FILE="${R2DIR}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
  gdk-pixbuf-query-loaders > ${GDK_PIXBUF_MODULE_FILE}
  export GDK_PIXBUF_MODULE_FILE
  GTK_PATH="${R2DIR}/lib/gtk-2.0"
  export GTK_PATH
  XDG_DATA_DIRS="${R2DIR}/share"
  export XDG_DATA_DIRS
  GTK2_RC_FILES=${TMPDIR}/etc/gtkrc-2.0
  export GTK2_RC_FILES
  echo > ${GTK2_RC_FILES}
  #echo "pixmap_path \"${R2DIR}/share/themes/\"" > ${GTK2_RC_FILES}
  echo "include \"${R2DIR}/share/themes/Clearlooks/gtk-2.0/gtkrc\"" >> ${GTK2_RC_FILES}
  echo >> ${GTK2_RC_FILES} <<EOF
style "font" {
  font_name = "Verdana 12"
}

widget_class "*" style "font"
gtk-font-name = "Verdana 12"
EOF
}



A sample gtkrc file will look like this:

$ cat .gtkrc-2.0.mine
pixmap_path "/path/to/share/themes"
style "font" {
font_name = "Verdana 12"
}

widget_class "*" style "font"
gtk-font-name = "Verdana 12"



--pancake