diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini
index 50dd9cf62..476904a80 100644
--- a/obs/data/locale/en-US.ini
+++ b/obs/data/locale/en-US.ini
@@ -357,6 +357,7 @@ Basic.Settings.General.WarnBeforeStartingStream="Show confirmation dialog when s
Basic.Settings.General.WarnBeforeStoppingStream="Show confirmation dialog when stopping streams"
Basic.Settings.General.Snapping="Source Alignment Snapping"
Basic.Settings.General.ScreenSnapping="Snap Sources to edge of screen"
+Basic.Settings.General.CenterSnapping="Snap Sources to horizontal and vertical center"
Basic.Settings.General.SnapDistance="Snap Sensitivity"
# basic mode 'stream' settings
diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui
index bd38e2185..f94c7d013 100644
--- a/obs/forms/OBSBasicSettings.ui
+++ b/obs/forms/OBSBasicSettings.ui
@@ -233,6 +233,16 @@
+ -
+
+
+ Basic.Settings.General.CenterSnapping
+
+
+ true
+
+
+
-
@@ -3616,6 +3626,22 @@
476
202
+
+ 515
+ 277
+
+
+
+
+ snappingEnabled
+ toggled(bool)
+ centerSnapping
+ setEnabled(bool)
+
+
+ 557
+ 207
+
777
206
diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp
index 86368e714..f435a22a4 100644
--- a/obs/obs-app.cpp
+++ b/obs/obs-app.cpp
@@ -343,6 +343,8 @@ bool OBSApp::InitGlobalConfigDefaults()
"SnappingEnabled", true);
config_set_default_bool(globalConfig, "BasicWindow",
"ScreenSnapping", true);
+ config_set_default_bool(globalConfig, "BasicWindow",
+ "CenterSnapping", false);
config_set_default_double(globalConfig, "BasicWindow",
"SnapDistance", 10.0);
diff --git a/obs/window-basic-preview.cpp b/obs/window-basic-preview.cpp
index cdc25e17f..7d6ebdf84 100644
--- a/obs/window-basic-preview.cpp
+++ b/obs/window-basic-preview.cpp
@@ -147,9 +147,13 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
const bool screenSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ScreenSnapping");
+ const bool centerSnap = config_get_bool(GetGlobalConfig(),
+ "BasicWindow", "CenterSnapping");
const float clampDist = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance") / main->previewScale;
+ const float centerX = br.x - (br.x - tl.x) / 2.0f;
+ const float centerY = br.y - (br.y - tl.y) / 2.0f;
// Left screen edge.
if (screenSnap &&
@@ -160,6 +164,11 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
fabsf(clampOffset.x) < EPSILON &&
fabsf(screenSize.x - br.x) < clampDist)
clampOffset.x = screenSize.x - br.x;
+ // Horizontal center.
+ if (centerSnap &&
+ fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
+ fabsf(screenSize.x / 2.0f - centerX) < clampDist)
+ clampOffset.x = screenSize.x / 2.0f - centerX;
// Top screen edge.
if (screenSnap &&
@@ -170,6 +179,11 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
fabsf(clampOffset.y) < EPSILON &&
fabsf(screenSize.y - br.y) < clampDist)
clampOffset.y = screenSize.y - br.y;
+ // Vertical center.
+ if (centerSnap &&
+ fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
+ fabsf(screenSize.y / 2.0f - centerY) < clampDist)
+ clampOffset.y = screenSize.y / 2.0f - centerY;
return clampOffset;
}
diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp
index 52f5a3c85..c3302e886 100644
--- a/obs/window-basic-settings.cpp
+++ b/obs/window-basic-settings.cpp
@@ -268,6 +268,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->warnBeforeStreamStop, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->snappingEnabled, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->screenSnapping, CHECK_CHANGED, GENERAL_CHANGED);
+ HookWidget(ui->centerSnapping, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->snapDistance, SCROLL_CHANGED, GENERAL_CHANGED);
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED);
@@ -774,6 +775,10 @@ void OBSBasicSettings::LoadGeneralSettings()
"BasicWindow", "ScreenSnapping");
ui->screenSnapping->setChecked(screenSnapping);
+ bool centerSnapping = config_get_bool(GetGlobalConfig(),
+ "BasicWindow", "CenterSnapping");
+ ui->centerSnapping->setChecked(centerSnapping);
+
double snapDistance = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance");
ui->snapDistance->setValue(snapDistance);
@@ -2062,6 +2067,10 @@ void OBSBasicSettings::SaveGeneralSettings()
config_set_bool(GetGlobalConfig(), "BasicWindow",
"ScreenSnapping",
ui->screenSnapping->isChecked());
+ if (WidgetChanged(ui->centerSnapping))
+ config_set_bool(GetGlobalConfig(), "BasicWindow",
+ "CenterSnapping",
+ ui->centerSnapping->isChecked());
if (WidgetChanged(ui->snapDistance))
config_set_double(GetGlobalConfig(), "BasicWindow",
"SnapDistance",