Index: src/documentprivate.h
===================================================================
--- src/documentprivate.h	(Revision 3162)
+++ src/documentprivate.h	(Arbeitskopie)
@@ -26,6 +26,7 @@
 #ifndef GEANY_DOCUMENT_PRIVATE_H
 #define GEANY_DOCUMENT_PRIVATE_H

+
 /* available UNDO actions, UNDO_SCINTILLA is a pseudo action to trigger Scintilla's
  * undo management */
 enum
@@ -36,7 +37,16 @@
 	UNDO_ACTIONS_MAX
 };

+typedef enum
+{
+	FILE_OK,
+	FILE_CHANGED,
+	FILE_MISSING,
+	FILE_IGNORE
+}
+FileDiskStatus;

+
 typedef struct FileEncoding
 {
 	gchar 			*encoding;
@@ -64,8 +74,18 @@
 	GTrashStack		*redo_actions;
 	/* Used so Undo/Redo works for encoding changes. */
 	FileEncoding	 saved_encoding;
-	gboolean		colourise_needed;	/* use document.c:queue_colourise() instead */
-	gint			line_count;			/* Number of lines in the document. */
+	gboolean		 colourise_needed;	/* use document.c:queue_colourise() instead */
+	gint			 line_count;		/* Number of lines in the document. */
+
+	/* File status on disk of the document, can be 'FILE_CHANGED', 'FILE_MISSING' (deleted) or
+	 * 'FILE_OK' if there are no known changes */
+	FileDiskStatus	 file_disk_status;
+	/* Reference to a GFileMonitor object, only used when GIO file monitoring is used. */
+	gpointer		 monitor;
+	/* Time of the last disk check, only used when legacy file monitoring is used. */
+	time_t			 last_check;
+	/* Modification time of the document on disk, only used when legacy file monitoring is used. */
+	time_t			 mtime;
 }
 GeanyDocumentPrivate;

Index: src/makefile.win32
===================================================================
--- src/makefile.win32	(Revision 3162)
+++ src/makefile.win32	(Arbeitskopie)
@@ -46,7 +46,7 @@
 ifdef GTK280
 ALL_GTK_LIBS +=-liconv
 else
-ALL_GTK_LIBS +=-lcairo -lpangocairo-1.0
+ALL_GTK_LIBS +=-lcairo -lpangocairo-1.0 -lgio-2.0
 endif

 WIN_LIBS=-mwindows -lkernel32 -limm32 -lshfolder -lshell32 \
Index: src/dialogs.c
===================================================================
--- src/dialogs.c	(Revision 3162)
+++ src/dialogs.c	(Arbeitskopie)
@@ -381,8 +381,7 @@


 #if ! GEANY_USE_WIN32_DIALOG
-static void handle_save_as(const gchar *utf8_filename, gboolean open_new_tab,
-		gboolean rename_file)
+static void handle_save_as(const gchar *utf8_filename, gboolean open_new_tab, gboolean rename_file)
 {
 	GeanyDocument *doc = document_get_current();

@@ -399,22 +398,16 @@
 		{
 			if (rename_file)
 			{
-				gchar *old_filename = utils_get_locale_from_utf8(doc->file_name);
-				gchar *new_filename = utils_get_locale_from_utf8(utf8_filename);
-
-				g_rename(old_filename, new_filename);
-				g_free(old_filename);
-				g_free(new_filename);
+				document_rename_file(doc, utf8_filename);
 			}
 			/* create a new tm_source_file object otherwise tagmanager won't work correctly */
 			tm_workspace_remove_object(doc->tm_file, TRUE, TRUE);
 			doc->tm_file = NULL;
 		}
 		document_save_file_as(doc, utf8_filename);
-	}

-	if (! open_new_tab)
 		build_menu_update(doc);
+	}
 }


Index: src/plugindata.h
===================================================================
--- src/plugindata.h	(Revision 3162)
+++ src/plugindata.h	(Arbeitskopie)
@@ -41,13 +41,13 @@
 enum {
 	/** The Application Programming Interface (API) version, incremented
 	 * whenever any plugin data types are modified or appended to. */
-	GEANY_API_VERSION = 104,
+	GEANY_API_VERSION = 105,

 	/** The Application Binary Interface (ABI) version, incremented whenever
 	 * existing fields in the plugin data types have to be changed or reordered. */
 	/* This should usually stay the same if fields are only appended, assuming only pointers to
 	 * structs and not structs themselves are declared by plugins. */
-	GEANY_ABI_VERSION = 47
+	GEANY_ABI_VERSION = 48
 };

 /** Check the plugin can be loaded by Geany.
@@ -238,7 +238,9 @@
 	void		(*set_encoding) (struct GeanyDocument *doc, const gchar *new_encoding);
 	void		(*set_text_changed) (struct GeanyDocument *doc, gboolean changed);
 	void		(*set_filetype) (struct GeanyDocument *doc, struct GeanyFiletype *type);
-	gboolean	(*close) (GeanyDocument *doc);
+	gboolean	(*close) (struct GeanyDocument *doc);
+	gboolean	(*save_file_as) (struct GeanyDocument *doc, const gchar *utf8_fname);
+	void		(*rename_file) (struct GeanyDocument *doc, const gchar *new_filename);
 }
 DocumentFuncs;

Index: src/document.c
===================================================================
--- src/document.c	(Revision 3162)
+++ src/document.c	(Arbeitskopie)
@@ -47,6 +47,10 @@
 /* gstdio.h also includes sys/stat.h */
 #include <glib/gstdio.h>

+#ifdef HAVE_GIO
+#include <gio/gio.h>
+#endif
+
 #include "document.h"
 #include "documentprivate.h"
 #include "filetypes.h"
@@ -316,9 +320,7 @@
 	new_doc->encoding = NULL;
 	new_doc->has_bom = FALSE;
 	new_doc->editor = NULL;
-	new_doc->mtime = 0;
 	new_doc->changed = FALSE;
-	new_doc->last_check = time(NULL);
 	new_doc->real_path = NULL;

 	new_doc->priv = g_new0(GeanyDocumentPrivate, 1);
@@ -363,6 +365,100 @@
 }


+#ifdef HAVE_GIO
+static void file_changed_cb(G_GNUC_UNUSED GFileMonitor *monitor, G_GNUC_UNUSED GFile *file,
+							G_GNUC_UNUSED GFile *other_file, GFileMonitorEvent event,
+							GeanyDocument *doc)
+{
+	const gchar *msg;
+
+	switch (event)
+	{
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		{
+			if (doc->priv->file_disk_status == FILE_IGNORE)
+			{	/* ignore this change completely, used after saving a file */
+				geany_debug("ignored");
+				doc->priv->file_disk_status = FILE_OK;
+				return;
+			}
+			doc->priv->file_disk_status = FILE_CHANGED;
+			msg = "G_FILE_MONITOR_EVENT_CREATED | G_FILE_MONITOR_EVENT_CHANGED";
+			break;
+		}
+		case G_FILE_MONITOR_EVENT_DELETED:
+		{
+			doc->priv->file_disk_status = FILE_MISSING;
+			msg = "G_FILE_MONITOR_EVENT_DELETED";
+			break;
+		}
+		/* ignore */
+		case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+		case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+		case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+		case G_FILE_MONITOR_EVENT_UNMOUNTED:
+		/* we ignore 'created' for now since it causes trouble when renaming files */
+		case G_FILE_MONITOR_EVENT_CREATED:
+			return;
+	}
+	geany_debug("File changed: %s -> %s (%d)", DOC_FILENAME(doc), msg, event);
+
+	if (doc->priv->file_disk_status != FILE_OK)
+	{
+		ui_update_tab_status(doc);
+	}
+}
+#endif
+
+
+void document_stop_file_monitoring(GeanyDocument *doc)
+{
+	g_return_if_fail(doc != NULL);
+
+	if (doc->priv->monitor != NULL)
+	{
+		g_object_unref(doc->priv->monitor);
+		doc->priv->monitor = NULL;
+	}
+}
+
+
+static void setup_file_monitoring(GeanyDocument *doc)
+{
+#ifdef HAVE_GIO
+	if (file_prefs.disk_check_timeout > 0)
+	{
+		gchar *locale_filename;
+		GFile *file;
+
+		/* stop any previous monitoring */
+		document_stop_file_monitoring(doc);
+
+		locale_filename = utils_get_locale_from_utf8(doc->file_name);
+
+		if (g_file_test(locale_filename, G_FILE_TEST_EXISTS))
+		{
+			/* get a file monitor and connect to the 'changed' signal */
+			file = g_file_new_for_path(locale_filename);
+			doc->priv->monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
+			g_signal_connect(doc->priv->monitor, "changed", G_CALLBACK(file_changed_cb), doc);
+
+			/* we set the rate limit according to the GUI pref but it's most probably not used */
+			//~ g_file_monitor_set_rate_limit(doc->priv->monitor, file_prefs.disk_check_timeout * 1000);
+
+			/* we don't need the file object any longer */
+			g_object_unref(file);
+		}
+		g_free(locale_filename);
+	}
+#else
+	doc->priv->last_check = time(NULL);
+	doc->priv->mtime = 0;
+#endif
+	doc->priv->file_disk_status = FILE_OK;
+}
+
+
 /* Creates a new document and editor, adding a tab in the notebook.
  * @return The created document */
 static GeanyDocument *document_create(const gchar *utf8_filename)
@@ -413,11 +509,12 @@

 	gtk_widget_grab_focus(GTK_WIDGET(this->editor->sci));

+	setup_file_monitoring(this);
+
 	this->is_valid = TRUE;	/* do this last to prevent UI updating with NULL items. */
 	return this;
 }

-
 /**
  *  Close the given document.
  *
@@ -479,6 +576,8 @@
 	editor_destroy(doc->editor);
 	doc->editor = NULL;

+	document_stop_file_monitoring(doc);
+
 	doc->is_valid = FALSE;
 	doc->file_name = NULL;
 	doc->real_path = NULL;
@@ -553,7 +652,7 @@
 	sci_set_undo_collection(doc->editor->sci, TRUE);
 	sci_empty_undo_buffer(doc->editor->sci);

-	doc->mtime = time(NULL);
+	doc->priv->mtime = time(NULL);

 	doc->encoding = g_strdup(encodings[file_prefs.default_new_encoding].charset);
 	/* store the opened encoding for undo/redo */
@@ -1062,7 +1161,7 @@

 	sci_set_undo_collection(doc->editor->sci, TRUE);

-	doc->mtime = filedata.mtime; /* get the modification time from file and keep it */
+	doc->priv->mtime = filedata.mtime; /* get the modification time from file and keep it */
 	g_free(doc->encoding);	/* if reloading, free old encoding */
 	doc->encoding = filedata.enc;
 	doc->has_bom = filedata.bom;
@@ -1212,6 +1311,7 @@

 static gboolean document_update_timestamp(GeanyDocument *doc)
 {
+#ifndef HAVE_GIO
 	struct stat st;
 	gchar *locale_filename;

@@ -1226,8 +1326,9 @@
 		return FALSE;
 	}

-	doc->mtime = st.st_mtime; /* get the modification time from file and keep it */
+	doc->priv->mtime = st.st_mtime; /* get the modification time from file and keep it */
 	g_free(locale_filename);
+#endif
 	return TRUE;
 }

@@ -1286,22 +1387,47 @@
 }


-/*
- * Save the %document, detecting the filetype.
+/**
+ *  Renames the file in @a doc to @a new_filename. Only the file on disk is actually renamed,
+ *  you still have to call @ref document_save_file_as() to change the @a doc object.
+ *  It also stops monitoring for file changes to prevent receiving too many file change events
+ *  while renaming. File monitoring is setup again in @ref document_save_file_as().
  *
+ *  @param doc The current document which should be renamed.
+ *  @param new_filename The new filename in UTF-8 encoding.
+ */
+void document_rename_file(GeanyDocument *doc, const gchar *new_filename)
+{
+	gchar *old_locale_filename = utils_get_locale_from_utf8(doc->file_name);
+	gchar *new_locale_filename = utils_get_locale_from_utf8(new_filename);
+
+	/* stop file monitoring to avoid getting events for deleting/creating files,
+	 * it's re-setup in document_save_file_as() */
+	document_stop_file_monitoring(doc);
+
+	g_rename(old_locale_filename, new_locale_filename);
+
+	g_free(old_locale_filename);
+	g_free(new_locale_filename);
+}
+
+
+/**
+ * Saves the document, detecting the filetype.
+ *
  * @param doc The document for the file to save.
  * @param utf8_fname The new name for the document, in UTF-8, or NULL.
  * @return @c TRUE if the file was saved or @c FALSE if the file could not be saved.
+ *
  * @see document_save_file().
  */
 gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
 {
 	gboolean ret;

-	if (doc == NULL)
-		return FALSE;
+	g_return_val_if_fail(doc != NULL, FALSE);

-	if (utf8_fname)
+	if (utf8_fname != NULL)
 	{
 		g_free(doc->file_name);
 		doc->file_name = g_strdup(utf8_fname);
@@ -1323,6 +1449,12 @@
 	replace_header_filename(doc);

 	ret = document_save_file(doc, TRUE);
+
+	/* file monitoring support, add file monitoring after the file has been saved
+	 * to ignore any earlier events */
+	setup_file_monitoring(doc);
+	doc->priv->file_disk_status = FILE_IGNORE;
+
 	if (ret)
 		ui_add_recent_file(doc->file_name);
 	return ret;
@@ -1501,6 +1633,9 @@
 	err = write_data_to_disk(doc, data, len);
 	g_free(data);

+	/* ignore file changed notification after writing the file */
+	doc->priv->file_disk_status = FILE_IGNORE;
+
 	if (err != 0)
 	{
 		ui_set_statusbar(TRUE, _("Error saving file (%s)."), g_strerror(err));
@@ -1532,10 +1667,10 @@
 		document_set_filetype(doc, doc->file_type);

 		tm_workspace_update(TM_WORK_OBJECT(app->tm_workspace), TRUE, TRUE, FALSE);
-		{
-			gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), base_name);
-			gtk_label_set_text(GTK_LABEL(doc->priv->tabmenu_label), base_name);
-		}
+
+		gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), base_name);
+		gtk_label_set_text(GTK_LABEL(doc->priv->tabmenu_label), base_name);
+
 		msgwin_status_add(_("File %s saved."), doc->file_name);
 		ui_update_statusbar(doc, -1);
 		g_free(base_name);
@@ -2411,6 +2546,7 @@
 {
 	static GdkColor red = {0, 0xFFFF, 0, 0};
 	static GdkColor green = {0, 0, 0x7FFF, 0};
+	static GdkColor orange = {0, 0xFFFF, 0x7FFF, 0};
 	GdkColor *color = NULL;

 	if (doc == NULL)
@@ -2418,6 +2554,8 @@

 	if (doc->changed)
 		color = &red;
+	else if (doc->priv->file_disk_status == FILE_MISSING || doc->priv->file_disk_status == FILE_CHANGED)
+		color = &orange;
 	else if (doc->readonly)
 		color = &green;

@@ -2545,62 +2683,103 @@
 }


+static gboolean check_resave_missing_file(GeanyDocument *doc)
+{
+	gboolean want_reload = FALSE;
+
+	/* file is missing - set unsaved state */
+	document_set_text_changed(doc, TRUE);
+	/* don't prompt more than once */
+	setptr(doc->real_path, NULL);
+
+	if (dialogs_show_question_full(NULL, GTK_STOCK_SAVE, GTK_STOCK_CANCEL,
+		_("Try to resave the file?"),
+		_("File \"%s\" was not found on disk!"), doc->file_name))
+	{
+		dialogs_show_save_as();
+		want_reload = TRUE;
+	}
+	return want_reload;
+}
+
+
+static time_t check_disk_status_real(GeanyDocument *doc, gboolean force)
+{
+	time_t t = 0;
+#ifndef HAVE_GIO
+	struct stat st;
+	gchar *locale_filename;
+
+	t = time(NULL);
+
+	if (! force && doc->priv->last_check > (t - file_prefs.disk_check_timeout))
+		return 0;
+
+	doc->priv->last_check = t;
+
+	locale_filename = utils_get_locale_from_utf8(doc->file_name);
+	if (g_stat(locale_filename, &st) != 0)
+	{
+		doc->priv->file_disk_status = FILE_MISSING;
+		return 0;
+	}
+	else if (doc->priv->mtime > t || st.st_mtime > t)
+	{
+		g_warning("%s: Something is wrong with the time stamps.", __func__);
+	}
+	else if (doc->priv->mtime < st.st_mtime)
+	{
+		doc->priv->file_disk_status = FILE_CHANGED;
+		/* return st.st_mtime to set it after the file has been possibly reloaded */
+		t = st.st_mtime;
+	}
+	g_free(locale_filename);
+#endif
+	return t;
+}
+
+
 /* Set force to force a disk check, otherwise it is ignored if there was a check
  * in the last file_prefs.disk_check_timeout seconds.
  * @return @c TRUE if the file has changed. */
 gboolean document_check_disk_status(GeanyDocument *doc, gboolean force)
 {
-	struct stat st;
+	gboolean ret = FALSE;
 	time_t t;
-	gchar *locale_filename;
-	gboolean ret = FALSE;

 	if (file_prefs.disk_check_timeout == 0)
 		return FALSE;
 	if (doc == NULL)
 		return FALSE;
 	/* ignore documents that have never been saved to disk */
-	if (doc->real_path == NULL) return FALSE;
-
-	t = time(NULL);
-
-	if (! force && doc->last_check > (t - file_prefs.disk_check_timeout))
+	if (doc->real_path == NULL)
 		return FALSE;

-	doc->last_check = t;
+	/* check the file's mtime in case we don't have GIO support, otherwise this is a no-op */
+	t = check_disk_status_real(doc, force);

-	locale_filename = utils_get_locale_from_utf8(doc->file_name);
-	if (g_stat(locale_filename, &st) != 0)
+	switch (doc->priv->file_disk_status)
 	{
-		/* file is missing - set unsaved state */
-		document_set_text_changed(doc, TRUE);
-		/* don't prompt more than once */
-		setptr(doc->real_path, NULL);
-
-		if (dialogs_show_question_full(NULL, GTK_STOCK_SAVE, GTK_STOCK_CANCEL,
-			_("Try to resave the file?"),
-			_("File \"%s\" was not found on disk!"), doc->file_name))
+		case FILE_CHANGED:
 		{
-			dialogs_show_save_as();
+			check_reload(doc);
+			doc->priv->mtime = t;
+			ret = TRUE;
+			break;
 		}
-	}
-	else if (doc->mtime > t || st.st_mtime > t)
-	{
-		geany_debug("Strange: Something is wrong with the time stamps.");
-	}
-	else if (doc->mtime < st.st_mtime)
-	{
-		if (check_reload(doc))
+		case FILE_MISSING:
 		{
-			/* Update the modification time */
-			doc->mtime = st.st_mtime;
+			check_resave_missing_file(doc);
+			ret = TRUE;
+			break;
 		}
-		else
-			doc->mtime = st.st_mtime;	/* Ignore this change on disk completely */
+		default:
+			break;
+	}

-		ret = TRUE; /* file has changed */
-	}
-	g_free(locale_filename);
+	doc->priv->file_disk_status = FILE_OK;
+	ui_update_tab_status(doc);
+
 	return ret;
 }

Index: src/plugins.c
===================================================================
--- src/plugins.c	(Revision 3162)
+++ src/plugins.c	(Arbeitskopie)
@@ -126,7 +126,9 @@
 	&document_set_encoding,
 	&document_set_text_changed,
 	&document_set_filetype,
-	&document_close
+	&document_close,
+	&document_save_file_as,
+	&document_rename_file
 };

 static EditorFuncs editor_funcs = {
Index: src/document.h
===================================================================
--- src/document.h	(Revision 3162)
+++ src/document.h	(Arbeitskopie)
@@ -93,10 +93,6 @@
 	gboolean		 readonly;
 	/** Whether this %document has been changed since it was last saved. */
 	gboolean		 changed;
-	/** Time of the last disk check. */
-	time_t			 last_check;
-	/** Modification time of this %document on disk. */
-	time_t			 mtime;
 	/** The link-dereferenced, locale-encoded file name.
 	 * If non-NULL, this indicates the file once existed on disk (not just as an
 	 * unsaved document with a filename set).
@@ -224,6 +220,7 @@

 void document_undo_add(GeanyDocument *doc, guint type, gpointer data);

+void document_rename_file(GeanyDocument *doc, const gchar *new_filename);

 GdkColor *document_get_status_color(GeanyDocument *doc);

Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(Revision 3162)
+++ src/Makefile.am	(Arbeitskopie)
@@ -67,7 +67,7 @@
 	utils.h


-INCLUDES = -I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include @GTK_CFLAGS@
+INCLUDES = -I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include @GTK_CFLAGS@ @GIO_CFLAGS@

 # tell automake we have a C++ file so it uses the C++ linker we need for Scintilla
 nodist_EXTRA_geany_SOURCES = dummy.cxx
@@ -77,7 +77,7 @@

 geany_SOURCES = $(SRCS) win32.c win32.h

-geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ $(INTLLIBS) \
+geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@ $(INTLLIBS) \
 			  -lkernel32 -limm32 -lshfolder -lshell32 -lole32 -luuid -lcomdlg32 \
 			  -lcomctl32 -liberty -lwsock32 geany_private.res

@@ -102,7 +102,7 @@

 geany_SOURCES = $(SRCS) vte.c vte.h

-geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@  $(INTLLIBS)
+geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@  $(INTLLIBS)

 AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
 			-DGEANY_DOCDIR=\""$(docdir)"\" \
Index: win32-config.h
===================================================================
--- win32-config.h	(Revision 3162)
+++ win32-config.h	(Arbeitskopie)
@@ -175,9 +175,6 @@
 /* Define to 1 if you have the `strdup' function. */
 #define HAVE_STRDUP 1

-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1

@@ -321,3 +318,6 @@
 /* Define if you want to detect a running instance */
 #define HAVE_SOCKET 1

+/* Building with new GTK/GLib is easy versions on Windows, so let's use GIO (GLib 2.16+) */
+#define HAVE_GIO 1
+
Index: configure.in
===================================================================
--- configure.in	(Revision 3162)
+++ configure.in	(Arbeitskopie)
@@ -133,6 +133,14 @@
 AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)

+# GIO checks
+gio_modules="gio-2.0 >= 2.16"
+PKG_CHECK_MODULES(GIO, [$gio_modules], have_gio=1, have_gio=0)
+AC_SUBST(GIO_CFLAGS)
+AC_SUBST(GIO_LIBS)
+AC_DEFINE_UNQUOTED(HAVE_GIO, $have_gio, [Whether GIO is available])
+
+
 # --disable-deprecated switch for GTK2 purification
 AC_ARG_ENABLE(deprecated, [  --disable-deprecated    Disable deprecated GTK functions. ],
 			  [GTK_CFLAGS="$GTK_CFLAGS -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"], [])
Index: wscript
===================================================================
--- wscript	(Revision 3162)
+++ wscript	(Arbeitskopie)
@@ -169,6 +169,8 @@

 	conf.check_cfg(package='gtk+-2.0', atleast_version='2.6.0', uselib_store='GTK', mandatory=True)
 	conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='GTK')
+	conf.check_cfg(package='gio-2.0', atleast_version='2.16.0', uselib_store='GTK')
+	conf.check_cfg(package='gio-2.0', args='--cflags --libs', uselib_store='GTK')

 	# GTK version check
 	have_gtk_210 = False
@@ -294,7 +296,7 @@
 	obj.target	   = 'geany'
 	obj.source	   = geany_sources
 	obj.includes	 = '. src/ scintilla/include/ tagmanager/include/'
-	obj.uselib	   = 'GTK'
+	obj.uselib	   = 'GTK GIO'
 	obj.uselib_local = 'scintilla tagmanager'

 	# Plugins
