[pygobject] Add sphinx based documentation



commit dfab41d0b66a15c8cf8229f7522160ec6b08a2b8
Author: Christoph Reiter <creiter src gnome org>
Date:   Sun Dec 10 20:38:47 2017 +0100

    Add sphinx based documentation
    
    Takes the documentation developed at
    https://github.com/pygobject/pygobject-docs
    and puts into /docs
    
    See https://pygobject.readthedocs.io for how it looks
    
    Now that we move to gitlab we can use webhooks to trigger builds
    on readthedocs from gitlab directly and we should also have a nicer
    contribution UX.
    
    This also gets rid of most of README/HACKING/INSTALL and moves most
    of the information into the documentation. The README is kept short
    and only makes clear what pygobject is and points to the online docs
    as that should answer all questions.
    
    setup.py now sets the content of README.rst as long_descriptions,
    as that is the content shown on PyPI. This makes the page on PyPI
    look the same as on gitlab.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=791448

 .gitignore                              |    2 +
 HACKING                                 |   37 ---
 INSTALL                                 |  370 -------------------------------
 MANIFEST.in                             |    3 +-
 Makefile.am                             |    5 +-
 README.rst                              |  137 ++----------
 docs/Makefile                           |   16 ++
 docs/changelog.rst                      |   10 +
 docs/conf.py                            |   50 ++++
 docs/contact.rst                        |   11 +
 docs/devguide/building_testing.rst      |   56 +++++
 docs/devguide/dev_environ.rst           |   46 ++++
 docs/devguide/index.rst                 |   13 +
 docs/devguide/override_guidelines.rst   |   90 ++++++++
 docs/devguide/overview.rst              |   32 +++
 docs/devguide/style_guide.rst           |  101 +++++++++
 docs/extra.css                          |   57 +++++
 docs/further.rst                        |   10 +
 docs/getting_started.rst                |  128 +++++++++++
 docs/guide/api/api.rst                  |   75 +++++++
 docs/guide/api/basic_types.rst          |   53 +++++
 docs/guide/api/flags_enums.rst          |   39 ++++
 docs/guide/api/gobject.rst              |   91 ++++++++
 docs/guide/api/index.rst                |   12 +
 docs/guide/api/properties.rst           |  119 ++++++++++
 docs/guide/api/signals.rst              |   93 ++++++++
 docs/guide/cairo_integration.rst        |   39 ++++
 docs/guide/code/cairo-demo.py           |  133 +++++++++++
 docs/guide/debug_profile.rst            |  112 ++++++++++
 docs/guide/deploy.rst                   |   52 +++++
 docs/guide/faq.rst                      |   11 +
 docs/guide/images/cairo_integration.png |  Bin 0 -> 24418 bytes
 docs/guide/index.rst                    |   17 ++
 docs/guide/porting.rst                  |  109 +++++++++
 docs/guide/testing.rst                  |   39 ++++
 docs/guide/threading.rst                |  290 ++++++++++++++++++++++++
 docs/icons.rst                          |   48 ++++
 docs/images/LICENSE                     |    3 +
 docs/images/favicon.ico                 |  Bin 0 -> 34494 bytes
 docs/images/logo.svg                    |  266 ++++++++++++++++++++++
 docs/images/overview.dia                |  Bin 0 -> 1885 bytes
 docs/images/overview.svg                |   72 ++++++
 docs/images/pygobject-small.svg         |  193 ++++++++++++++++
 docs/images/pygobject.svg               |  244 ++++++++++++++++++++
 docs/images/start_linux.png             |  Bin 0 -> 9893 bytes
 docs/images/start_macos.png             |  Bin 0 -> 13949 bytes
 docs/images/start_windows.png           |  Bin 0 -> 11454 bytes
 docs/index.rst                          |   89 ++++++++
 docs/maintguide.rst                     |   32 +++
 docs/packagingguide.rst                 |   55 +++++
 setup.py                                |    6 +-
 51 files changed, 2933 insertions(+), 533 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index aba77a1..8dfaeaf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,3 +77,5 @@ Makefile.in
 /dist/
 /pygobject.egg-info/
 /MANIFEST
+/docs/_build
+/PyGObject.egg-info/
diff --git a/MANIFEST.in b/MANIFEST.in
index b9f067e..72a2813 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -2,9 +2,7 @@ include *.am
 include autogen.sh
 include configure.ac
 include COPYING
-include HACKING
 include *.in
-include INSTALL
 include m4/introspection.m4
 include m4/python.m4
 include NEWS
@@ -15,3 +13,4 @@ recursive-include examples *.py *.am *.png *.css *.ui *.gif *.gresource *.jpg *.
 recursive-include gi *.am *.h
 recursive-include pygtkcompat *.am
 recursive-include tests *.py *.c *.h *.xml *.supp *nouppera *.am
+recursive-include docs *.rst *.svg LICENSE *.ico *.png *.css *.py *.dia Makefile
diff --git a/Makefile.am b/Makefile.am
index 643aefc..c097d9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,10 +22,10 @@ EXTRA_DIST = \
        m4/introspection.m4 \
        setup.py \
        MANIFEST.in \
-       README.rst
+       README.rst \
+       docs
 
 MAINTAINERCLEANFILES = \
-       $(srcdir)/INSTALL \
        $(srcdir)/aclocal.m4 \
        $(srcdir)/autoscan.log \
        $(srcdir)/compile \
@@ -143,6 +143,7 @@ dist-hook: $(BUILT_EXTRA_DIST)
        for f in $$files; do \
          if test -f $$f; then d=.; else d=$(srcdir); fi; \
          rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done
+       rm -rf "$(distdir)/docs/_build"
 
 # pycheck_subdirs = 
 
diff --git a/README.rst b/README.rst
index 7eb7c8b..c163301 100644
--- a/README.rst
+++ b/README.rst
@@ -1,126 +1,21 @@
-=========
-PyGObject
-=========
+.. image:: https://pygobject.readthedocs.io/en/latest/_images/pygobject.svg
+   :align: center
+   :width: 400px
+   :height: 98px
 
-This archive contains bindings for the GLib, and GObject,
-to be used in Python. It is a fairly complete set of bindings,
-it's already rather useful, and is usable to write moderately
-complex programs.  (see the examples directory for some examples
-of the simpler programs you could write).
+|
 
-If you have any enhancements or bug reports, please file them in
-bugzilla at:
+**PyGObject** is a Python package which provides bindings for `GObject
+<https://developer.gnome.org/gobject/stable/>`__ based libraries such as `GTK+
+<https://www.gtk.org/>`__, `GStreamer <https://gstreamer.freedesktop.org/>`__,
+`WebKitGTK+ <https://webkitgtk.org/>`__, `GLib
+<https://developer.gnome.org/glib/stable/>`__, `GIO
+<https://developer.gnome.org/gio/stable/>`__ and many more.
 
-    http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject
+It supports Linux, Windows and macOS and works with **Python 2.7+** as well as
+**Python 3.4+**. PyGObject, including this documentation, is licensed under
+the **LGPLv2.1+**.
 
-If you have a patch, file the bug first and then use the "create new
-attachment" link on the bug's info page.  My preferred format for
-patches is unified diff format (ie. diff -u).  Please don't send me
-diffs which don't have any context, as these make it very difficult to
-see what the patch does.
+----
 
-
-New Versions
-============
-
-New versions of this package can be found at:
-
-    http://ftp.gnome.org/pub/GNOME/sources/pygobject/
-
-
-Mailing list
-============
-
-pygobject development is discussed on the GNOME python-hackers mailing list.
-You can subscribe to it through the web interface:
-
-  https://mail.gnome.org/mailman/listinfo/python-hackers-list/
-
-
-Requirements
-============
-
-  * C compiler (GCC and MSVC supported)
-  * Python 2.7 or higher
-  * Glib/Gio 2.38.0 or higher
-  * gobject-introspection 1.46.0 or higher
-  * libffi (optional)
-
-
-Copyright Information
-=====================
-
-This software is covered by the GNU Lesser General Public Licence
-(version 2.1, or if you choose, a later version).  Basically just don't
-say you wrote bits you didn't.
-
-
-Compilation
-===========
-
-PyGObject uses the standard autotools for the build infrastructure.  To
-build, it should be as simple as running::
-
-    $ ./configure --prefix=<prefix where python is installed>
-    $ make
-    $ make install
-
-By default, configure searches for a few well-known Python interpreter
-names, such as "python3", "python2", "python2.7", or "python".  If your
-Python interpreter isn't in the path, or is not called "python", you can
-configure pygobject to build against that with --with-python=<path> or
-setting the PYTHON environment variable::
-
-    $ ./configure --with-python=python3
-    $ PYTHON=python3.2 ./configure
-    $ ./configure --with-python=~/my-patched-python/python
-
-If configure can't find GTK+, you may need to set the PKG_CONFIG_PATH
-environment variable to help it find the libraries.
-
-The "make install" target will generate normal and optimised bytecode
-for all the .py files.
-
-Note. If you're installing to another prefix than the one where python
-is installed you'll need to set the PYTHONPATH variable to the
-$prefix/lib/pythonX.Y/site-packages directory created by
-the PyGObject installation.
-
-
-Tests
-=====
-
-After having compiled and installed pygobject, you may want to test them.
-There are a number of example programs available in the examples/
-subdirectory.
-
-
-Getting Help
-============
-
-If you have questions about programming with PyGObject, you might want to
-check the documentation on
-
-    https://live.gnome.org/PyGObject/
-
-If that does not help, send a message to the mailing list (information on
-subscribing is above), or join #python on irc.gnome.org.
-
-
-Authors
-=======
-
-Original authors:
-    * James Henstridge <james daa com au>
-    * Johan Dahlin <johan gnome org>
-
-Current maintainers:
-    * Tomeu Vizoso <tomeu vizoso collabora co uk>
-    * Martin Pitt <martinpitt gnome org>
-    * Paolo Borelli <pborelli gnome org>
-    * Ignacio Casal Quinteiro <icq gnome org>
-    * Sebastian Pölsterl <sebp k-d-w org>
-    * Simon Feltman <sfeltman gnome org>
-    * Christoph Reiter <reiter christoph gmail com>
-
-See the NEWS file and the git history for a list of all contributors.
+For more information visit https://pygobject.readthedocs.io
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..7b13225
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,16 @@
+DIAS = $(wildcard images/*.dia)
+DIA_SVGS = $(patsubst %.dia,%.svg,$(DIAS))
+
+all: _build
+
+images/%.svg: images/%.dia
+       dia $< --export=$@ --filter=dia-svg
+
+_build: Makefile *.rst devguide/*.rst guide/*.rst conf.py images/*.png $(DIA_SVGS) ../README.rst
+       sphinx-build -b html . _build
+
+linkcheck:
+       sphinx-build -b linkcheck -n . _build
+
+clean:
+       rm -R _build
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..2c4f6b1
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1,10 @@
+Changelog
+=========
+
+Versions with an odd minor version are unstable releases (e.g. 3.27.x) while
+versions with even minor version are stable releases (e.g. 3.28.x)
+
+For more details see the GIT log: https://git.gnome.org//browse/pygobject/log
+
+.. include:: ../NEWS
+    :code:
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..aff0fff
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+extensions = [
+    'sphinx.ext.todo',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.extlinks',
+]
+
+intersphinx_mapping = {
+    'gtk': ('https://lazka.github.io/pgi-docs/Gtk-3.0', None),
+    'gobject': ('https://lazka.github.io/pgi-docs/GObject-2.0', None),
+    'glib': ('https://lazka.github.io/pgi-docs/GLib-2.0', None),
+    'gdk': ('https://lazka.github.io/pgi-docs/Gdk-3.0', None),
+    'gio': ('https://lazka.github.io/pgi-docs/Gio-2.0', None),
+    'python2': ('https://docs.python.org/2.7', None),
+    'python3': ('https://docs.python.org/3', None),
+}
+
+source_suffix = '.rst'
+master_doc = 'index'
+exclude_patterns = ['_build', 'README.rst']
+
+pygments_style = 'tango'
+html_theme = 'sphinx_rtd_theme'
+html_show_copyright = False
+html_favicon = "images/favicon.ico"
+project = "PyGObject"
+html_title = project
+
+html_context = {
+    'extra_css_files': [
+        'https://quodlibet.github.io/fonts/font-mfizz.css',
+        '_static/extra.css',
+    ],
+}
+
+html_static_path = [
+    "extra.css",
+    "images/pygobject-small.svg",
+]
+
+html_theme_options = {
+    "display_version": False,
+}
+
+extlinks = {
+    'gnomebug': ('https://bugzilla.gnome.org/show_bug.cgi?id=%s', '#'),
+}
+
+suppress_warnings = ["image.nonlocal_uri"]
diff --git a/docs/contact.rst b/docs/contact.rst
new file mode 100644
index 0000000..f41de73
--- /dev/null
+++ b/docs/contact.rst
@@ -0,0 +1,11 @@
+=======
+Contact
+=======
+
+**IRC**
+    #python on irc.gnome.org
+
+    Logs for the channel: https://quodlibet.duckdns.org/irc/pygobject
+
+**Mailinglist**
+    https://mail.gnome.org/mailman/listinfo/python-hackers-list
diff --git a/docs/devguide/building_testing.rst b/docs/devguide/building_testing.rst
new file mode 100644
index 0000000..87f8600
--- /dev/null
+++ b/docs/devguide/building_testing.rst
@@ -0,0 +1,56 @@
+==================
+Building & Testing
+==================
+
+Building with Autotools
+-----------------------
+
+Building for Python 2:
+
+::
+
+    ./autogen.sh --with-python=python2
+    make
+
+Building for Python 3:
+
+::
+
+    ./autogen.sh --with-python=python3
+    make
+
+
+Building with Setuptools
+------------------------
+
+Building in the source directory:
+
+::
+
+    python setup.py buildext --inplace
+
+
+Testing
+-------
+
+To run the test suite::
+
+    make check
+
+To test only a specific file/class/function::
+
+    make check TEST_NAMES=test_gi
+    make check TEST_NAMES=test_gi.TestUtf8
+    make check TEST_NAMES=test_gi.TestUtf8.test_utf8_full_return
+
+To execute all the tests in a gdb session::
+
+    make check.gdb
+
+To executes all the tests in valgrind::
+
+    make check.valgrind
+
+To execute pyflakes and pep8 tests::
+
+    make check.quality
diff --git a/docs/devguide/dev_environ.rst b/docs/devguide/dev_environ.rst
new file mode 100644
index 0000000..4d3985f
--- /dev/null
+++ b/docs/devguide/dev_environ.rst
@@ -0,0 +1,46 @@
+.. include:: ../icons.rst
+
+==================================
+Creating a Development Environment
+==================================
+
+This describes how to work on PyGObject itself. Please follow the instructions
+on ":ref:`gettingstarted`" first, as they are a pre-requirement.
+
+
+|ubuntu-logo| Ubuntu / |debian-logo| Debian
+-------------------------------------------
+
+.. code:: console
+
+    sudo apt build-dep pygobject
+    sudo apt install autoconf-archive
+    git clone https://git.gnome.org/browse/pygobject
+    cd pygobject
+    ./autogen.sh
+    make
+    make check
+
+
+|windows-logo| Windows
+----------------------
+
+.. code:: console
+
+    pacman -S --needed --noconfirm base-devel mingw-w64-i686-toolchain git \
+        mingw-w64-i686-python3 mingw-w64-i686-python3-cairo \
+        mingw-w64-i686-gobject-introspection mingw-w64-i686-gtk3 \
+        mingw-w64-i686-libffi autoconf-archive
+    git clone https://git.gnome.org/browse/pygobject
+    cd pygobject
+    ./autogen.sh
+    make
+    make check
+
+
+|macosx-logo| macOS
+-------------------
+
+.. code:: console
+
+    # TODO
diff --git a/docs/devguide/index.rst b/docs/devguide/index.rst
new file mode 100644
index 0000000..0458eda
--- /dev/null
+++ b/docs/devguide/index.rst
@@ -0,0 +1,13 @@
+=================
+Development Guide
+=================
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    overview
+    dev_environ
+    building_testing
+    style_guide
+    override_guidelines
diff --git a/docs/devguide/override_guidelines.rst b/docs/devguide/override_guidelines.rst
new file mode 100644
index 0000000..9315a69
--- /dev/null
+++ b/docs/devguide/override_guidelines.rst
@@ -0,0 +1,90 @@
+==========================
+Python Override Guidelines
+==========================
+
+This document serves as a guide for developers creating new PyGObject
+overrides or modifying existing ones. This document is not intended as hard
+rules as there may always be pragmatic exceptions to what is listed here. It
+is also a good idea to study the `Zen of Python by Tim Peters
+<https://www.python.org/dev/peps/pep-0020/>`__.
+
+In general, overrides should be minimized and preference should always be
+placed on updating the underlying API to be more bindable, adding features to
+GI to support the requirement, or adding mechanical features to PyGObject
+which can apply generically to all overrides (:gnomebug:`721226` and
+:gnomebug:`640812`).
+
+If a GI feature or more bindable API for a library is in the works, it is a
+good idea to avoid the temptation to add temporary short term workarounds in
+overrides. The reason is this can creaste unnecessary conflicts when the
+bindable API becomes a reality (:gnomebug:`707280`).
+
+* Minimize class overrides when possible.
+
+  *Reason*: Class overrides incur a load time performance penalty because
+  they require the classes GType and all of the Python method bindings to be
+  created. See :gnomebug:`705810`
+
+* Prefer monkey patching methods on repository classes over inheritance.
+
+  *Reason*: Class overrides add an additional level to the method
+  resolution order (mro) which has a performance penalty. Since overrides are
+  designed for specific repository library APIs, monkey patching is
+  reasonable because it is utilized in a controlled manner by the API
+  designer (as opposed to monkey patching a third-party library which is more
+  fragile).
+
+* Avoid overriding ``__init__``
+  *Reason*: Sub-classing the overridden class then becomes challenging and
+  has the potential to cause bugs (see :gnomebug:`711487` and reasoning
+  listed in https://wiki.gnome.org/Projects/PyGObject/InitializerDeprecations).
+
+* Unbindable functions which take variadic arguments are generally ok to add
+  Python implementations, but keep in mind the prior noted guidelines. A lot
+  of times adding bindable versions of the functions to the underlying library
+  which take a list is acceptable. For example: :gnomebug:`706119`. Another
+  problem here is if an override is added, then later a bindable version of
+  the API is added which takes a list, there is a good chance we have to live
+  with the override forever which masks a working version implemented by GI.
+
+* Avoid side effects beyond the intended repositories API in function/method
+  overrides.
+
+  *Reason*: This conflates the original API and adds a documentation burden
+  on the override maintainer.
+
+* Don't change function signatures from the original API and don't add default
+  values.
+
+  *Reason*: This turns into a documentation discrepancy between the libraries
+  API and the Python version of the API. Default value work should focus on
+  bug :gnomebug:`558620`, not cherry-picking individual Python functions and
+  adding defaults.
+
+* Avoid implicit side effects to the Python standard library (or anywhere).
+
+  * Don't modify or use sys.argv
+
+    *Reason*: sys.argv should only be explicitly controlled by application
+    developers. Otherwise it requires hacks to work around a module modifying
+    or using the developers command line args which they rightfully own.
+
+    .. code:: python
+
+        saved_argv = sys.argv.copy()
+        sys.argv = []
+        from gi.repository import Gtk
+        sys.argv = saved_argv
+
+  * Never set Pythons default encoding.
+
+    *Reason*: Read or watch Ned Batchelders "`Pragmatic Unicode
+    <https://nedbatchelder.com/text/unipain.html>`__"
+
+* For PyGTK compatibility APIs, add them to PyGTKCompat not overrides.
+* Prefer adapter patterns over of inheritance and overrides.
+
+  *Reason*: An adapter allows more flexibility and less dependency on
+  overrides. It allows application developers to use the raw GI API without
+  having to think about if a particular typelibs overrides have been installed
+  or not.
diff --git a/docs/devguide/overview.rst b/docs/devguide/overview.rst
new file mode 100644
index 0000000..28527b6
--- /dev/null
+++ b/docs/devguide/overview.rst
@@ -0,0 +1,32 @@
+========
+Overview
+========
+
+
+Bug Tracker
+-----------
+
+You can search through the GNOME Bugzilla for existing bug reports:
+https://bugzilla.gnome.org/page.cgi?id=browse.html&product=pygobject
+
+You can also file a new bug report:
+https://bugzilla.gnome.org/enter_bug.cgi?product=pygobject
+
+
+Git Repos
+---------
+
+PyGObject itself is hosted at https://git.gnome.org/browse/pygobject/
+
+In addition a GitHub organization exists which contains various related
+projects: https://github.com/pygobject
+
+
+Continuous Testing
+------------------
+
+The test suite gets regularly run on all supported platforms using
+https://github.com/pygobject/pygobject-ci
+
+There is currently no integration with bugzilla/git.gnome.org for this and the
+status has to be checked manually.
diff --git a/docs/devguide/style_guide.rst b/docs/devguide/style_guide.rst
new file mode 100644
index 0000000..0cd01fd
--- /dev/null
+++ b/docs/devguide/style_guide.rst
@@ -0,0 +1,101 @@
+================
+Style Guidelines
+================
+
+Python Code
+-----------
+
+* Generally follow Python's `PEP8
+  <https://www.python.org/dev/peps/pep-0008/>`__ style guidelines. We run the
+  pep8 command to verify this during unittest runs.
+
+* Break up logical blocks of related code with a newline. Specifically add a
+  blank newline after conditional or looping blocks.
+* Don't comment what is obvious. Instead prefer meaningful names of functions
+  and variables:
+
+  .. code:: python
+
+        # Get the functions signal annotations <-- this comment is unnecessary
+        return_type, arg_types = get_signal_annotations(func)
+
+* Use comments to explain non-obvious blocks and conditionals, magic,
+  workarounds (with bug references), or generally complex pieces of code.
+  Good examples:
+
+  .. code:: python
+
+        # If a property was defined with a decorator, it may already have
+        # a name; if it was defined with an assignment (prop = Property(...))
+        # we set the property's name to the member name
+        if not prop.name:
+            prop.name = name
+
+  .. code:: python
+
+        # Python causes MRO's to be calculated starting with the lowest
+        # base class and working towards the descendant, storing the result
+        # in __mro__ at each point. Therefore at this point we know that
+        # we already have our base class MRO's available to us, there is
+        # no need for us to (re)calculate them.
+        if hasattr(base, '__mro__'):
+            bases_of_subclasses += [list(base.__mro__)]
+
+
+Python Doc Strings
+------------------
+
+* Doc strings should generally follow
+  `PEP257 <https://www.python.org/dev/peps/pep-0257/>`__ unless noted here.
+* Use `reStructuredText (resST) <http://sphinx-doc.org/rest.html>`__
+  annotations.
+* Use three double quotes for doc strings (``"""``).
+* Use a brief description on the same line as the triple quote.
+* Include function parameter documentation (including types, returns, and
+  raises) between the brief description and the full description. Use a
+  newline with indentation for the parameters descriptions.
+
+  .. code:: python
+
+        def spam(amount):
+            """Creates a Spam object with the given amount.
+
+            :param int amount:
+                The amount of spam.
+            :returns:
+                A new Spam instance with the given amount set.
+            :rtype: Spam
+            :raises ValueError:
+                If amount is not a numeric type.
+
+            More complete description.
+            """
+
+* For class documentation, use the classes doc string for an explanation of
+  what the class is used for and how it works, including Python examples.
+  Include ``__init__`` argument documentation after the brief description in
+  the classes doc string. The class ``__init__`` should generally be the first
+  method defined in a class putting it as close as possible (location wise) to
+  the class documentation.
+
+  .. code:: python
+
+        class Bacon(CookedFood):
+            """Bacon is a breakfast food.
+
+            :param CookingType cooking_type:
+                Enum for the type of cooking to use.
+            :param float cooking_time:
+                Amount of time used to cook the Bacon in minutes.
+
+            Use Bacon in combination with other breakfast foods for
+            a complete breakfast. For example, combine Bacon with
+            other items in a list to make a breakfast:
+
+            .. code-block:: python
+
+                breakfast = [Bacon(), Spam(), Spam(), Eggs()]
+
+            """
+            def __init__(self, cooking_type=CookingType.BAKE, cooking_time=15.0):
+                super(Bacon, self).__init__(cooking_type, cooking_time)
diff --git a/docs/extra.css b/docs/extra.css
new file mode 100644
index 0000000..3ae7bdb
--- /dev/null
+++ b/docs/extra.css
@@ -0,0 +1,57 @@
+.wy-side-nav-search {
+    background-color: initial;
+}
+
+.wy-nav-top {
+    background-color: #171A2F;
+}
+
+.wy-side-nav-search input[type="text"] {
+    border-color: transparent;
+}
+
+.wy-nav-content {
+    margin: initial;
+}
+
+.wy-nav-side {
+    background-color: #171A2F;
+}
+
+.rst-content div[role=navigation], footer {
+   font-size: 0.85em;
+   color: #999;
+}
+
+.rst-content div[role=navigation] hr {
+    margin-top: 6px;
+}
+
+footer hr {
+    margin-bottom: 6px;
+}
+
+.rst-footer-buttons {
+    display: none;
+}
+
+a.icon-home, a.icon-home:hover {
+    display: inline-block;
+    padding: 4px 4px 4px 21px;
+    background: transparent url(pygobject-small.svg) center left no-repeat;
+    background-size: 1.2em;
+    margin-top: 0.2em;
+    margin-bottom: 1em;
+}
+
+
+.fa-home::before, .icon-home::before {
+    content: "";
+}
+
+.wy-nav-top a {
+    margin: -2em;
+    background: transparent url(pygobject-small.svg) center left no-repeat;
+    background-size: 1.2em;
+    padding: 4px 4px 4px 24px;
+}
diff --git a/docs/further.rst b/docs/further.rst
new file mode 100644
index 0000000..832cf45
--- /dev/null
+++ b/docs/further.rst
@@ -0,0 +1,10 @@
+=================
+Further Resources
+=================
+
+`Python GTK+ 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.io>`__
+    Many examples showing how to build an application using PyGObject and GTK+.
+
+`Python GI API Reference <https://lazka.github.io/pgi-docs>`__
+    Auto generated API documentation for many libraries accessible through
+    PyGObject.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
new file mode 100644
index 0000000..c6e95b2
--- /dev/null
+++ b/docs/getting_started.rst
@@ -0,0 +1,128 @@
+.. include:: icons.rst
+
+.. _gettingstarted:
+
+===============
+Getting Started
+===============
+
+To get things started we will try to run a very simple `GTK+
+<https://www.gtk.org/>`_ based GUI application using the :doc:`PyGObject <index>` provided
+Python bindings. First create a small Python script called ``hello.py`` with
+the following content and save it somewhere:
+
+.. code:: python
+
+    import gi
+    gi.require_version("Gtk", "3.0")
+    from gi.repository import Gtk
+
+    window = Gtk.Window(title="Hello World")
+    window.show()
+    window.connect("destroy", Gtk.main_quit)
+    Gtk.main()
+
+Before we can run the example application we need to install PyGObject, GTK+
+and their dependencies. Follow the instructions for your platform below.
+
+======================================= ==================================== 
==================================== ==========================================
+|ubuntu-logo| :ref:`Ubuntu <ubuntu>`    |fedora-logo| :ref:`Fedora <fedora>` |arch-logo| :ref:`Arch Linux 
<arch>` |opensuse-logo| :ref:`openSUSE <opensuse>`
+|windows-logo| :ref:`Windows <windows>` |macosx-logo| :ref:`macOS <macosx>`  |python-logo| :ref:`PyPI <pypi>`
+======================================= ==================================== 
==================================== ==========================================
+
+
+.. _windows:
+
+|windows-logo| Windows
+----------------------
+
+1) Go to http://www.msys2.org/ and download the x86_64 installer
+2) Follow the instructions on the page for setting up the basic environment
+3) Run ``C:\msys64\mingw32.exe`` - a terminal window should pop up
+4) Execute ``pacman -S mingw-w64-i686-gtk3 mingw-w64-i686-python2-gobject mingw-w64-i686-python3-gobject``
+5) To test that GTK+3 is working you can run ``gtk3-demo``
+6) Copy the ``hello.py`` script you created to ``C:\msys64\home\<username>``
+7) In the mingw32 terminal execute ``python2 hello.py`` - a window should appear.
+
+.. figure:: images/start_windows.png
+    :scale: 60%
+
+
+.. _ubuntu:
+
+|ubuntu-logo| Ubuntu / |debian-logo| Debian
+-------------------------------------------
+
+1) Open a terminal
+2) Execute ``sudo apt install python-gi python-gi-cairo python3-gi python3-gi-cairo gir1.2-gtk-3.0``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+.. figure:: images/start_linux.png
+    :scale: 60%
+
+
+.. _fedora:
+
+|fedora-logo| Fedora
+--------------------
+
+1) Open a terminal
+2) Execute ``sudo dnf install pygobject3 python3-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _arch:
+
+|arch-logo| Arch Linux
+----------------------
+
+1) Open a terminal
+2) Execute ``sudo pacman -S python-gobject python2-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _opensuse:
+
+|opensuse-logo| openSUSE
+------------------------
+
+1) Open a terminal
+2) Execute ``sudo zypper install python-gobject python3-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _macosx:
+
+|macosx-logo| macOS
+-------------------
+
+1) Go to https://brew.sh/ and install homebrew
+2) Open a terminal
+3) Execute ``brew install pygobject3 --with-python3 gtk+3`` to install for both python2 and python3
+4) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+5) Run ``python2 hello.py``
+
+.. figure:: images/start_macos.png
+    :scale: 70%
+
+
+.. _pypi:
+
+|python-logo| From PyPI
+-----------------------
+
+PyGObject is also available on PyPI: https://pypi.org/project/PyGObject
+
+For this approach you have to make sure that all runtime and build
+dependencies are present yourself as pip will only take care of pycairo.
+
+.. code::
+
+    virtualenv --python=python3 myvenv
+    source myvenv/bin/activate
+    pip install pygobject
+    python hello.py
diff --git a/docs/guide/api/api.rst b/docs/guide/api/api.rst
new file mode 100644
index 0000000..c5e019f
--- /dev/null
+++ b/docs/guide/api/api.rst
@@ -0,0 +1,75 @@
+================
+GI Documentation
+================
+
+This is the API provided by the toplevel "gi" package.
+
+
+.. function:: gi.require_version(namespace, version)
+
+    :param str namespace: The namespace
+    :param str version: The version of the namespace which should be loaded
+    :raises: :obj:`ValueError <exceptions.ValueError>`
+
+    Ensures the namespace gets loaded with the given version. If the namespace
+    was already loaded with a different version or a different version was
+    required previously raises ValueError.
+
+    ::
+
+        import gi
+        gi.require_version('Gtk', '3.0')
+
+
+.. function:: gi.require_foreign(namespace, symbol=None)
+
+    :param str namespace:
+        Introspection namespace of the foreign module (e.g. "cairo")
+    :param symbol:
+        Optional symbol typename to ensure a converter exists.
+    :type symbol: :obj:`str` or :obj:`None`
+    :raises: :obj:`ImportError <exceptions.ImportError>`
+
+    Ensure the given foreign marshaling module is available and loaded.
+
+    Example:
+
+    .. code-block:: python
+
+        import gi
+        import cairo
+        gi.require_foreign('cairo')
+        gi.require_foreign('cairo', 'Surface')
+
+
+.. function:: gi.check_version(version)
+
+    :param tuple version: A version tuple
+    :raises: :obj:`ValueError <exceptions.ValueError>`
+
+    Compares the passed in version tuple with the gi version and does nothing
+    if gi version is the same or newer. Otherwise raises ValueError.
+
+
+.. function:: gi.get_required_version(namespace)
+
+    :returns: The version successfully required previously by :func:`gi.require_version` or :obj:`None`
+    :rtype: str or :obj:`None`
+
+
+.. data:: gi.version_info
+    :annotation: = (3, 18, 1)
+
+    The version of PyGObject
+
+
+.. class:: gi.PyGIDeprecationWarning
+
+    The warning class used for deprecations in PyGObject and the included
+    Python overrides. It inherits from DeprecationWarning and is hidden
+    by default.
+
+
+.. class:: gi.PyGIWarning
+
+    Like :class:`gi.PyGIDeprecationWarning` but visible by default.
diff --git a/docs/guide/api/basic_types.rst b/docs/guide/api/basic_types.rst
new file mode 100644
index 0000000..b41fee9
--- /dev/null
+++ b/docs/guide/api/basic_types.rst
@@ -0,0 +1,53 @@
+===========
+Basic Types
+===========
+
+PyGObject will automatically convert between C types and Python types. In
+cases where it's appropriate it will use default Python types like :obj:`int`,
+:obj:`list`, and :obj:`dict`.
+
+
+Number Types
+------------
+
+All glib integer types get mapped to :obj:`int`, :obj:`long` and :obj:`float`.
+Since the glib integer types are always range limited, conversions from Python
+int/long can fail with :class:`OverflowError`:
+
+.. code:: pycon
+
+    >>> GLib.random_int_range(0, 2**31-1)
+    1684142898
+    >>> GLib.random_int_range(0, 2**31)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    OverflowError: 2147483648 not in range -2147483648 to 2147483647
+    >>> 
+
+
+Text Types
+----------
+
+In case you use Python 2 then text is utf-8 encoded :obj:`str`, in case of
+Python 3 :obj:`str` is used.
+
+
+Platform String Types
+---------------------
+
+* Windows + Python 2: utf-8 encoded :obj:`str`
+* Windows + Python 3: :obj:`str`
+* Unix + Python 2: :obj:`str`
+* Unix + Python 3: :obj:`str`
+
+On Python 3 there is currently no support for :obj:`bytes`, see `bug 746564
+<https://bugzilla.gnome.org/show_bug.cgi?id=746564>`__ for more details.
+
+
+Other Types
+-----------
+
+* GList <-> :obj:`list`
+* GSList <-> :obj:`list`
+* GHashTable <-> :obj:`dict`
+* arrays <-> :obj:`list`
diff --git a/docs/guide/api/flags_enums.rst b/docs/guide/api/flags_enums.rst
new file mode 100644
index 0000000..0a90735
--- /dev/null
+++ b/docs/guide/api/flags_enums.rst
@@ -0,0 +1,39 @@
+=============
+Flags & Enums
+=============
+
+Flags are subclasses of :class:`GObject.GFlags` and represent bit fields where
+some bits also have names:
+
+.. code:: pycon
+
+    >>> Gtk.DialogFlags.MODAL
+    <flags GTK_DIALOG_MODAL of type Gtk.DialogFlags>
+    >>> Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT
+    <flags GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT of type Gtk.DialogFlags>
+    >>> int(_)
+    3
+    >>> Gtk.DialogFlags(3)
+    <flags GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT of type Gtk.DialogFlags>
+    >>> isinstance(Gtk.DialogFlags.MODAL, Gtk.DialogFlags)
+    True
+    >>>
+
+Bitwise operations on them will produce a value of the same type.
+
+
+Enums are subclasses of :class:`GObject.GEnum` and represent a list of named
+constants:
+
+.. code:: pycon
+
+    >>> Gtk.Align.CENTER
+    <enum GTK_ALIGN_CENTER of type Gtk.Align>
+    >>> int(Gtk.Align.CENTER)
+    3
+    >>> int(Gtk.Align.END)
+    2
+    >>> Gtk.Align(1)
+    <enum GTK_ALIGN_START of type Gtk.Align>
+    >>> isinstance(Gtk.Align.CENTER, Gtk.Align)
+    True
diff --git a/docs/guide/api/gobject.rst b/docs/guide/api/gobject.rst
new file mode 100644
index 0000000..08c124b
--- /dev/null
+++ b/docs/guide/api/gobject.rst
@@ -0,0 +1,91 @@
+==============
+GObject.Object
+==============
+
+Compare to other types, :obj:`GObject.Object` has the best integration between
+the GObject and Python type system.
+
+1) It is possible to subclass a :obj:`GObject.Object`. Subclassing
+   creates a new :obj:`GObject.GType` which is connected to the new Python
+   type. This means you can use it with API which takes :obj:`GObject.GType`.
+2) The Python wrapper instance for a :obj:`GObject.Object` is always the same.
+   For the same C instance you will always get the same Python instance.
+
+
+In addition :obj:`GObject.Object` has support for :any:`signals <signals>` and
+:any:`properties <properties>`
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+    :hidden:
+
+    signals
+    properties
+
+
+Examples
+--------
+
+Subclassing:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class A(GObject.Object):
+    ...     pass
+    ... 
+    >>> A()
+    <__main__.A object at 0x7f9113fc3280 (__main__+A at 0x559d9861acc0)>
+    >>> A.__gtype__
+    <GType __main__+A (94135355573712)>
+    >>> A.__gtype__.name
+    '__main__+A'
+    >>> 
+
+In case you want to specify the GType name we have to provide a
+``__gtype_name__``:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class B(GObject.Object):
+    ...     __gtype_name__ = "MyName"
+    ... 
+    >>> B.__gtype__
+    <GType MyName (94830143629776)>
+    >>> 
+
+:obj:`GObject.Object` only supports single inheritance, this means you can
+only subclass one :obj:`GObject.Object`, but multiple Python classes:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class MixinA(object):
+    ...     pass
+    ... 
+    >>> class MixinB(object):
+    ...     pass
+    ... 
+    >>> class MyClass(GObject.Object, MixinA, MixinB):
+    ...     pass
+    ... 
+    >>> instance = MyClass()
+
+
+Here we can see how we create a :obj:`Gio.ListStore` for our new subclass and
+that we get back the same Python instance we put into it:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject, Gio
+    >>> class A(GObject.Object):
+    ...     pass
+    ... 
+    >>> store = Gio.ListStore.new(A)
+    >>> instance = A()
+    >>> store.append(instance)
+    >>> store.get_item(0) is instance
+    True
+    >>> 
diff --git a/docs/guide/api/index.rst b/docs/guide/api/index.rst
new file mode 100644
index 0000000..efeade3
--- /dev/null
+++ b/docs/guide/api/index.rst
@@ -0,0 +1,12 @@
+=============
+API Reference
+=============
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    api
+    basic_types
+    flags_enums
+    gobject
diff --git a/docs/guide/api/properties.rst b/docs/guide/api/properties.rst
new file mode 100644
index 0000000..0241109
--- /dev/null
+++ b/docs/guide/api/properties.rst
@@ -0,0 +1,119 @@
+==========
+Properties
+==========
+
+Properties are part of a class and are defined through a
+:obj:`GObject.ParamSpec`, which contains the type, name, value range and so
+on.
+
+To find all the registered properties of a class you can use the
+:meth:`GObject.Object.list_properties` class method.
+
+.. code:: pycon
+
+    >>> Gio.Application.list_properties()
+    [<GParamString 'application-id'>, <GParamFlags 'flags'>, <GParamString
+    'resource-base-path'>, <GParamBoolean 'is-registered'>, <GParamBoolean
+    'is-remote'>, <GParamUInt 'inactivity-timeout'>, <GParamObject
+    'action-group'>, <GParamBoolean 'is-busy'>]
+    >>> param = Gio.Application.list_properties()[0]
+    >>> param.name
+    'application-id'
+    >>> param.owner_type
+    <GType GApplication (94881584893168)>
+    >>> param.value_type
+    <GType gchararray (64)>
+    >>> 
+
+The :obj:`GObject.Object` contructor takes multiple properties as keyword
+arguments. Property names usually contain "-" for seperating words. In Python
+you can either use "-" or "_". In this case variable names don't allow "-", so
+we use "_".
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+
+To get and set the property value see :meth:`GObject.Object.get_property` and
+:meth:`GObject.Object.set_property`.
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> app
+    <Gio.Application object at 0x7f7499284fa0 (GApplication at 0x564b571e7c00)>
+    >>> app.get_property("application_id")
+    'foo.bar'
+    >>> app.set_property("application_id", "a.b")
+    >>> app.get_property("application-id")
+    'a.b'
+    >>> 
+
+
+Each instance also has a ``props`` attribute which exposes all properties
+as instance attributes:
+
+.. code:: pycon
+
+    >>> from gi.repository import Gtk
+    >>> button = Gtk.Button(label="foo")
+    >>> button.props.label
+    'foo'
+    >>> button.props.label = "bar"
+    >>> button.get_label()
+    'bar'
+    >>> 
+
+
+To track changes of properties, :obj:`GObject.Object` has a special ``notify``
+signal with the property name as the detail string. Note that in this case you
+have to give the real property name and replacing "-" with "_" wont work.
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> def my_func(instance, param):
+    ...     print("New value %r" % instance.get_property(param.name))
+    ... 
+    >>> app.connect("notify::application-id", my_func)
+    11L
+    >>> app.set_property("application-id", "something.different")
+    New value 'something.different'
+    >>> 
+
+You can define your own properties using the :obj:`GObject.Property` decorator,
+which can be used similarly to the builtin Python :any:`property` decorator:
+
+.. function:: GObject.Property(type=None, default=None, nick='', blurb='', \
+    flags=GObject.ParamFlags.READWRITE, minimum=None, maximum=None)
+
+    :param GObject.GType type: Either a GType, a type with a GType or a
+        Python type which maps to a default GType
+    :param object default: A default value
+    :param str nick: Property nickname
+    :param str block: Short description
+    :param GObject.ParamFlags flags: Property configuration flags
+    :param object minimum: Minimum value, depends on the type
+    :param object maximum: Maximum value, depends on the type
+
+
+.. code:: python
+
+    class AnotherObject(GObject.Object):
+        value = 0
+
+        @GObject.Property
+        def prop_pyobj(self):
+            """Read only property."""
+
+            return object()
+
+        @GObject.Property(type=int)
+        def prop_gint(self):
+            """Read-write integer property."""
+
+            return self.value
+
+        @prop_gint.setter
+        def prop_gint(self, value):
+            self.value = value
diff --git a/docs/guide/api/signals.rst b/docs/guide/api/signals.rst
new file mode 100644
index 0000000..0001862
--- /dev/null
+++ b/docs/guide/api/signals.rst
@@ -0,0 +1,93 @@
+=======
+Signals
+=======
+
+GObject signals are a system for registering callbacks for specific events.
+
+To find all signals of a class you can use the
+:func:`GObject.signal_list_names` function:
+
+
+.. code:: pycon
+
+    >>> GObject.signal_list_names(Gio.Application)
+    ('activate', 'startup', 'shutdown', 'open', 'command-line', 'handle-local-options')
+    >>> 
+
+
+To connect to a signal, use :meth:`GObject.Object.connect`:
+
+.. code:: pycon
+
+    >>> app = Gio.Application()
+    >>> def on_activate(instance):
+    ...     print("Activated:", instance)
+    ... 
+    >>> app.connect("activate", on_activate)
+    17L
+    >>> app.run()
+    ('Activated:', <Gio.Application object at 0x7f1bbb304320 (GApplication at 0x5630f1faf200)>)
+    0
+    >>> 
+
+It returns number which identifies the connection during its lifetime and which
+can be used to modify the connection.
+
+For example it can be used to temporarily ignore signal emissions using
+:meth:`GObject.Object.handler_block`:
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> def on_change(*args):
+    ...     print(args)
+    ... 
+    >>> c = app.connect("notify::application-id", on_change)
+    >>> app.props.application_id = "foo.bar"
+    (<Gio.Application object at 0x7f1bbb304550 (GApplication at 0x5630f1faf2b0)>, <GParamString 
'application-id'>)
+    >>> with app.handler_block(c):
+    ...     app.props.application_id = "no.change"
+    ... 
+    >>> app.props.application_id = "change.again"
+    (<Gio.Application object at 0x7f1bbb304550 (GApplication at 0x5630f1faf2b0)>, <GParamString 
'application-id'>)
+    >>> 
+
+
+You can define your own signals using the :obj:`GObject.Signal` decorator:
+
+
+.. function:: GObject.Signal(name='', flags=GObject.SignalFlags.RUN_FIRST, \
+    return_type=None, arg_types=None, accumulator=None, accu_data=None)
+
+    :param str name: The signal name
+    :param GObject.SignalFlags flags: Signal flags
+    :param GObject.GType return_type: Return type
+    :param list arg_types: List of :class:`GObject.GType` argument types
+    :param GObject.SignalAccumulator accumulator: Accumulator function
+    :param object accu_data: User data for the accumulator
+
+
+.. code:: python
+
+    class MyClass(GObject.Object):
+
+        @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, return_type=bool,
+                        arg_types=(object,),
+                        accumulator=GObject.signal_accumulator_true_handled)
+        def test(self, *args):
+            print("Handler", args)
+
+        @GObject.Signal
+        def noarg_signal(self):
+            print("noarg_signal")
+
+    instance = MyClass()
+
+    def test_callback(inst, obj):
+        print "Handled", inst, obj
+        return True
+
+    instance.connect("test", test_callback)
+    instance.emit("test", object())
+
+    instance.emit("noarg_signal")
diff --git a/docs/guide/cairo_integration.rst b/docs/guide/cairo_integration.rst
new file mode 100644
index 0000000..84ea3f3
--- /dev/null
+++ b/docs/guide/cairo_integration.rst
@@ -0,0 +1,39 @@
+=================
+Cairo Integration
+=================
+
+Despite `cairo <https://cairographics.org/>`__ not being a GObject based
+library, PyGObject provides special cairo integration through `pycairo
+<https://pycairo.readthedocs.io>`__. Functions returning and taking cairo data
+types get automatically converted to pycairo objects and vice versa.
+
+Some distros ship the PyGObject cairo support in a separate package. If you've
+followed the instructions on ":ref:`gettingstarted`" you should have everything
+installed.
+
+If your application requires the cairo integration you can use
+:func:`gi.require_foreign`:
+
+.. code:: python
+
+    try:
+        gi.require_foreign("cairo")
+    except ImportError:
+        print("No pycairo integration :(")
+
+Note that PyGObject currently does not support `cairocffi
+<https://pypi.python.org/pypi/cairocffi>`__, only pycairo.
+
+
+Demo
+----
+
+The following example shows a :obj:`Gtk.Window` with a custom drawing in Python
+using pycairo.
+
+.. figure:: images/cairo_integration.png
+    :scale: 75%
+    :align: center
+
+.. literalinclude:: code/cairo-demo.py
+    :linenos:
diff --git a/docs/guide/code/cairo-demo.py b/docs/guide/code/cairo-demo.py
new file mode 100755
index 0000000..f5ac112
--- /dev/null
+++ b/docs/guide/code/cairo-demo.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+"""
+Based on cairo-demo/X11/cairo-demo.c
+"""
+
+import cairo
+import gi
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk
+
+SIZE = 30
+
+
+def triangle(ctx):
+    ctx.move_to(SIZE, 0)
+    ctx.rel_line_to(SIZE, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.close_path()
+
+
+def square(ctx):
+    ctx.move_to(0, 0)
+    ctx.rel_line_to(2 * SIZE, 0)
+    ctx.rel_line_to(0, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.close_path()
+
+
+def bowtie(ctx):
+    ctx.move_to(0, 0)
+    ctx.rel_line_to(2 * SIZE, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.rel_line_to(2 * SIZE, -2 * SIZE)
+    ctx.close_path()
+
+
+def inf(ctx):
+    ctx.move_to(0, SIZE)
+    ctx.rel_curve_to(0, SIZE, SIZE, SIZE, 2 * SIZE, 0)
+    ctx.rel_curve_to(SIZE, -SIZE, 2 * SIZE, -SIZE, 2 * SIZE, 0)
+    ctx.rel_curve_to(0, SIZE, -SIZE, SIZE, - 2 * SIZE, 0)
+    ctx.rel_curve_to(-SIZE, -SIZE, - 2 * SIZE, -SIZE, - 2 * SIZE, 0)
+    ctx.close_path()
+
+
+def draw_shapes(ctx, x, y, fill):
+    ctx.save()
+
+    ctx.new_path()
+    ctx.translate(x + SIZE, y + SIZE)
+    bowtie(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    square(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    triangle(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    inf(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.restore()
+
+
+def fill_shapes(ctx, x, y):
+    draw_shapes(ctx, x, y, True)
+
+
+def stroke_shapes(ctx, x, y):
+    draw_shapes(ctx, x, y, False)
+
+
+def draw(da, ctx):
+    ctx.set_source_rgb(0, 0, 0)
+
+    ctx.set_line_width(SIZE / 4)
+    ctx.set_tolerance(0.1)
+
+    ctx.set_line_join(cairo.LINE_JOIN_ROUND)
+    ctx.set_dash([SIZE / 4.0, SIZE / 4.0], 0)
+    stroke_shapes(ctx, 0, 0)
+
+    ctx.set_dash([], 0)
+    stroke_shapes(ctx, 0, 3 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
+    stroke_shapes(ctx, 0, 6 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_MITER)
+    stroke_shapes(ctx, 0, 9 * SIZE)
+
+    fill_shapes(ctx, 0, 12 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
+    fill_shapes(ctx, 0, 15 * SIZE)
+    ctx.set_source_rgb(1, 0, 0)
+    stroke_shapes(ctx, 0, 15 * SIZE)
+
+
+def main():
+    win = Gtk.Window()
+    win.connect('destroy', lambda w: Gtk.main_quit())
+    win.set_default_size(450, 550)
+
+    drawingarea = Gtk.DrawingArea()
+    win.add(drawingarea)
+    drawingarea.connect('draw', draw)
+
+    win.show_all()
+    Gtk.main()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/docs/guide/debug_profile.rst b/docs/guide/debug_profile.rst
new file mode 100644
index 0000000..628bab1
--- /dev/null
+++ b/docs/guide/debug_profile.rst
@@ -0,0 +1,112 @@
+=====================
+Debugging & Profiling
+=====================
+
+Things can go wrong, these tools may help you find the cause. If you know any
+more tricks please share them.
+
+
+GObject Instance Count Leak Check
+---------------------------------
+
+Requires a development (only available in debug mode) version of glib. Jhbuild
+recommended.
+
+::
+
+    jhbuild shell
+    GOBJECT_DEBUG=instance-count GTK_DEBUG=interactive ./quodlibet.py
+
+* In the GTK+ Inspector switch to the "Statistics" tab
+* Sort by "Cumulative" and do the action which you suspect does leak or where
+  you want to make sure it doesn't repeatedly. Like for example opening
+  and closing a window or switching between media files to present.
+* If something in the "Cumulative" column steadily increases there probably
+  is a leak.
+
+cProfile Performance Profiling
+------------------------------
+
+* https://docs.python.org/2/library/profile.html
+* bundled with python
+
+::
+
+    python -m cProfile -s [sort_order] quodlibet.py > cprof.txt
+
+
+where ``sort_order`` can one of the following:
+calls, cumulative, file, line, module, name, nfl, pcalls, stdname, time
+
+Example output::
+
+             885311 function calls (866204 primitive calls) in 12.110 seconds
+
+       Ordered by: cumulative time
+
+       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+            1    0.002    0.002   12.112   12.112 quodlibet.py:11(<module>)
+            1    0.007    0.007   12.026   12.026 quodlibet.py:25(main)
+    19392/13067    0.151    0.000    4.342    0.000 __init__.py:639(__get__)
+            1    0.003    0.003    4.232    4.232 quodlibetwindow.py:121(__init__)
+            1    0.000    0.000    4.029    4.029 quodlibetwindow.py:549(select_browser)
+            1    0.002    0.002    4.022    4.022 albums.py:346(__init__)
+            ...
+            ...
+
+SnakeViz - cProfile Based Visualization
+---------------------------------------
+
+* https://jiffyclub.github.io/snakeviz/
+* ``pip install snakeviz``
+
+::
+
+    python -m cProfile -o prof.out quodlibet.py
+    snakeviz prof.out
+
+
+Sysprof - System-wide Performance Profiler for Linux
+----------------------------------------------------
+
+* http://sysprof.com/
+
+::
+
+    sysprof-cli -c "python quodlibet/quodlibet.py"
+    sysprof capture.syscap
+
+GDB
+---
+
+::
+
+    gdb --args python quodlibet/quodlibet.py
+    # type "run" and hit enter
+
+
+Debugging Wayland Issues
+------------------------
+
+::
+
+    mutter --nested --wayland
+    # start your app, it should show up in the nested mutter
+
+::
+
+    weston
+    # start your app, it should show up in the nested weston
+
+
+Debugging HiDPI Issue
+---------------------
+
+::
+
+    GDK_SCALE=2 ./quodlibet/quodlibet.py
+
+::
+
+    MUTTER_DEBUG_NUM_DUMMY_MONITORS=2 MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2 mutter --nested --wayland
+    # start your app, it should show up in the nested mutter
diff --git a/docs/guide/deploy.rst b/docs/guide/deploy.rst
new file mode 100644
index 0000000..efee20c
--- /dev/null
+++ b/docs/guide/deploy.rst
@@ -0,0 +1,52 @@
+.. include:: ../icons.rst
+
+======================
+Application Deployment
+======================
+
+There is currently no nice deployment story, but it's not impossible. This is
+a list of random notes and examples.
+
+|linux-logo| Linux
+------------------
+
+On Linux there is no single strategy. Quod Libet uses distutils, MyPaint uses
+SCons. Gramps uses distutils.
+
+|macosx-logo| macOS
+-------------------
+
+On OSX you can use `gtk-osx <https://git.gnome.org/browse/gtk-osx>`__ which is
+based on jhbuild and then `gtk-mac-bundler
+<https://git.gnome.org/browse/gtk-mac-bundler>`__ for packaging things up and
+making libraries relocatable. With macOS bundles you generally have a startup
+shell script which sets all the various env vars relative to the bundle,
+similar to jhbuild.
+
+|windows-logo| Windows
+----------------------
+
+On Windows things are usually build to be relocatable by default, so no env
+vars are needed. You can build/install through MSYS2, copy the bits you need
+and you are done. For GUI application you'll also need an exe launcher that
+links against the python dll.
+
+Example Deployments
+-------------------
+
+* `Quod Libet <https://quodlibet.readthedocs.io/>`__ provides a Windows
+  installer based on MSYS2 and NSIS3. On macOS, jhbuild is used for building,
+  gtk.mac-bundler for packing things up and `dmgbuild
+  <https://pypi.python.org/pypi/dmgbuild>`__ for creating a dmg. distutis is
+  used for building/installing the application into the final environment.
+  Most of this is automated and scripts can be found in the git repo.
+
+* `MyPaint <http://mypaint.org/>`__ provides a Windows installer based on
+  MSYS2 and Inno Setup. It uses SCons for building/installing the application.
+
+* ...?
+
+Other options
+-------------
+
+* `PyInstaller <http://www.pyinstaller.org/>`_ is a program that freezes (packages) Python programs into 
stand-alone executables, under Windows, Linux, Mac OS X, and more. PyInstaller's packager has built-in 
support for automatically including PyGObject dependencies with your application without requiring additional 
configuration.
diff --git a/docs/guide/faq.rst b/docs/guide/faq.rst
new file mode 100644
index 0000000..48031b0
--- /dev/null
+++ b/docs/guide/faq.rst
@@ -0,0 +1,11 @@
+==========================
+Frequently Asked Questions
+==========================
+
+How can I use PyGObject with the official CPython builds on Windows?
+--------------------------------------------------------------------
+
+https://sourceforge.net/projects/pygobjectwin32 provides binaries which should
+be ABI compatible with the official CPython binaries. I'd recommend using
+msys2 if at all possible, since there are more people involved and it's easier
+to fix/patch things yourself.
diff --git a/docs/guide/images/cairo_integration.png b/docs/guide/images/cairo_integration.png
new file mode 100644
index 0000000..4726875
Binary files /dev/null and b/docs/guide/images/cairo_integration.png differ
diff --git a/docs/guide/index.rst b/docs/guide/index.rst
new file mode 100644
index 0000000..ac966d7
--- /dev/null
+++ b/docs/guide/index.rst
@@ -0,0 +1,17 @@
+==========
+User Guide
+==========
+
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    api/index
+    cairo_integration
+    threading
+    debug_profile
+    deploy
+    testing
+    porting
+    faq
diff --git a/docs/guide/porting.rst b/docs/guide/porting.rst
new file mode 100644
index 0000000..8ee1134
--- /dev/null
+++ b/docs/guide/porting.rst
@@ -0,0 +1,109 @@
+============================
+Porting from Static Bindings
+============================
+
+Before PyGObject 3, bindings where not generated automatically through gobject
+introspection and where provided as separate Python libraries like pygobject,
+pygtk, pygst etc. We call them static bindings.
+
+If your code contains imports like ``import gtk``, ``import gst``, ``import
+glib`` or ``import gobject`` you are using the old bindings and you should
+upgrade.
+
+Note that using old and new bindings in the same process is not supported, you
+have to switch everything at once.
+
+
+Static Bindings Library Differences
+-----------------------------------
+
+**pygtk** supported GTK+ 2.0 and Python 2 only. PyGObject supports GTK+ >=3.0
+and Python 2/3. If you port away from pygtk you also have to move to GTK+ 3.0
+at the same time. **pygtkcompat** described below can help you with that
+transition.
+
+**pygst** supports GStreamer 0.10 and Python 2 only. Like with GTK+ you have
+to move to PyGObject and GStreamer 1.0 at the same time.
+
+**pygobject 2** supports glib 2.0 and Python 2. The new bindings also support
+glib 2.0 and Python 2/3.
+
+
+General Porting Tips
+--------------------
+
+PyGObject contains a shell script which can help you with the many naming
+differences between static and dynamic bindings:
+
+https://git.gnome.org/browse/pygobject/plain/tools/pygi-convert.sh
+
+::
+
+    ./pygi-convert.sh mymodule.py
+
+It just does basic text replacement. It reduces the amount of naming changes
+you have to make in the beginning, but nothing more.
+
+1) Run on a Python module
+2) Check/Verify the changes made (e.g. using ``git diff``)
+3) Finish porting the module by hand
+4) Continue to the next module...
+
+
+Porting Tips for GTK+
+---------------------
+
+While PyGObject theoretically supports GTK+ 2.0 it is not really usable. It
+will be easier to port to GTK+ 3.0 right away.
+
+For some general advice regarding the migration from GTK+ 2.0 to 3.0 see the
+`offical migration guide
+<https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html>`__. If you
+need to know how a C symbol is exposed in Python have a look at the `symbol
+mapping listing <https://lazka.github.io/pgi-docs/#Gtk-3.0/mapping.html>`__.
+
+
+Using the pygtkcompat Compatibility Layer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+PyGObject ships a compatibility layer for pygtk which partially emulates the
+old interfaces:
+
+::
+
+    from gi import pygtkcompat
+    pygtkcompat.enable()
+    pygtkcompat.enable_gtk(version='3.0')
+
+    import gtk
+
+``enable()`` has to be called once before the first ``gtk`` import.
+
+Note that pygtkcompat is just for helping you through the transition by
+allowing you to port one module at a time. Only a limited subset of the
+interfaces are emulated correctly and you should try to get rid of it in the
+end.
+
+
+Default Encoding Changes
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Importing ``gtk`` had the side effect of changing the default Python encoding
+from ASCII to UTF-8 (check ``sys.getdefaultencoding()``) and that no longer
+happens with PyGObject. Since text with pygtk is returned as utf-8 encoded
+str, your code is likely depending auto-decoding in many places and you can
+change it manually by doing:
+
+::
+
+    # Python 2 only
+    import sys
+    reload(sys)
+    sys.setdefaultencoding("utf-8")
+    # see if auto decoding works:
+    assert '\xc3\xb6' + u'' ==  u'\xf6'
+
+While this is not officially supported by Python I don't know of any
+downsides. Once you are sure that you explicitly decode in all places or you
+move to Python 3 where things are unicode by default you can remove this
+again.
diff --git a/docs/guide/testing.rst b/docs/guide/testing.rst
new file mode 100644
index 0000000..6a7c663
--- /dev/null
+++ b/docs/guide/testing.rst
@@ -0,0 +1,39 @@
+.. include:: ../icons.rst
+
+==================================
+Testing and Continuous Integration
+==================================
+
+To get automated tests of GTK+ code running on a headless server use Xvfb
+(virtual framebuffer X server). It provides the ``xvfb-run -a`` command which
+creates a temporary X server without the need for any real display hardware.
+
+::
+
+    xvfb-run -a python my_script.py
+
+
+Continuous Integration using Travis CI / CircleCI
+-------------------------------------------------
+
+Travis CI uses a rather old Ubuntu and thus the supported GTK+ is at 3.10 and
+PyGObject is at 3.12. If that's enough for you then have a look at our Travis
+CI example project:
+
+    |github-logo| https://github.com/pygobject/pygobject-travis-ci-examples
+
+    .. image:: https://travis-ci.org/pygobject/pygobject-travis-ci-examples.svg?branch=master
+        :target: https://travis-ci.org/pygobject/pygobject-travis-ci-examples
+
+To get newer PyGObject, GTK+, etc. working on `Travis CI
+<https://travis-ci.org>`__ or `CircleCI <https://circleci.com>`__ you can use
+Docker with an image of your choosing. Have a look at our Docker example
+project which runs tests on various Debian, Ubuntu and Fedora versions:
+
+    |github-logo| https://github.com/pygobject/pygobject-travis-ci-docker-examples
+
+    .. image:: https://travis-ci.org/pygobject/pygobject-travis-ci-docker-examples.svg?branch=master
+        :target: https://travis-ci.org/pygobject/pygobject-travis-ci-docker-examples
+
+    .. image:: https://circleci.com/gh/pygobject/pygobject-travis-ci-docker-examples.svg?style=shield
+        :target: https://circleci.com/gh/pygobject/pygobject-travis-ci-docker-examples
diff --git a/docs/guide/threading.rst b/docs/guide/threading.rst
new file mode 100644
index 0000000..c1bac32
--- /dev/null
+++ b/docs/guide/threading.rst
@@ -0,0 +1,290 @@
+=====================
+Threads & Concurrency
+=====================
+
+Operations which could potentially block should not be executed in the main 
+loop. The main loop is in charge of input processing and drawing and 
+blocking it results in the user interface freezing. For the user this means 
+not getting any feedback and not being able to pause or abort the operation 
+which causes the problem.
+
+Such an operation might be:
+
+* Loading external resources like an image file on the web
+* Searching the local file system
+* Writing, reading and copying files
+* Calculations where the runtime depends on some external factor
+
+The following examples show
+
+* how Python threads, running in parallel to GTK+, can interact with the UI
+* how to use and control asynchronous I/O operations in glib
+
+
+Threads
+-------
+
+The first example uses a Python thread to execute code in the background 
+while still showing feedback on the progress in a window.
+
+.. code:: python
+
+    import threading
+    import time
+
+    from gi.repository import GLib, Gtk, GObject
+
+
+    def app_main():
+        win = Gtk.Window(default_height=50, default_width=300)
+        win.connect("destroy", Gtk.main_quit)
+
+        progress = Gtk.ProgressBar(show_text=True)
+        win.add(progress)
+
+        def update_progess(i):
+            progress.pulse()
+            progress.set_text(str(i))
+            return False
+
+        def example_target():
+            for i in range(50):
+                GLib.idle_add(update_progess, i)
+                time.sleep(0.2)
+
+        win.show_all()
+
+        thread = threading.Thread(target=example_target)
+        thread.daemon = True
+        thread.start()
+
+
+    if __name__ == "__main__":
+        app_main()
+        Gtk.main()
+
+
+The example shows a simple window containing a progress bar. After everything
+is set up it constructs a Python thread, passes it a function to execute,
+starts the thread and the GTK+ main loop. After the main loop is started it is
+possible to see the window and interact with it.
+
+In the background ``example_target()`` gets executed and calls
+:func:`GLib.idle_add` and :func:`time.sleep` in a loop. In this example
+:func:`time.sleep` represents the blocking operation. :func:`GLib.idle_add`
+takes the ``update_progess()`` function and arguments that will get passed to
+the function and asks the main loop to schedule its execution in the main
+thread. This is needed because GTK+ isn't thread safe; only one thread, the
+main thread, is allowed to call GTK+ code at all times.
+
+
+Threads: FAQ
+------------
+
+* I'm porting code from pygtk (GTK+ 2) to PyGObject (GTK+ 3). Has anything 
+  changed regarding threads?
+
+  Short answer: No.
+
+  Long answer: ``gtk.gdk.threads_init()``, ``gtk.gdk.threads_enter()`` and
+  ``gtk.gdk.threads_leave()`` are now :func:`Gdk.threads_init`,
+  :func:`Gdk.threads_enter` and :func:`Gdk.threads_leave`.
+  ``gobject.threads_init()`` can be removed.
+
+* I'm using :func:`Gdk.threads_init` and want to get rid of it. What do I 
+  need to do?
+
+  * Remove any :func:`Gdk.threads_init()`, :func:`Gdk.threads_enter` and  
+    :func:`Gdk.threads_leave` calls. In case they get executed in a thread,
+    move the GTK+ code into its own function and schedule it using
+    :func:`GLib.idle_add`. Be aware that the newly created function will be
+    executed some time later, so other stuff can happen in between.
+
+  * Replace any call to ``Gdk.threads_add_*()`` with their GLib counterpart.
+    For example :func:`GLib.idle_add` instead of :func:`Gdk.threads_add_idle`.
+
+* What about signals and threads?
+
+  Signals get executed in the context they are emitted from. In which context
+  the object is created or where ``connect()`` is called from doesn't matter.
+  In GStreamer, for example, some signals can be called from a different
+  thread, see the respective signal documentation for when this is the case.
+  In case you connect to such a signal you have to make sure to not call any
+  GTK+ code or use :func:`GLib.idle_add` accordingly.
+
+* What if I need to call GTK+ code in signal handlers emitted from a thread?
+
+  In case you have a signal that is emitted from another thread and you need
+  to call GTK+ code during and not after signal handling, you can push the
+  operation with an :class:`threading.Event` object to the main loop and wait
+  in the signal handler until the operation gets scheduled and the result is
+  available. Be aware that if the signal is emitted from the main loop this
+  will deadlock. See the following example
+
+  .. code:: python
+
+        # [...]
+
+        toggle_button = Gtk.ToggleButton()
+
+        def signal_handler_in_thread():
+
+            def function_calling_gtk(event, result):
+                result.append(toggle_button.get_active())
+                event.set()
+
+            event = threading.Event()
+            result = []
+            GLib.idle_add(function_calling_gtk, event, result)
+            event.wait()
+            toggle_button_is_active = result[0]
+            print(toggle_button_is_active)
+
+        # [...]
+
+* What about the Python `GIL
+  <https://en.wikipedia.org/wiki/Global_Interpreter_Lock>`__ ?
+
+  Similar to I/O operations in Python, all PyGObject calls release the 
+  GIL during their execution and other Python threads can be executed 
+  during that time.
+
+
+Asynchronous Operations
+-----------------------
+
+In addition to functions for blocking I/O glib also provides corresponding
+asynchronous versions, usually with the same name plus a ``_async`` suffix.
+These functions do the same operation as the synchronous ones but don't block
+during their execution. Instead of blocking they execute the operation in the
+background and call a callback once the operation is finished or got canceled.
+
+The following example shows how to download a web page and display the 
+source in a text field. In addition it's possible to abort the running 
+operation.
+
+
+.. code:: python
+
+    import time
+
+    from gi.repository import Gio, GLib, Gtk
+
+
+    class DownloadWindow(Gtk.Window):
+
+        def __init__(self):
+            super(DownloadWindow, self).__init__(
+                default_width=500, default_height=400, title="Async I/O Example")
+
+            self.cancellable = Gio.Cancellable()
+
+            self.cancel_button = Gtk.Button(label="Cancel")
+            self.cancel_button.connect("clicked", self.on_cancel_clicked)
+            self.cancel_button.set_sensitive(False)
+
+            self.start_button = Gtk.Button(label="Load")
+            self.start_button.connect("clicked", self.on_start_clicked)
+
+            textview = Gtk.TextView()
+            self.textbuffer = textview.get_buffer()
+            scrolled = Gtk.ScrolledWindow()
+            scrolled.add(textview)
+
+            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6,
+                          border_width=12)
+            box.pack_start(self.start_button, False, True, 0)
+            box.pack_start(self.cancel_button, False, True, 0)
+            box.pack_start(scrolled, True, True, 0)
+
+            self.add(box)
+
+        def append_text(self, text):
+            iter_ = self.textbuffer.get_end_iter()
+            self.textbuffer.insert(iter_, "[%s] %s\n" % (str(time.time()), text))
+
+        def on_start_clicked(self, button):
+            button.set_sensitive(False)
+            self.cancel_button.set_sensitive(True)
+            self.append_text("Start clicked...")
+
+            file_ = Gio.File.new_for_uri(
+                "http://python-gtk-3-tutorial.readthedocs.org/";)
+            file_.load_contents_async(
+                self.cancellable, self.on_ready_callback, None)
+
+        def on_cancel_clicked(self, button):
+            self.append_text("Cancel clicked...")
+            self.cancellable.cancel()
+
+        def on_ready_callback(self, source_object, result, user_data):
+            try:
+                succes, content, etag = source_object.load_contents_finish(result)
+            except GLib.GError as e:
+                self.append_text("Error: " + e.message)
+            else:
+                content_text = content[:100].decode("utf-8")
+                self.append_text("Got content: " + content_text + "...")
+            finally:
+                self.cancellable.reset()
+                self.cancel_button.set_sensitive(False)
+                self.start_button.set_sensitive(True)
+
+
+    if __name__ == "__main__":
+        win = DownloadWindow()
+        win.show_all()
+        win.connect("destroy", Gtk.main_quit)
+
+        Gtk.main()
+
+
+The example uses the asynchronous version of :meth:`Gio.File.load_contents` to
+load the content of an URI pointing to a web page, but first we look at the
+simpler blocking alternative:
+
+We create a :class:`Gio.File` instance for our URI and call
+:meth:`Gio.File.load_contents`, which, if it doesn't raise an error, returns
+the content of the web page we wanted.
+
+.. code:: python
+
+    file = Gio.File.new_for_uri("http://python-gtk-3-tutorial.readthedocs.org/";)
+    try:
+        status, contents, etag_out = file.load_contents(None)
+    except GLib.GError:
+        print("Error!")
+    else:
+        print(contents)
+
+In the asynchronous variant we need two more things:
+
+* A :class:`Gio.Cancellable`, which we can use during the operation to 
+  abort or cancel it.
+* And a :func:`Gio.AsyncReadyCallback` callback function, which gets called
+  once the operation is finished and we can collect the result.
+
+The window contains two buttons for which we register ``clicked`` signal
+handlers:
+
+* The ``on_start_clicked()`` signal handler calls 
+  :meth:`Gio.File.load_contents_async` with a :class:`Gio.Cancellable` 
+  and ``on_ready_callback()`` as :func:`Gio.AsyncReadyCallback`.
+* The ``on_cancel_clicked()`` signal handler calls 
+  :meth:`Gio.Cancellable.cancel` to cancel the running operation.
+
+Once the operation is finished, either because the result is available, an
+error occurred or the operation was canceled, ``on_ready_callback()`` will be
+called with the :class:`Gio.File` instance and a :class:`Gio.AsyncResult`
+instance which holds the result.
+
+To get the result we now have to call :meth:`Gio.File.load_contents_finish` 
+which returns the same things as :meth:`Gio.File.load_contents` except in 
+this case the result is already there and it will return immediately 
+without blocking.
+
+After all this is done we call :meth:`Gio.Cancellable.reset` so the 
+:class:`Gio.Cancellable` can be re-used for new operations and we can click 
+the "Load" button again. This works since we made sure that only one 
+operation can be active at any time by deactivating the "Load" button using 
+:meth:`Gtk.Widget.set_sensitive`.
diff --git a/docs/icons.rst b/docs/icons.rst
new file mode 100644
index 0000000..7637df2
--- /dev/null
+++ b/docs/icons.rst
@@ -0,0 +1,48 @@
+.. |python-logo| raw:: html
+
+    <i class="icon-python"></i>
+
+
+.. |ubuntu-logo| raw:: html
+
+    <i class="icon-ubuntu"></i>
+
+.. |debian-logo| raw:: html
+
+    <i class="icon-debian"></i>
+
+.. |fedora-logo| raw:: html
+
+    <i class="icon-fedora"></i>
+
+.. |opensuse-logo| raw:: html
+
+    <i class="icon-suse"></i>
+
+.. |windows-logo| raw:: html
+
+    <i class="fa fa-windows"></i>
+
+.. |source-logo| raw:: html
+
+    <i class="fa fa-file"></i>
+
+.. |arch-logo| raw:: html
+
+    <i class="icon-archlinux"></i>
+
+.. |macosx-logo| raw:: html
+
+    <i class="fa fa-apple"></i>
+
+.. |github-logo| raw:: html
+
+    <i class="fa fa-github"></i>
+
+.. |bug-logo| raw:: html
+
+    <i class="fa fa-bug"></i>
+
+.. |linux-logo| raw:: html
+
+    <i class="fa fa-linux"></i>
diff --git a/docs/images/LICENSE b/docs/images/LICENSE
new file mode 100644
index 0000000..0fbbdbf
--- /dev/null
+++ b/docs/images/LICENSE
@@ -0,0 +1,3 @@
+pygobject.svg and pygobject-small.svg are based on the GTK+ logo, created by
+Andreas Nilsson, licensed under CC BY-SA 3.0. For more info see
+https://commons.wikimedia.org/wiki/File:GTK%2B_logo.svg
diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico
new file mode 100644
index 0000000..905b200
Binary files /dev/null and b/docs/images/favicon.ico differ
diff --git a/docs/images/logo.svg b/docs/images/logo.svg
new file mode 100644
index 0000000..3f4ebde
--- /dev/null
+++ b/docs/images/logo.svg
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="135"
+   height="135"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.91 r13725"
+   version="1.0"
+   sodipodi:docname="logo.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2897" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2450" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2474">
+      <path
+         d="m 0,450.7086 121.89,0 0,153.071 -121.89,0 0,-153.071 z"
+         id="path2476"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2484">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2486"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2494">
+      <path
+         d="m 0,1802.8342 487.5601,0 0,578.1658 L 0,2381 0,1802.8342 z"
+         id="path2496"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2504">
+      <path
+         d="m -1.5e-6,-2.94433 2.3255315,0 0,3.88873 -2.3255315,0 0,-3.88873 z"
+         id="path2506"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2514">
+      <path
+         d="m 0,1802.8342 487.5601,0 0,578.1658 L 0,2381 0,1802.8342 z"
+         id="path2516"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2532">
+      <path
+         d="m 9.806,537.3086 104.874,0 0,28.203 -104.874,0 0,-28.203 z"
+         id="path2534"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2542">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2544"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2552">
+      <path
+         d="m 39.2241,2149.2344 419.4961,0 0,112.812 -419.4961,0 0,-112.812 z"
+         id="path2554"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2562">
+      <path
+         d="m -0.0935124,-19.05134 2.7028824,0 0,21.10663 -2.7028824,0 0,-21.10663 z"
+         id="path2564"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2572">
+      <path
+         d="m 39.2241,2149.2344 419.4961,0 0,112.812 -419.4961,0 0,-112.812 z"
+         id="path2574"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2612">
+      <path
+         d="m 0,-9.1245 291.968,0 0,462.668 -291.968,0 0,-462.668 z"
+         id="path2614"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2618">
+      <path
+         d="m 0,0 283.5,0 0,453.5436 -283.5,0 L 0,0 z"
+         id="path2620"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2628">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2630"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2638">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2640"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2644">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2646"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2654">
+      <path
+         d="m 8.716e-4,0.0203769 0.9688584,0 0,1.2848631 -0.9688584,0 0,-1.2848631 z"
+         id="path2656"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2664">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2666"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <inkscape:perspective
+       id="perspective2777"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       style="color-interpolation-filters:sRGB"
+       id="filter4210"
+       x="-0.013603581"
+       width="1.0272072"
+       y="-0.010734612"
+       height="1.0214692">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="0.17314453"
+         id="feGaussianBlur4212" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.979899"
+     inkscape:cx="18.317077"
+     inkscape:cy="97.877634"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="674"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0"
+     showborder="true"
+     fit-margin-top="9"
+     fit-margin-left="9"
+     fit-margin-right="9"
+     fit-margin-bottom="9" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-74.24472,-374.35257)">
+    <rect
+       style="fill:#000000;fill-opacity:1"
+       id="rect3079"
+       width="117"
+       height="117"
+       x="83.24472"
+       y="383.35257"
+       ry="23.031063" />
+    <g
+       id="g3855"
+       transform="translate(0.7466894,0.04879762)"
+       style="fill:#4e9a06" />
+    <text
+       xml:space="preserve"
+       
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4210)"
+       x="106.41864"
+       y="461.19006"
+       id="text4178"
+       sodipodi:linespacing="125%"
+       transform="matrix(1.1069586,0,0,1.1069586,-15.44004,-48.180085)"><tspan
+         sodipodi:role="line"
+         id="tspan4180"
+         x="106.41864"
+         y="461.19006"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:87.5px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1">gi</tspan></text>
+  </g>
+</svg>
diff --git a/docs/images/overview.dia b/docs/images/overview.dia
new file mode 100644
index 0000000..08b0243
Binary files /dev/null and b/docs/images/overview.dia differ
diff --git a/docs/images/overview.svg b/docs/images/overview.svg
new file mode 100644
index 0000000..37d6e2c
--- /dev/null
+++ b/docs/images/overview.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd";>
+<svg width="27cm" height="10cm" viewBox="220 135 524 199" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink";>
+  <defs/>
+  <g id="Background">
+    <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; 
stroke: #646464" x="456.332" y="136.698" width="134.923" height="196.302" rx="8" ry="8"/>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: 
round; stroke: #5a9fd4" x="221.09" y="214.954" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="261.09" y="237.604">
+        <tspan x="261.09" y="237.604">Python</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: 
round; stroke: #5a9fd4" x="338" y="216.562" width="81.6" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="378.8" y="239.212">
+        <tspan x="378.8" y="239.212">PyGObject</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: 
round; stroke: #5a9fd4" x="473.126" y="147.249" width="100.6" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.426" y="169.899">
+        <tspan x="523.426" y="169.899">libgirepository</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: 
round; stroke: #5a9fd4" x="483.752" y="192.25" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.752" y="214.9">
+        <tspan x="523.752" y="214.9">libglib</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: 
round; stroke: #5a9fd4" x="483.834" y="238.25" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.834" y="260.9">
+        <tspan x="523.834" y="260.9">libgobject</tspan>
+      </text>
+    </g>
+    <g>
+      <line style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #646464" 
x1="301.09" y1="232.954" x2="330.289" y2="233.558"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" 
fill-rule="evenodd" points="334.788,233.651 328.727,236.527 330.289,233.558 328.851,230.528 "/>
+    </g>
+    <g>
+      <line style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" x1="419.6" y1="234.562" 
x2="449.596" y2="234.796"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" 
fill-rule="evenodd" points="454.096,234.831 448.073,237.784 449.596,234.796 448.12,231.784 "/>
+    </g>
+    <g>
+      <path style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" d="M 591.256 234.848 C 
615.096,234.848 615.096,200.938 632.302,200.938"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" 
fill-rule="evenodd" points="636.802,200.938 630.802,203.938 632.302,200.938 630.802,197.938 "/>
+    </g>
+    <g>
+      <path style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" d="M 591.256 234.848 C 
615.096,234.848 615.096,270.234 631.594,270.234"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" 
fill-rule="evenodd" points="636.094,270.234 630.094,273.234 631.594,270.234 630.094,267.234 "/>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" 
x="484" y="285.9" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="524" y="308.55">
+        <tspan x="524" y="308.55">libffi</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" 
x="639.038" y="182.938" width="104.05" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="691.063" y="205.588">
+        <tspan x="691.063" y="205.588">Gtk-3.0.typelib</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" 
x="638.33" y="252.234" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: 
none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="678.33" y="274.884">
+        <tspan x="678.33" y="274.884">libgtk-3.so</tspan>
+      </text>
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/pygobject-small.svg b/docs/images/pygobject-small.svg
new file mode 100644
index 0000000..e6576e8
--- /dev/null
+++ b/docs/images/pygobject-small.svg
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="88.572403"
+   height="96.050858"
+   id="svg6843"
+   sodipodi:docname="pygobject-small.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="674"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.2285173"
+     inkscape:cx="135.96584"
+     inkscape:cy="-1.8615718"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <defs
+     id="defs6845">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4534">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4530" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4532" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4522">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4518" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4520" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4660">
+      <stop
+         style="stop-color:#646464;stop-opacity:1;"
+         offset="0"
+         id="stop4656" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4658" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4652">
+      <stop
+         style="stop-color:#5a9fd4;stop-opacity:1;"
+         offset="0"
+         id="stop4648" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.94650203"
+         offset="1"
+         id="stop4650" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4644">
+      <stop
+         style="stop-color:#edd400;stop-opacity:1;"
+         offset="0"
+         id="stop4640" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4642" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4644"
+       id="linearGradient4646"
+       x1="53.816978"
+       y1="111.10486"
+       x2="20.88413"
+       y2="30.82696"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4652"
+       id="linearGradient4654"
+       x1="70.43454"
+       y1="17.875593"
+       x2="53.816978"
+       y2="111.10486"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4660"
+       id="linearGradient4662"
+       x1="23.216625"
+       y1="81.319481"
+       x2="107.33282"
+       y2="39.060543"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4522"
+       id="linearGradient4524"
+       x1="70.587303"
+       y1="17.177763"
+       x2="70.485733"
+       y2="67.361443"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4534"
+       id="linearGradient4536"
+       x1="69.029457"
+       y1="87.363297"
+       x2="70.373047"
+       y2="68.046875"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     transform="translate(-19.822261,-15.90723)"
+     id="layer1">
+    <g
+       id="g4527"
+       transform="translate(0,-0.20854102)">
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;opacity:1;fill:url(#linearGradient4654);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12400007;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6976"
+         d="M 20.88413,30.82696 53.816977,55.527708 107.33282,39.060543 70.587303,17.177763 Z" />
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;fill:url(#linearGradient4662);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6978"
+         d="M 22.94243,82.287118 20.88413,30.82696 53.816977,55.527708 v 55.577152 z" />
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;opacity:1;fill:url(#linearGradient4646);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6980"
+         d="M 53.816977,111.10486 103.21619,90.5207 107.33282,39.060543 53.816977,55.527708 Z" />
+      <path
+         
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4536);fill-opacity:1;fill-rule:nonzero;
 
stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 70.597656,66.675781 -47.558594,14.044922 0.355469,1.197266 46.978516,-13.871094 
32.652343,22.910156 0.71875,-1.023437 z"
+         id="path6982"
+         inkscape:connector-curvature="0" />
+      <path
+         
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4524);fill-opacity:1;fill-rule:evenodd;
 
stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 69.808594,17.875 v 49.109375 h 1.25 V 17.875 Z"
+         id="path6984"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/pygobject.svg b/docs/images/pygobject.svg
new file mode 100644
index 0000000..fbf88e1
--- /dev/null
+++ b/docs/images/pygobject.svg
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="392.86777"
+   height="96.050858"
+   id="svg6843"
+   sodipodi:docname="pygobject.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="674"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.2285173"
+     inkscape:cx="135.96584"
+     inkscape:cy="-1.8615724"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g4527" />
+  <defs
+     id="defs6845">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4534">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4530" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4532" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4522">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4518" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4520" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4660">
+      <stop
+         style="stop-color:#646464;stop-opacity:1;"
+         offset="0"
+         id="stop4656" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4658" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4652">
+      <stop
+         style="stop-color:#5a9fd4;stop-opacity:1;"
+         offset="0"
+         id="stop4648" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.94650203"
+         offset="1"
+         id="stop4650" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4644">
+      <stop
+         style="stop-color:#edd400;stop-opacity:1;"
+         offset="0"
+         id="stop4640" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4642" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4644"
+       id="linearGradient4646"
+       x1="53.816978"
+       y1="111.10486"
+       x2="20.88413"
+       y2="30.82696"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4652"
+       id="linearGradient4654"
+       x1="70.43454"
+       y1="17.875593"
+       x2="53.816978"
+       y2="111.10486"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4660"
+       id="linearGradient4662"
+       x1="23.216625"
+       y1="81.319481"
+       x2="107.33282"
+       y2="39.060543"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4522"
+       id="linearGradient4524"
+       x1="70.587303"
+       y1="17.177763"
+       x2="70.485733"
+       y2="67.361443"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4534"
+       id="linearGradient4536"
+       x1="69.029457"
+       y1="87.363297"
+       x2="70.373047"
+       y2="68.046875"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     transform="translate(-19.822261,-15.90723)"
+     id="layer1">
+    <g
+       id="g4527"
+       transform="translate(0,-0.20854102)">
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;opacity:1;fill:url(#linearGradient4654);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12400007;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6976"
+         d="M 20.88413,30.82696 53.816977,55.527708 107.33282,39.060543 70.587303,17.177763 Z" />
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;fill:url(#linearGradient4662);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6978"
+         d="M 22.94243,82.287118 20.88413,30.82696 53.816977,55.527708 v 55.577152 z" />
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;opacity:1;fill:url(#linearGradient4646);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6980"
+         d="M 53.816977,111.10486 103.21619,90.5207 107.33282,39.060543 53.816977,55.527708 Z" />
+      <path
+         
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4536);fill-opacity:1;fill-rule:nonzero;
 
stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 70.597656,66.675781 -47.558594,14.044922 0.355469,1.197266 46.978516,-13.871094 
32.652343,22.910156 0.71875,-1.023437 z"
+         id="path6982"
+         inkscape:connector-curvature="0" />
+      <path
+         
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4524);fill-opacity:1;fill-rule:evenodd;
 
stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 69.808594,17.875 v 49.109375 h 1.25 V 17.875 Z"
+         id="path6984"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       aria-label="PyGObject"
+       
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:25px;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:-2px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="text4518"
+       transform="matrix(0.73060434,0,0,0.73060434,39.415227,17.281548)">
+      <path
+         d="m 134.29489,66.572751 c 14.8,0 26.88,-2.96 26.88,-17.44 0,-10.96 -7.68,-16.4 -22.96,-16.4 h 
-18.32 v 55.36 h 9.84 v -21.52 z m 16.8,-17.04 c 0,7.44 -7.76,8 -16.4,8 h -4.96 v -15.76 h 7.44 c 7.36,0 
13.92,0.96 13.92,7.76 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4529"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 164.91864,49.612751 17.44,38.8 -8.8,20.399999 h 10.8 l 23.6,-59.199999 h -10.16 l -10.4,29.52 
-11.44,-29.52 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4531"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 211.70114,60.092751 c 0,18.64 11.12,28.8 27.68,28.8 9.68,0 17.04,-2.4 22.4,-6.64 v -25.44 h 
-24.4 v 9.04 h 14.56 v 11.68 c -3.28,1.6 -5.84,2.32 -10.96,2.32 -11.28,0 -19.44,-6.48 -19.44,-20.16 0,-12.96 
6.08,-19.04 19.68,-19.04 6.4,0 12,2.24 16.24,4.4 l 2.72,-8.72 c -5.28,-3.2 -12.48,-4.72 -19.2,-4.72 -19.52,0 
-29.28,11.36 -29.28,28.48 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4533"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 297.97114,31.612751 c -16.48,0 -27.52,11.92 -27.52,28.64 0,16.8 10.88,28.64 27.2,28.64 16.8,0 
27.84,-12.24 27.84,-29.2 0,-16.64 -11.04,-28.08 -27.52,-28.08 z m -0.4,9.04 c 11.12,0 18.08,8.08 18.08,19.6 
0,11.52 -6.24,19.6 -17.36,19.6 -11.2,0 -18,-8.72 -18,-20.24 0,-11.28 6.32,-18.96 17.28,-18.96 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4535"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 340.09739,88.092751 1.92,-2.48 c 3.84,2.24 7.68,3.28 11.6,3.28 11.52,0 18.32,-8.56 
18.32,-20.24 0,-11.68 -4.72,-19.92 -16.56,-19.92 -4.56,0 -8.32,1.12 -11.6,2.8 v -20.88 h -9.84 v 57.44 z m 
3.68,-29.2 c 1.92,-0.8 5.68,-2.16 9.2,-2.16 6.88,0 9.12,4.96 9.12,12.48 0,7.52 -3.52,11.92 -10.08,11.92 
-3.2,0 -5.92,-0.8 -8.24,-2.64 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4537"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 385.06739,44.972751 c 3.12,0 5.92,-2.8 5.92,-5.92 0,-3.12 -2.8,-5.92 -5.92,-5.92 -3.12,0 
-5.92,2.8 -5.92,5.92 0,3.12 2.8,5.92 5.92,5.92 z m -8.48,56.319999 c -1.2,0 -2.24,-0.24 -2.24,-0.24 l 
-1.92,7.36 c 0,0 2.64,0.8 5.44,0.8 10.16,0 12.24,-6.96 12.24,-13.999999 v -45.6 h -9.84 v 43.6 c 0,4.96 
-0.56,8.079999 -3.68,8.079999 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4539"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 420.17989,81.132751 c -9.44,0 -11.6,-4.08 -12,-9.04 h 26.4 v -3.76 c 0,-12.56 -5.92,-19.6 
-17.44,-19.6 -11.44,0 -18.88,8.96 -18.88,20.08 0,12.48 7.68,20.08 20.64,20.08 5.12,0 10.08,-0.88 14.8,-2.4 l 
-1.92,-7.36 c -3.52,1.36 -7.36,2 -11.6,2 z m -11.92,-15.84 c 0.48,-4.64 2.48,-8.96 9.04,-8.96 4.8,0 7.44,2.8 
7.44,8.96 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4541"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 450.44364,68.812751 c 0,-7.44 4.4,-12.4 12.8,-12.4 5.04,0 7.84,1.2 9.6,2.16 l 1.92,-7.36 c 
-1.92,-1.2 -5.44,-2.48 -12.56,-2.48 -13.2,0 -21.6,7.76 -21.6,20.08 0,12 8.72,20.08 21.92,20.08 6.08,0 
11.04,-1.76 12.4,-2.4 l -1.92,-7.36 c -1.68,0.8 -4.72,2.08 -9.76,2.08 -7.92,0 -12.8,-5.12 -12.8,-12.4 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4543"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 510.91239,86.732751 -1.44,-6.8 c -1.44,0.4 -4.4,1.12 -7.12,1.12 -5.28,0 -6.48,-2.64 -6.48,-5.6 
v -18.16 h 13.28 v -7.68 h -13.28 v -12.08 h -9.84 v 12.08 h -6.4 v 7.68 h 6.4 v 18.4 c 0,6.8 1.68,13.2 
13.92,13.2 3.68,0 8.24,-1.12 10.96,-2.16 z"
+         
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell
 Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4545"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/start_linux.png b/docs/images/start_linux.png
new file mode 100644
index 0000000..5a557ee
Binary files /dev/null and b/docs/images/start_linux.png differ
diff --git a/docs/images/start_macos.png b/docs/images/start_macos.png
new file mode 100644
index 0000000..8b35a95
Binary files /dev/null and b/docs/images/start_macos.png differ
diff --git a/docs/images/start_windows.png b/docs/images/start_windows.png
new file mode 100644
index 0000000..db4ce32
Binary files /dev/null and b/docs/images/start_windows.png differ
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..82e76a9
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,89 @@
+.. include:: icons.rst
+
+.. title:: Overview
+
+.. toctree::
+    :hidden:
+    :titlesonly:
+    :maxdepth: 1
+
+    getting_started
+    changelog
+    guide/index
+    devguide/index
+    packagingguide
+    maintguide
+    further
+    contact
+
+.. image:: images/pygobject.svg
+   :align: center
+   :width: 400px
+   :height: 98px
+
+|
+
+.. include:: ../README.rst
+    :start-after: |
+    :end-before: ----
+
+If you want to write a Python application for `GNOME
+<https://www.gnome.org/>`__ or a Python GUI application using GTK+, then
+PyGObject is the way to go. For more information on specific libraries check
+out the "`Python GTK+ 3 Tutorial
+<https://python-gtk-3-tutorial.readthedocs.io>`__" and the "`Python GI API
+Reference <https://lazka.github.io/pgi-docs>`__".
+
+.. code:: python
+
+    import gi
+    gi.require_version("Gtk", "3.0")
+    from gi.repository import Gtk
+
+    window = Gtk.Window(title="Hello World")
+    window.show()
+    window.connect("destroy", Gtk.main_quit)
+    Gtk.main()
+
+
+How does it work?
+-----------------
+
+.. figure:: images/overview.svg
+    :width: 600px
+    :height: 222px
+    :align: center
+
+PyGObject uses `glib <https://developer.gnome.org/glib/stable/>`__, `gobject
+<https://developer.gnome.org/gobject/stable/>`__, `girepository
+<https://developer.gnome.org/gi/stable/>`__, `libffi
+<https://sourceware.org/libffi/>`__ and other libraries to access the C
+library (libgtk-3.so) in combination with the additional metadata from the
+accompanying typelib file (Gtk-3.0.typelib) and dynamically provides a Python
+interface based on that information.
+
+
+Who Is Using PyGObject?
+-----------------------
+
+* `D-Feet <https://wiki.gnome.org/action/show/Apps/DFeet>`__ - an easy to use D-Bus debugger
+* `GNOME Music <https://wiki.gnome.org/Apps/Music>`__ - a music player for GNOME
+* `GNOME Tweak Tool <https://wiki.gnome.org/action/show/Apps/GnomeTweakTool>`__ - a tool to customize 
advanced GNOME 3 options
+* `Gramps <https://gramps-project.org/>`__ - a genealogy program
+* `Lollypop <https://gnumdk.github.io/lollypop-web/>`__ - a modern music player
+* `Meld <http://meldmerge.org/>`__ - a visual diff and merge tool
+* `MyPaint <http://mypaint.org/>`__ - a nimble, distraction-free, and easy tool for digital painters
+* `Orca <https://wiki.gnome.org/Projects/Orca>`__ - a flexible and extensible screen reader
+* `Pithos <https://pithos.github.io/>`__ - a Pandora Radio client
+* `Pitivi <http://www.pitivi.org/>`__ - a free and open source video editor
+* `Quod Libet <https://quodlibet.readthedocs.io/>`__ - a music library manager / player
+* `Transmageddon <http://www.linuxrising.org/>`__ - a video transcoder
+
+
+The following applications or libraries use PyGObject for optional features,
+such as plugins or as optional backends:
+
+* `beets <http://beets.io/>`__ - a music library manager and MusicBrainz tagger
+* `gedit <https://wiki.gnome.org/Apps/Gedit>`_- a GNOME text editor
+* `matplotlib <http://matplotlib.org/>`__ - a python 2D plotting library
+* `Totem <https://wiki.gnome.org/Apps/Videos>`__ - a video player for GNOME
diff --git a/docs/maintguide.rst b/docs/maintguide.rst
new file mode 100644
index 0000000..c9cec1b
--- /dev/null
+++ b/docs/maintguide.rst
@@ -0,0 +1,32 @@
+================
+Maintainer Guide
+================
+
+Making a Release
+----------------
+
+#. Make sure configure.ac has the right version number
+#. Update NEWS file (use ``make release-news`` target and then edit as you see
+   fit)
+#. Run ``make distcheck``, fix any issues and commit.
+#. Commit NEWS as ``"release 3.X.Y"`` and push
+#. Tag with: ``git tag -s 3.X.Y -m "release 3.X.Y"``
+#. Push tag with: ``git push origin 3.X.Y``
+#. Commit post-release version bump to configure.ac
+#. Upload tarball: ``scp pygobject-3.X.Y.tar.gz user master gnome org:``
+#. Install tarball:
+   ``ssh user master gnome org 'ftpadmin install pygobject-3.X.Y.tar.gz'``
+
+Based on https://wiki.gnome.org/MaintainersCorner/Releasing
+
+
+Branching
+---------
+
+Each cycle after the feature freeze, we create a stable branch so development
+can continue in the master branch unaffected by the freezes.
+
+#. Create the branch locally with: ``git checkout -b pygobject-3-2``
+#. Push new branch: ``git push origin pygobject-3-2``
+#. In master, update configure.ac to what will be the next version number
+   (3.3.0)
diff --git a/docs/packagingguide.rst b/docs/packagingguide.rst
new file mode 100644
index 0000000..ab1fffe
--- /dev/null
+++ b/docs/packagingguide.rst
@@ -0,0 +1,55 @@
+Packaging Guide
+===============
+
+Some notes on how to package PyGObject
+
+Source packages can be found at
+https://ftp.gnome.org/pub/GNOME/sources/pygobject
+
+
+Existing Packages:
+
+* https://www.archlinux.org/packages/extra/x86_64/python-gobject
+* https://packages.qa.debian.org/p/pygobject.html
+* https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-pygobject
+
+
+Building::
+
+    ./configure --with-python=${PYTHON} --prefix="${PREFIX}"
+    make check # if you want to run the test suite
+    make DESTDIR="${PKGDIR}" install
+
+Runtime dependencies:
+
+    * glib
+    * libgirepository (gobject-introspection)
+    * libffi
+    * Python 2 or 3
+
+    The overrides directory contains various files which includes various
+    Python imports mentioning gtk, gdk etc. They are only used when the
+    corresponding library is present, they are not direct dependencies.
+
+Build dependencies:
+
+    * The runtime dependencies
+    * cairo (optional)
+    * pycairo (optional)
+    * pkg-config
+
+    If autotools is used:
+
+        * gnome-common for PyGObject < 3.26
+        * autoconf-archive for PyGObject >= 3.26
+
+    If setup.py is used:
+
+        * setuptools
+
+Test Suite dependencies:
+
+    * The runtime dependencies
+    * GTK+ 3 (optional)
+    * pango (optional)
+    * pycairo (optional)
diff --git a/setup.py b/setup.py
index 284722c..95a4fe3 100644
--- a/setup.py
+++ b/setup.py
@@ -323,6 +323,10 @@ def main():
     for s in cairo_sources:
         sources.remove(s)
 
+    readme = os.path.join(script_dir, "README.rst")
+    with io.open(readme, encoding="utf-8") as h:
+        long_description = h.read()
+
     gi_ext = Extension(
         name='gi._gi',
         sources=sources,
@@ -347,7 +351,7 @@ def main():
         maintainer=pkginfo["Maintainer"],
         maintainer_email=pkginfo["Maintainer-email"],
         license=pkginfo["License"],
-        long_description=pkginfo["Description"],
+        long_description=long_description,
         platforms=pkginfo.get_all("Platform"),
         classifiers=pkginfo.get_all("Classifier"),
         packages=find_packages(script_dir),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]