diff --git a/gui/playlist.c b/gui/playlist.c
index d32611cd..51315dd7 100644
--- a/gui/playlist.c
+++ b/gui/playlist.c
@@ -207,6 +207,31 @@ void __gui_playlist_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter,
gui_sidebar_filter_row_expanded(iter, true);
}
+void __gui_playlist_drag_data_received(GtkTreeView *treeview, GdkDragContext *context,
+ gint x, gint y, GtkSelectionData *data,
+ guint info, guint time, gpointer user_data)
+{
+ struct playlist *playlist;
+ GtkTreeIter iter;
+
+ if (gui_sidebar_iter_from_xy(x, y, &iter))
+ playlist = gui_sidebar_iter_playlist(&iter);
+ if (!playlist)
+ playlist = gui_pl_user_add_dialog();
+ if (!playlist)
+ goto out;
+
+ if (playlist == playlist_lookup(PL_SYSTEM, "Collection") &&
+ gui_model_get_playlist() == playlist_lookup(PL_SYSTEM, "Hidden"))
+ __gui_playlist_delete(NULL, NULL);
+ else if (playlist != playlist_lookup(PL_SYSTEM, "History"))
+ __gui_playlist_add_selected_to(playlist);
+
+out:
+ g_signal_stop_emission_by_name(treeview, "drag_data_received");
+ gtk_drag_finish(context, true, true, time);
+}
+
bool __gui_playlist_init_idle()
{
struct playlist *playlist = playlist_current();
diff --git a/gui/sidebar.c b/gui/sidebar.c
index 8aa8add8..cfc47eac 100644
--- a/gui/sidebar.c
+++ b/gui/sidebar.c
@@ -256,6 +256,10 @@ void gui_sidebar_init()
GtkTreeSelection *selection;
GtkTreeIter iter;
+ gtk_tree_view_enable_model_drag_dest(gui_sidebar_treeview(),
+ gui_model_drag_targets, gui_model_n_targets,
+ GDK_ACTION_MOVE);
+
if (!gui_sidebar_iter_first(&iter)) {
__gui_sidebar_add_header(&iter, "Playlists", "emblem-documents");
__gui_sidebar_add_header(&iter, "Dynamic", "emblem-generic");
diff --git a/share/ocarina/ocarina.ui b/share/ocarina/ocarina.ui
index 50e8cce7..d335c8b1 100644
--- a/share/ocarina/ocarina.ui
+++ b/share/ocarina/ocarina.ui
@@ -768,6 +768,8 @@ audio-volume-medium
1
True
+
+