# GTK+

Related articles

- Uniform Look for Qt and GTK Applications
- Qt
- GNU Project

From the GTK+ website:

  GTK+, or the GIMP Toolkit, is a multi-platform toolkit for creating graphical user interfaces. Offering a complete set of widgets, GTK+ is suitable for projects ranging from small one-off tools to complete application suites.

GTK+, The GIMP Toolkit, was initially made by the GNU Project for the GIMP but is now a very popular toolkit with bindings for many languages. This article will explore the tools used to configure the GTK+ theme, style, icon, font and font size, and also detail manual configuration.

## Configuration programs

These GUI programs allow theme selection and at least customising of a font. They generally overwrite the `~/.gtkrc-2.0` file.

- lxappearance: A configuration tool from the LXDE project, which does not require any other parts of LXDE or other desktop environment. More flexible customisation than the other programs.
- gtk-chtheme
- gtk-theme-switch2
- gtk2_prefs

Note: As `~/.gtkrc-2.0` and other user theme files are not read by other accounts, the custom theme will not apply to X applications run as root. Possible solutions include:

- Create symlinks, e.g

    # ln -s /home/USER/.gtkrc-2.0 /root/.gtkrc-2.0

- Adjust the theme as root

    # gksu lxappearance

- Use a settings daemon (this is what most desktop environments do). A desktop-agnostic variant using XSETTINGS is available in the AUR under xsettingsd-git.

See also Uniform Look for Qt and GTK Applications#Changing styles in each toolkit.

## Themes

### GTK+ 1.x

There are loads of GTK+ 1.x themes in the AUR: search for gtk-theme. A good start is gtk-smooth-engine.

Most major desktop environments provide tools to configure the GTK+ theme, icons, font and font size.

Alternatively, use gtk-theme-switch2. Run it with the `switch` command.

### GTK+ 2.x

There are loads of GTK+ 2.x themes in the AUR: search for gtk2-theme. A good start is gtk-engines which includes the popular Clearlooks theme.

Most major desktop environments provide tools to configure the GTK+ theme, icons, font and font size.

Alternatively, GTK+ settings can be configured manually by editing `~/.gtkrc-2.0`. A list of GTK+ settings can be found in the GNOME library. To manually change the GTK+ theme, icons, font and font size, add the following to `~/.gtkrc-2.0`:

    ~/.gtkrc-2.0

    gtk-icon-theme-name = "[name-of-icon-theme]"
    gtk-theme-name = "[name-of-theme]"
    gtk-font-name = "[font-name] [size]"

For example:

    ~/.gtkrc-2.0

    gtk-icon-theme-name = "Tango"
    gtk-theme-name = "Murrine-Gray"
    gtk-font-name = "DejaVu Sans 8"

Note: The above example requires the packages ttf-dejavu, tangerine-icon-theme, gtk-engine-murrine from the official repositories, and gtk-theme-murrine-collection from the AUR.

Another example:

    ~/.gtkrc-2.0

    # GTK theme
    include "/usr/share/themes/Clearlooks/gtk-2.0/gtkrc"

    # Font
    style "myfont" {
        font_name = "DejaVu Sans 8"
    }
    widget_class "*" style "myfont"
    gtk-font-name = "DejaVu Sans 8"

    # Icon theme
    gtk-icon-theme-name = "Tango"

    # Toolbar style
    gtk-toolbar-style = GTK_TOOLBAR_ICONS

Note:

- The icon theme name is the name defined in the theme's index file, not the name of its directory.
- Valid toolbar styles are `GTK_TOOLBAR_ICONS`, `GTK_TOOLBAR_TEXT`, `GTK_TOOLBAR_BOTH`, and `GTK_TOOLBAR_BOTH_HORIZ`.
- If you edit your `.gtkrc-2.0` file, only newly started applications will display the changes.

### GTK+ 3.x

A good start is gnome-themes-standard which includes the popular Adwaita theme.

If selected style has both GTK+ 2.x and GTK+ 3.x themes, they will be used. If selected style has only GTK+ 2.x theme, it will be used for GTK+ 2.x applications and (ugly) defaults will be used for GTK+ 3.x applications. If selected style has only GTK+ 3.x theme, it will be used for GTK+ 3.x applications and (ugly) defaults will be used for GTK+ 2.x applications. Thus for uniform UI appearance and best experience one can use style that has both GTK+ 2.x and GTK+ 3.x themes.

Most major desktop environments provide tools to configure the GTK+ theme, icons, font and font size. If you use GNOME, use GNOME Tweak Tool: install gnome-tweak-tool. If you use Xfce, use the Appearance tool: go to Settings > Appearance.

An alternative without huge dependencies is lxappearance.

If you prefer not to install a theme manager at all, your theme can be set manually in `$XDG_CONFIG_HOME/gtk-3.0/settings.ini` (this is usually `~/.config/gtk-3.0/settings.ini`). An example `settings.ini` file:

    $XDG_CONFIG_HOME/gtk-3.0/settings.ini

    [Settings]
    gtk-application-prefer-dark-theme = false
    gtk-theme-name = Zukitwo
    gtk-fallback-icon-theme = gnome
    gtk-icon-theme-name = [icon theme name]
    gtk-font-name = [font name] [font size]

If it still does not change, delete old `gtk-3.0` folder in `$XDG_CONFIG_HOME` and copy `gtk-3.0` folder from /path/to/theme to `$XDG_CONFIG_HOME`. Example:

    $ rm -r ~/.config/gtk-3.0/
    $ cp -r /usr/share/themes/Zukitwo/gtk-3.0/ ~/.config/

After this, you need to set the same theme in your DE's appearance configuration tool. There are only a few themes which provide a uniform look for GTK+ 3.x and GTK+ 2.x apps. A few examples:

1. Adwaita (part of gnome-themes-standard)
2. Clearlooks-Phenix (AUR: clearlooks-phenix-gtk-theme)
3. Newlooks for GTK+ 3 and Clearlooks for GTK+ 2
4. Zukitwo (zukitwo-themes)
5. Elegant Brit
6. Atolm
7. Hope
8. OMG

Note:

- Some themes may require librsvg to display correctly, but not all specify it as a dependency. Try installing it if the chosen theme looks broken.
- There probably are other themes. Some of these themes are available in the AUR. Also, some of them are not usable as-is for displaying a GTK+ 2.x panel (light text over light background), so you need to use the provided panel background.

You could find what themes installed on your system have both an GTK+ 2.x and GTK+ 3.x version by using this command (does not work with names containing spaces):

    find $(find ~/.themes /usr/share/themes/ -wholename "*/gtk-3.0" | sed -e "s/^\(.*\)\/gtk-3.0$/\1/")\
    -wholename "*/gtk-2.0" | sed -e "s/.*\/\(.*\)\/gtk-2.0/\1"/

### GTK+ and Qt

If you have GTK+ and Qt (KDE) applications on your desktop then you know that their looks do not blend well. If you wish to make your GTK+ styles match your Qt styles please read Uniform Look for Qt and GTK Applications.

### GTK+ and HTML with Broadway

The GDK Broadway backend provides support for displaying GTK+ applications in a web browser, using HTML5 and web sockets. [1]

When using broadwayd, specify the display number to use, prefixed with a colon, similar to X. The default display number is 1.

    $ display_number=:5

Start it.

    $ broadwayd $display_number

Port Used on default

    port = 8080 + ($display_number - 1)

Point your browser to http://localhost:port

To Start apps

    $ GDK_BACKEND=broadway BROADWAY_DISPLAY=$display_number <<app>>

Alternatively can set address and port

    $ broadwayd --port $port_number --address $address $display_number

## Configuration file

Note: See the GtkSettings properties in the GTK+ programming reference manual for the full list of GTK configuration options.

The purpose of this section is to collect GTK+ configuration settings which can e.g. be used within one's GTK+ configuration files.

There are two relevant locations for GTK+ configuration files (which are in an ini format) : $XDG_CONFIG_HOME/gtk-3.0/ (usually ~/.config/gtk-3.0/) and /etc/gtk-3.0/. The former is reserved for user wide settings, and the latter for system wide settings.

### Enabling Customizable Keyboard Shortcuts

You can customize your GTK+ applications' keyboard shortcuts (those are called accelerators in GTK+ terminology) by hovering your mouse over a menu item and pressing your desired key combination. However, this feature is disabled by default. To enable it, set

    gtk-can-change-accels = 1

### Speed up your GNOME menu

This setting controls the delay between you pointing the mouse at a menu and that menu opening in GNOME. Change this to a setting you prefer. I guess the number is in milliseconds, e.g. 250 being a quarter of a second.

    gtk-menu-popup-delay = 0

### Reduce widget sizes

If you have a small screen or you just do not like big icons and widgets, you can resize things easily. To have icons without text in toolbars, use

    gtk-toolbar-style = GTK_TOOLBAR_ICONS

To use smaller icons, use a line like this:

    gtk-icon-sizes = "panel-menu=16,16:panel=16,16:gtk-menu=16,16:gtk-large-toolbar=16,16\
    :gtk-small-toolbar=16,16:gtk-button=16,16"

Or to remove icons from buttons completely:

    gtk-button-images = 0

You can also remove icons from menus:

    gtk-menu-images = 0

There is some more tweaking to do in your themes gtkrc like explained here and there's another theme that does it all.

## Troubleshooting

### Client-side decorations

GTK 3.12 introduced client-side decorations, which move the title-bar away from the window manager. This only works correctly in GNOME.

Other environments may suffer from double title-bars or no title-bar at all. Some composite managers also conflict.

As a workaround, patch ([2]) and rebuild gtk3 with ABS. Then define the following variable:

    export GTK_DISABLE_CSD=1

## Development

When writing a start-from-scratch GTK+ 3 program with C, it's necessary to add CFLAGS for gcc:

    $ gcc -g -Wall $(pkg-config --cflags --libs gtk+-3.0) -o base base.c

-g and -Wall parameters are not necessary since they are only for verbose debugging outputs. You may try out the official Hello World example.

### Write a simple message dialog app

You can write your own GTK+ 3 message dialog easily in many programming languages through GObject-Introspection or bindings, or you can simply use bash.

The following examples display a simple "Hello world" in a message dialog.

Ada

- Dependency: gtkada from AUR
- Makedependency: gcc-ada
- Build with: `gnatmake hello_world `gtkada-config``

    hello_world.adb

    with Gtk.Main;
    with Gtk.Dialog;           use Gtk.Dialog;
    with Gtk.Message_Dialog;   use Gtk.Message_Dialog;

    procedure hello_world is
      Dialog   : Gtk_Message_Dialog;
      Response : Gtk_Response_Type;
    begin
      Gtk.Main.Init;
      Gtk_New (Dialog   => Dialog,
               Parent   => null,
               Flags    => 0,
               The_Type => Message_Info,
               Buttons  => Buttons_OK,
               Message  => "Hello world!");
      Format_Secondary_Markup (Dialog, "This is an example dialog.");
      Response := Run (Dialog);
    end hello_world;

Bash

- Dependency: zenity

    hello_world.sh

    #!/bin/bash
    zenity --info --title='Hello world!' --text='This is an example dialog.'

Boo

- Dependency: gtk-sharp-3 (and boo)
- Makedependency: boo
- Build with: `booc hello_world.boo`
- Run with: `mono hello_world.exe` (or `booi hello_world.boo`)

    hello_world.boo

    import Gtk from "gtk-sharp"
    Application.Init()
    Hello = MessageDialog(null, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, "Hello world!")
    Hello.SecondaryText = "This is an example dialog."
    Hello.Run()

C

- Dependency: gtk3
- Build with: `gcc -o hello_world $(pkg-config --cflags --libs gtk+-3.0) hello_world.c`

    hello_world.c

    #include <gtk/gtk.h>
    void main (int argc, char *argv[]) {
    	gtk_init (&argc, &argv);
            GtkWidget *hello = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Hello world!");
    	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (hello), "This is an example dialog.");
            gtk_dialog_run(GTK_DIALOG (hello));
    }

C++

- Dependency: gtkmm3
- Build with: `g++ -o hello_world $(pkg-config --cflags --libs gtkmm-3.0) hello_world.cc`

    hello_world.cc

    #include <gtkmm/main.h>
    #include <gtkmm/messagedialog.h>
    int main(int argc, char *argv[]) {
    	Gtk::Main kit(argc, argv);
    	Gtk::MessageDialog Hello("Hello world!", false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
    	Hello.set_secondary_text("This is an example dialog.");
    	Hello.run();
    }

C#

- Dependency: gtk-sharp-3
- Build with: `mcs -pkg:gtk-sharp-3.0 hello_world.cs`
- Run with: `mono hello_world.exe`

    hello_world.cs

    using Gtk;
    public class HelloWorld {
    	static void Main() {
    		Application.Init ();
    		MessageDialog Hello = new MessageDialog (null, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, "Hello world!");
    		Hello.SecondaryText="This is an example dialog.";
    		Hello.Run ();
    	}
    }

Cobra

- Dependency: gtk-sharp-3
- Makedependency: cobra from AUR
- Build with: `cobra -c hello_world`
- Run with: `mono hello_world.exe`

    hello_world.cobra

    @args -pkg:gtk-sharp-3.0
    use Gtk

    class HelloWorld
        def main
            Application.init
            hello = MessageDialog(nil, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, "Hello world!")
            hello.secondaryText = "This is an example dialog."
            hello.run

D

- Dependency: gtkd from AUR
- Makedependency: dmd
- Build with: `dmd hello_world $(pkg-config --cflags --libs gtkd-2)`

    hello_world.d

    import gtk.Main;
    import gtk.MessageDialog;

    void main(string[] args)
    {
    	Main.init(args);
    	MessageDialog dialog = new MessageDialog(null, GtkDialogFlags.MODAL, MessageType.INFO, ButtonsType.OK, "Hello world!");
    	dialog.run();
    }

F#

- Dependency: gtk-sharp-3
- Makedependency: fsharp from AUR
- Build with: `fsharpc -r:gtk-sharp.dll -I:/usr/lib/mono/gtk-sharp-3.0/`
- Run with: `mono hello_world.exe`

    hello_world.fs

    open Gtk
    Application.Init()
    let Hello = new MessageDialog(null, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, "Hello world!")
    Hello.SecondaryText <- "This is an example dialog."
    Hello.Run() |> ignore

Fortran

- Dependency: gtk-3-fortran-git from AUR
- Makedependency: gcc-fortran
- Build with: `gfortran hello_world.f90 -o hello_world $(pkg-config --cflags --libs gtk-3-fortran)`

    hello_world.f90

    program hello_world
      use gtk_hl
      use gtk, only: gtk_init

      integer(c_int) :: resp
      character(40), dimension(2) :: msg

      call gtk_init()
      msg(1) ="Hello world!"
      msg(2) = "This is an example dialog."
      resp = hl_gtk_message_dialog_show(msg, GTK_BUTTONS_OK, type=GTK_MESSAGE_INFO)
    end program hello_world

Genie

- Dependency: gtk3
- Makedependency: vala
- Build with: `valac --pkg gtk+-3.0 hello_world.gs`

    hello_world.gs

    uses
    	Gtk
    init
    	Gtk.init (ref args)
    	var Hello=new MessageDialog (null, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Hello world!")
    	Hello.format_secondary_text ("This is an example dialog.")
    	Hello.run ()

Go

- Dependency: gtk3
- Makedependency: gotk3-git from AUR
- Build with: `go build hello_world.go`
- (Or run with: `go run hello_world.go`)

    hello_world.go

    package main
    import ("github.com/conformal/gotk3/gtk")

    func main() {
    	gtk.Init(nil)
    	dialog := gtk.MessageDialogNew(nil, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Hello world!")
    	dialog.FormatSecondaryText("This is an example notification.")
    	dialog.Run()
    }

Groovy

- Dependencies: groovy, java-gnome from AUR
- Build with: `groovyc -cp /usr/share/java/gtk.jar HelloWorld.groovy && jar cfe HelloWorld.jar HelloWorld HelloWorld.class`
- Run with: `java -cp /usr/share/groovy/embeddable/groovy-all.jar:/usr/share/java/gtk.jar:HelloWorld.jar HelloWorld` (or `groovy -cp /usr/share/java/gtk.jar HelloWorld.groovy`)

    HelloWorld.groovy

    import org.gnome.gtk.*
    Gtk.init()
    def Hello = new InfoMessageDialog(null, "Hello world!", "This is an example dialog.")
    Hello.run()

Haskell

- Dependency: gtk3
- Makedependency: haskell-gtk3 from AUR
- Build with: `ghc hello_world`

    hello_world.hs

    import Graphics.UI.Gtk

    main = do
    	initGUI
    	dialog <- messageDialogNew Nothing [DialogModal] MessageInfo ButtonsOk "Hello world!"
    	messageDialogSetSecondaryText dialog "This is an example dialog."
    	_res <- dialogRun dialog
    	return 0

Java

- Dependency: java-gnome from AUR
- Makedependency: java-environment
- Build with: `javac -cp /usr/share/java/gtk.jar HelloWorld.java && jar cfe HelloWorld.jar HelloWorld HelloWorld.class`
- Run with: `java -cp /usr/share/java/gtk.jar:HelloWorld.jar HelloWorld`

    HelloWorld.java

    import org.gnome.gtk.Gtk;
    import org.gnome.gtk.Dialog;
    import org.gnome.gtk.InfoMessageDialog;

    public class HelloWorld {
        public static void main(String[] args) {
            Gtk.init(args);
            Dialog Hello = new InfoMessageDialog(null, "Hello world!", "This is an example dialog.");
            Hello.run();
        }
    }

JavaScript

- Dependencies: gtk3, gjs (works also with seed)

    hello_world.js

    #!/usr/bin/gjs
    const Gtk = imports.gi.Gtk
    Gtk.init(null, null)
    var Hello = new Gtk.MessageDialog({type: Gtk.MessageType.INFO,
                                       buttons: Gtk.ButtonsType.OK,
                                       text: "Hello world!",
                                       "secondary-text": "This is an example dialog."})
    Hello.run()

Lua

- Dependencies: gtk3, lua-lgi

    hello_world.lua

    #!/usr/bin/lua
    lgi = require 'lgi'
    Gtk = lgi.require('Gtk')
    Gtk.init()
    Hello=Gtk.MessageDialog {message_type = Gtk.MessageType.INFO,
                             buttons = Gtk.ButtonsType.OK,
                             text = "Hello world!",
                             secondary_text = "This is an example dialog."}
    Hello:run()

Pascal

- Dependency: gtk3
- Makedependencies: fpc, Gtk+3.0 bindings
- Build with: `fpc hello_world`

    hello_world.pas

    program	hello_world;
    uses	Math, Gtk3;
    var	dialog: PGtkWidget;
    begin
    	SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
    	gtk_init(@argc, @argv);
    	dialog := gtk_message_dialog_new(nil, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, '%s', ['Hello world!']);
    	gtk_message_dialog_format_secondary_text(PGtkMessageDialog(dialog), '%s', ['This is an example dialog.']);
    	gtk_dialog_run(PGtkDialog(dialog));
    end.

Perl

- Dependency: perl-gtk3 from AUR

    hello_world.pl

    #!/usr/bin/perl
    use Gtk3 -init;
    my $hello = Gtk3::MessageDialog->new (undef, 'modal', 'info', 'ok', "Hello world!");
    $hello->set ('secondary-text' => 'This is an example dialog.');
    $hello->run;

Python

- Dependencies: gtk3, python-gobject

    hello_world.py

    #!/usr/bin/python
    from gi.repository import Gtk
    Gtk.init(None)
    Hello=Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Hello world!")
    Hello.format_secondary_text("This is an example dialog.")
    Hello.run()

Ruby

- Dependency: ruby-gtk3

    hello_world.rb

    #!/usr/bin/ruby
    require 'gtk3'
    Gtk.init
    Hello = Gtk::MessageDialog.new(:type => :info,
                                   :buttons_type => :ok,
                                   :message => "Hello world!")
    Hello.secondary_text = "This is an example dialog."
    Hello.run

Scala

- Dependency: java-gnome from AUR (and scala)
- Makedependency: scala
- Build with: `scalac -cp /usr/share/java/gtk.jar -d HelloWorld.jar HelloWorld.scala`
- Run with: `java -cp /usr/share/java/gtk.jar:HelloWorld.jar HelloWorld` (or `scala -cp /usr/share/java/gtk.jar HelloWorld.scala`)

    HelloWorld.scala

    import org.gnome.gtk._

    object HelloWorld {
      def main(args: Array[String]) {
        Gtk.init(args)
        var hello = new InfoMessageDialog(null, "Hello world!", "This is an example dialog.")
        hello.run()
      }
    }

Vala

- Dependency: gtk3
- Makedependency: vala
- Build with: `valac --pkg gtk+-3.0 hello_world.vala`

    hello_world.vala

    using Gtk;
    public class HelloWorld {
    	static void main (string[] args) {
    		Gtk.init (ref args);
    		var Hello=new MessageDialog (null, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Hello world!");
    		Hello.format_secondary_text ("This is an example dialog.");
    		Hello.run ();
    	}
    }

Visual Basic .NET

- Dependency: gtk-sharp-3
- Makedependency: mono-basic
- Build with: `vbnc -r:/usr/lib/mono/gtk-sharp-3.0/gio-sharp.dll -r:/usr/lib/mono/gtk-sharp-3.0/glib-sharp.dll -r:/usr/lib/mono/gtk-sharp-3.0/gtk-sharp.dll hello_world.vb`
- Run with: `mono hello_world.exe`

    hello_world.vb

    Imports Gtk
    Public Class Hello
    	Inherits MessageDialog
    	Public Sub New
    		MyBase.New(Me, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, "Hello world!")
    		Me.SecondaryText = "This is an example dialog."
    	End Sub
    	Public Shared Sub Main
    		Application.Init
    		Dim Dialog As New Hello
    		Dialog.Run
    	End Sub
    End Class

## See also

- The official GTK+ website
- Wikipedia article about GTK+
- GTK+ 2.0 Tutorial
- GTK+ 3 Reference Manual
- gtkmm Tutorial
- gtkmm Reference Manual

Category:

- Widget Toolkits