Pārlūkot izejas kodu

UI: Replace/simplify device toolbar

The old version of the device toolbar was a complex situation.  Because
of the fact that device properties can take significant time to query,
this put an unpleasant burden on the UI thread; so to fix this problem,
the device toolbar was made to be threaded.  However, threading is a
complex and dangerous thing, and there is a fear that this could cause
complications down the line whenever users are simply selecting devices.

So for the time being, as a safety precaution, simplify the device
toolbar down to just the "activate" button, and make it so that if users
really need to query and change the devices, that they need to
explicitly open the properties.  That way the devices aren't being
queried constantly every time a device source is selected.

Alternatively in the future, device enumeration could be cached, but
seeing as that's a significant amount of work and needs to take in to
account whether a user adds/removes a device while the process is
active, that's not going to happen any time soon.
jp9000 5 gadi atpakaļ
vecāks
revīzija
50d3130b64

+ 0 - 2
UI/CMakeLists.txt

@@ -238,7 +238,6 @@ set(obs_SOURCES
 	item-widget-helpers.cpp
 	context-bar-controls.cpp
 	horizontal-scroll-area.cpp
-	context-bar-controls-devices.cpp
 	vertical-scroll-area.cpp
 	visibility-item-widget.cpp
 	slider-absoluteset-style.cpp
@@ -306,7 +305,6 @@ set(obs_HEADERS
 	item-widget-helpers.hpp
 	visibility-checkbox.hpp
 	context-bar-controls.hpp
-	context-bar-controls-devices.hpp
 	locked-checkbox.hpp
 	horizontal-scroll-area.hpp
 	expand-checkbox.hpp

+ 0 - 149
UI/context-bar-controls-devices.cpp

@@ -1,149 +0,0 @@
-#include "context-bar-controls.hpp"
-#include "context-bar-controls-devices.hpp"
-#include "window-basic-main.hpp"
-
-#include "ui_device-select-toolbar.h"
-
-#ifdef _WIN32
-#define get_os_module(win, mac, linux) obs_get_module(win)
-#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
-#elif __APPLE__
-#define get_os_module(win, mac, linux) obs_get_module(mac)
-#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
-#else
-#define get_os_module(win, mac, linux) obs_get_module(linux)
-#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
-#endif
-
-/* ========================================================================= */
-
-DeviceToolbarPropertiesThread::~DeviceToolbarPropertiesThread()
-{
-	obs_properties_destroy(props);
-}
-
-void DeviceToolbarPropertiesThread::run()
-{
-	props = obs_source_properties(source);
-	source = nullptr;
-	QMetaObject::invokeMethod(this, "Ready");
-}
-
-void DeviceToolbarPropertiesThread::Ready()
-{
-	OBSBasic *main = OBSBasic::Get();
-	QLayoutItem *la = main->ui->emptySpace->layout()->itemAt(0);
-	if (la) {
-		DeviceCaptureToolbar *dct =
-			qobject_cast<DeviceCaptureToolbar *>(la->widget());
-		if (dct) {
-			dct->SetProperties(props);
-			props = nullptr;
-		}
-	}
-}
-
-/* ========================================================================= */
-
-DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
-	: QWidget(parent),
-	  weakSource(OBSGetWeakRef(source)),
-	  ui(new Ui_DeviceSelectToolbar)
-{
-	ui->setupUi(this);
-
-#ifndef _WIN32
-	delete ui->activateButton;
-	ui->activateButton = nullptr;
-#endif
-
-	setEnabled(false);
-
-	obs_module_t *mod =
-		get_os_module("win-dshow", "mac-avcapture", "linux-v4l2");
-	const char *device_str = obs_module_get_locale_text(mod, "Device");
-	ui->deviceLabel->setText(device_str);
-
-	OBSBasic *main = OBSBasic::Get();
-	if (!main->devicePropertiesThread ||
-	    !main->devicePropertiesThread->isRunning()) {
-		main->devicePropertiesThread.reset(
-			new DeviceToolbarPropertiesThread(source));
-		main->devicePropertiesThread->start();
-	}
-}
-
-DeviceCaptureToolbar::~DeviceCaptureToolbar()
-{
-	delete ui;
-	obs_properties_destroy(props);
-}
-
-void DeviceCaptureToolbar::UpdateActivateButtonName()
-{
-	obs_property_t *p = obs_properties_get(props, "activate");
-	ui->activateButton->setText(obs_property_description(p));
-}
-
-extern void UpdateSourceComboToolbarProperties(QComboBox *combo,
-					       OBSSource source,
-					       obs_properties_t *props,
-					       const char *prop_name,
-					       bool is_int);
-extern void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source,
-					  int idx, const char *prop_name,
-					  bool is_int);
-
-void DeviceCaptureToolbar::SetProperties(obs_properties_t *props_)
-{
-	OBSSource source = OBSGetStrongRef(weakSource);
-	if (!source) {
-		obs_properties_destroy(props_);
-		return;
-	}
-
-#ifdef _WIN32
-	prop_name = "video_device_id";
-#elif __APPLE__
-	prop_name = "device";
-#else
-	prop_name = "device_id";
-#endif
-
-	props = props_;
-	UpdateSourceComboToolbarProperties(ui->device, source, props, prop_name,
-					   false);
-#ifdef _WIN32
-	UpdateActivateButtonName();
-#endif
-	setEnabled(true);
-}
-
-void DeviceCaptureToolbar::on_device_currentIndexChanged(int idx)
-{
-	OBSSource source = OBSGetStrongRef(weakSource);
-	if (idx == -1 || !source) {
-		return;
-	}
-
-	UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name,
-				      false);
-}
-
-void DeviceCaptureToolbar::on_activateButton_clicked()
-{
-	OBSSource source = OBSGetStrongRef(weakSource);
-	if (!source) {
-		return;
-	}
-
-	obs_property_t *p = obs_properties_get(props, "activate");
-	if (!p) {
-		return;
-	}
-
-	obs_property_button_clicked(p, source.Get());
-#ifdef _WIN32
-	UpdateActivateButtonName();
-#endif
-}

+ 0 - 25
UI/context-bar-controls-devices.hpp

@@ -1,25 +0,0 @@
-#pragma once
-
-#include <obs.hpp>
-#include <string>
-#include <QThread>
-
-class DeviceToolbarPropertiesThread : public QThread {
-	Q_OBJECT
-
-	OBSSource source;
-	obs_properties_t *props;
-
-	void run() override;
-
-public:
-	inline DeviceToolbarPropertiesThread(OBSSource source_)
-		: source(source_)
-	{
-	}
-
-	~DeviceToolbarPropertiesThread() override;
-
-public slots:
-	void Ready();
-};

+ 59 - 0
UI/context-bar-controls.cpp

@@ -255,6 +255,65 @@ void DisplayCaptureToolbar::Init()
 
 /* ========================================================================= */
 
+DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
+	: QWidget(parent),
+	  weakSource(OBSGetWeakRef(source)),
+	  ui(new Ui_DeviceSelectToolbar)
+{
+	ui->setupUi(this);
+
+	delete ui->deviceLabel;
+	delete ui->device;
+	ui->deviceLabel = nullptr;
+	ui->device = nullptr;
+
+	obs_data_t *settings = obs_source_get_settings(source);
+	active = obs_data_get_bool(settings, "active");
+	obs_data_release(settings);
+
+	obs_module_t *mod = obs_get_module("win-dshow");
+	activateText = obs_module_get_locale_text(mod, "Activate");
+	deactivateText = obs_module_get_locale_text(mod, "Deactivate");
+
+	ui->activateButton->setText(active ? deactivateText : activateText);
+}
+
+DeviceCaptureToolbar::~DeviceCaptureToolbar()
+{
+	delete ui;
+}
+
+void DeviceCaptureToolbar::on_activateButton_clicked()
+{
+	OBSSource source = OBSGetStrongRef(weakSource);
+	if (!source) {
+		return;
+	}
+
+	obs_data_t *settings = obs_source_get_settings(source);
+	bool now_active = obs_data_get_bool(settings, "active");
+	obs_data_release(settings);
+
+	bool desyncedSetting = now_active != active;
+
+	active = !active;
+
+	const char *text = active ? deactivateText : activateText;
+	ui->activateButton->setText(text);
+
+	if (desyncedSetting) {
+		return;
+	}
+
+	calldata_t cd = {};
+	calldata_set_bool(&cd, "active", active);
+	proc_handler_t *ph = obs_source_get_proc_handler(source);
+	proc_handler_call(ph, "activate", &cd);
+	calldata_free(&cd);
+}
+
+/* ========================================================================= */
+
 GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
 	: SourceToolbar(parent, source), ui(new Ui_GameCaptureToolbar)
 {

+ 4 - 7
UI/context-bar-controls.hpp

@@ -90,20 +90,17 @@ class DeviceCaptureToolbar : public QWidget {
 	Q_OBJECT
 
 	OBSWeakSource weakSource;
-	Ui_DeviceSelectToolbar *ui;
-	obs_properties_t *props = nullptr;
-	const char *prop_name;
 
-	void UpdateActivateButtonName();
+	Ui_DeviceSelectToolbar *ui;
+	const char *activateText;
+	const char *deactivateText;
+	bool active;
 
 public:
 	DeviceCaptureToolbar(QWidget *parent, OBSSource source);
 	~DeviceCaptureToolbar();
 
-	void SetProperties(obs_properties_t *prpos);
-
 public slots:
-	void on_device_currentIndexChanged(int idx);
 	void on_activateButton_clicked();
 };
 

+ 1 - 3
UI/window-basic-main.cpp

@@ -2966,9 +2966,7 @@ void OBSBasic::UpdateContextBar()
 			c->Init();
 			ui->emptySpace->layout()->addWidget(c);
 
-		} else if (strcmp(id, "dshow_input") == 0 ||
-			   strcmp(id, "av_capture_input") == 0 ||
-			   strcmp(id, "v4l2_input") == 0) {
+		} else if (strcmp(id, "dshow_input") == 0) {
 			DeviceCaptureToolbar *c = new DeviceCaptureToolbar(
 				ui->emptySpace, source);
 			ui->emptySpace->layout()->addWidget(c);