--- .travis.yml.old
+++ .travis.yml
@@ -5,7 +5,7 @@ compiler:
   - clang
 before_install:
   - sudo apt-get -qq update
-  - sudo apt-get install libgtk2.0-dev qtbase5-dev
+  - sudo apt-get install libgtk-3-dev qtbase5-dev
 script:
   - ./autogen.sh
   - ./configure --prefix=/opt/aud --enable-qt
--- acinclude.m4.old
+++ acinclude.m4
@@ -185,12 +185,14 @@ AC_ARG_ENABLE(gtk,
  USE_GTK=$enableval, USE_GTK=yes)
 
 if test $USE_GTK = yes ; then
-    PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.24)
+    PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.4)
     AC_DEFINE(USE_GTK, 1, [Define if GTK+ support enabled])
 fi
 
 AC_SUBST(USE_GTK)
 
+AC_DEFINE(GDK_VERSION_MIN_REQUIRED, GDK_VERSION_3_4, [Ignore post 3.4 deprecations])
+
 if test $HAVE_MSWINDOWS = yes ; then
     PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.32)
 else
--- src/libaudgui/about.cc.old
+++ src/libaudgui/about.cc
@@ -75,7 +75,7 @@ static GtkWidget * create_about_window ()
 
     audgui_destroy_on_escape (about_window);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_container_add ((GtkContainer *) about_window, vbox);
 
     AudguiPixbuf logo (gdk_pixbuf_new_from_resource_at_scale
@@ -88,11 +88,9 @@ static GtkWidget * create_about_window ()
     gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_CENTER);
     gtk_box_pack_start ((GtkBox *) vbox, label, false, false, 0);
 
-    GtkWidget * align = gtk_alignment_new (0.5, 0.5, 0, 0);
-    gtk_box_pack_start ((GtkBox *) vbox, align, false, false, 0);
-
     GtkWidget * button = gtk_link_button_new (website);
-    gtk_container_add ((GtkContainer *) align, button);
+    gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
+    gtk_box_pack_start ((GtkBox *) vbox, button, false, false, 0);
 
     auto credits = VFSFile::read_file (filename_build ({data_dir, "AUTHORS"}), VFS_APPEND_NULL);
     auto license = VFSFile::read_file (filename_build ({data_dir, "COPYING"}), VFS_APPEND_NULL);
--- src/libaudgui/eq-preset.cc.old
+++ src/libaudgui/eq-preset.cc
@@ -243,16 +243,16 @@ static GtkWidget * create_eq_preset_window ()
 
     g_signal_connect (window, "destroy", (GCallback) cleanup_eq_preset_window, nullptr);
 
-    GtkWidget * outer = gtk_vbox_new (false, 0);
+    GtkWidget * outer = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) window, outer);
 
     gtk_box_pack_start ((GtkBox *) outer, create_menu_bar (), false, false, 0);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_container_set_border_width ((GtkContainer *) vbox, 6);
     gtk_box_pack_start ((GtkBox *) outer, vbox, true, true, 0);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0);
 
     entry = gtk_entry_new ();
@@ -277,7 +277,7 @@ static GtkWidget * create_eq_preset_window ()
     audgui_list_add_column (list, nullptr, 0, G_TYPE_STRING, -1);
     gtk_container_add ((GtkContainer *) scrolled, list);
 
-    GtkWidget * hbox2 = gtk_hbox_new (false, 6);
+    GtkWidget * hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox2, false, false, 0);
 
     GtkWidget * remove = audgui_button_new (_("Delete Selected"), "edit-delete",
--- src/libaudgui/equalizer.cc.old
+++ src/libaudgui/equalizer.cc
@@ -68,13 +68,14 @@ static void slider_moved (GtkRange * slider)
 
 static GtkWidget * create_slider (const char * name, int band, GtkWidget * hbox)
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
 
     GtkWidget * label = gtk_label_new (name);
     gtk_label_set_angle ((GtkLabel *) label, 90);
     gtk_box_pack_start ((GtkBox *) vbox, label, true, false, 0);
 
-    GtkWidget * slider = gtk_vscale_new_with_range (-AUD_EQ_MAX_GAIN, AUD_EQ_MAX_GAIN, 1);
+    GtkWidget * slider = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
+     -AUD_EQ_MAX_GAIN, AUD_EQ_MAX_GAIN, 1);
     gtk_scale_set_draw_value ((GtkScale *) slider, true);
     gtk_scale_set_value_pos ((GtkScale *) slider, GTK_POS_BOTTOM);
     gtk_range_set_inverted ((GtkRange *) slider, true);
@@ -132,10 +133,10 @@ static GtkWidget * create_window ()
     gtk_container_set_border_width ((GtkContainer *) window, 6);
     audgui_destroy_on_escape (window);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_container_add ((GtkContainer *) window, vbox);
 
-    GtkWidget * top_row = gtk_hbox_new (false, 6);
+    GtkWidget * top_row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, top_row, false, false, 0);
 
     gtk_box_pack_start ((GtkBox *) top_row, create_on_off (), false, false, 0);
@@ -148,13 +149,14 @@ static GtkWidget * create_window ()
      (AudguiCallback) reset_to_zero, nullptr);
     gtk_box_pack_end ((GtkBox *) top_row, zero, false, false, 0);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,  6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0);
 
     GtkWidget * preamp = create_slider (_("Preamp"), -1, hbox);
     g_object_set_data ((GObject *) window, "preamp", preamp);
 
-    gtk_box_pack_start ((GtkBox *) hbox, gtk_vseparator_new (), false, false, 0);
+    gtk_box_pack_start ((GtkBox *) hbox,
+     gtk_separator_new (GTK_ORIENTATION_VERTICAL), false, false, 0);
 
     for (int i = 0; i < AUD_EQ_NBANDS; i ++)
     {
--- src/libaudgui/file-opener.cc.old
+++ src/libaudgui/file-opener.cc
@@ -96,9 +96,8 @@ static GtkWidget * create_filebrowser (gboolean open)
     gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG);
     gtk_window_set_title ((GtkWindow *) window, window_title);
     gtk_window_set_default_size ((GtkWindow *) window, 7 * dpi, 5 * dpi);
-    gtk_container_set_border_width ((GtkContainer *) window, 10);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) window, vbox);
 
     GtkWidget * chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
@@ -109,17 +108,24 @@ static GtkWidget * create_filebrowser (gboolean open)
     if (path[0])
         gtk_file_chooser_set_current_folder ((GtkFileChooser *) chooser, path);
 
-    gtk_box_pack_start ((GtkBox *) vbox, chooser, true, true, 3);
+    gtk_box_pack_start ((GtkBox *) vbox, chooser, true, true, 0);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 0);
-    gtk_box_pack_end ((GtkBox *) vbox, hbox, false, false, 3);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+    gtk_box_pack_end ((GtkBox *) vbox, hbox, false, false, 0);
+
+#if GTK_CHECK_VERSION (3, 14, 0)
+    gtk_container_set_border_width ((GtkContainer *) hbox, 6);
+#else
+    gtk_widget_set_margin_top (hbox, 12);
+    gtk_container_set_border_width ((GtkContainer *) window, 12);
+#endif
 
     GtkWidget * toggle = gtk_check_button_new_with_mnemonic (toggle_text);
     gtk_toggle_button_set_active ((GtkToggleButton *) toggle, aud_get_bool ("audgui", option));
     g_signal_connect (toggle, "toggled", (GCallback) toggled_cb, (void *) option);
     gtk_box_pack_start ((GtkBox *) hbox, toggle, true, true, 0);
 
-    GtkWidget * bbox = gtk_hbutton_box_new ();
+    GtkWidget * bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_button_box_set_layout ((GtkButtonBox *) bbox, GTK_BUTTONBOX_END);
     gtk_box_set_spacing ((GtkBox *) bbox, 6);
     gtk_box_pack_end ((GtkBox *) hbox, bbox, true, true, 0);
--- src/libaudgui/infopopup.cc.old
+++ src/libaudgui/infopopup.cc
@@ -36,9 +36,6 @@
 
 static void infopopup_move_to_mouse (GtkWidget * infopopup);
 
-static const GdkColor gray = {0, 40960, 40960, 40960};
-static const GdkColor white = {0, 65535, 65535, 65535};
-
 static struct {
     GtkWidget * title_header, * title_label;
     GtkWidget * artist_header, * artist_label;
@@ -102,68 +99,20 @@ static void infopopup_progress_cb (void *)
         gtk_widget_hide (widgets.progress);
 }
 
-static void infopopup_realized (GtkWidget * widget)
-{
-    GdkWindow * window = gtk_widget_get_window (widget);
-    gdk_window_set_back_pixmap (window, nullptr, false);
-    infopopup_move_to_mouse (widget);
-}
-
-/* borrowed from the gtkui infoarea */
-static gboolean infopopup_draw_bg (GtkWidget * widget)
-{
-    double r = 1, g = 1, b = 1;
-
-    /* In a dark theme, try to match the tone of the base color */
-    auto & c = (gtk_widget_get_style (widget))->base[GTK_STATE_NORMAL];
-    int v = aud::max (aud::max (c.red, c.green), c.blue);
-
-    if (v >= 10*256 && v < 80*256)
-    {
-        r = (double)c.red / v;
-        g = (double)c.green / v;
-        b = (double)c.blue / v;
-    }
-
-    GtkAllocation alloc;
-    gtk_widget_get_allocation (widget, & alloc);
-
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
-
-    cairo_pattern_t * gradient = cairo_pattern_create_linear (0, 0, 0, alloc.height);
-    cairo_pattern_add_color_stop_rgb (gradient, 0, 0.25 * r, 0.25 * g, 0.25 * b);
-    cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.15 * r, 0.15 * g, 0.15 * b);
-    cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.1 * r, 0.1 * g, 0.1 * b);
-    cairo_pattern_add_color_stop_rgb (gradient, 1, 0, 0, 0);
-
-    cairo_set_source (cr, gradient);
-    cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
-    cairo_fill (cr);
-
-    cairo_pattern_destroy (gradient);
-    cairo_destroy (cr);
-    return false;
-}
-
 static void infopopup_add_category (GtkWidget * grid, int position,
  const char * text, GtkWidget * * header, GtkWidget * * label)
 {
     * header = gtk_label_new (nullptr);
     * label = gtk_label_new (nullptr);
 
-    gtk_misc_set_alignment ((GtkMisc *) * header, 1, 0.5);
-    gtk_misc_set_alignment ((GtkMisc *) * label, 0, 0.5);
-
-    gtk_widget_modify_fg (* header, GTK_STATE_NORMAL, & gray);
-    gtk_widget_modify_fg (* label, GTK_STATE_NORMAL, & white);
+    gtk_widget_set_halign (* header, GTK_ALIGN_END);
+    gtk_widget_set_halign (* label, GTK_ALIGN_START);
 
     CharPtr markup (g_markup_printf_escaped ("<span style=\"italic\">%s</span>", text));
     gtk_label_set_markup ((GtkLabel *) * header, markup);
 
-    gtk_table_attach ((GtkTable *) grid, * header, 0, 1, position, position + 1,
-     GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach ((GtkTable *) grid, * label, 1, 2, position, position + 1,
-     GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) grid, * header, 0, position, 1, 1);
+    gtk_grid_attach ((GtkGrid *) grid, * label, 1, position, 1, 1);
 
     gtk_widget_set_no_show_all (* header, true);
     gtk_widget_set_no_show_all (* label, true);
@@ -190,7 +139,7 @@ static GtkWidget * infopopup_create ()
     gtk_window_set_decorated ((GtkWindow *) infopopup, false);
     gtk_container_set_border_width ((GtkContainer *) infopopup, 4);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,  6);
     gtk_container_add ((GtkContainer *) infopopup, hbox);
 
     widgets.image = gtk_image_new ();
@@ -198,8 +147,8 @@ static GtkWidget * infopopup_create ()
     gtk_box_pack_start ((GtkBox *) hbox, widgets.image, false, false, 0);
     gtk_widget_set_no_show_all (widgets.image, true);
 
-    GtkWidget * grid = gtk_table_new (0, 0, false);
-    gtk_table_set_col_spacings ((GtkTable *) grid, 6);
+    GtkWidget * grid = gtk_grid_new ();
+    gtk_grid_set_column_spacing ((GtkGrid *) grid, 6);
     gtk_box_pack_start ((GtkBox *) hbox, grid, true, true, 0);
 
     infopopup_add_category (grid, 0, _("Title"), & widgets.title_header, & widgets.title_label);
@@ -212,19 +161,15 @@ static GtkWidget * infopopup_create ()
 
     /* track progress */
     widgets.progress = gtk_progress_bar_new ();
+    gtk_widget_set_margin_top (widgets.progress, 6);
+    gtk_progress_bar_set_show_text ((GtkProgressBar *) widgets.progress, true);
     gtk_progress_bar_set_text ((GtkProgressBar *) widgets.progress, "");
-    gtk_table_set_row_spacing ((GtkTable *) grid, 6, 4);
-    gtk_table_attach ((GtkTable *) grid, widgets.progress, 0, 2, 7, 8,
-     GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) grid, widgets.progress, 0, 7, 2, 1);
 
     /* do not show the track progress */
     gtk_widget_set_no_show_all (widgets.progress, true);
 
-    /* override background drawing */
-    gtk_widget_set_app_paintable (infopopup, true);
-
-    g_signal_connect (infopopup, "realize", (GCallback) infopopup_realized, nullptr);
-    g_signal_connect (infopopup, "expose-event", (GCallback) infopopup_draw_bg, nullptr);
+    g_signal_connect (infopopup, "realize", (GCallback) infopopup_move_to_mouse, nullptr);
 
     return infopopup;
 }
--- src/libaudgui/infowin.cc.old
+++ src/libaudgui/infowin.cc
@@ -135,7 +135,7 @@ static GtkWidget * small_label_new (const char * text)
 
     GtkWidget * label = gtk_label_new (text);
     gtk_label_set_attributes ((GtkLabel *) label, attrs);
-    gtk_misc_set_alignment ((GtkMisc *) label, 0, 0.5);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
 
     return label;
 }
@@ -299,10 +299,11 @@ static void add_entry (GtkWidget * grid, const char * title, GtkWidget * entry,
 {
     GtkWidget * label = small_label_new (title);
 
-    gtk_table_attach ((GtkTable *) grid, label, x, x + span, y, y + 1,
-     GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach ((GtkTable *) grid, entry, x, x + span, y + 1, y + 2,
-     GTK_FILL, GTK_FILL, 0, 0);
+    if (y > 0)
+        gtk_widget_set_margin_top (label, 6);
+
+    gtk_grid_attach ((GtkGrid *) grid, label, x, y, span, 1);
+    gtk_grid_attach ((GtkGrid *) grid, entry, x, y + 1, span, 1);
 
     g_signal_connect (entry, "changed", (GCallback) entry_changed, nullptr);
 }
@@ -317,44 +318,41 @@ static void create_infowin ()
     gtk_window_set_type_hint ((GtkWindow *) infowin,
      GDK_WINDOW_TYPE_HINT_DIALOG);
 
-    GtkWidget * main_grid = gtk_table_new (0, 0, false);
-    gtk_table_set_col_spacings ((GtkTable *) main_grid, 6);
-    gtk_table_set_row_spacings ((GtkTable *) main_grid, 6);
+    GtkWidget * main_grid = gtk_grid_new ();
+    gtk_grid_set_column_spacing ((GtkGrid *) main_grid, 6);
+    gtk_grid_set_row_spacing ((GtkGrid *) main_grid, 6);
     gtk_container_add ((GtkContainer *) infowin, main_grid);
 
     widgets.image = audgui_scaled_image_new (nullptr);
-    gtk_table_attach_defaults ((GtkTable *) main_grid, widgets.image, 0, 1, 0, 1);
+    gtk_widget_set_hexpand (widgets.image, true);
+    gtk_widget_set_vexpand (widgets.image, true);
+    gtk_grid_attach ((GtkGrid *) main_grid, widgets.image, 0, 0, 1, 1);
 
     widgets.location = gtk_label_new ("");
-    gtk_widget_set_size_request (widgets.location, 2 * dpi, -1);
+    gtk_label_set_max_width_chars ((GtkLabel *) widgets.location, 40);
     gtk_label_set_line_wrap ((GtkLabel *) widgets.location, true);
     gtk_label_set_line_wrap_mode ((GtkLabel *) widgets.location, PANGO_WRAP_WORD_CHAR);
     gtk_label_set_selectable ((GtkLabel *) widgets.location, true);
-    gtk_table_attach ((GtkTable *) main_grid, widgets.location, 0, 1, 1, 2,
-     GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) main_grid, widgets.location, 0, 1, 1, 1);
 
-    GtkWidget * codec_grid = gtk_table_new (0, 0, false);
-    gtk_table_set_row_spacings ((GtkTable *) codec_grid, 2);
-    gtk_table_set_col_spacings ((GtkTable *) codec_grid, 12);
-    gtk_table_attach ((GtkTable *) main_grid, codec_grid, 0, 1, 2, 3,
-     GTK_FILL, GTK_FILL, 0, 0);
+    GtkWidget * codec_grid = gtk_grid_new ();
+    gtk_grid_set_row_spacing ((GtkGrid *) codec_grid, 3);
+    gtk_grid_set_column_spacing ((GtkGrid *) codec_grid, 12);
+    gtk_grid_attach ((GtkGrid *) main_grid, codec_grid, 0, 2, 1, 1);
 
     for (int row = 0; row < CODEC_ITEMS; row ++)
     {
         GtkWidget * label = small_label_new (_(codec_labels[row]));
-        gtk_table_attach ((GtkTable *) codec_grid, label, 0, 1, row, row + 1,
-         GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach ((GtkGrid *) codec_grid, label, 0, row, 1, 1);
 
         widgets.codec[row] = small_label_new (nullptr);
-        gtk_table_attach ((GtkTable *) codec_grid, widgets.codec[row], 1, 2, row, row + 1,
-         GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach ((GtkGrid *) codec_grid, widgets.codec[row], 1, row, 1, 1);
     }
 
-    GtkWidget * grid = gtk_table_new (0, 0, false);
-    gtk_table_set_row_spacings ((GtkTable *) grid, 2);
-    gtk_table_set_col_spacings ((GtkTable *) grid, 6);
-    gtk_table_attach ((GtkTable *) main_grid, grid, 1, 2, 0, 3,
-     GTK_FILL, GTK_FILL, 0, 0);
+    GtkWidget * grid = gtk_grid_new ();
+    gtk_grid_set_column_homogeneous ((GtkGrid *) grid, true);
+    gtk_grid_set_column_spacing ((GtkGrid *) grid, 6);
+    gtk_grid_attach ((GtkGrid *) main_grid, grid, 1, 0, 1, 3);
 
     widgets.title = gtk_entry_new ();
     gtk_widget_set_size_request (widgets.title, 3 * dpi, -1);
@@ -382,9 +380,8 @@ static void create_infowin ()
     widgets.track = gtk_entry_new ();
     add_entry (grid, _("Track Number"), widgets.track, 1, 12, 1);
 
-    GtkWidget * bottom_hbox = gtk_hbox_new (false, 6);
-    gtk_table_attach ((GtkTable *) main_grid, bottom_hbox, 0, 2, 3, 4,
-     GTK_FILL, GTK_FILL, 0, 0);
+    GtkWidget * bottom_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+    gtk_grid_attach ((GtkGrid *) main_grid, bottom_hbox, 0, 3, 2, 1);
 
     widgets.clear = gtk_check_button_new_with_mnemonic
      (_("Clea_r fields when moving to next song"));
--- src/libaudgui/jump-to-track.cc.old
+++ src/libaudgui/jump-to-track.cc
@@ -245,7 +245,7 @@ static GtkWidget * create_window ()
     gtk_container_set_border_width ((GtkContainer *) jump_to_track_win, 10);
     gtk_window_set_default_size ((GtkWindow *) jump_to_track_win, 6 * dpi, 5 * dpi);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
     gtk_container_add ((GtkContainer *) jump_to_track_win, vbox);
 
     treeview = audgui_list_new (& callbacks, nullptr, 0);
@@ -258,7 +258,7 @@ static GtkWidget * create_window ()
      "changed", (GCallback) selection_changed, nullptr);
     g_signal_connect (treeview, "row-activated", (GCallback) do_jump, nullptr);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 3);
 
     /* filter box */
@@ -282,17 +282,14 @@ static GtkWidget * create_window ()
     gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrollwin, GTK_SHADOW_IN);
     gtk_box_pack_start ((GtkBox *) vbox, scrollwin, true, true, 0);
 
-    GtkWidget * hbox2 = gtk_hbox_new (false, 0);
+    GtkWidget * hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_box_pack_end ((GtkBox *) vbox, hbox2, false, false, 0);
 
-    GtkWidget * bbox = gtk_hbutton_box_new ();
+    GtkWidget * bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_button_box_set_layout ((GtkButtonBox *) bbox, GTK_BUTTONBOX_END);
+    gtk_widget_set_margin_left (bbox, 6);
     gtk_box_set_spacing ((GtkBox *) bbox, 6);
-
-    GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
-    gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 6, 0);
-    gtk_container_add ((GtkContainer *) alignment, bbox);
-    gtk_box_pack_end ((GtkBox *) hbox2, alignment, true, true, 0);
+    gtk_box_pack_end ((GtkBox *) hbox2, bbox, true, true, 0);
 
     /* close dialog toggle */
     GtkWidget * toggle = gtk_check_button_new_with_mnemonic (_("C_lose on jump"));
--- src/libaudgui/list.cc.old
+++ src/libaudgui/list.cc
@@ -389,7 +389,7 @@ static void autoscroll (void * widget)
     ListModel * model = (ListModel *) gtk_tree_view_get_model
      ((GtkTreeView *) widget);
 
-    GtkAdjustment * adj = gtk_tree_view_get_vadjustment ((GtkTreeView *) widget);
+    GtkAdjustment * adj = gtk_scrollable_get_vadjustment ((GtkScrollable *) widget);
     g_return_if_fail (adj);
 
     int pos, end;
@@ -406,7 +406,7 @@ static void autoscroll (void * widget)
 
 static void start_autoscroll (ListModel * model, GtkWidget * widget, int speed)
 {
-    GtkAdjustment * adj = gtk_tree_view_get_vadjustment ((GtkTreeView *) widget);
+    GtkAdjustment * adj = gtk_scrollable_get_vadjustment ((GtkScrollable *) widget);
     g_return_if_fail (adj);
 
     int pos, end;
@@ -534,6 +534,10 @@ static void drag_data_received (GtkWidget * widget, GdkDragContext * context, in
 
 static void destroy_cb (GtkWidget * list, ListModel * model)
 {
+    /* workaround for Gnome bug #679291 */
+    g_signal_handlers_disconnect_matched (list, G_SIGNAL_MATCH_DATA, 0, 0, NULL,
+     NULL, model);
+
     stop_autoscroll (model, list);
     g_list_free (model->column_types);
     g_object_unref (model);
--- src/libaudgui/plugin-prefs.cc.old
+++ src/libaudgui/plugin-prefs.cc
@@ -168,7 +168,7 @@ EXPORT void audgui_show_plugin_prefs (PluginHandle * plugin)
     }
 
     GtkWidget * content = gtk_dialog_get_content_area ((GtkDialog *) window);
-    GtkWidget * box = gtk_vbox_new (false, 0);
+    GtkWidget * box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     audgui_create_widgets_with_domain (box, p->widgets, header->info.domain);
     gtk_box_pack_start ((GtkBox *) content, box, true, true, 0);
 
--- src/libaudgui/plugin-view.cc.old
+++ src/libaudgui/plugin-view.cc
@@ -214,7 +214,7 @@ static void button_destroy (GtkWidget * b)
 
 GtkWidget * plugin_view_new (PluginType type)
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_container_set_border_width ((GtkContainer *) vbox, 6);
 
     GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr);
@@ -229,7 +229,7 @@ GtkWidget * plugin_view_new (PluginType type)
     g_signal_connect (tree, "realize", (GCallback) list_fill, aud::to_ptr (type));
     g_signal_connect (tree, "destroy", (GCallback) list_destroy, nullptr);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,  6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0);
 
     GtkWidget * config = audgui_button_new (_("_Settings"), "preferences-system", do_config, tree);
--- src/libaudgui/prefs-widget.cc.old
+++ src/libaudgui/prefs-widget.cc
@@ -200,7 +200,7 @@ static void create_label (const PreferencesWidget * widget, GtkWidget * * label,
     * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label));
     gtk_label_set_use_markup ((GtkLabel *) * label, true);
     gtk_label_set_line_wrap ((GtkLabel *) * label, true);
-    gtk_misc_set_alignment ((GtkMisc *) * label, 0, 0.5);
+    gtk_widget_set_halign (* label, GTK_ALIGN_START);
 }
 
 /* WIDGET_SPIN_BTN */
@@ -212,7 +212,7 @@ static void create_spin_button (const PreferencesWidget * widget,
     if (widget->label)
     {
         * label_pre = gtk_label_new (dgettext (domain, widget->label));
-        gtk_misc_set_alignment ((GtkMisc *) * label_pre, 1, 0.5);
+        gtk_widget_set_halign (* label_pre, GTK_ALIGN_END);
     }
 
     * spin_btn = gtk_spin_button_new_with_range (widget->data.spin_btn.min,
@@ -221,7 +221,7 @@ static void create_spin_button (const PreferencesWidget * widget,
     if (widget->data.spin_btn.right_label)
     {
         * label_past = gtk_label_new (dgettext (domain, widget->data.spin_btn.right_label));
-        gtk_misc_set_alignment ((GtkMisc *) * label_past, 0, 0.5);
+        gtk_widget_set_halign (* label_past, GTK_ALIGN_START);
     }
 
     widget_init (* spin_btn, widget);
@@ -233,13 +233,14 @@ void create_font_btn (const PreferencesWidget * widget, GtkWidget * * label,
  GtkWidget * * font_btn, const char * domain)
 {
     * font_btn = gtk_font_button_new ();
+
     gtk_font_button_set_use_font ((GtkFontButton *) * font_btn, true);
     gtk_font_button_set_use_size ((GtkFontButton *) * font_btn, true);
 
     if (widget->label)
     {
         * label = gtk_label_new (dgettext (domain, widget->label));
-        gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
+        gtk_widget_set_halign (* label, GTK_ALIGN_END);
     }
 
     if (widget->data.font_btn.title)
@@ -255,12 +256,13 @@ static void create_entry (const PreferencesWidget * widget, GtkWidget * * label,
  GtkWidget * * entry, const char * domain)
 {
     * entry = gtk_entry_new ();
+    gtk_widget_set_hexpand (* entry, true);
     gtk_entry_set_visibility ((GtkEntry *) * entry, ! widget->data.entry.password);
 
     if (widget->label)
     {
         * label = gtk_label_new (dgettext (domain, widget->label));
-        gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
+        gtk_widget_set_halign (* label, GTK_ALIGN_END);
     }
 
     widget_init (* entry, widget);
@@ -282,10 +284,12 @@ static void create_file_entry (const PreferencesWidget * widget,
         break;
     }
 
+    gtk_widget_set_hexpand (* entry, true);
+
     if (widget->label)
     {
         * label = gtk_label_new (dgettext (domain, widget->label));
-        gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
+        gtk_widget_set_halign (* label, GTK_ALIGN_END);
     }
 
     widget_init (* entry, widget);
@@ -303,8 +307,7 @@ static void combobox_update (GtkWidget * combobox, const PreferencesWidget * wid
 
     g_object_set_data ((GObject *) combobox, "comboitems", (void *) items.data);
 
-    /* no gtk_combo_box_text_clear()? */
-    gtk_list_store_clear ((GtkListStore *) gtk_combo_box_get_model ((GtkComboBox *) combobox));
+    gtk_combo_box_text_remove_all ((GtkComboBoxText *) combobox);
 
     for (const ComboItem & item : items)
         gtk_combo_box_text_append_text ((GtkComboBoxText *) combobox,
@@ -346,7 +349,7 @@ static void create_cbox (const PreferencesWidget * widget, GtkWidget * * label,
     if (widget->label)
     {
         * label = gtk_label_new (dgettext (domain, widget->label));
-        gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
+        gtk_widget_set_halign (* label, GTK_ALIGN_END);
     }
 
     g_object_set_data ((GObject *) * combobox, "combodomain", (void *) domain);
@@ -361,7 +364,6 @@ static void fill_table (GtkWidget * table,
     for (const PreferencesWidget & w : widgets)
     {
         GtkWidget * widget_left = nullptr, * widget_middle = nullptr, * widget_right = nullptr;
-        GtkAttachOptions middle_policy = (GtkAttachOptions) (GTK_FILL);
 
         switch (w.type)
         {
@@ -380,12 +382,10 @@ static void fill_table (GtkWidget * table,
 
             case PreferencesWidget::Entry:
                 create_entry (& w, & widget_left, & widget_middle, domain);
-                middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
                 break;
 
             case PreferencesWidget::FileEntry:
                 create_file_entry (& w, & widget_left, & widget_middle, domain);
-                middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
                 break;
 
             case PreferencesWidget::ComboBox:
@@ -399,16 +399,13 @@ static void fill_table (GtkWidget * table,
         int i = & w - widgets.data;
 
         if (widget_left)
-            gtk_table_attach ((GtkTable *) table, widget_left, 0, 1, i, i + 1,
-             GTK_FILL, GTK_FILL, 0, 0);
+            gtk_grid_attach ((GtkGrid *) table, widget_left, 0, i, 1, 1);
 
         if (widget_middle)
-            gtk_table_attach ((GtkTable *) table, widget_middle, 1, 2, i, i + 1,
-             middle_policy, GTK_FILL, 0, 0);
+            gtk_grid_attach ((GtkGrid *) table, widget_middle, 1, i, 1, 1);
 
         if (widget_right)
-            gtk_table_attach ((GtkTable *) table, widget_right, 2, 3, i, i + 1,
-             GTK_FILL, GTK_FILL, 0, 0);
+            gtk_grid_attach ((GtkGrid *) table, widget_right, 2, i, 1, 1);
     }
 }
 
@@ -433,13 +430,11 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
         {
             if (! child_box)
             {
-                child_box = gtk_vbox_new (false, 0);
+                child_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
                 g_object_set_data ((GObject *) widget, "child", child_box);
 
-                GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
-                gtk_box_pack_start ((GtkBox *) box, alignment, false, false, 0);
-                gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 12, 0);
-                gtk_container_add ((GtkContainer *) alignment, child_box);
+                gtk_widget_set_margin_left (child_box, 12);
+                gtk_box_pack_start ((GtkBox *) box, child_box, false, false, 0);
 
                 if (disable_child)
                     gtk_widget_set_sensitive (child_box, false);
@@ -448,10 +443,6 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
         else
             child_box = nullptr;
 
-        GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
-        gtk_alignment_set_padding ((GtkAlignment *) alignment, spacing, 0, indent, 0);
-        gtk_box_pack_start ((GtkBox *) (child_box ? child_box : box), alignment, false, false, 0);
-
         widget = nullptr;
         disable_child = false;
 
@@ -461,6 +452,9 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
         if (! w.child)
             radio_btn_group[true] = nullptr;
 
+        int pad_left = indent;
+        int pad_top = spacing;
+
         switch (w.type)
         {
             case PreferencesWidget::Button:
@@ -479,7 +473,8 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
                 if (strstr (w.label, "<b>"))
                 {
                     /* headings get double spacing and no indent */
-                    gtk_alignment_set_padding ((GtkAlignment *) alignment, 2 * spacing, 0, 0, 0);
+                    pad_left = 0;
+                    pad_top = 2 * spacing;
 
                     /* set indent for items below the heading */
                     indent = 12;
@@ -490,7 +485,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
 
                 if (icon)
                 {
-                    widget = gtk_hbox_new (false, 6);
+                    widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
                     gtk_box_pack_start ((GtkBox *) widget, icon, false, false, 0);
                     gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0);
                 }
@@ -510,7 +505,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
 
             case PreferencesWidget::SpinButton:
             {
-                widget = gtk_hbox_new (false, 6);
+                widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
                 GtkWidget * label_pre = nullptr, * spin_btn = nullptr, * label_past = nullptr;
                 create_spin_button (& w, & label_pre, & spin_btn, & label_past, domain);
@@ -533,7 +528,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
 
             case PreferencesWidget::FontButton:
             {
-                widget = gtk_hbox_new (false, 6);
+                widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
                 GtkWidget * font_btn = nullptr;
                 create_font_btn (& w, & label, & font_btn, domain);
@@ -547,9 +542,9 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
             }
 
             case PreferencesWidget::Table:
-                widget = gtk_table_new (0, 0, false);
-                gtk_table_set_col_spacings ((GtkTable *) widget, 6);
-                gtk_table_set_row_spacings ((GtkTable *) widget, 6);
+                widget = gtk_grid_new ();
+                gtk_grid_set_column_spacing ((GtkGrid *) widget, 6);
+                gtk_grid_set_row_spacing ((GtkGrid *) widget, 6);
 
                 fill_table (widget, w.data.table.widgets, domain);
 
@@ -558,7 +553,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
             case PreferencesWidget::Entry:
             case PreferencesWidget::FileEntry:
             {
-                widget = gtk_hbox_new (false, 6);
+                widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
                 GtkWidget * entry = nullptr;
 
@@ -577,7 +572,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
 
             case PreferencesWidget::ComboBox:
             {
-                widget = gtk_hbox_new (false, 6);
+                widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
                 GtkWidget * combo = nullptr;
                 create_cbox (& w, & label, & combo, domain);
@@ -592,9 +587,9 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
 
             case PreferencesWidget::Box:
                 if (w.data.box.horizontal)
-                    widget = gtk_hbox_new (false, 6);
+                    widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
                 else
-                    widget = gtk_vbox_new (false, 0);
+                    widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
                 audgui_create_widgets_with_domain (widget, w.data.box.widgets, domain);
 
@@ -608,13 +603,11 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
                 break;
 
             case PreferencesWidget::Notebook:
-                gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 0, 0);
-
                 widget = gtk_notebook_new ();
 
                 for (const NotebookTab & tab : w.data.notebook.tabs)
                 {
-                    GtkWidget * vbox = gtk_vbox_new (false, 0);
+                    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
                     gtk_container_set_border_width ((GtkContainer *) vbox, 6);
 
                     audgui_create_widgets_with_domain (vbox, tab.widgets, domain);
@@ -623,11 +616,13 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
                      gtk_label_new (dgettext (domain, tab.name)));
                 }
 
+                pad_top = 0;
+
                 break;
 
             case PreferencesWidget::Separator:
-                widget = w.data.separator.horizontal ?
-                 gtk_hseparator_new () : gtk_vseparator_new ();
+                widget = gtk_separator_new (w.data.separator.horizontal
+                 ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
                 break;
 
             default:
@@ -635,7 +630,11 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
         }
 
         if (widget)
-            gtk_container_add ((GtkContainer *) alignment, widget);
+        {
+            gtk_widget_set_margin_left (widget, pad_left);
+            gtk_widget_set_margin_top (widget, pad_top);
+            gtk_box_pack_start ((GtkBox *) (child_box ? child_box : box), widget, false, false, 0);
+        }
 
         /* wait till after first widget to set item spacing */
         if (gtk_orientable_get_orientation ((GtkOrientable *) box) == GTK_ORIENTATION_VERTICAL)
--- src/libaudgui/prefs-window.cc.old
+++ src/libaudgui/prefs-window.cc
@@ -546,29 +546,31 @@ static void create_titlestring_widgets (GtkWidget * * cbox, GtkWidget * * entry)
 
 static void * create_titlestring_table ()
 {
-    GtkWidget * grid = gtk_table_new (0, 0, false);
-    gtk_table_set_row_spacings ((GtkTable *) grid, 6);
-    gtk_table_set_col_spacings ((GtkTable *) grid, 6);
+    GtkWidget * grid = gtk_grid_new ();
+    gtk_grid_set_row_spacing ((GtkGrid *) grid, 4);
+    gtk_grid_set_column_spacing ((GtkGrid *) grid, 12);
 
     GtkWidget * label = gtk_label_new (_("Title format:"));
-    gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5);
-    gtk_table_attach ((GtkTable *) grid, label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) grid, label, 0, 0, 1, 1);
+    gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_RIGHT);
+    gtk_widget_set_halign (label, GTK_ALIGN_END);
 
     label = gtk_label_new (_("Custom string:"));
-    gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5);
-    gtk_table_attach ((GtkTable *) grid, label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) grid, label, 0, 1, 1, 1);
+    gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_RIGHT);
+    gtk_widget_set_halign (label, GTK_ALIGN_END);
 
     GtkWidget * titlestring_cbox;
     create_titlestring_widgets (& titlestring_cbox, & titlestring_entry);
-    gtk_table_attach_defaults ((GtkTable *) grid, titlestring_cbox, 1, 2, 0, 1);
-    gtk_table_attach_defaults ((GtkTable *) grid, titlestring_entry, 1, 2, 1, 2);
+    gtk_widget_set_hexpand (titlestring_cbox, true);
+    gtk_widget_set_hexpand (titlestring_entry, true);
+    gtk_grid_attach ((GtkGrid *) grid, titlestring_cbox, 1, 0, 1, 1);
+    gtk_grid_attach ((GtkGrid *) grid, titlestring_entry, 1, 1, 1, 1);
 
     GtkWidget * titlestring_help_button = gtk_button_new ();
     gtk_widget_set_can_focus (titlestring_help_button, false);
-    gtk_button_set_focus_on_click ((GtkButton *) titlestring_help_button, false);
     gtk_button_set_relief ((GtkButton *) titlestring_help_button, GTK_RELIEF_HALF);
-    gtk_table_attach ((GtkTable *) grid, titlestring_help_button, 2, 3, 1, 2,
-     GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach ((GtkGrid *) grid, titlestring_help_button, 2, 1, 1, 1);
 
     GtkWidget * titlestring_tag_menu = create_titlestring_tag_menu ();
 
@@ -583,14 +585,14 @@ static void * create_titlestring_table ()
 
 static void create_playlist_category ()
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) category_notebook, vbox);
     audgui_create_widgets (vbox, playlist_page_widgets);
 }
 
 static void create_song_info_category ()
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) category_notebook, vbox);
     audgui_create_widgets (vbox, song_info_page_widgets);
 }
@@ -633,14 +635,14 @@ static ArrayRef<ComboItem> iface_combo_fill ()
 
 static void * iface_create_prefs_box ()
 {
-    iface_prefs_box = gtk_vbox_new (false, 0);
+    iface_prefs_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     iface_fill_prefs_box ();
     return iface_prefs_box;
 }
 
 static void create_appearance_category ()
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) category_notebook, vbox);
     audgui_create_widgets (vbox, appearance_page_widgets);
 }
@@ -771,17 +773,17 @@ static void record_update (void * = nullptr, void * = nullptr)
 
 static void create_audio_category ()
 {
-    GtkWidget * audio_page_vbox = gtk_vbox_new (false, 0);
+    GtkWidget * audio_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     audgui_create_widgets (audio_page_vbox, audio_page_widgets);
     gtk_container_add ((GtkContainer *) category_notebook, audio_page_vbox);
 }
 
 static void create_connectivity_category ()
 {
-    GtkWidget * connectivity_page_vbox = gtk_vbox_new (false, 0);
+    GtkWidget * connectivity_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) category_notebook, connectivity_page_vbox);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_box_pack_start ((GtkBox *) connectivity_page_vbox, vbox, true, true, 0);
 
     audgui_create_widgets (vbox, connectivity_page_widgets);
@@ -790,6 +792,7 @@ static void create_connectivity_category ()
 static void create_plugin_category ()
 {
     plugin_notebook = gtk_notebook_new ();
+    gtk_notebook_set_scrollable ((GtkNotebook *) plugin_notebook, true);
     gtk_container_add ((GtkContainer *) category_notebook, plugin_notebook);
 
     for (const PluginCategory & category : plugin_categories)
@@ -799,7 +802,7 @@ static void create_plugin_category ()
 
 static void create_advanced_category ()
 {
-    GtkWidget * advanced_page_vbox = gtk_vbox_new (false, 0);
+    GtkWidget * advanced_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     audgui_create_widgets (advanced_page_vbox, advanced_page_widgets);
     gtk_container_add ((GtkContainer *) category_notebook, advanced_page_vbox);
 }
@@ -824,10 +827,10 @@ static void create_prefs_window ()
     gtk_container_set_border_width ((GtkContainer *) prefswin, 12);
     gtk_window_set_title ((GtkWindow *) prefswin, _("Audacious Settings"));
 
-    GtkWidget * vbox = gtk_vbox_new (false, 0);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) prefswin, vbox);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,  8);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, true, true, 0);
 
     GtkWidget * scrolledwindow = gtk_scrolled_window_new (nullptr, nullptr);
@@ -858,17 +861,17 @@ static void create_prefs_window ()
     create_plugin_category ();
     create_advanced_category ();
 
-    GtkWidget * hseparator = gtk_hseparator_new ();
+    GtkWidget * hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_box_pack_start ((GtkBox *) vbox, hseparator, false, false, 6);
 
-    hbox = gtk_hbox_new (false, 0);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,  0);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0);
 
     GtkWidget * audversionlabel = gtk_label_new (aud_version_string);
     gtk_box_pack_start ((GtkBox *) hbox, audversionlabel, false, false, 0);
     gtk_label_set_use_markup ((GtkLabel *) audversionlabel, true);
 
-    GtkWidget * prefswin_button_box = gtk_hbutton_box_new ();
+    GtkWidget * prefswin_button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_box_pack_start ((GtkBox *) hbox, prefswin_button_box, true, true, 0);
     gtk_button_box_set_layout ((GtkButtonBox *) prefswin_button_box, GTK_BUTTONBOX_END);
     gtk_box_set_spacing ((GtkBox *) prefswin_button_box, 6);
--- src/libaudgui/scaled-image.cc.old
+++ src/libaudgui/scaled-image.cc
@@ -57,7 +57,7 @@ static GdkPixbuf * get_scaled (GtkWidget * widget, int maxwidth, int maxheight)
     return scaled;
 }
 
-static int expose_cb (GtkWidget * widget, GdkEventExpose * event)
+static gboolean draw_cb (GtkWidget * widget, cairo_t * cr)
 {
     GdkRectangle rect;
     gtk_widget_get_allocation (widget, & rect);
@@ -69,10 +69,8 @@ static int expose_cb (GtkWidget * widget, GdkEventExpose * event)
         int x = (rect.width - gdk_pixbuf_get_width (scaled)) / 2;
         int y = (rect.height - gdk_pixbuf_get_height (scaled)) / 2;
 
-        cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
         gdk_cairo_set_source_pixbuf (cr, scaled, x, y);
         cairo_paint (cr);
-        cairo_destroy (cr);
     }
 
     return true;
@@ -93,7 +91,7 @@ EXPORT GtkWidget * audgui_scaled_image_new (GdkPixbuf * pixbuf)
 {
     GtkWidget * widget = gtk_drawing_area_new ();
 
-    g_signal_connect (widget, "expose-event", (GCallback) expose_cb, nullptr);
+    g_signal_connect (widget, "draw", (GCallback) draw_cb, nullptr);
 
     audgui_scaled_image_set (widget, pixbuf);
 
--- src/libaudgui/status.cc.old
+++ src/libaudgui/status.cc
@@ -37,7 +37,7 @@ static void create_progress_window ()
     gtk_window_set_resizable ((GtkWindow *) progress_window, false);
     gtk_container_set_border_width ((GtkContainer *) progress_window, 6);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_container_add ((GtkContainer *) progress_window, vbox);
 
     progress_label = gtk_label_new (nullptr);
--- src/libaudgui/url-opener.cc.old
+++ src/libaudgui/url-opener.cc
@@ -86,14 +86,14 @@ static GtkWidget * create_url_opener (bool open)
 
     g_object_set_data ((GObject *) entry, "open", GINT_TO_POINTER (open));
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     audgui_create_widgets (hbox, widgets);
 
     GtkWidget * clear_button = audgui_button_new (_("C_lear history"),
      "edit-clear", clear_cb, combo);
     gtk_box_pack_end ((GtkBox *) hbox, clear_button, false, false, 0);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, combo, false, false, 0);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0);
 
--- src/libaudgui/util.cc.old
+++ src/libaudgui/util.cc
@@ -89,12 +89,28 @@ EXPORT int audgui_get_digit_width (GtkWidget * widget)
 
 EXPORT void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y)
 {
-    gtk_widget_get_pointer (widget, x, y);
+    int xwin, ywin;
+    GdkRectangle alloc;
+
+    GdkWindow * window = gtk_widget_get_window (widget);
+    GdkDisplay * display = gdk_window_get_display (window);
+    GdkDeviceManager * manager = gdk_display_get_device_manager (display);
+    GdkDevice * device = gdk_device_manager_get_client_pointer (manager);
+
+    gdk_window_get_device_position (window, device, & xwin, & ywin, nullptr);
+    gtk_widget_get_allocation (widget, & alloc);
+
+    * x = xwin - alloc.x;
+    * y = ywin - alloc.y;
 }
 
 EXPORT void audgui_get_mouse_coords (GdkScreen * screen, int * x, int * y)
 {
-    gdk_display_get_pointer (gdk_screen_get_display (screen), nullptr, x, y, nullptr);
+    GdkDisplay * display = gdk_screen_get_display (screen);
+    GdkDeviceManager * manager = gdk_display_get_device_manager (display);
+    GdkDevice * device = gdk_device_manager_get_client_pointer (manager);
+
+    gdk_device_get_position (device, nullptr, x, y);
 }
 
 EXPORT void audgui_get_monitor_geometry (GdkScreen * screen, int x, int y, GdkRectangle * geom)
@@ -231,6 +247,18 @@ static void set_label_wrap (GtkWidget * label, void *)
         gtk_label_set_line_wrap_mode ((GtkLabel *) label, PANGO_WRAP_WORD_CHAR);
 }
 
+static const char * icon_for_message_type (GtkMessageType type)
+{
+    switch (type)
+    {
+        case GTK_MESSAGE_INFO: return "dialog-information";
+        case GTK_MESSAGE_WARNING: return "dialog-warning";
+        case GTK_MESSAGE_QUESTION: return "dialog-question";
+        case GTK_MESSAGE_ERROR: return "dialog-error";
+        default: return nullptr;
+    }
+}
+
 EXPORT GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title,
  const char * text, GtkWidget * button1, GtkWidget * button2)
 {
@@ -241,6 +269,13 @@ EXPORT GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title,
     GtkWidget * box = gtk_message_dialog_get_message_area ((GtkMessageDialog *) dialog);
     gtk_container_foreach ((GtkContainer *) box, set_label_wrap, nullptr);
 
+    const char * icon = icon_for_message_type (type);
+    if (icon)
+    {
+        GtkWidget * image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_DIALOG);
+        gtk_message_dialog_set_image ((GtkMessageDialog *) dialog, image);
+    }
+
     if (button2)
     {
         gtk_dialog_add_action_widget ((GtkDialog *) dialog, button2, GTK_RESPONSE_NONE);
