diff --git a/obs/forms/OBSBasic.ui b/obs/forms/OBSBasic.ui
index 42fd544ab..5498bd062 100644
--- a/obs/forms/OBSBasic.ui
+++ b/obs/forms/OBSBasic.ui
@@ -369,6 +369,21 @@
QFrame::NoFrame
+
+ true
+
+
+ true
+
+
+ QAbstractItemView::InternalMove
+
+
+ QAbstractItemView::ExtendedSelection
+
+
+ Qt::IgnoreAction
+
diff --git a/obs/source-list-widget.cpp b/obs/source-list-widget.cpp
index 9cef2289e..d537fbc3b 100644
--- a/obs/source-list-widget.cpp
+++ b/obs/source-list-widget.cpp
@@ -1,8 +1,46 @@
#include
+
+#include
+
+#include "qt-wrappers.hpp"
#include "source-list-widget.hpp"
+Q_DECLARE_METATYPE(OBSSceneItem);
+
void SourceListWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
QListWidget::mouseDoubleClickEvent(event);
}
+
+void SourceListWidget::dropEvent(QDropEvent *event)
+{
+ QListWidget::dropEvent(event);
+ if (!event->isAccepted() || !count())
+ return;
+
+ auto GetSceneItem = [&](int i)
+ {
+ return item(i)->data(Qt::UserRole).value();
+ };
+
+ std::vector newOrder;
+ newOrder.reserve(count());
+ for (int i = count() - 1; i >= 0; i--)
+ newOrder.push_back(GetSceneItem(i));
+
+ auto UpdateOrderAtomically = [&](obs_scene_t *scene)
+ {
+ ignoreReorder = true;
+ obs_scene_reorder_items(scene, newOrder.data(),
+ newOrder.size());
+ ignoreReorder = false;
+ };
+ using UpdateOrderAtomically_t = decltype(UpdateOrderAtomically);
+
+ auto scene = obs_sceneitem_get_scene(GetSceneItem(0));
+ obs_scene_atomic_update(scene, [](void *data, obs_scene_t *scene)
+ {
+ (*static_cast(data))(scene);
+ }, static_cast(&UpdateOrderAtomically));
+}
diff --git a/obs/source-list-widget.hpp b/obs/source-list-widget.hpp
index b571bf5ad..d2215b0c2 100644
--- a/obs/source-list-widget.hpp
+++ b/obs/source-list-widget.hpp
@@ -6,12 +6,17 @@ class QMouseEvent;
class SourceListWidget : public QListWidget {
Q_OBJECT
+
+ bool ignoreReorder = false;
public:
inline SourceListWidget(QWidget *parent = nullptr)
: QListWidget(parent)
{
}
+ bool IgnoreReorder() const { return ignoreReorder; }
+
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
+ virtual void dropEvent(QDropEvent *event) override;
};