--- a/src/geanywraplabel.c
+++ b/src/geanywraplabel.c
@@ -30,7 +30,6 @@
 #include "geanywraplabel.h"
 
 
-
 struct _GeanyWrapLabelClass
 {
 	GtkLabelClass parent_class;
@@ -49,9 +48,22 @@
 };
 
 
+#if GTK_CHECK_VERSION(3, 0, 0)
+static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr);
+static void geany_wrap_label_get_preferred_width (GtkWidget *widget,
+		gint *minimal_width, gint *natural_width);
+static void geany_wrap_label_get_preferred_height (GtkWidget *widget,
+		gint *minimal_height, gint *natural_height);
+static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+		gint height, gint *minimal_width, gint *natural_width);
+static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+		gint width, gint *minimal_height, gint *natural_height);
+static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget);
+#else
+static gboolean geany_wrap_label_expose		(GtkWidget *widget, GdkEventExpose *event);
 static void geany_wrap_label_size_request	(GtkWidget *widget, GtkRequisition *req);
+#endif
 static void geany_wrap_label_size_allocate	(GtkWidget *widget, GtkAllocation *alloc);
-static gboolean geany_wrap_label_expose		(GtkWidget *widget, GdkEventExpose *event);
 static void geany_wrap_label_set_wrap_width	(GtkWidget *widget, gint width);
 static void geany_wrap_label_label_notify	(GObject *object, GParamSpec *pspec, gpointer data);
 
@@ -62,9 +74,18 @@
 {
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 
+	widget_class->size_allocate = geany_wrap_label_size_allocate;
+#if GTK_CHECK_VERSION(3, 0, 0)
+	widget_class->draw = geany_wrap_label_draw;
+	widget_class->get_preferred_width = geany_wrap_label_get_preferred_width;
+	widget_class->get_preferred_width_for_height = geany_wrap_label_get_preferred_width_for_height;
+	widget_class->get_preferred_height = geany_wrap_label_get_preferred_height;
+	widget_class->get_preferred_height_for_width = geany_wrap_label_get_preferred_height_for_width;
+	widget_class->get_request_mode = geany_wrap_label_get_request_mode;
+#else
 	widget_class->size_request = geany_wrap_label_size_request;
-	widget_class->size_allocate = geany_wrap_label_size_allocate;
 	widget_class->expose_event = geany_wrap_label_expose;
+#endif
 
 	g_type_class_add_private(klass, sizeof (GeanyWrapLabelPrivate));
 }
@@ -119,6 +140,67 @@
 }
 
 
+#if GTK_CHECK_VERSION(3, 0, 0)
+/* makes sure the layout is setup for rendering and chains to parent renderer */
+static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr)
+{
+	GeanyWrapLabel *self = GEANY_WRAP_LABEL(widget);
+	PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+	pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE);
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+
+	return (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->draw)(widget, cr);
+}
+
+
+static void geany_wrap_label_get_preferred_width (GtkWidget *widget,
+		gint *minimal_width, gint *natural_width)
+{
+	*minimal_width = *natural_width = 0;
+}
+
+
+static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+		gint height, gint *minimal_width, gint *natural_width)
+{
+	PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));;
+
+	pango_layout_set_height(layout, height * PANGO_SCALE);
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+	pango_layout_get_pixel_size(layout, natural_width, NULL);
+
+	*minimal_width = 0;
+}
+
+
+static void geany_wrap_label_get_preferred_height (GtkWidget *widget,
+		gint *minimal_height, gint *natural_height)
+{
+	*minimal_height = *natural_height = GEANY_WRAP_LABEL(widget)->priv->wrap_height;
+}
+
+
+static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+		gint width, gint *minimal_height, gint *natural_height)
+{
+	PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+	pango_layout_set_width(layout, width * PANGO_SCALE);
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+	pango_layout_get_pixel_size(layout, NULL, natural_height);
+
+	*minimal_height = *natural_height;
+}
+
+
+static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget)
+{
+	return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
+#else /* GTK3 */
+
 /* makes sure the layout is setup for rendering and chains to parent renderer */
 static gboolean geany_wrap_label_expose(GtkWidget *widget, GdkEventExpose *event)
 {
@@ -139,6 +221,7 @@
 	req->width = 0;
 	req->height = GEANY_WRAP_LABEL(widget)->priv->wrap_height;
 }
+#endif /* GTK3 */
 
 
 /* Sets the wrap width to the width allocated to us. */
@@ -147,6 +230,16 @@
 	(* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->size_allocate)(widget, alloc);
 
 	geany_wrap_label_set_wrap_width(widget, alloc->width);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+{
+	/* ask the parent to recompute our size, because it seems GTK3 size
+	 * caching is too aggressive */
+	GtkWidget *parent = gtk_widget_get_parent(widget);
+	if (GTK_IS_CONTAINER(parent))
+		gtk_container_check_resize(GTK_CONTAINER(parent));
+}
+#endif
 }