forked from quickshell/quickshell
		
	service/pipewire: ignore insignificant device volume changes
Fixes devices getting stuck in a "waiting for volume change acknowledgement" state forever.
This commit is contained in:
		
							parent
							
								
									a116f39c63
								
							
						
					
					
						commit
						f6ad617b67
					
				
					 2 changed files with 32 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -228,10 +228,10 @@ void PwNodeBoundAudio::onInfo(const pw_node_info* info) {
 | 
			
		|||
 | 
			
		||||
			if (param.id == SPA_PARAM_Props) {
 | 
			
		||||
				if ((param.flags & SPA_PARAM_INFO_READWRITE) == SPA_PARAM_INFO_READWRITE) {
 | 
			
		||||
					qCDebug(logNode) << "Enumerating props param for" << this;
 | 
			
		||||
					qCDebug(logNode) << "Enumerating props param for" << this->node;
 | 
			
		||||
					pw_node_enum_params(this->node->proxy(), 0, param.id, 0, UINT32_MAX, nullptr);
 | 
			
		||||
				} else {
 | 
			
		||||
					qCWarning(logNode) << "Unable to enumerate props param for" << this
 | 
			
		||||
					qCWarning(logNode) << "Unable to enumerate props param for" << this->node
 | 
			
		||||
					                   << "as the param does not have read+write permissions.";
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -266,6 +266,10 @@ void PwNodeBoundAudio::updateVolumeProps(const spa_pod* param) {
 | 
			
		|||
		qCInfo(logNode) << "Got updated channels of" << this->node << '-' << this->mChannels;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->mServerVolumes != volumeProps.volumes) {
 | 
			
		||||
		this->mServerVolumes = volumeProps.volumes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->mVolumes != volumeProps.volumes) {
 | 
			
		||||
		this->mVolumes = volumeProps.volumes;
 | 
			
		||||
		volumesChanged = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +290,7 @@ void PwNodeBoundAudio::updateVolumeProps(const spa_pod* param) {
 | 
			
		|||
void PwNodeBoundAudio::onUnbind() {
 | 
			
		||||
	this->mChannels.clear();
 | 
			
		||||
	this->mVolumes.clear();
 | 
			
		||||
	this->mServerVolumes.clear();
 | 
			
		||||
	this->mDeviceVolumes.clear();
 | 
			
		||||
	this->waitingVolumes.clear();
 | 
			
		||||
	emit this->channelsChanged();
 | 
			
		||||
| 
						 | 
				
			
			@ -381,13 +386,32 @@ void PwNodeBoundAudio::setVolumes(const QVector<float>& volumes) {
 | 
			
		|||
			                << "via device";
 | 
			
		||||
			this->waitingVolumes = realVolumes;
 | 
			
		||||
		} else {
 | 
			
		||||
			qCInfo(logNode) << "Changing volumes of" << this->node << "to" << realVolumes << "via device";
 | 
			
		||||
			auto significantChange = this->mServerVolumes.isEmpty();
 | 
			
		||||
			for (auto i = 0; i < this->mServerVolumes.length(); i++) {
 | 
			
		||||
				auto serverVolume = this->mServerVolumes.value(i);
 | 
			
		||||
				auto targetVolume = realVolumes.value(i);
 | 
			
		||||
				if (targetVolume == 0 || abs(targetVolume - serverVolume) >= 0.0001) {
 | 
			
		||||
					significantChange = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (significantChange) {
 | 
			
		||||
				qCInfo(logNode) << "Changing volumes of" << this->node << "to" << realVolumes
 | 
			
		||||
				                << "via device";
 | 
			
		||||
				if (!this->node->device->setVolumes(this->node->routeDevice, realVolumes)) {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this->mDeviceVolumes = realVolumes;
 | 
			
		||||
				this->node->device->waitForDevice();
 | 
			
		||||
			} else {
 | 
			
		||||
				// Insignificant changes won't cause an info event on the device, leaving qs hung in the
 | 
			
		||||
				// "waiting for acknowledgement" state forever.
 | 
			
		||||
				qCInfo(logNode) << "Ignoring volume change for" << this->node << "to" << realVolumes
 | 
			
		||||
				                << "from" << this->mServerVolumes
 | 
			
		||||
				                << "as it is a device node and the change is too small.";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		auto buffer = std::array<quint8, 1024>();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,7 @@ private:
 | 
			
		|||
	bool mMuted = false;
 | 
			
		||||
	QVector<PwAudioChannel::Enum> mChannels;
 | 
			
		||||
	QVector<float> mVolumes;
 | 
			
		||||
	QVector<float> mServerVolumes;
 | 
			
		||||
	QVector<float> mDeviceVolumes;
 | 
			
		||||
	QVector<float> waitingVolumes;
 | 
			
		||||
	PwNode* node;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue