mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-09-01 05:44:43 +08:00
frontend: Fix volume control state desync
This commit is contained in:
@@ -95,10 +95,11 @@ VolumeControl::VolumeControl(obs_source_t *source, QWidget *parent, bool vertica
|
||||
|
||||
volumeMeter = new VolumeMeter(this, source);
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
obsMuted = obs_source_muted(source);
|
||||
bool unassigned = isSourceUnassigned(source);
|
||||
obsMonitoringType = obs_source_get_monitoring_type(source);
|
||||
|
||||
volumeMeter->setMuted(muted || unassigned);
|
||||
volumeMeter->setMuted(obsMuted || unassigned);
|
||||
|
||||
setLayoutVertical(vertical);
|
||||
setName(sourceName);
|
||||
@@ -107,10 +108,8 @@ VolumeControl::VolumeControl(obs_source_t *source, QWidget *parent, bool vertica
|
||||
|
||||
obsSignals.reserve(9);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "mute", obsVolumeMuted, this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_mixers", obsMixersOrMonitoringChanged,
|
||||
this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_monitoring", obsMixersOrMonitoringChanged,
|
||||
this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_mixers", obsMixersChanged, this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_monitoring", obsMonitoringChanged, this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "activate", VolumeControl::obsSourceActivated,
|
||||
this);
|
||||
obsSignals.emplace_back(obs_source_get_signal_handler(source), "deactivate",
|
||||
@@ -151,7 +150,7 @@ VolumeControl::VolumeControl(obs_source_t *source, QWidget *parent, bool vertica
|
||||
// Call volume changed once to init the slider position and label
|
||||
changeVolume();
|
||||
|
||||
updateMixerState();
|
||||
processMixerState();
|
||||
}
|
||||
|
||||
VolumeControl::~VolumeControl()
|
||||
@@ -202,17 +201,26 @@ void VolumeControl::obsVolumeChanged(void *data, float)
|
||||
QMetaObject::invokeMethod(volControl, "changeVolume", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void VolumeControl::obsVolumeMuted(void *data, calldata_t *)
|
||||
void VolumeControl::obsVolumeMuted(void *data, calldata_t *params)
|
||||
{
|
||||
VolumeControl *volControl = static_cast<VolumeControl *>(data);
|
||||
bool muted = calldata_bool(params, "muted");
|
||||
|
||||
QMetaObject::invokeMethod(volControl, "updateMixerState", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(volControl, "onMuteChanged", Qt::QueuedConnection, Q_ARG(bool, muted));
|
||||
}
|
||||
|
||||
void VolumeControl::obsMixersOrMonitoringChanged(void *data, calldata_t *)
|
||||
void VolumeControl::obsMixersChanged(void *data, calldata_t *)
|
||||
{
|
||||
VolumeControl *volControl = static_cast<VolumeControl *>(data);
|
||||
QMetaObject::invokeMethod(volControl, "updateMixerState", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(volControl, "processMixerState", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void VolumeControl::obsMonitoringChanged(void *data, calldata_t *params)
|
||||
{
|
||||
VolumeControl *volControl = static_cast<VolumeControl *>(data);
|
||||
auto type = static_cast<int>(calldata_int(params, "type"));
|
||||
|
||||
QMetaObject::invokeMethod(volControl, "onMonitoringChanged", Qt::QueuedConnection, Q_ARG(int, type));
|
||||
}
|
||||
|
||||
void VolumeControl::obsSourceActivated(void *data, calldata_t *)
|
||||
@@ -594,6 +602,18 @@ void VolumeControl::setLocked(bool locked)
|
||||
emit main->mixerStatusChanged(uuid);
|
||||
}
|
||||
|
||||
void VolumeControl::onMuteChanged(bool muted)
|
||||
{
|
||||
obsMuted = muted;
|
||||
processMixerState();
|
||||
}
|
||||
|
||||
void VolumeControl::onMonitoringChanged(int type)
|
||||
{
|
||||
obsMonitoringType = static_cast<obs_monitoring_type>(type);
|
||||
processMixerState();
|
||||
}
|
||||
|
||||
void VolumeControl::updateCategoryLabel()
|
||||
{
|
||||
QString labelText = QTStr("Basic.AudioMixer.Category.Active");
|
||||
@@ -724,14 +744,15 @@ void VolumeControl::setMonitoring(obs_monitoring_type type)
|
||||
|
||||
void VolumeControl::sourceActiveChanged(bool active)
|
||||
{
|
||||
setUseDisabledColors(!active);
|
||||
processMixerState();
|
||||
|
||||
mixerStatus().set(VolumeControl::MixerStatus::Active, active);
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
emit main->mixerStatusChanged(uuid);
|
||||
}
|
||||
|
||||
void VolumeControl::updateMixerState()
|
||||
void VolumeControl::processMixerState()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource());
|
||||
if (!source) {
|
||||
@@ -739,9 +760,7 @@ void VolumeControl::updateMixerState()
|
||||
return;
|
||||
}
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
bool unassigned = isSourceUnassigned(source);
|
||||
obs_monitoring_type monitoringType = obs_source_get_monitoring_type(source);
|
||||
|
||||
bool isActive = obs_source_active(source) && obs_source_audio_active(source);
|
||||
|
||||
@@ -751,9 +770,9 @@ void VolumeControl::updateMixerState()
|
||||
QSignalBlocker blockMute(muteButton);
|
||||
QSignalBlocker blockMonitor(monitorButton);
|
||||
|
||||
bool showAsMuted = muted || monitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY;
|
||||
bool showAsMonitored = !muted && monitoringType != OBS_MONITORING_TYPE_NONE;
|
||||
bool showAsUnassigned = !muted && unassigned;
|
||||
bool showAsMuted = obsMuted || obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY;
|
||||
bool showAsMonitored = obsMonitoringType != OBS_MONITORING_TYPE_NONE;
|
||||
bool showAsUnassigned = !obsMuted && unassigned;
|
||||
|
||||
volumeMeter->setMuted((showAsMuted || showAsUnassigned) && !showAsMonitored);
|
||||
setUseDisabledColors(showAsMuted || !isActive);
|
||||
@@ -805,11 +824,10 @@ void VolumeControl::handleMuteButton(bool mute)
|
||||
// The Mute and Monitor buttons in the volume mixer work as a pseudo quad-state toggle.
|
||||
// Both buttons must be in their "off" state in order to actually process it as a mute.
|
||||
// Otherwise, clicking "Mute" with monitoring enabled will toggle the monitoring type.
|
||||
obs_monitoring_type monitoringType = obs_source_get_monitoring_type(source);
|
||||
|
||||
if (mute && monitoringType == OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT) {
|
||||
if (mute && obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT) {
|
||||
setMonitoring(OBS_MONITORING_TYPE_MONITOR_ONLY);
|
||||
} else if (!mute && monitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY) {
|
||||
} else if (!mute && obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY) {
|
||||
setMonitoring(OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
|
||||
} else {
|
||||
setMuted(mute);
|
||||
@@ -825,19 +843,16 @@ void VolumeControl::handleMonitorButton(bool enableMonitoring)
|
||||
|
||||
// The Mute and Monitor buttons in the volume mixer work as a pseudo quad-state toggle.
|
||||
// The source is only ever actually "Muted" if Monitoring is set to None.
|
||||
obs_monitoring_type monitoringType = obs_source_get_monitoring_type(source);
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
|
||||
if (!enableMonitoring) {
|
||||
setMonitoring(OBS_MONITORING_TYPE_NONE);
|
||||
if (monitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY) {
|
||||
if (obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY) {
|
||||
setMuted(true);
|
||||
}
|
||||
} else if (enableMonitoring && muted) {
|
||||
} else if (enableMonitoring && obsMuted) {
|
||||
setMonitoring(OBS_MONITORING_TYPE_MONITOR_ONLY);
|
||||
setMuted(false);
|
||||
} else if (enableMonitoring && !muted) {
|
||||
} else if (enableMonitoring && !obsMuted) {
|
||||
setMonitoring(OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ private:
|
||||
OBSWeakSource weakSource_;
|
||||
const char *uuid;
|
||||
std::vector<OBSSignal> obsSignals;
|
||||
obs_monitoring_type obsMonitoringType;
|
||||
bool obsMuted;
|
||||
|
||||
QBoxLayout *mainLayout;
|
||||
QLabel *categoryLabel;
|
||||
@@ -98,7 +100,8 @@ private:
|
||||
|
||||
static void obsVolumeChanged(void *param, float db);
|
||||
static void obsVolumeMuted(void *data, calldata_t *calldata);
|
||||
static void obsMixersOrMonitoringChanged(void *data, calldata_t *);
|
||||
static void obsMixersChanged(void *data, calldata_t *);
|
||||
static void obsMonitoringChanged(void *data, calldata_t *);
|
||||
static void obsSourceActivated(void *data, calldata_t *params);
|
||||
static void obsSourceDeactivated(void *data, calldata_t *params);
|
||||
static void obsSourceDestroy(void *data, calldata_t *params);
|
||||
@@ -115,7 +118,7 @@ public slots:
|
||||
void sourceActiveChanged(bool active);
|
||||
void setUseDisabledColors(bool greyscale);
|
||||
void setLocked(bool locked);
|
||||
void updateMixerState();
|
||||
void processMixerState();
|
||||
|
||||
private slots:
|
||||
void renameSource();
|
||||
@@ -128,6 +131,8 @@ private slots:
|
||||
void setName(QString name);
|
||||
|
||||
void handleSourceDestroyed() { deleteLater(); }
|
||||
void onMuteChanged(bool muted);
|
||||
void onMonitoringChanged(int type);
|
||||
|
||||
signals:
|
||||
void unhideAll();
|
||||
|
||||
@@ -364,7 +364,7 @@ VolumeMeter::~VolumeMeter()
|
||||
void VolumeMeter::obsSourceDestroyed(void *data, calldata_t *)
|
||||
{
|
||||
VolumeMeter *self = static_cast<VolumeMeter *>(data);
|
||||
QMetaObject::invokeMethod(self, "handleSourceDestroyed", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(self, "onSourceDestroyed", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS], const float peak[MAX_AUDIO_CHANNELS],
|
||||
|
||||
@@ -371,7 +371,6 @@ void AudioMixer::updateControlVisibility(QString uuid)
|
||||
bool show = getMixerVisibilityForControl(control);
|
||||
|
||||
if (show) {
|
||||
control->updateMixerState();
|
||||
control->show();
|
||||
} else {
|
||||
control->hide();
|
||||
|
||||
Reference in New Issue
Block a user