--- .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 qtmultimedia5-dev
+  - sudo apt-get install libgtk-3-dev qtbase5-dev qtmultimedia5-dev
   - sudo apt-get install libasound2-dev libavformat-dev libbinio-dev libbs2b-dev
   - sudo apt-get install libcddb2-dev libcdio-cdda-dev libcue-dev libcurl4-gnutls-dev
   - sudo apt-get install libdbus-glib-1-dev libfaad-dev libflac-dev libfluidsynth-dev
@@ -16,7 +16,7 @@ before_install:
   - sudo apt-get install libsndfile1-dev libsoxr-dev libvorbis-dev libwavpack-dev
   - sudo apt-get install libxml2-dev libadplug-dev
 install:
-  - git clone git://github.com/audacious-media-player/audacious.git audacious
+  - git clone -b master-gtk3 git://github.com/audacious-media-player/audacious.git audacious
   - cd audacious
   - ./autogen.sh
   - ./configure --prefix=/opt/aud --enable-qt
--- acinclude.m4.old
+++ acinclude.m4
@@ -165,12 +165,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
--- configure.ac.old
+++ configure.ac
@@ -455,7 +455,7 @@ ENABLE_PLUGIN_WITH_DEP(hotkey,
     auto,
     GENERAL,
     GDKX11,
-    gdk-x11-2.0)
+    gdk-x11-3.0)
 
 ENABLE_PLUGIN_WITH_DEP(aosd,
     X11 OSD,
--- src/alarm/interface.cc.old
+++ src/alarm/interface.cc
@@ -158,62 +158,71 @@ GtkWidget *create_config_notebook ()
 
     /* Page 1 */
     frame = gtk_frame_new (_("Time"));
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    grid = gtk_table_new (0, 0, false);
-    gtk_table_set_col_spacings (GTK_TABLE (grid), 6);
-    gtk_table_set_row_spacings (GTK_TABLE (grid), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    grid = gtk_grid_new ();
+    gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
+    gtk_grid_set_row_homogeneous (GTK_GRID (grid), true);
+    gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
 
     label = gtk_label_new (_("Alarm at (default):"));
-    gtk_table_attach (GTK_TABLE (grid), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_margin_right (label, 10);
+    gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
 
-    adjustment = (GtkAdjustment *) gtk_adjustment_new (6, 0, 23, 1, 10, 0);
+    adjustment = gtk_adjustment_new (6, 0, 23, 1, 10, 0);
     alarm_h_spin = gtk_spin_button_new (adjustment, 1, 0);
+    gtk_widget_set_valign (alarm_h_spin, GTK_ALIGN_CENTER);
     g_object_set_data (G_OBJECT (notebook), "alarm_h_spin", alarm_h_spin);
     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_h_spin), GTK_UPDATE_IF_VALID);
     gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_h_spin), true);
     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_h_spin), true);
-    gtk_table_attach (GTK_TABLE (grid), alarm_h_spin, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), alarm_h_spin, 1, 0, 1, 1);
 
     label = gtk_label_new (":");
-    gtk_table_attach (GTK_TABLE (grid), label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
 
-    adjustment = (GtkAdjustment *) gtk_adjustment_new (30, 0, 59, 1, 10, 0);
+    adjustment = gtk_adjustment_new (30, 0, 59, 1, 10, 0);
     alarm_m_spin = gtk_spin_button_new (adjustment, 1, 0);
+    gtk_widget_set_valign (alarm_m_spin, GTK_ALIGN_CENTER);
     g_object_set_data (G_OBJECT (notebook), "alarm_m_spin", alarm_m_spin);
     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_m_spin), GTK_UPDATE_IF_VALID);
     gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_m_spin), true);
     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_m_spin), true);
-    gtk_table_attach (GTK_TABLE (grid), alarm_m_spin, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), alarm_m_spin, 3, 0, 1, 1);
 
     label = gtk_label_new (_("h"));
-    gtk_table_attach (GTK_TABLE (grid), label, 4, 5, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
+    gtk_grid_attach (GTK_GRID (grid), label, 4, 0, 1, 1);
 
     stop_checkb = gtk_check_button_new_with_label (_("Quiet after:"));
     g_object_set_data (G_OBJECT (notebook), "stop_checkb", stop_checkb);
-    gtk_table_attach (GTK_TABLE (grid), stop_checkb, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_margin_right (stop_checkb, 10);
+    gtk_widget_set_valign (stop_checkb, GTK_ALIGN_CENTER);
+    gtk_grid_attach (GTK_GRID (grid), stop_checkb, 0, 1, 1, 1);
 
-    adjustment = (GtkAdjustment *) gtk_adjustment_new (0, 0, 100, 1, 10, 0);
+    adjustment = gtk_adjustment_new (0, 0, 100, 1, 10, 0);
     stop_h_spin = gtk_spin_button_new (adjustment, 1, 0);
+    gtk_widget_set_valign (stop_h_spin, GTK_ALIGN_CENTER);
     g_object_set_data (G_OBJECT (notebook), "stop_h_spin", stop_h_spin);
     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_h_spin), GTK_UPDATE_IF_VALID);
     gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_h_spin), true);
     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_h_spin), true);
-    gtk_table_attach (GTK_TABLE (grid), stop_h_spin, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), stop_h_spin, 1, 1, 1, 1);
 
     label = gtk_label_new (_("hours"));
-    gtk_table_attach (GTK_TABLE (grid), label, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_margin_right (label, 10);
+    gtk_grid_attach (GTK_GRID (grid), label, 2, 1, 1, 1);
 
-    adjustment = (GtkAdjustment *) gtk_adjustment_new (0, 0, 59, 1, 10, 0);
+    adjustment = gtk_adjustment_new (0, 0, 59, 1, 10, 0);
     stop_m_spin = gtk_spin_button_new (adjustment, 1, 0);
+    gtk_widget_set_valign (stop_m_spin, GTK_ALIGN_CENTER);
     g_object_set_data (G_OBJECT (notebook), "stop_m_spin", stop_m_spin);
     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_m_spin), GTK_UPDATE_IF_VALID);
     gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_m_spin), true);
     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_m_spin), true);
-    gtk_table_attach (GTK_TABLE (grid), stop_m_spin, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), stop_m_spin, 3, 1, 1, 1);
 
     label = gtk_label_new (_("minutes"));
-    gtk_table_attach (GTK_TABLE (grid), label, 4, 5, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), label, 4, 1, 1, 1);
     gtk_container_add (GTK_CONTAINER (frame), grid);
 
     label = gtk_label_new (_("Time"));
@@ -222,24 +231,25 @@ GtkWidget *create_config_notebook ()
 
     /* Page 2 */
     frame = gtk_frame_new (_("Choose the days for the alarm to come on"));
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    grid = gtk_table_new (0, 0, false);
-    gtk_table_set_col_spacings (GTK_TABLE (grid), 6);
-    gtk_table_set_row_spacings (GTK_TABLE (grid), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    grid = gtk_grid_new ();
+    gtk_grid_set_column_spacing (GTK_GRID (grid), 15);
+    gtk_grid_set_row_homogeneous (GTK_GRID (grid), true);
+    gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
 
     label = gtk_label_new (_("Day"));
-    gtk_table_attach (GTK_TABLE (grid), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
 
     label = gtk_label_new (_("Time"));
-    gtk_table_attach (GTK_TABLE (grid), label, 2, 5, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 3, 1);
 
     for (i = 0; i < 7; i ++)
     {
         widget[i] = gtk_check_button_new_with_label (_(weekdays[i]));
         g_object_set_data (G_OBJECT (notebook), day_cb[i], widget[i]);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[i]), true);
-        gtk_table_attach (GTK_TABLE (grid), widget[i], 0, 1, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+        gtk_widget_set_valign (widget[i], GTK_ALIGN_CENTER);
+        gtk_grid_attach (GTK_GRID (grid), widget[i], 0, i + 1, 1, 1);
     }
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[6]), false);
 
@@ -248,30 +258,31 @@ GtkWidget *create_config_notebook ()
         checkbutton = gtk_check_button_new_with_label (_("Default"));
         g_object_set_data (G_OBJECT (notebook), day_def[i], checkbutton);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), true);
+        gtk_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
         g_signal_connect (checkbutton, "toggled", G_CALLBACK (cb_def[i]), nullptr);
-        gtk_table_attach (GTK_TABLE (grid), checkbutton, 1, 2, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach (GTK_GRID (grid), checkbutton, 1, i + 1, 1, 1);
     }
 
     for (i = 7, j = 0; i < 14; i ++, j ++)
     {
-        adjustment = (GtkAdjustment *) gtk_adjustment_new (6, 0, 23, 1, 10, 0);
+        adjustment = gtk_adjustment_new (6, 0, 23, 1, 10, 0);
         widget[i] = gtk_spin_button_new (adjustment, 1, 0);
         g_object_set_data (G_OBJECT (notebook), day_h[j], widget[i]);
-        gtk_table_attach (GTK_TABLE (grid), widget[i], 2, 3, j + 1, j + 2, GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach (GTK_GRID (grid), widget[i], 2, j + 1, 1, 1);
     }
 
     for (i = 0; i < 7; i ++)
     {
         label = gtk_label_new (":");
-        gtk_table_attach (GTK_TABLE (grid), label, 3, 4, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach (GTK_GRID (grid), label, 3, i + 1, 1, 1);
     }
 
     for (i = 14, j = 0; i < 21; i ++, j ++)
     {
-        adjustment = (GtkAdjustment *) gtk_adjustment_new (30, 0, 59, 1, 10, 0);
+        adjustment = gtk_adjustment_new (30, 0, 59, 1, 10, 0);
         widget[i] = gtk_spin_button_new (adjustment, 1, 0);
         g_object_set_data (G_OBJECT (notebook), day_m[j], widget[i]);
-        gtk_table_attach (GTK_TABLE (grid), widget[i], 4, 5, j + 1, j + 2, GTK_FILL, GTK_FILL, 0, 0);
+        gtk_grid_attach (GTK_GRID (grid), widget[i], 4, j + 1, 1, 1);
     }
 
     label = gtk_label_new (_("Days"));
@@ -280,107 +291,113 @@ GtkWidget *create_config_notebook ()
 
 
     /* Page 3 */
-    vbox = gtk_vbox_new (false, 6);
-    hbox = gtk_hbox_new (false, 6);
+    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
     frame = gtk_frame_new (_("Fading"));
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
-    adjustment = (GtkAdjustment *) gtk_adjustment_new (120, 0, 3600, 1, 10, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
+    adjustment = gtk_adjustment_new (120, 0, 3600, 1, 10, 0);
     fading_spin = gtk_spin_button_new (adjustment, 1, 0);
     g_object_set_data (G_OBJECT (notebook), "fading_spin", fading_spin);
     gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fading_spin), true);
     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (fading_spin), GTK_UPDATE_IF_VALID);
     label = gtk_label_new (_("seconds"));
 
-    gtk_box_pack_start (GTK_BOX (hbox), fading_spin, true, true, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), label, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (hbox), fading_spin);
+    gtk_box_pack_start (GTK_BOX (hbox), label, false, false, 3);
     gtk_container_add (GTK_CONTAINER (frame), hbox);
-    gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox), frame);
 
     frame = gtk_frame_new (_("Volume"));
-    vbox2 = gtk_vbox_new (false, 6);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
+    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox2), 8);
 
     label = gtk_label_new (_("Start at"));
-    gtk_box_pack_start (GTK_BOX (vbox2), label, false, false, 0);
+    gtk_widget_set_margin_bottom (label, 2);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
+    gtk_container_add (GTK_CONTAINER (vbox2), label);
 
-    quiet_vol_scale = gtk_hscale_new ((GtkAdjustment *) gtk_adjustment_new (20, 0, 100, 1, 5, 0));
+    quiet_vol_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, gtk_adjustment_new (20, 0, 100, 1, 5, 0));
     g_object_set_data (G_OBJECT (notebook), "quiet_vol_scale", quiet_vol_scale);
     gtk_scale_set_value_pos (GTK_SCALE (quiet_vol_scale), GTK_POS_RIGHT);
     gtk_scale_set_digits (GTK_SCALE (quiet_vol_scale), 0);
     label = gtk_label_new ("%");
-    hbox2 = gtk_hbox_new (false, 6);
+    hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
     gtk_box_pack_start (GTK_BOX (hbox2), quiet_vol_scale, true, true, 0);
-    gtk_box_pack_start (GTK_BOX (hbox2), label, false, false, 0);
-    gtk_box_pack_start (GTK_BOX (vbox2), hbox2, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (hbox2), label);
+    gtk_container_add (GTK_CONTAINER (vbox2), hbox2);
 
-    separator = gtk_hseparator_new ();
-    gtk_box_pack_start (GTK_BOX (vbox2), separator, false, false, 0);
+    separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+    gtk_box_pack_start (GTK_BOX (vbox2), separator, false, false, 10);
 
     label = gtk_label_new (_("Final"));
-    gtk_box_pack_start (GTK_BOX (vbox2), label, false, false, 0);
+    gtk_widget_set_margin_bottom (label, 2);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
+    gtk_container_add (GTK_CONTAINER (vbox2), label);
 
-    vol_scale = gtk_hscale_new ((GtkAdjustment *) gtk_adjustment_new (80, 0, 100, 1, 5, 0));
+    vol_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, gtk_adjustment_new (80, 0, 100, 1, 5, 0));
     g_object_set_data (G_OBJECT (notebook), "vol_scale", vol_scale);
     gtk_scale_set_value_pos (GTK_SCALE (vol_scale), GTK_POS_RIGHT);
     gtk_scale_set_digits (GTK_SCALE (vol_scale), 0);
     label = gtk_label_new ("%");
-    hbox2 = gtk_hbox_new (false, 6);
+    hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
     gtk_box_pack_start (GTK_BOX (hbox2), vol_scale, true, true, 0);
-    gtk_box_pack_start (GTK_BOX (hbox2), label, false, false, 0);
-    gtk_box_pack_start (GTK_BOX (vbox2), hbox2, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (hbox2), label);
+    gtk_container_add (GTK_CONTAINER (vbox2), hbox2);
 
     current_button = gtk_button_new_with_label (_("Current"));
+    gtk_widget_set_margin_top (current_button, 10);
+    gtk_widget_set_halign (current_button, GTK_ALIGN_END);
     g_signal_connect (current_button, "clicked", G_CALLBACK (alarm_current_volume), nullptr);
-    gtk_box_pack_start (GTK_BOX (vbox2), current_button, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox2), current_button);
 
     gtk_container_add (GTK_CONTAINER (frame), vbox2);
-    gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox), frame);
 
     label = gtk_label_new (_("Volume"));
     gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
 
 
     /* Page 4 */
-    vbox = gtk_vbox_new (false, 6);
+    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     frame = gtk_frame_new (_("Additional Command"));
-    hbox = gtk_hbox_new (false, 6);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
     cmd_entry = gtk_entry_new ();
     g_object_set_data (G_OBJECT (notebook), "cmd_entry", cmd_entry);
     cmd_checkb = gtk_check_button_new_with_label (_("enable"));
     g_object_set_data (G_OBJECT (notebook), "cmd_checkb", cmd_checkb);
     gtk_box_pack_start (GTK_BOX (hbox), cmd_entry, true, true, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), cmd_checkb, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (hbox), cmd_checkb);
     gtk_container_add (GTK_CONTAINER (frame), hbox);
-    gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox), frame);
 
     frame = gtk_frame_new (_("Playlist (optional)"));
-    hbox = gtk_hbox_new (false, 6);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
     playlist_entry = audgui_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN, _("Select a playlist"));
     g_object_set_data (G_OBJECT (notebook), "playlist", playlist_entry);
 
     gtk_box_pack_start (GTK_BOX (hbox), playlist_entry, true, true, 0);
     gtk_container_add (GTK_CONTAINER (frame), hbox);
-    gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox), frame);
 
     frame = gtk_frame_new (_("Reminder"));
-    hbox = gtk_hbox_new (false, 6);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
     reminder_text = gtk_entry_new ();
     reminder_checkb = gtk_check_button_new_with_label (_("enable"));
     g_object_set_data (G_OBJECT (notebook), "reminder_text", reminder_text);
     g_object_set_data (G_OBJECT (notebook), "reminder_cb", reminder_checkb);
     gtk_box_pack_start (GTK_BOX (hbox), reminder_text, true, true, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), reminder_checkb, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (hbox), reminder_checkb);
     gtk_container_add (GTK_CONTAINER (frame), hbox);
-    gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
+    gtk_container_add (GTK_CONTAINER (vbox), frame);
 
     label = gtk_label_new (_("Options"));
     gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
@@ -388,7 +405,7 @@ GtkWidget *create_config_notebook ()
 
     /* Page 5 */
     frame = gtk_frame_new (_("What do these options mean?"));
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+    gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
     view = gtk_text_view_new ();
     gtk_text_view_set_editable (GTK_TEXT_VIEW (view), false);
     gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), false);
--- src/amidiplug/i_configure-fluidsynth.cc.old
+++ src/amidiplug/i_configure-fluidsynth.cc
@@ -218,9 +218,8 @@ void * create_soundfont_list ()
             g_strfreev (sffiles);
         }
 
-        soundfont_file_hbox = gtk_hbox_new (false, 2);
+        soundfont_file_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
         soundfont_file_lv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (soundfont_file_store));
-        gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (soundfont_file_lv), true);
         g_object_unref (soundfont_file_store);
         soundfont_file_lv_text_rndr = gtk_cell_renderer_text_new();
         soundfont_file_lv_fname_col = gtk_tree_view_column_new_with_attributes (
@@ -243,7 +242,7 @@ void * create_soundfont_list ()
         gtk_container_add (GTK_CONTAINER (soundfont_file_lv_sw), soundfont_file_lv);
 
         /* soundfont settings - soundfont files - buttonbox */
-        soundfont_file_bbox_vbox = gtk_vbox_new (false, 0);
+        soundfont_file_bbox_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
         soundfont_file_bbox_addbt = gtk_button_new();
         gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_addbt),
                               gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU));
--- src/amidiplug/i_fileinfo.cc.old
+++ src/amidiplug/i_fileinfo.cc
@@ -49,11 +49,14 @@ void i_fileinfo_grid_add_entry (char * field_text, char * value_text,
     GtkWidget * field, *value;
     field = gtk_label_new (field_text);
     gtk_label_set_attributes (GTK_LABEL (field), attrlist);
-    gtk_misc_set_alignment (GTK_MISC (field), 0, 0);
-    gtk_table_attach (GTK_TABLE (grid), field, 0, 1, line, line + 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_halign (field, GTK_ALIGN_START);
+    gtk_label_set_justify (GTK_LABEL (field), GTK_JUSTIFY_LEFT);
+    gtk_grid_attach (GTK_GRID (grid), field, 0, line, 1, 1);
     value = gtk_label_new (value_text);
-    gtk_misc_set_alignment (GTK_MISC (value), 0, 0);
-    gtk_table_attach (GTK_TABLE (grid), value, 1, 2, line, line + 1, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_set_halign (value, GTK_ALIGN_START);
+    gtk_label_set_justify (GTK_LABEL (value), GTK_JUSTIFY_LEFT);
+    gtk_grid_attach (GTK_GRID (grid), value, 1, line, 1, 1);
+    return;
 }
 
 
@@ -145,7 +148,7 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
     g_signal_connect (G_OBJECT (fileinfowin), "destroy", G_CALLBACK (gtk_widget_destroyed), &fileinfowin);
     gtk_container_set_border_width (GTK_CONTAINER (fileinfowin), 10);
 
-    fileinfowin_vbox = gtk_vbox_new (false, 10);
+    fileinfowin_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
     gtk_container_add (GTK_CONTAINER (fileinfowin), fileinfowin_vbox);
 
     /* pango attributes */
@@ -157,13 +160,12 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
 
     /******************
      *** TITLE LINE ***/
-    title_hbox = gtk_hbox_new (false, 5);
+    title_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), title_hbox, false, false, 0);
 
     title_icon_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) amidiplug_xpm_midiicon);
     title_icon_image = gtk_image_new_from_pixbuf (title_icon_pixbuf);
     g_object_unref (title_icon_pixbuf);
-    gtk_misc_set_alignment (GTK_MISC (title_icon_image), 0, 0);
     gtk_box_pack_start (GTK_BOX (title_hbox), title_icon_image, false, false, 0);
 
     title_name_f_label = gtk_label_new (_("Name:"));
@@ -175,12 +177,12 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
     gtk_widget_set_size_request (GTK_WIDGET (title_name_v_entry), 200, -1);
     gtk_box_pack_start (GTK_BOX (title_hbox), title_name_v_entry, true, true, 0);
 
-    fileinfowin_columns_hbox = gtk_hbox_new (false, 2);
+    fileinfowin_columns_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
     gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), fileinfowin_columns_hbox, true, true, 0);
 
     /*********************
      *** MIDI INFO BOX ***/
-    midiinfoboxes_vbox = gtk_vbox_new (false, 2);
+    midiinfoboxes_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
     gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), midiinfoboxes_vbox, false, false, 0);
 
     info_frame_tl = gtk_label_new ("");
@@ -189,10 +191,10 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
 
     info_frame = gtk_frame_new (nullptr);
     gtk_box_pack_start (GTK_BOX (midiinfoboxes_vbox), info_frame, true, true, 0);
-    info_grid = gtk_table_new (0, 0, false);
-    gtk_table_set_row_spacings (GTK_TABLE (info_grid), 2);
-    gtk_table_set_col_spacings (GTK_TABLE (info_grid), 6);
-    gtk_container_set_border_width (GTK_CONTAINER (info_grid), 6);
+    info_grid = gtk_grid_new();
+    gtk_grid_set_row_spacing (GTK_GRID (info_grid), 4);
+    gtk_grid_set_column_spacing (GTK_GRID (info_grid), 10);
+    gtk_container_set_border_width (GTK_CONTAINER (info_grid), 3);
     gtk_container_add (GTK_CONTAINER (info_frame), info_grid);
     value_gstring = g_string_new ("");
 
@@ -229,7 +231,7 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
 
     /**********************************
      *** MIDI COMMENTS/LYRICS BOXES ***/
-    miditextboxes_vbox = gtk_vbox_new (false, 2);
+    miditextboxes_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
     gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), miditextboxes_vbox, true, true, 0);
 
     text_frame_tl = gtk_label_new ("");
@@ -237,7 +239,7 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
                           _("<span size=\"smaller\"> MIDI Comments and Lyrics </span>"));
     gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), text_frame_tl, false, false, 0);
 
-    miditextboxes_paned = gtk_vpaned_new ();
+    miditextboxes_paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
     gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), miditextboxes_paned, true, true, 0);
 
     text_frame = gtk_frame_new (nullptr);
@@ -301,7 +303,7 @@ bool i_fileinfo_gui (const char * filename_uri, VFSFile & file)
 
     /**************
      *** FOOTER ***/
-    footer_hbbox = gtk_hbutton_box_new ();
+    footer_hbbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_button_box_set_layout (GTK_BUTTON_BOX (footer_hbbox), GTK_BUTTONBOX_END);
     footer_bclose = gtk_button_new_with_mnemonic (_("_Close"));
     g_signal_connect (G_OBJECT (footer_bclose), "clicked", G_CALLBACK (i_fileinfo_ev_close), fileinfowin);
--- src/aosd/aosd_ui.cc.old
+++ src/aosd/aosd_ui.cc
@@ -33,25 +33,29 @@
 #include "aosd_osd.h"
 
 
-static void chooser_get_aosd_color (GtkColorButton * chooser, aosd_color_t * color)
+static void chooser_get_aosd_color (GtkColorChooser * chooser, aosd_color_t * color)
 {
-  GdkColor gdk_color;
-  gtk_color_button_get_color (chooser, & gdk_color);
+  GdkRGBA rgba;
+  gtk_color_chooser_get_rgba (chooser, & rgba);
 
-  color->red = gdk_color.red;
-  color->green = gdk_color.green;
-  color->blue = gdk_color.blue;
-  color->alpha = gtk_color_button_get_alpha (chooser);
+  color->red = rint (rgba.red * 65535.0);
+  color->green = rint (rgba.green * 65535.0);
+  color->blue = rint (rgba.blue * 65535.0);
+  color->alpha = rint (rgba.alpha * 65535.0);
 }
 
 
-static void chooser_set_aosd_color (GtkColorButton * chooser, const aosd_color_t * color)
+static void chooser_set_aosd_color (GtkColorChooser * chooser, const aosd_color_t * color)
 {
-  GdkColor gdk_color = {0, (uint16_t) color->red, (uint16_t) color->green, (uint16_t) color->blue};
-
-  gtk_color_button_set_color (chooser, & gdk_color);
-  gtk_color_button_set_use_alpha (chooser, true);
-  gtk_color_button_set_alpha (chooser, color->alpha);
+  GdkRGBA rgba = {
+      color->red / 65535.0,
+      color->green / 65535.0,
+      color->blue / 65535.0,
+      color->alpha / 65535.0
+  };
+
+  gtk_color_chooser_set_use_alpha (chooser, true);
+  gtk_color_chooser_set_rgba (chooser, & rgba);
 }
 
 
@@ -80,16 +84,14 @@ aosd_callback_list_run ( aosd_cfg_t * cfg )
 
 static gboolean
 aosd_cb_configure_position_expose ( GtkWidget * darea ,
-                                    GdkEventExpose * event ,
+                                    cairo_t * cr ,
                                     void * coord_gp )
 {
   int coord = GPOINTER_TO_INT(coord_gp);
 
-  cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (darea));
   cairo_set_source_rgb ( cr , 0 , 0 , 0 );
   cairo_rectangle ( cr , (coord % 3) * 10 , (coord / 3) * 16 , 20 , 8 );
   cairo_fill ( cr );
-  cairo_destroy (cr);
 
   return false;
 }
@@ -156,16 +158,16 @@ aosd_ui_configure_position ( aosd_cfg_t * cfg )
   int monitors_num = gdk_screen_get_n_monitors( gdk_screen_get_default() );
   int i = 0;
 
-  pos_vbox = gtk_vbox_new( false , 4 );
+  pos_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
   gtk_container_set_border_width( GTK_CONTAINER(pos_vbox) , 6 );
 
   pos_placement_frame = gtk_frame_new( _("Placement") );
-  pos_placement_hbox = gtk_hbox_new( false , 0 );
+  pos_placement_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 0 );
   gtk_container_set_border_width( GTK_CONTAINER(pos_placement_hbox) , 6 );
   gtk_container_add( GTK_CONTAINER(pos_placement_frame) , pos_placement_hbox );
   gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_placement_frame , false , false , 0 );
 
-  pos_placement_grid = gtk_table_new (0, 0, false);
+  pos_placement_grid = gtk_grid_new();
   for ( i = 0 ; i < 9 ; i++ )
   {
     if ( i == 0 )
@@ -176,10 +178,9 @@ aosd_ui_configure_position ( aosd_cfg_t * cfg )
     pos_placement_bt_darea[i] = gtk_drawing_area_new();
     gtk_widget_set_size_request( pos_placement_bt_darea[i] , 40 , 40 );
     gtk_container_add( GTK_CONTAINER(pos_placement_bt[i]) , pos_placement_bt_darea[i] );
-    g_signal_connect( G_OBJECT(pos_placement_bt_darea[i]) , "expose-event" ,
+    g_signal_connect( G_OBJECT(pos_placement_bt_darea[i]) , "draw" ,
                       G_CALLBACK(aosd_cb_configure_position_expose) , GINT_TO_POINTER(i) );
-    gtk_table_attach_defaults( GTK_TABLE(pos_placement_grid) , pos_placement_bt[i] ,
-                               (i % 3) , (i % 3) + 1 , (i / 3) , (i / 3) + 1 );
+    gtk_grid_attach( GTK_GRID(pos_placement_grid) , pos_placement_bt[i] , (i % 3) , (i / 3) , 1 , 1 );
     g_object_set_data( G_OBJECT(pos_placement_bt[i]) , "value" , GINT_TO_POINTER(i+1) );
     if ( cfg->position.placement == (i+1) )
       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , true );
@@ -187,38 +188,38 @@ aosd_ui_configure_position ( aosd_cfg_t * cfg )
   gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_placement_grid , false , false , 0 );
   aosd_cb_list.append( pos_placement_grid , aosd_cb_configure_position_placement_commit );
 
-  gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , gtk_vseparator_new() , false , false , 6 );
+  gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , false , false , 6 );
 
-  pos_offset_grid = gtk_table_new (0, 0, false);
-  gtk_table_set_row_spacings( GTK_TABLE(pos_offset_grid) , 4 );
-  gtk_table_set_col_spacings( GTK_TABLE(pos_offset_grid) , 4 );
+  pos_offset_grid = gtk_grid_new();
+  gtk_grid_set_row_spacing( GTK_GRID(pos_offset_grid) , 4 );
+  gtk_grid_set_column_spacing( GTK_GRID(pos_offset_grid) , 4 );
   pos_offset_x_label = gtk_label_new( _( "Relative X offset:" ) );
-  gtk_misc_set_alignment( GTK_MISC(pos_offset_x_label) , 0 , 0.5 );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_label , 0 , 1 , 0 , 1 );
+  gtk_widget_set_halign( pos_offset_x_label , GTK_ALIGN_START );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_x_label , 0 , 0 , 1 , 1 );
   pos_offset_x_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_x_spinbt) , cfg->position.offset_x );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_spinbt , 1 , 2 , 0 , 1 );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_x_spinbt , 1 , 0 , 1 , 1 );
   g_object_set_data( G_OBJECT(pos_offset_grid) , "offx" , pos_offset_x_spinbt );
   pos_offset_y_label = gtk_label_new( _( "Relative Y offset:" ) );
-  gtk_misc_set_alignment( GTK_MISC(pos_offset_y_label) , 0 , 0.5 );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_label , 0 , 1 , 1 , 2 );
+  gtk_widget_set_halign( pos_offset_y_label , GTK_ALIGN_START );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_y_label , 0 , 1 , 1 , 1 );
   pos_offset_y_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_y_spinbt) , cfg->position.offset_y );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_spinbt , 1 , 2 , 1 , 2 );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_y_spinbt , 1 , 1 , 1 , 1 );
   g_object_set_data( G_OBJECT(pos_offset_grid) , "offy" , pos_offset_y_spinbt );
   pos_maxsize_width_label = gtk_label_new( _("Max OSD width:") );
-  gtk_misc_set_alignment( GTK_MISC(pos_maxsize_width_label) , 0 , 0.5 );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_label , 0 , 1 , 2 , 3 );
+  gtk_widget_set_halign( pos_maxsize_width_label , GTK_ALIGN_START );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_maxsize_width_label , 0 , 2 , 1 , 1 );
   pos_maxsize_width_spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
   g_object_set_data( G_OBJECT(pos_offset_grid) , "maxsize_width" , pos_maxsize_width_spinbt );
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_maxsize_width_spinbt) , cfg->position.maxsize_width );
-  gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_spinbt , 1 , 2 , 2 , 3 );
+  gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_maxsize_width_spinbt , 1 , 2 , 1 , 1 );
   gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_offset_grid , false , false , 0 );
   aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_offset_commit );
   aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_maxsize_commit );
 
   pos_multimon_frame = gtk_frame_new( _("Multi-Monitor options") );
-  pos_multimon_hbox = gtk_hbox_new( false , 4 );
+  pos_multimon_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
   gtk_container_set_border_width( GTK_CONTAINER(pos_multimon_hbox) , 6 );
   gtk_container_add( GTK_CONTAINER(pos_multimon_frame), pos_multimon_hbox );
   pos_multimon_label = gtk_label_new( _("Display OSD using:") );
@@ -244,7 +245,7 @@ static GtkWidget *
 aosd_ui_configure_animation_timing ( char * label_string )
 {
   GtkWidget *hbox, *desc_label, *spinbt;
-  hbox = gtk_hbox_new( false , 4 );
+  hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
   desc_label = gtk_label_new( label_string );
   spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
   gtk_box_pack_start( GTK_BOX(hbox) , desc_label , false , false , 0 );
@@ -274,10 +275,10 @@ aosd_ui_configure_animation ( aosd_cfg_t * cfg )
   GtkWidget *ani_timing_fadein_widget, *ani_timing_fadeout_widget, *ani_timing_stay_widget;
   GtkSizeGroup *sizegroup;
 
-  ani_vbox = gtk_vbox_new( false , 0 );
+  ani_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
   gtk_container_set_border_width( GTK_CONTAINER(ani_vbox) , 6 );
 
-  ani_timing_hbox = gtk_hbox_new( false , 0 );
+  ani_timing_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 0 );
   ani_timing_frame = gtk_frame_new( _("Timing (ms)") );
   gtk_container_set_border_width( GTK_CONTAINER(ani_timing_hbox) , 6 );
   gtk_container_add( GTK_CONTAINER(ani_timing_frame) , ani_timing_hbox );
@@ -287,12 +288,12 @@ aosd_ui_configure_animation ( aosd_cfg_t * cfg )
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
     G_OBJECT(ani_timing_stay_widget),"spinbt")) , cfg->animation.timing_display );
   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_stay_widget , true , true , 0 );
-  gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , false , false , 4 );
+  gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , false , false , 4 );
   ani_timing_fadein_widget = aosd_ui_configure_animation_timing( _("Fade in:") );
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
     G_OBJECT(ani_timing_fadein_widget),"spinbt")) , cfg->animation.timing_fadein );
   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadein_widget , true , true , 0 );
-  gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , false , false , 4 );
+  gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , false , false , 4 );
   ani_timing_fadeout_widget = aosd_ui_configure_animation_timing( _("Fade out:") );
   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
     G_OBJECT(ani_timing_fadeout_widget),"spinbt")) , cfg->animation.timing_fadeout );
@@ -328,7 +329,7 @@ static void
 aosd_cb_configure_text_font_commit ( GtkWidget * fontbt , aosd_cfg_t * cfg )
 {
   int fontnum = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(fontbt) , "fontnum" ));
-  GtkColorButton * chooser;
+  GtkColorChooser * chooser;
 
   cfg->text.fonts_name[fontnum] =
    String (gtk_font_button_get_font_name (GTK_FONT_BUTTON (fontbt)));
@@ -336,10 +337,10 @@ aosd_cb_configure_text_font_commit ( GtkWidget * fontbt , aosd_cfg_t * cfg )
   cfg->text.fonts_draw_shadow[fontnum] = gtk_toggle_button_get_active(
     GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(fontbt),"use_shadow")) );
 
-  chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "color");
+  chooser = (GtkColorChooser *) g_object_get_data ((GObject *) fontbt, "color");
   chooser_get_aosd_color (chooser, & cfg->text.fonts_color[fontnum]);
 
-  chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "shadow_color");
+  chooser = (GtkColorChooser *) g_object_get_data ((GObject *) fontbt, "shadow_color");
   chooser_get_aosd_color (chooser, & cfg->text.fonts_shadow_color[fontnum]);
 }
 
@@ -354,14 +355,14 @@ aosd_ui_configure_text ( aosd_cfg_t * cfg )
   GtkWidget *tex_font_shadow_colorbt[3];
   int i = 0;
 
-  tex_vbox = gtk_vbox_new( false , 4 );
+  tex_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
   gtk_container_set_border_width( GTK_CONTAINER(tex_vbox) , 6 );
 
   tex_font_frame = gtk_frame_new( _("Fonts") );
-  tex_font_grid = gtk_table_new (0, 0, false);
+  tex_font_grid = gtk_grid_new();
   gtk_container_set_border_width( GTK_CONTAINER(tex_font_grid) , 6 );
-  gtk_table_set_row_spacings( GTK_TABLE(tex_font_grid) , 4 );
-  gtk_table_set_col_spacings( GTK_TABLE(tex_font_grid) , 4 );
+  gtk_grid_set_row_spacing ( GTK_GRID(tex_font_grid) , 4 );
+  gtk_grid_set_column_spacing ( GTK_GRID(tex_font_grid) , 4 );
   for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
   {
     char *label_str = g_strdup_printf( _("Font %i:") , i+1 );
@@ -373,16 +374,17 @@ aosd_ui_configure_text ( aosd_cfg_t * cfg )
     gtk_font_button_set_use_font( GTK_FONT_BUTTON(tex_font_fontbt[i]) , false );
     gtk_font_button_set_use_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , false );
     gtk_font_button_set_font_name( GTK_FONT_BUTTON(tex_font_fontbt[i]) , cfg->text.fonts_name[i] );
+    gtk_widget_set_hexpand( tex_font_fontbt[i] , true );
 
     tex_font_colorbt[i] = gtk_color_button_new ();
-    chooser_set_aosd_color ((GtkColorButton *) tex_font_colorbt[i],
+    chooser_set_aosd_color ((GtkColorChooser *) tex_font_colorbt[i],
      & cfg->text.fonts_color[i]);
 
     tex_font_shadow_togglebt[i] = gtk_toggle_button_new_with_label( _("Shadow") );
     gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) , false );
 
     tex_font_shadow_colorbt[i] = gtk_color_button_new ();
-    chooser_set_aosd_color ((GtkColorButton *) tex_font_shadow_colorbt[i],
+    chooser_set_aosd_color ((GtkColorChooser *) tex_font_shadow_colorbt[i],
      & cfg->text.fonts_shadow_color[i]);
 
     gtk_widget_set_sensitive( tex_font_shadow_colorbt[i] , false );
@@ -391,11 +393,11 @@ aosd_ui_configure_text ( aosd_cfg_t * cfg )
                       tex_font_shadow_colorbt[i] );
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) ,
       cfg->text.fonts_draw_shadow[i] );
-    gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_label[i] , 0 , 1 , i , i + 1 );
-    gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_fontbt[i] , 1 , 2 , i , i + 1 );
-    gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_colorbt[i] , 2 , 3 , i , i + 1 );
-    gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_togglebt[i] , 3 , 4 , i , i + 1 );
-    gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_colorbt[i] , 4 , 5 , i , i + 1 );
+    gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_label[i] , 0 , 0 , 1 , 1 );
+    gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_fontbt[i] , 1 , 0 , 1 , 1 );
+    gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_colorbt[i] , 2 , 0 , 1 , 1 );
+    gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_shadow_togglebt[i] , 3 , 0 , 1 , 1 );
+    gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_shadow_colorbt[i] , 4 , 0 , 1 , 1 );
     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "fontnum" , GINT_TO_POINTER(i) );
     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "color" , tex_font_colorbt[i] );
     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "use_shadow" , tex_font_shadow_togglebt[i] );
@@ -429,7 +431,7 @@ static void
 aosd_cb_configure_decoration_color_commit ( GtkWidget * colorbt , aosd_cfg_t * cfg )
 {
   aosd_color_t color;
-  chooser_get_aosd_color ((GtkColorButton *) colorbt, & color);
+  chooser_get_aosd_color ((GtkColorChooser *) colorbt, & color);
 
   int colnum = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(colorbt) , "colnum" ) );
   cfg->decoration.colors[colnum] = color;
@@ -450,7 +452,7 @@ aosd_ui_configure_decoration ( aosd_cfg_t * cfg )
   GtkWidget *dec_rstyleopts_frame, *dec_rstyleopts_grid;
   int colors_max_num = 0, i = 0;
 
-  dec_hbox = gtk_hbox_new( false , 4 );
+  dec_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
   gtk_container_set_border_width( GTK_CONTAINER(dec_hbox) , 6 );
 
   /* decoration style model
@@ -494,31 +496,31 @@ aosd_ui_configure_decoration ( aosd_cfg_t * cfg )
   gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_lv_frame , false , false , 0 );
   aosd_cb_list.append( dec_rstyle_lv , aosd_cb_configure_decoration_style_commit );
 
-  dec_rstyle_hbox = gtk_vbox_new( false , 4 );
+  dec_rstyle_hbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
   gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_hbox , true , true , 0 );
 
   /* in colors_max_num now there's the maximum number of colors used by decoration styles */
   dec_rstyleopts_frame = gtk_frame_new( _("Colors") );
-  dec_rstyleopts_grid = gtk_table_new (0, 0, false);
+  dec_rstyleopts_grid = gtk_grid_new();
   gtk_container_set_border_width( GTK_CONTAINER(dec_rstyleopts_grid) , 6 );
-  gtk_table_set_row_spacings( GTK_TABLE(dec_rstyleopts_grid) , 4 );
-  gtk_table_set_col_spacings( GTK_TABLE(dec_rstyleopts_grid) , 8 );
+  gtk_grid_set_row_spacing( GTK_GRID(dec_rstyleopts_grid) , 4 );
+  gtk_grid_set_column_spacing( GTK_GRID(dec_rstyleopts_grid) , 8 );
   gtk_container_add( GTK_CONTAINER(dec_rstyleopts_frame) , dec_rstyleopts_grid );
   for ( i = 0 ; i < colors_max_num ; i++ )
   {
     GtkWidget *hbox, *label;
     char *label_str = nullptr;
-    hbox = gtk_hbox_new( false , 4 );
+    hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
     label_str = g_strdup_printf( _("Color %i:") , i+1 );
     label = gtk_label_new( label_str );
     g_free( label_str );
 
     GtkWidget * colorbt = gtk_color_button_new ();
-    chooser_set_aosd_color ((GtkColorButton *) colorbt, & cfg->decoration.colors[i]);
+    chooser_set_aosd_color ((GtkColorChooser *) colorbt, & cfg->decoration.colors[i]);
 
     gtk_box_pack_start( GTK_BOX(hbox) , label , false , false , 0 );
     gtk_box_pack_start( GTK_BOX(hbox) , colorbt , false , false , 0 );
-    gtk_table_attach_defaults( GTK_TABLE(dec_rstyleopts_grid) , hbox , (i % 3) , (i % 3) + 1, (i / 3) , (i / 3) + 1);
+    gtk_grid_attach( GTK_GRID(dec_rstyleopts_grid) , hbox , (i % 3) , (i / 3) , 1 , 1 );
     g_object_set_data( G_OBJECT(colorbt) , "colnum" , GINT_TO_POINTER(i) );
     aosd_cb_list.append( colorbt , aosd_cb_configure_decoration_color_commit );
   }
@@ -572,7 +574,7 @@ aosd_ui_configure_trigger ( aosd_cfg_t * cfg )
   gtk_notebook_set_show_tabs( GTK_NOTEBOOK(tri_event_nb) , false );
   gtk_notebook_set_show_border( GTK_NOTEBOOK(tri_event_nb) , false );
 
-  tri_hbox = gtk_hbox_new( false , 4 );
+  tri_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
   gtk_container_set_border_width( GTK_CONTAINER(tri_hbox) , 6 );
 
   /* trigger model
@@ -590,19 +592,19 @@ aosd_ui_configure_trigger ( aosd_cfg_t * cfg )
     gtk_list_store_set( tri_event_store , &iter ,
       0 , _(aosd_trigger_get_name( i )) ,
       1 , i , 2 , i , -1 );
-    vbox = gtk_vbox_new( false , 0 );
+    vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
     gtk_container_set_border_width( GTK_CONTAINER(vbox) , 6 );
     label = gtk_label_new( _(aosd_trigger_get_desc( i )) );
     gtk_label_set_line_wrap( GTK_LABEL(label) , true );
     gtk_label_set_max_width_chars( GTK_LABEL(label), 40 );
-    gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
+    gtk_widget_set_halign( label , GTK_ALIGN_START );
     checkbt = gtk_check_button_new_with_label( _("Enable trigger") );
     if ( cfg->trigger.enabled[i] )
       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , true );
     else
       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , false );
     gtk_box_pack_start( GTK_BOX(vbox) , checkbt , false , false , 0 );
-    gtk_box_pack_start( GTK_BOX(vbox) , gtk_hseparator_new() , false , false , 4 );
+    gtk_box_pack_start( GTK_BOX(vbox) , gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) , false , false , 4 );
     gtk_box_pack_start( GTK_BOX(vbox) , label , false , false , 0 );
     frame = gtk_frame_new( nullptr );
     gtk_container_add( GTK_CONTAINER(frame) , vbox );
@@ -698,10 +700,10 @@ aosd_ui_configure_misc ( aosd_cfg_t * cfg )
   GtkWidget *mis_transp_status_frame, *mis_transp_status_hbox;
   GtkWidget *mis_transp_status_img, *mis_transp_status_label;
 
-  mis_vbox = gtk_vbox_new( false , 0 );
+  mis_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
   gtk_container_set_border_width( GTK_CONTAINER(mis_vbox) , 6 );
 
-  mis_transp_vbox = gtk_vbox_new( false , 0 );
+  mis_transp_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
   mis_transp_frame = gtk_frame_new( _("Transparency") );
   gtk_container_set_border_width( GTK_CONTAINER(mis_transp_vbox) , 6 );
   gtk_container_add( GTK_CONTAINER(mis_transp_frame) , mis_transp_vbox );
@@ -718,16 +720,15 @@ aosd_ui_configure_misc ( aosd_cfg_t * cfg )
   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_fake_rbt , true , true , 0 );
   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_real_rbt , true , true , 0 );
 
-  mis_transp_status_hbox = gtk_hbox_new( false , 4 );
+  mis_transp_status_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
   mis_transp_status_frame = gtk_frame_new( nullptr );
   gtk_container_set_border_width( GTK_CONTAINER(mis_transp_status_hbox) , 3 );
   gtk_container_add( GTK_CONTAINER(mis_transp_status_frame) , mis_transp_status_hbox );
   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_status_frame , true , true , 0 );
 
   mis_transp_status_img = gtk_image_new();
-  gtk_misc_set_alignment( GTK_MISC(mis_transp_status_img) , 0.5 , 0 );
   mis_transp_status_label = gtk_label_new( "" );
-  gtk_misc_set_alignment( GTK_MISC(mis_transp_status_label) , 0 , 0.5 );
+  gtk_widget_set_halign( mis_transp_status_label , GTK_ALIGN_START );
   gtk_label_set_line_wrap( GTK_LABEL(mis_transp_status_label) , true );
   gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_img , false , false , 0 );
   gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_label , true , true , 0 );
--- src/blur_scope/blur_scope.cc.old
+++ src/blur_scope/blur_scope.cc
@@ -71,13 +71,14 @@ public:
 
 private:
     void resize (int w, int h);
+    void draw_to_cairo (cairo_t * cr);
     void draw ();
 
     void blur ();
     void draw_vert_line (int x, int y1, int y2);
 
     static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event, void * user);
-    static gboolean expose_event (GtkWidget * widget, GdkEventExpose * event, void * user);
+    static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, void * user);
 
     GtkWidget * area = nullptr;
     int width = 0, height = 0, stride = 0, image_size = 0;
@@ -113,17 +114,22 @@ void BlurScope::resize (int w, int h)
     corner = image + stride + 1;
 }
 
-void BlurScope::draw ()
+void BlurScope::draw_to_cairo (cairo_t * cr)
 {
-    if (! area || ! gtk_widget_get_window (area))
-        return;
-
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (area));
     cairo_surface_t * surf = cairo_image_surface_create_for_data
      ((unsigned char *) image, CAIRO_FORMAT_RGB24, width, height, stride << 2);
     cairo_set_source_surface (cr, surf, 0, 0);
     cairo_paint (cr);
     cairo_surface_destroy (surf);
+}
+
+void BlurScope::draw ()
+{
+    if (! area || ! gtk_widget_get_window (area))
+        return;
+
+    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (area));
+    draw_to_cairo (cr);
     cairo_destroy (cr);
 }
 
@@ -133,9 +139,9 @@ gboolean BlurScope::configure_event (GtkWidget * widget, GdkEventConfigure * eve
     return true;
 }
 
-gboolean BlurScope::expose_event (GtkWidget * widget, GdkEventExpose * event, void * user)
+gboolean BlurScope::draw_cb (GtkWidget * widget, cairo_t * cr, void * user)
 {
-    ((BlurScope *) user)->draw ();
+    ((BlurScope *) user)->draw_to_cairo (cr);
     return true;
 }
 
@@ -143,7 +149,7 @@ void * BlurScope::get_gtk_widget ()
 {
     area = gtk_drawing_area_new ();
 
-    g_signal_connect (area, "expose-event", (GCallback) expose_event, this);
+    g_signal_connect (area, "draw_cb", (GCallback) draw_cb, this);
     g_signal_connect (area, "configure-event", (GCallback) configure_event, this);
     g_signal_connect (area, "destroy", (GCallback) gtk_widget_destroyed, & area);
 
@@ -212,17 +218,25 @@ void BlurScope::render_mono_pcm (const float * pcm)
 
 static void color_set_cb (GtkWidget * chooser)
 {
-    GdkColor gdk_color;
-    gtk_color_button_get_color ((GtkColorButton *) chooser, & gdk_color);
-    bscope_color = ((gdk_color.red & 0xff00) << 8) | (gdk_color.green & 0xff00) | (gdk_color.blue >> 8);
+    GdkRGBA rgba;
+    gtk_color_chooser_get_rgba ((GtkColorChooser *) chooser, & rgba);
+
+    int red = round (rgba.red * 255);
+    int green = round (rgba.green * 255);
+    int blue = round (rgba.blue * 255);
+    bscope_color = (red << 16) | (green << 8) | blue;
 }
 
 static void /* GtkWidget */ * bscope_get_color_chooser ()
 {
-    GdkColor gdk_color = {0, (uint16_t) ((bscope_color & 0xff0000) >> 8),
-     (uint16_t) (bscope_color & 0xff00), (uint16_t) ((bscope_color & 0xff) << 8)};
-    GtkWidget * chooser = gtk_color_button_new_with_color (& gdk_color);
-    gtk_color_button_set_use_alpha ((GtkColorButton *) chooser, false);
+    GdkRGBA rgba = {
+        ((bscope_color & 0xff0000) >> 16) / 255.0,
+        ((bscope_color & 0xff00) >> 8) / 255.0,
+        (bscope_color & 0xff) / 255.0
+    };
+
+    GtkWidget * chooser = gtk_color_button_new_with_rgba (& rgba);
+    gtk_color_chooser_set_use_alpha ((GtkColorChooser *) chooser, false);
 
     g_signal_connect (chooser, "color-set", (GCallback) color_set_cb, nullptr);
 
--- src/cairo-spectrum/cairo-spectrum.cc.old
+++ src/cairo-spectrum/cairo-spectrum.cc
@@ -123,41 +123,6 @@ void CairoSpectrum::clear ()
         gtk_widget_queue_draw (spect_widget);
 }
 
-static void rgb_to_hsv (float r, float g, float b, float * h, float * s, float * v)
-{
-    float max, min;
-
-    max = r;
-    if (g > max)
-        max = g;
-    if (b > max)
-        max = b;
-
-    min = r;
-    if (g < min)
-        min = g;
-    if (b < min)
-        min = b;
-
-    * v = max;
-
-    if (max == min)
-    {
-        * h = 0;
-        * s = 0;
-        return;
-    }
-
-    if (r == max)
-        * h = 1 + (g - b) / (max - min);
-    else if (g == max)
-        * h = 3 + (b - r) / (max - min);
-    else
-        * h = 5 + (r - g) / (max - min);
-
-    * s = (max - min) / max;
-}
-
 static void hsv_to_rgb (float h, float s, float v, float * r, float * g, float * b)
 {
     for (; h >= 2; h -= 2)
@@ -186,18 +151,15 @@ static void hsv_to_rgb (float h, float s, float v, float * r, float * g, float *
     * b = v * (1 - s * (1 - * b));
 }
 
-static void get_color (GtkWidget * widget, int i, float * r, float * g, float * b)
+static void get_color (gint i, gfloat * r, gfloat * g, gfloat * b)
 {
-    GdkColor * c = (gtk_widget_get_style (widget))->base + GTK_STATE_SELECTED;
-    float h, s, v;
-
-    rgb_to_hsv (c->red / 65535.0, c->green / 65535.0, c->blue / 65535.0, & h, & s, & v);
+    gfloat h, s, v, n;
 
-    if (s < 0.1) /* monochrome theme? use blue instead */
-        h = 4.6;
+    h = 4.6; /* hard-coded to blue due to repeatedly broken theming in GTK3 */
 
-    s = 1 - 0.9 * i / (bands - 1);
-    v = 0.75 + 0.25 * i / (bands - 1);
+    n = i / (gfloat) (bands - 1);
+    s = 1 - 0.9 * n;
+    v = 0.75 + 0.25 * n;
 
     hsv_to_rgb (h, s, v, r, g, b);
 }
@@ -218,7 +180,7 @@ static void draw_visualizer (GtkWidget *widget, cairo_t *cr)
         int x = ((width / bands) * i) + 2;
         float r, g, b;
 
-        get_color (widget, i, & r, & g, & b);
+        get_color (i, & r, & g, & b);
         cairo_set_source_rgb (cr, r, g, b);
         cairo_rectangle (cr, x + 1, height - (bars[i] * height / 40),
          (width / bands) - 1, (bars[i] * height / 40));
@@ -239,14 +201,11 @@ static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event)
     return true;
 }
 
-static gboolean draw_event (GtkWidget * widget)
+static gboolean draw_event (GtkWidget * widget, cairo_t * cr, GtkWidget * area)
 {
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
-
     draw_background (widget, cr);
     draw_visualizer (widget, cr);
 
-    cairo_destroy (cr);
     return true;
 }
 
@@ -255,7 +214,7 @@ void * CairoSpectrum::get_gtk_widget ()
     GtkWidget *area = gtk_drawing_area_new();
     spect_widget = area;
 
-    g_signal_connect(area, "expose-event", (GCallback) draw_event, nullptr);
+    g_signal_connect(area, "draw", (GCallback) draw_event, nullptr);
     g_signal_connect(area, "configure-event", (GCallback) configure_event, nullptr);
     g_signal_connect(area, "destroy", (GCallback) gtk_widget_destroyed, & spect_widget);
 
--- src/glspectrum/gl-spectrum.cc.old
+++ src/glspectrum/gl-spectrum.cc
@@ -246,7 +246,7 @@ static void draw_bars ()
     glPopMatrix ();
 }
 
-static gboolean draw_cb (GtkWidget * widget)
+static gboolean draw_cb (GtkWidget * widget, cairo_t * cr)
 {
 #ifdef GDK_WINDOWING_X11
     if (! s_context)
@@ -417,12 +417,11 @@ void * GLSpectrum::get_gtk_widget ()
 
     s_widget = gtk_drawing_area_new ();
 
-    g_signal_connect (s_widget, "expose-event", (GCallback) draw_cb, nullptr);
+    g_signal_connect (s_widget, "draw", (GCallback) draw_cb, nullptr);
     g_signal_connect (s_widget, "realize", (GCallback) widget_realized, nullptr);
     g_signal_connect (s_widget, "destroy", (GCallback) widget_destroyed, nullptr);
     g_signal_connect (s_widget, "configure-event", (GCallback) widget_resize, nullptr);
 
-    /* Disable GTK double buffering */
     gtk_widget_set_double_buffered (s_widget, false);
 
     return s_widget;
--- src/gtkui/columns.cc.old
+++ src/gtkui/columns.cc
@@ -301,7 +301,7 @@ void * pw_col_create_chooser ()
             avail.append (i, false);
     }
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_widget_set_size_request (hbox, -1, audgui_get_dpi () * 5 / 4);
 
     GtkWidget * scroll = gtk_scrolled_window_new (nullptr, nullptr);
@@ -315,7 +315,7 @@ void * pw_col_create_chooser ()
     audgui_list_add_column (avail_list, _("Available columns"), 0, G_TYPE_STRING, -1);
     gtk_container_add ((GtkContainer *) scroll, avail_list);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_box_pack_start ((GtkBox *) hbox, vbox, false, false, 0);
 
     GtkWidget * button = gtk_button_new ();
--- src/gtkui/layout.cc.old
+++ src/gtkui/layout.cc
@@ -98,8 +98,9 @@ static int item_by_name (Item * item, const char * name)
 GtkWidget * layout_new ()
 {
     g_return_val_if_fail (! layout, nullptr);
-    layout = gtk_alignment_new (0, 0, 1, 1);
-    gtk_alignment_set_padding ((GtkAlignment *) layout, 3, 3, 3, 3);
+    layout = gtk_frame_new (nullptr);
+    gtk_frame_set_shadow_type ((GtkFrame *) layout, GTK_SHADOW_NONE);
+    gtk_container_set_border_width ((GtkContainer *) layout, 3);
     NULL_ON_DESTROY (layout);
     return layout;
 }
@@ -188,7 +189,7 @@ static GtkWidget * vbox_new (GtkWidget * widget, const char * name)
 {
     g_return_val_if_fail (widget && name, nullptr);
 
-    GtkWidget * vbox = gtk_vbox_new (false, 2);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
 
     GtkWidget * ebox = gtk_event_box_new ();
     gtk_box_pack_start ((GtkBox *) vbox, ebox, false, false, 0);
@@ -198,7 +199,7 @@ static GtkWidget * vbox_new (GtkWidget * widget, const char * name)
     GtkWidget * label = gtk_label_new (nullptr);
     CharPtr markup (g_markup_printf_escaped ("<small><b>%s</b></small>", name));
     gtk_label_set_markup ((GtkLabel *) label, markup);
-    gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
     gtk_container_add ((GtkContainer *) ebox, label);
 
     gtk_box_pack_start ((GtkBox *) vbox, widget, true, true, 0);
@@ -228,10 +229,13 @@ static void restore_size_cb (GtkPaned * paned, GdkRectangle *, RestoreSizeData *
 
 static GtkWidget * paned_new (bool vertical, bool after, int w, int h)
 {
-    GtkWidget * paned = vertical ? gtk_vpaned_new () : gtk_hpaned_new ();
+    GtkWidget * paned = gtk_paned_new (vertical ? GTK_ORIENTATION_VERTICAL :
+     GTK_ORIENTATION_HORIZONTAL);
 
-    GtkWidget * mine = gtk_alignment_new (0, 0, 1, 1);
-    GtkWidget * next = gtk_alignment_new (0, 0, 1, 1);
+    GtkWidget * mine = gtk_frame_new (nullptr);
+    GtkWidget * next = gtk_frame_new (nullptr);
+    gtk_frame_set_shadow_type ((GtkFrame *) mine, GTK_SHADOW_NONE);
+    gtk_frame_set_shadow_type ((GtkFrame *) next, GTK_SHADOW_NONE);
     gtk_paned_pack1 ((GtkPaned *) paned, after ? next : mine, after, false);
     gtk_paned_pack2 ((GtkPaned *) paned, after ? mine : next, ! after, false);
 
--- src/gtkui/ui_gtk.cc.old
+++ src/gtkui/ui_gtk.cc
@@ -779,15 +779,17 @@ bool GtkUI::init ()
     accel = gtk_accel_group_new ();
     gtk_window_add_accel_group ((GtkWindow *) window, accel);
 
-    vbox_outer = gtk_vbox_new (false, 0);
+    vbox_outer = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_container_add ((GtkContainer *) window, vbox_outer);
 
-    menu_box = gtk_hbox_new (false, 0);
+    menu_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_box_pack_start ((GtkBox *) vbox_outer, menu_box, false, false, 0);
 
     toolbar = gtk_toolbar_new ();
     gtk_toolbar_set_style ((GtkToolbar *) toolbar, GTK_TOOLBAR_ICONS);
     gtk_toolbar_set_show_arrow ((GtkToolbar *) toolbar, false);
+    GtkStyleContext * context = gtk_widget_get_style_context (toolbar);
+    gtk_style_context_add_class (context, GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
     gtk_box_pack_start ((GtkBox *) vbox_outer, toolbar, false, false, 0);
 
     /* search button */
@@ -823,12 +825,13 @@ bool GtkUI::init ()
     gtk_tool_item_set_expand (boxitem1, true);
     gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem1, -1);
 
-    GtkWidget * box1 = gtk_hbox_new (false, 0);
+    GtkWidget * box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_container_add ((GtkContainer *) boxitem1, box1);
 
-    slider = gtk_hscale_new (nullptr);
+    slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, nullptr);
     gtk_scale_set_draw_value ((GtkScale *) slider, false);
     gtk_widget_set_size_request (slider, audgui_get_dpi () * 5 / 4, -1);
+    gtk_widget_set_valign (slider, GTK_ALIGN_CENTER);
     gtk_widget_set_can_focus (slider, false);
     gtk_box_pack_start ((GtkBox *) box1, slider, true, true, 6);
 
@@ -852,7 +855,7 @@ bool GtkUI::init ()
     GtkToolItem * boxitem2 = gtk_tool_item_new ();
     gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem2, -1);
 
-    GtkWidget * box2 = gtk_hbox_new (false, 0);
+    GtkWidget * box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_container_add ((GtkContainer *) boxitem2, box2);
 
     volume = gtk_volume_button_new ();
@@ -873,7 +876,7 @@ bool GtkUI::init ()
     GtkWidget * layout = layout_new ();
     gtk_box_pack_start ((GtkBox *) vbox_outer, layout, true, true, 0);
 
-    vbox = gtk_vbox_new (false, 6);
+    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     layout_add_center (vbox);
 
     gtk_box_pack_start ((GtkBox *) vbox, pl_notebook_new (), true, true, 0);
@@ -954,15 +957,13 @@ void GtkUI::cleanup ()
 
 static void menu_position_cb (GtkMenu *, int * x, int * y, int * push, void * button)
 {
-    GtkAllocation alloc;
     int xorig, yorig, xwin, ywin;
 
-    gtk_widget_get_allocation ((GtkWidget *) button, & alloc);
     gdk_window_get_origin (gtk_widget_get_window (window), & xorig, & yorig);
     gtk_widget_translate_coordinates ((GtkWidget *) button, window, 0, 0, & xwin, & ywin);
 
     * x = xorig + xwin;
-    * y = yorig + ywin + alloc.height;
+    * y = yorig + ywin + gtk_widget_get_allocated_height ((GtkWidget *) button);
     * push = true;
 }
 
--- src/gtkui/ui_infoarea.cc.old
+++ src/gtkui/ui_infoarea.cc
@@ -136,26 +136,13 @@ void InfoAreaVis::clear ()
 
 static void clear (GtkWidget * widget, cairo_t * cr)
 {
-    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_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, 0, 0.25, 0.25, 0.25);
+    cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.15, 0.15, 0.15);
+    cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.1, 0.1, 0.1);
     cairo_pattern_add_color_stop_rgb (gradient, 1, 0, 0, 0);
 
     cairo_set_source (cr, gradient);
@@ -187,42 +174,6 @@ static void draw_text (GtkWidget * widget, cairo_t * cr, int x, int y, int
 
 /****************************************************************************/
 
-static void rgb_to_hsv (float r, float g, float b, float * h, float * s,
- float * v)
-{
-    float max, min;
-
-    max = r;
-    if (g > max)
-        max = g;
-    if (b > max)
-        max = b;
-
-    min = r;
-    if (g < min)
-        min = g;
-    if (b < min)
-        min = b;
-
-    * v = max;
-
-    if (max == min)
-    {
-        * h = 0;
-        * s = 0;
-        return;
-    }
-
-    if (r == max)
-        * h = 1 + (g - b) / (max - min);
-    else if (g == max)
-        * h = 3 + (b - r) / (max - min);
-    else
-        * h = 5 + (r - g) / (max - min);
-
-    * s = (max - min) / max;
-}
-
 static void hsv_to_rgb (float h, float s, float v, float * r, float * g,
  float * b)
 {
@@ -252,15 +203,11 @@ static void hsv_to_rgb (float h, float s, float v, float * r, float * g,
     * b = v * (1 - s * (1 - * b));
 }
 
-static void get_color (GtkWidget * widget, int i, float * r, float * g, float * b)
+static void get_color (int i, float * r, float * g, float * b)
 {
-    auto & c = (gtk_widget_get_style (widget))->base[GTK_STATE_SELECTED];
     float h, s, v;
 
-    rgb_to_hsv (c.red / 65535.0, c.green / 65535.0, c.blue / 65535.0, & h, & s, & v);
-
-    if (s < 0.1) /* monochrome theme? use blue instead */
-        h = 4.6;
+    h = 4.6; /* hard-coded to blue due to repeatedly broken theming in GTK3 */
 
     s = 1 - 0.9 * i / (VIS_BANDS - 1);
     v = 0.75 + 0.25 * i / (VIS_BANDS - 1);
@@ -268,10 +215,8 @@ static void get_color (GtkWidget * widget, int i, float * r, float * g, float *
     hsv_to_rgb (h, s, v, r, g, b);
 }
 
-static int expose_vis_cb (GtkWidget * widget, GdkEventExpose * event)
+static gboolean draw_vis_cb (GtkWidget * widget, cairo_t * cr)
 {
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
-
     clear (widget, cr);
 
     for (int i = 0; i < VIS_BANDS; i++)
@@ -281,7 +226,7 @@ static int expose_vis_cb (GtkWidget * widget, GdkEventExpose * event)
         int m = aud::min (VIS_CENTER + v, HEIGHT);
 
         float r, g, b;
-        get_color (widget, i, & r, & g, & b);
+        get_color (i, & r, & g, & b);
 
         cairo_set_source_rgb (cr, r, g, b);
         cairo_rectangle (cr, x, VIS_CENTER - v, BAND_WIDTH, v);
@@ -292,7 +237,6 @@ static int expose_vis_cb (GtkWidget * widget, GdkEventExpose * event)
         cairo_fill (cr);
     }
 
-    cairo_destroy (cr);
     return true;
 }
 
@@ -347,16 +291,15 @@ static void draw_title (cairo_t * cr)
          0.7, 0.7, area->last_alpha, "9", area->last_album);
 }
 
-static int expose_cb (GtkWidget * widget, GdkEventExpose * event)
+static gboolean draw_cb (GtkWidget * widget, cairo_t * cr)
 {
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+    g_return_val_if_fail (area, false);
 
     clear (widget, cr);
 
     draw_album_art (cr);
     draw_title (cr);
 
-    cairo_destroy (cr);
     return true;
 }
 
@@ -478,7 +421,7 @@ void ui_infoarea_show_vis (bool show)
         gtk_widget_set_size_request (vis.widget, VIS_WIDTH, HEIGHT);
         gtk_box_pack_start ((GtkBox *) area->box, vis.widget, false, false, 0);
 
-        g_signal_connect (vis.widget, "expose-event", (GCallback) expose_vis_cb, nullptr);
+        g_signal_connect (vis.widget, "draw", (GCallback) draw_vis_cb, nullptr);
         gtk_widget_show (vis.widget);
 
         aud_visualizer_add (& vis);
@@ -520,13 +463,13 @@ GtkWidget * ui_infoarea_new ()
     compute_sizes ();
 
     area = new UIInfoArea ();
-    area->box = gtk_hbox_new (false, 0);
+    area->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
     area->main = gtk_drawing_area_new ();
     gtk_widget_set_size_request (area->main, HEIGHT, HEIGHT);
     gtk_box_pack_start ((GtkBox *) area->box, area->main, true, true, 0);
 
-    g_signal_connect (area->main, "expose-event", (GCallback) expose_cb, nullptr);
+    g_signal_connect (area->main, "draw", (GCallback) draw_cb, nullptr);
 
     hook_associate ("tuple change", (HookFunction) ui_infoarea_set_title, nullptr);
     hook_associate ("playback ready", (HookFunction) ui_infoarea_playback_start, nullptr);
--- src/gtkui/ui_playlist_notebook.cc.old
+++ src/gtkui/ui_playlist_notebook.cc
@@ -59,6 +59,7 @@ void apply_column_widths (GtkWidget * treeview)
     {
         GtkTreeViewColumn * col = gtk_tree_view_get_column ((GtkTreeView *) treeview, i);
         gtk_tree_view_column_set_fixed_width (col, pw_col_widths[pw_cols[i]]);
+        gtk_tree_view_column_set_expand (col, false);
     }
 }
 
@@ -115,39 +116,16 @@ static void close_button_cb (GtkWidget * button, void * data)
     audgui_confirm_playlist_delete (aud::from_ptr<Playlist> (data));
 }
 
-static void close_button_style_set (GtkWidget * button)
-{
-    int w, h;
-    gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
-     GTK_ICON_SIZE_MENU, & w, & h);
-    gtk_widget_set_size_request (button, w + 2, h + 2);
-}
-
 static GtkWidget * make_close_button (GtkWidget * ebox, Playlist list)
 {
     GtkWidget * button = gtk_button_new ();
     GtkWidget * image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU);
     gtk_button_set_image ((GtkButton *) button, image);
     gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
-    gtk_button_set_focus_on_click ((GtkButton *) button, false);
-    gtk_widget_set_name (button, "gtkui-tab-close-button");
+    gtk_widget_set_can_focus (button, false);
 
     g_signal_connect (button, "clicked", (GCallback) close_button_cb, aud::to_ptr (list));
 
-    gtk_rc_parse_string (
-     "style \"gtkui-tab-close-button-style\" {"
-     " GtkButton::default-border = {0, 0, 0, 0}"
-     " GtkButton::default-outside-border = {0, 0, 0, 0}"
-     " GtkButton::inner-border = {0, 0, 0, 0}"
-     " GtkWidget::focus-padding = 0"
-     " GtkWidget::focus-line-width = 0"
-     " xthickness = 0"
-     " ythickness = 0 }"
-     "widget \"*.gtkui-tab-close-button\" style \"gtkui-tab-close-button-style\""
-    );
-
-    g_signal_connect (button, "style-set", (GCallback) close_button_style_set, nullptr);
-
     gtk_widget_show (button);
 
     return button;
@@ -302,7 +280,7 @@ static void create_tab (int list_idx, Playlist list)
     GtkWidget * ebox = gtk_event_box_new ();
     gtk_event_box_set_visible_window ((GtkEventBox *) ebox, false);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 2);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
 
     GtkWidget * label = gtk_label_new ("");
     update_tab_label ((GtkLabel *) label, list);
--- src/gtkui/ui_statusbar.cc.old
+++ src/gtkui/ui_statusbar.cc
@@ -135,7 +135,7 @@ static void ui_statusbar_destroy_cb ()
 
 GtkWidget * ui_statusbar_new ()
 {
-    GtkWidget * hbox = gtk_hbox_new (false, 3);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
     GtkWidget * status = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 0.0, nullptr);
     GtkWidget * length = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 1.0, nullptr);
 
--- src/hotkey/gui.cc.old
+++ src/hotkey/gui.cc
@@ -324,16 +324,18 @@ KeyControls* add_event_controls(KeyControls* list,
     }
 
     controls->combobox = gtk_combo_box_text_new();
+    gtk_widget_set_hexpand(controls->combobox, true);
     for (i=0;i<EVENT_MAX;i++)
     {
         gtk_combo_box_text_append_text((GtkComboBoxText *) controls->combobox, _(event_desc[i]));
     }
     gtk_combo_box_set_active(GTK_COMBO_BOX(controls->combobox), controls->hotkey.event);
-    gtk_table_attach_defaults (GTK_TABLE (grid), controls->combobox, 0, 1, row, row + 1);
+    gtk_grid_attach (GTK_GRID (grid), controls->combobox, 0, row, 1, 1);
 
 
     controls->keytext = gtk_entry_new ();
-    gtk_table_attach_defaults (GTK_TABLE (grid), controls->keytext, 1, 2, row, row + 1);
+    gtk_widget_set_hexpand (controls->keytext, true);
+    gtk_grid_attach (GTK_GRID (grid), controls->keytext, 1, row, 1, 1);
     gtk_editable_set_editable(GTK_EDITABLE(controls->keytext), false);
 
 
@@ -351,7 +353,7 @@ KeyControls* add_event_controls(KeyControls* list,
     controls->button = gtk_button_new();
     gtk_button_set_image (GTK_BUTTON (controls->button),
      gtk_image_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_BUTTON));
-    gtk_table_attach_defaults (GTK_TABLE (grid), controls->button, 2, 3, row, row + 1);
+    gtk_grid_attach (GTK_GRID (grid), controls->button, 2, row, 1, 1);
     g_signal_connect (G_OBJECT (controls->button), "clicked",
             G_CALLBACK (clear_keyboard), controls);
 
@@ -363,7 +365,6 @@ void *make_config_widget ()
 {
     KeyControls *current_controls;
     GtkWidget *main_vbox, *hbox;
-    GtkWidget *alignment;
     GtkWidget *frame;
     GtkWidget *label;
     GtkWidget *image;
@@ -379,18 +380,15 @@ void *make_config_widget ()
 
     ungrab_keys();
 
-    main_vbox = gtk_vbox_new (false, 4);
+    main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
 
-    alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
-    gtk_box_pack_start (GTK_BOX (main_vbox), alignment, false, true, 0);
-    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 4, 0, 0, 0);
-    hbox = gtk_hbox_new (false, 2);
-    gtk_container_add (GTK_CONTAINER (alignment), hbox);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+    gtk_box_pack_start (GTK_BOX (main_vbox), hbox, false, true, 0);
     image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_DIALOG);
     gtk_box_pack_start (GTK_BOX (hbox), image, false, true, 0);
     label = gtk_label_new (_("Press a key combination inside a text field.\nYou can also bind mouse buttons."));
     gtk_box_pack_start (GTK_BOX (hbox), label, true, true, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
 
     label = gtk_label_new (nullptr);
     gtk_label_set_markup (GTK_LABEL (label), _("Hotkeys:"));
@@ -398,27 +396,23 @@ void *make_config_widget ()
     gtk_frame_set_label_widget (GTK_FRAME (frame), label);
     gtk_box_pack_start (GTK_BOX (main_vbox), frame, true, true, 0);
     gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
-    alignment = gtk_alignment_new (0, 0, 1, 0);
-    gtk_container_add (GTK_CONTAINER (frame), alignment);
-    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3);
 
-    grid = gtk_table_new (0, 0, false);
-    gtk_table_set_col_spacings (GTK_TABLE (grid), 2);
-    gtk_container_add (GTK_CONTAINER (alignment), grid);
+    grid = gtk_grid_new ();
+    gtk_container_set_border_width (GTK_CONTAINER (grid), 3);
+    gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
+    gtk_container_add (GTK_CONTAINER (frame), grid);
 
     label = gtk_label_new (nullptr);
     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
-    gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
     gtk_label_set_markup (GTK_LABEL (label),
             _("<b>Action:</b>"));
-    gtk_table_attach_defaults (GTK_TABLE (grid), label, 0, 1, 0, 1);
+    gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
 
     label = gtk_label_new (nullptr);
     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
-    gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
     gtk_label_set_markup (GTK_LABEL (label),
             _("<b>Key Binding:</b>"));
-    gtk_table_attach_defaults (GTK_TABLE (grid), label, 1, 2, 0, 1);
+    gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
 
 
     hotkey = &(plugin_cfg->first);
@@ -457,10 +451,10 @@ void *make_config_widget ()
     add_event_controls(current_controls, grid, i, &temphotkey);
 
 
-    hbox = gtk_hbox_new (false, 0);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_box_pack_start (GTK_BOX (main_vbox), hbox, false, true, 0);
 
-    button_box = gtk_hbutton_box_new ();
+    button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_box_pack_start (GTK_BOX (hbox), button_box, false, true, 0);
     gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_START);
     gtk_box_set_spacing (GTK_BOX (button_box), 4);
@@ -520,9 +514,9 @@ static void clear_keyboard (GtkWidget *widget, void * data)
             gtk_container_remove( GTK_CONTAINER(c->grid) , c->keytext);
             gtk_container_remove( GTK_CONTAINER(c->grid) , c->button);
 
-            gtk_table_attach_defaults (GTK_TABLE (c->grid), c->combobox, 0, 1, row, row + 1);
-            gtk_table_attach_defaults (GTK_TABLE (c->grid), c->keytext, 1, 2, row, row + 1);
-            gtk_table_attach_defaults (GTK_TABLE (c->grid), c->button, 2, 3, row, row + 1);
+            gtk_grid_attach (GTK_GRID (c->grid), c->combobox, 0, row, 1, 1);
+            gtk_grid_attach (GTK_GRID (c->grid), c->keytext, 1, row, 1, 1);
+            gtk_grid_attach (GTK_GRID (c->grid), c->button, 2, row, 1, 1);
 
             g_object_unref(c->combobox);
             g_object_unref(c->keytext);
--- src/ladspa/plugin.cc.old
+++ src/ladspa/plugin.cc
@@ -424,7 +424,7 @@ static void configure_plugin (LoadedPlugin & loaded)
     {
         ControlData & control = plugin.controls[i];
 
-        GtkWidget * hbox = gtk_hbox_new (false, 6);
+        GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
         gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
 
         if (control.is_toggle)
@@ -472,10 +472,10 @@ static void * make_config_widget ()
 {
     int dpi = audgui_get_dpi ();
 
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_widget_set_size_request (vbox, 5 * dpi, 4 * dpi);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
 
     GtkWidget * label = gtk_label_new (_("Module paths:"));
@@ -486,17 +486,17 @@ static void * make_config_widget ()
      _("<small>Separate multiple paths with a colon.\n"
      "These paths are searched in addition to LADSPA_PATH.\n"
      "After adding new paths, press Enter to scan for new plugins.</small>"));
-    gtk_misc_set_padding ((GtkMisc *) label, 12, 6);
-    gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
+    gtk_widget_set_margin_left (label, 12);
+    gtk_widget_set_halign (label, GTK_ALIGN_START);
     gtk_box_pack_start ((GtkBox *) vbox, label, 0, 0, 0);
 
     GtkWidget * entry = gtk_entry_new ();
     gtk_box_pack_start ((GtkBox *) hbox, entry, 1, 1, 0);
 
-    hbox = gtk_hbox_new (false, 6);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox, hbox, 1, 1, 0);
 
-    GtkWidget * vbox2 = gtk_vbox_new (false, 6);
+    GtkWidget * vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
 
     label = gtk_label_new (_("Available plugins:"));
@@ -509,13 +509,13 @@ static void * make_config_widget ()
     plugin_list = create_plugin_list ();
     gtk_container_add ((GtkContainer *) scrolled, plugin_list);
 
-    GtkWidget * hbox2 = gtk_hbox_new (false, 6);
+    GtkWidget * hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
 
     GtkWidget * enable_button = gtk_button_new_with_label (_("Enable"));
     gtk_box_pack_end ((GtkBox *) hbox2, enable_button, 0, 0, 0);
 
-    vbox2 = gtk_vbox_new (false, 6);
+    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
     gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
 
     label = gtk_label_new (_("Enabled plugins:"));
@@ -528,7 +528,7 @@ static void * make_config_widget ()
     loaded_list = create_loaded_list ();
     gtk_container_add ((GtkContainer *) scrolled, loaded_list);
 
-    hbox2 = gtk_hbox_new (false, 6);
+    hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
 
     GtkWidget * disable_button = gtk_button_new_with_label (_("Disable"));
--- src/lyricwiki/lyricwiki.cc.old
+++ src/lyricwiki/lyricwiki.cc
@@ -334,7 +334,7 @@ static GtkWidget * build_widget ()
     GtkWidget * scrollview = gtk_scrolled_window_new (nullptr, nullptr);
     gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrollview, GTK_SHADOW_IN);
     gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrollview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
 
     gtk_container_add ((GtkContainer *) scrollview, (GtkWidget *) textview);
     gtk_box_pack_start ((GtkBox *) vbox, scrollview, true, true, 0);
@@ -345,7 +345,7 @@ static GtkWidget * build_widget ()
     gtk_text_buffer_create_tag (textbuffer, "size_x_large", "scale", PANGO_SCALE_X_LARGE, nullptr);
     gtk_text_buffer_create_tag (textbuffer, "style_italic", "style", PANGO_STYLE_ITALIC, 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);
 
     edit_button = gtk_button_new_with_mnemonic (_("Edit lyrics ..."));
--- src/playlist-manager/playlist-manager.cc.old
+++ src/playlist-manager/playlist-manager.cc
@@ -192,7 +192,7 @@ static void destroy_cb (GtkWidget * window)
 
 void * PlaylistManager::get_gtk_widget ()
 {
-    GtkWidget * playman_vbox = gtk_vbox_new (false, 6);
+    GtkWidget * playman_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
 
     /* ListView */
     GtkWidget * playman_pl_lv = audgui_list_new (& callbacks, nullptr, Playlist::n_playlists ());
@@ -214,7 +214,7 @@ void * PlaylistManager::get_gtk_widget ()
     gtk_box_pack_start ((GtkBox *) playman_vbox, playman_pl_lv_sw, true, true, 0);
 
     /* ButtonBox */
-    GtkWidget * playman_button_hbox = gtk_hbox_new (false, 6);
+    GtkWidget * playman_button_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     GtkWidget * new_button = audgui_button_new (_("_New"), "document-new",
      [] (void *) { Playlist::new_playlist (); }, nullptr);
     GtkWidget * delete_button = audgui_button_new (_("_Remove"), "edit-delete", delete_cb, nullptr);
--- src/search-tool/search-tool.cc.old
+++ src/search-tool/search-tool.cc
@@ -773,11 +773,11 @@ bool SearchTool::init ()
 
 void * SearchTool::get_gtk_widget ()
 {
-    GtkWidget * vbox = gtk_vbox_new (false, 6);
+    GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
 
     entry = gtk_entry_new ();
     gtk_entry_set_icon_from_icon_name ((GtkEntry *) entry, GTK_ENTRY_ICON_PRIMARY, "edit-find");
-    (void) _("Search library");  // translated string is used in GTK3 branch
+    gtk_entry_set_placeholder_text ((GtkEntry *) entry, _("Search library"));
     g_signal_connect (entry, "destroy", (GCallback) gtk_widget_destroyed, & entry);
     gtk_box_pack_start ((GtkBox *) vbox, entry, false, false, 0);
 
@@ -814,7 +814,7 @@ void * SearchTool::get_gtk_widget ()
     gtk_widget_set_no_show_all (stats_label, true);
     gtk_box_pack_start ((GtkBox *) vbox, stats_label, false, false, 0);
 
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     gtk_box_pack_end ((GtkBox *) vbox, hbox, false, false, 0);
 
     GtkWidget * file_entry = audgui_file_entry_new
--- src/skins/menus.cc.old
+++ src/skins/menus.cc
@@ -295,7 +295,7 @@ static void position_menu (GtkMenu * menu, int * x, int * y, gboolean * push_in,
     audgui_get_monitor_geometry (gtk_widget_get_screen ((GtkWidget *) menu), pos->x, pos->y, & geom);
 
     GtkRequisition request;
-    gtk_widget_size_request ((GtkWidget *) menu, & request);
+    gtk_widget_get_preferred_size ((GtkWidget *) menu, nullptr, & request);
 
     if (pos->leftward)
         * x = aud::max (pos->x - request.width, geom.x);
--- src/skins/search-select.cc.old
+++ src/skins/search-select.cc
@@ -76,39 +76,43 @@ void action_playlist_search_and_select ()
      _("Cancel"), GTK_RESPONSE_REJECT, _("Search"), GTK_RESPONSE_ACCEPT, nullptr);
 
     /* help text and logo */
-    GtkWidget * hbox = gtk_hbox_new (false, 6);
+    GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
     GtkWidget * logo = gtk_image_new_from_icon_name ("edit-find", GTK_ICON_SIZE_DIALOG);
     GtkWidget * helptext = gtk_label_new (_("Select entries in playlist by filling one or more "
      "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how "
      "regular expressions work, simply insert a literal portion of what you're searching for."));
+    gtk_label_set_max_width_chars ((GtkLabel *) helptext, 70);
     gtk_label_set_line_wrap ((GtkLabel *) helptext, true);
     gtk_box_pack_start ((GtkBox *) hbox, logo, false, false, 0);
     gtk_box_pack_start ((GtkBox *) hbox, helptext, false, false, 0);
 
     /* title */
     GtkWidget * label_title = gtk_label_new (_("Title:"));
-    gtk_misc_set_alignment ((GtkMisc *) label_title, 1, 0.5);
     GtkWidget * entry_title = gtk_entry_new ();
+    gtk_widget_set_hexpand (entry_title, true);
+    gtk_widget_set_halign (label_title, GTK_ALIGN_START);
     g_signal_connect (entry_title, "key-press-event", (GCallback) search_kp_cb, dialog);
 
     /* album */
     GtkWidget * label_album = gtk_label_new (_("Album:"));
-    gtk_misc_set_alignment ((GtkMisc *) label_album, 1, 0.5);
     GtkWidget * entry_album = gtk_entry_new ();
+    gtk_widget_set_hexpand (entry_album, true);
+    gtk_widget_set_halign (label_album, GTK_ALIGN_START);
     g_signal_connect (entry_album, "key-press-event", (GCallback) search_kp_cb, dialog);
 
     /* artist */
     GtkWidget * label_performer = gtk_label_new (_("Artist:"));
-    gtk_misc_set_alignment ((GtkMisc *) label_performer, 1, 0.5);
     GtkWidget * entry_performer = gtk_entry_new ();
+    gtk_widget_set_hexpand (entry_performer, true);
+    gtk_widget_set_halign (label_performer, GTK_ALIGN_START);
     g_signal_connect (entry_performer, "key-press-event", (GCallback) search_kp_cb, dialog);
 
     /* file name */
     GtkWidget * label_file_name = gtk_label_new (_("File Name:"));
-    gtk_misc_set_alignment ((GtkMisc *) label_file_name, 1, 0.5);
     GtkWidget * entry_file_name = gtk_entry_new ();
-    g_signal_connect (entry_file_name, "key-press-event",
-     (GCallback) search_kp_cb, dialog);
+    gtk_widget_set_hexpand (entry_file_name, true);
+    gtk_widget_set_halign (label_file_name, GTK_ALIGN_START);
+    g_signal_connect (entry_file_name, "key-press-event", (GCallback) search_kp_cb, dialog);
 
     /* some options that control behaviour */
     GtkWidget * checkbt_clearprevsel = gtk_check_button_new_with_label (
@@ -127,21 +131,22 @@ void action_playlist_search_and_select ()
      (GCallback) search_cbt_cb, checkbt_autoenqueue);
 
     /* place fields in grid */
-    GtkTable * grid = (GtkTable *) gtk_table_new (0, 0, false);
-    gtk_table_set_row_spacings (grid, 6);
-    gtk_table_set_col_spacings (grid, 6);
-    gtk_table_attach_defaults (grid, hbox, 0, 2, 0, 1);
-    gtk_table_attach (grid, label_title, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach_defaults (grid, entry_title, 1, 2, 1, 2);
-    gtk_table_attach (grid, label_album, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach_defaults (grid, entry_album, 1, 2, 2, 3);
-    gtk_table_attach (grid, label_performer, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach_defaults (grid, entry_performer, 1, 2, 3, 4);
-    gtk_table_attach (grid, label_file_name, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
-    gtk_table_attach_defaults (grid, entry_file_name, 1, 2, 4, 5);
-    gtk_table_attach_defaults (grid, checkbt_clearprevsel, 0, 2, 5, 6);
-    gtk_table_attach_defaults (grid, checkbt_autoenqueue, 0, 2, 6, 7);
-    gtk_table_attach_defaults (grid, checkbt_newplaylist, 0, 2, 7, 8);
+    GtkGrid * grid = (GtkGrid *) gtk_grid_new ();
+    gtk_grid_set_row_spacing (grid, 2);
+    gtk_widget_set_margin_bottom (hbox, 8);
+    gtk_widget_set_margin_top (checkbt_clearprevsel, 8);
+    gtk_grid_attach (grid, hbox, 0, 0, 2, 1);
+    gtk_grid_attach (grid, label_title, 0, 1, 1, 1);
+    gtk_grid_attach (grid, entry_title, 1, 1, 1, 1);
+    gtk_grid_attach (grid, label_album, 0, 2, 1, 1);
+    gtk_grid_attach (grid, entry_album, 1, 2, 1, 1);
+    gtk_grid_attach (grid, label_performer, 0, 3, 1, 1);
+    gtk_grid_attach (grid, entry_performer, 1, 3, 1, 1);
+    gtk_grid_attach (grid, label_file_name, 0, 4, 1, 1);
+    gtk_grid_attach (grid, entry_file_name, 1, 4, 1, 1);
+    gtk_grid_attach (grid, checkbt_clearprevsel, 0, 5, 2, 1);
+    gtk_grid_attach (grid, checkbt_autoenqueue, 0, 6, 2, 1);
+    gtk_grid_attach (grid, checkbt_newplaylist, 0, 7, 2, 1);
 
     gtk_container_set_border_width ((GtkContainer *) grid, 5);
     gtk_container_add ((GtkContainer *) gtk_dialog_get_content_area
--- src/skins/skinselector.cc.old
+++ src/skins/skinselector.cc
@@ -183,6 +183,11 @@ static void skin_view_on_cursor_changed (GtkTreeView * treeview)
     GtkTreeIter iter;
 
     auto selection = gtk_tree_view_get_selection (treeview);
+
+    /* workaround for Gnome bug #679291 */
+    if (! selection)
+        return;
+
     if (! gtk_tree_selection_get_selected (selection, & model, & iter))
         return;
 
@@ -199,7 +204,6 @@ void skin_view_realize (GtkTreeView * treeview)
 {
     gtk_widget_show_all ((GtkWidget *) treeview);
 
-    gtk_tree_view_set_rules_hint (treeview, true);
     gtk_tree_view_set_headers_visible (treeview, false);
 
     GtkListStore * store = gtk_list_store_new (SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF,
--- src/skins/view.cc.old
+++ src/skins/view.cc
@@ -245,13 +245,13 @@ void view_apply_show_remaining ()
     mainwin_update_song_info ();
 }
 
-static GdkRegion * scale_mask (const Index<GdkRectangle> & mask, int scale)
+static cairo_region_t * scale_mask (const Index<GdkRectangle> & mask, int scale)
 {
-    GdkRegion * region = nullptr;
+    cairo_region_t * region = nullptr;
 
     for (auto & rect : mask)
     {
-        GdkRectangle scaled = {
+        cairo_rectangle_int_t scaled = {
             rect.x * scale,
             rect.y * scale,
             rect.width * scale,
@@ -259,9 +259,9 @@ static GdkRegion * scale_mask (const Index<GdkRectangle> & mask, int scale)
         };
 
         if (region)
-            gdk_region_union_with_rect (region, & scaled);
+            cairo_region_union_rectangle (region, & scaled);
         else
-            region = gdk_region_rectangle (& scaled);
+            region = cairo_region_create_rectangle (& scaled);
     }
 
     return region;
--- src/skins/widget.cc.old
+++ src/skins/widget.cc
@@ -55,7 +55,7 @@ void Widget::set_drawable (GtkWidget * widget)
 {
     m_drawable = widget;
     g_signal_connect (widget, "realize", (GCallback) Widget::realize_cb, this);
-    g_signal_connect (widget, "expose-event", (GCallback) Widget::draw_cb, this);
+    g_signal_connect (widget, "draw", (GCallback) Widget::draw_cb, this);
 
     if (! m_widget)
     {
@@ -98,28 +98,30 @@ void Widget::add_drawable (int width, int height)
 
 void Widget::draw_now ()
 {
-    if (m_drawable && gtk_widget_is_drawable (m_drawable))
-        draw_cb (m_drawable, nullptr, this);
-}
+    if (! m_drawable || ! gtk_widget_is_drawable (m_drawable))
+        return;
 
-gboolean Widget::draw_cb (GtkWidget * widget, GdkEventExpose * event, Widget * me)
-{
-    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+    cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (m_drawable));
 
-    if (! gtk_widget_get_has_window (widget))
+    if (! gtk_widget_get_has_window (m_drawable))
     {
         GtkAllocation alloc;
-        gtk_widget_get_allocation (widget, & alloc);
+        gtk_widget_get_allocation (m_drawable, & alloc);
         cairo_translate (cr, alloc.x, alloc.y);
         cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
         cairo_clip (cr);
     }
 
+    draw_cb (m_drawable, cr, this);
+
+    cairo_destroy (cr);
+}
+
+gboolean Widget::draw_cb (GtkWidget * widget, cairo_t * cr, Widget * me)
+{
     if (me->m_scale != 1)
         cairo_scale (cr, me->m_scale, me->m_scale);
 
     me->draw (cr);
-
-    cairo_destroy (cr);
     return false;
 }
--- src/skins/widget.h.old
+++ src/skins/widget.h
@@ -68,7 +68,7 @@ private:
     static void realize_cb (GtkWidget * widget, Widget * me)
         { me->realize (); }
 
-    static gboolean draw_cb (GtkWidget * widget, GdkEventExpose * event, Widget * me);
+    static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, Widget * me);
 
     static gboolean keypress_cb (GtkWidget * widget, GdkEventKey * event, Widget * me)
         { return me->keypress (event); }
--- src/skins/window.cc.old
+++ src/skins/window.cc
@@ -33,7 +33,6 @@ void Window::apply_shape ()
 
 void Window::realize ()
 {
-    gdk_window_set_back_pixmap (gtk_widget_get_window (gtk ()), nullptr, false);
     apply_shape ();
 }
 
@@ -44,11 +43,11 @@ bool Window::button_press (GdkEventButton * event)
         return false;
 
     if (m_is_moving)
-        return true;
+        return false;
 
     dock_move_start (m_id, event->x_root, event->y_root);
     m_is_moving = true;
-    return true;
+    return false;
 }
 
 bool Window::button_release (GdkEventButton * event)
@@ -57,16 +56,16 @@ bool Window::button_release (GdkEventButton * event)
         return false;
 
     m_is_moving = false;
-    return true;
+    return false;
 }
 
 bool Window::motion (GdkEventMotion * event)
 {
     if (! m_is_moving)
-        return true;
+        return false;
 
     dock_move (event->x_root, event->y_root);
-    return true;
+    return false;
 }
 
 bool Window::close ()
@@ -108,12 +107,6 @@ Window::Window (int id, int * x, int * y, int w, int h, bool shaded) :
      GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
     gtk_window_add_accel_group ((GtkWindow *) window, menu_get_accel_group ());
 
-    /* We set None as the background pixmap in order to avoid flickering.
-     * Setting a blank GtkStyle prevents GTK 2.x from overriding this. */
-    GtkStyle * style = gtk_style_new ();
-    gtk_widget_set_style (window, style);
-    g_object_unref (style);
-
     set_input (window);
     set_drawable (window);
     set_scale (config.scale);
@@ -144,7 +137,7 @@ void Window::resize (int w, int h)
     dock_set_size (m_id, w, h);
 }
 
-void Window::set_shapes (GdkRegion * shape, GdkRegion * sshape)
+void Window::set_shapes (cairo_region_t * shape, cairo_region_t * sshape)
 {
     m_shape.capture (shape);
     m_sshape.capture (sshape);
--- src/skins/window.h.old
+++ src/skins/window.h
@@ -40,7 +40,7 @@ public:
     ~Window ();
 
     void resize (int w, int h);
-    void set_shapes (GdkRegion * shape, GdkRegion * sshape);
+    void set_shapes (cairo_region_t * shape, cairo_region_t * sshape);
     bool is_shaded () { return m_is_shaded; }
     void set_shaded (bool shaded);
     void put_widget (bool shaded, Widget * widget, int x, int y);
@@ -68,7 +68,7 @@ private:
     bool m_is_shaded = false;
     bool m_is_moving = false;
     GtkWidget * m_normal = nullptr, * m_shaded = nullptr;
-    SmartPtr<GdkRegion, gdk_region_destroy> m_shape, m_sshape;
+    SmartPtr<cairo_region_t, cairo_region_destroy> m_shape, m_sshape;
 };
 
 void dock_add_window (int id, Window * window, int * x, int * y, int w, int h);
