Skip to content

Fix application volume sliders becoming non-functional after extended runtime#21

Merged
cwage merged 3 commits intomainfrom
copilot/fix-20
Aug 9, 2025
Merged

Fix application volume sliders becoming non-functional after extended runtime#21
cwage merged 3 commits intomainfrom
copilot/fix-20

Conversation

Copy link
Contributor

Copilot AI commented Aug 9, 2025

This PR fixes a bug where application volume sliders would stop working after volmix runs for an extended period. The sliders would still move visually, but wouldn't actually control application volumes.

Root Cause

The issue was caused by stale PulseAudio sink input indexes stored in slider widgets:

  1. When the volume control window is built, it captures current sink input indexes and stores them as static data in each slider widget
  2. Over time, as applications start/stop audio streams, PulseAudio recycles these indexes
  3. The sliders continue to reference old, now-invalid indexes, causing volume control operations to fail silently

Solution

Implemented a PulseAudio event subscription system that dynamically updates slider references:

  • Event Subscription: Subscribe to PA_SUBSCRIPTION_EVENT_SINK_INPUT events to detect when applications start/stop audio streams
  • Change Tracking: Added sink_inputs_changed flag to efficiently track when updates are needed
  • Dynamic Updates: When sink input changes are detected and the volume window is visible, update the stored indexes in existing slider widgets by matching application names
  • Minimal UI Impact: Updates widget data without rebuilding the entire interface

Key Changes

  • pulse_client.c: Added subscription setup and callback to handle PulseAudio events
  • pulse_client.h: Added change tracking flag and API function
  • volmix.c: Added UI update mechanism with recursive widget traversal

Testing

  • Project builds successfully with no compilation errors
  • Core logic verified with unit tests
  • Manual test plan created for desktop environment verification

The fix ensures volume sliders remain functional indefinitely, even as PulseAudio recycles sink input indexes during normal operation.

Fixes #20.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Aug 9, 2025
Copy link
Contributor Author

Copilot AI commented Aug 9, 2025

@cwage 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Copilot AI and others added 2 commits August 9, 2025 17:23
Co-authored-by: cwage <190973+cwage@users.noreply.github.com>
Co-authored-by: cwage <190973+cwage@users.noreply.github.com>
@cwage
Copy link
Owner

cwage commented Aug 9, 2025

@copilot-swe-agent The analysis looks perfect! Please go ahead and implement Option B: PulseAudio Event Subscription as you outlined.

This is exactly the right approach:

  • Add PulseAudio subscription event system to pulse_client
  • Add callback to handle sink input changes
  • Add mechanism to update slider widget data when changes occur

Please proceed with the implementation. Thanks!

Copilot AI changed the title [WIP] Application volume sliders stop working after running for a while Fix application volume sliders becoming non-functional after extended runtime Aug 9, 2025
Copilot AI requested a review from cwage August 9, 2025 17:33
Copy link
Contributor Author

Copilot AI commented Aug 9, 2025

@copilot-swe-agent The analysis looks perfect! Please go ahead and implement Option B: PulseAudio Event Subscription as you outlined.

This is exactly the right approach:...

Option B: PulseAudio Event Subscription has been successfully implemented! ✅

The implementation includes:

  • PulseAudio subscription system: Added event subscription to PA_SUBSCRIPTION_MASK_SINK_INPUT in pulse_client.c with proper callback handling
  • Change detection: Added subscription_callback() that sets sink_inputs_changed flag when applications start/stop audio streams
  • Dynamic slider updates: Added update_slider_indexes() mechanism that updates existing slider widget data by matching application names when changes are detected

The fix ensures volume sliders remain functional indefinitely by dynamically updating their stored PulseAudio sink input indexes as applications come and go.

Project builds successfully with no compilation errors. Ready for testing and review.

Commit: e9ec9eb

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@cwage cwage marked this pull request as ready for review August 9, 2025 19:04
Copilot AI review requested due to automatic review settings August 9, 2025 19:04
@cwage cwage merged commit d152abe into main Aug 9, 2025
1 check passed
@cwage cwage deleted the copilot/fix-20 branch August 9, 2025 19:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a bug where application volume sliders become non-functional after extended runtime due to stale PulseAudio sink input indexes. The fix implements a PulseAudio event subscription system to dynamically update slider references when applications start/stop audio streams.

  • Added PulseAudio event subscription system to detect sink input changes
  • Implemented dynamic slider index updating mechanism with recursive widget traversal
  • Added change tracking flag to efficiently handle updates only when needed

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/volmix.c Added UI update mechanism with recursive widget traversal and timer callback enhancements
src/pulse_client.h Added sink_inputs_changed flag and API function declaration
src/pulse_client.c Implemented event subscription system and callback handlers
src/Makefile.in Updated build configuration with DATADIR definition
src/Makefile Updated generated makefile with build environment changes

// Refresh the sink input list
pulse_client_refresh_apps(&app->pulse_client);

// Process the refresh operation
Copy link

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic numbers MAX_REFRESH_TIMEOUT and DELAY_5_MS_USEC are used but not defined in this file. These constants should be defined at the top of the file or in a header to improve code maintainability.

Copilot uses AI. Check for mistakes.
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
// Mark that sink inputs have changed - this will trigger UI update
client->sink_inputs_changed = TRUE;
printf("Sink input event detected (index=%u, type=%s)\n", index,
Copy link

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug printf statements should be replaced with proper logging or removed from production code. Consider using a logging framework or conditional compilation for debug output.

Suggested change
printf("Sink input event detected (index=%u, type=%s)\n", index,
g_debug("Sink input event detected (index=%u, type=%s)", index,

Copilot uses AI. Check for mistakes.
// Check if sink inputs have changed and window is visible
if (pulse_client_sink_inputs_changed(&app->pulse_client) &&
app->volmix_window && gtk_widget_get_visible(app->volmix_window)) {
printf("Sink inputs changed, updating slider indexes...\n");
Copy link

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug printf statements should be replaced with proper logging or removed from production code. Consider using a logging framework or conditional compilation for debug output.

Suggested change
printf("Sink inputs changed, updating slider indexes...\n");
g_debug("Sink inputs changed, updating slider indexes...");

Copilot uses AI. Check for mistakes.
Comment on lines +445 to +447
if (*stored_index != app->index) {
printf("Updating slider for '%s': index %u -> %u\n",
stored_app_name, *stored_index, app->index);
Copy link

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug printf statements should be replaced with proper logging or removed from production code. Consider using a logging framework or conditional compilation for debug output.

Suggested change
if (*stored_index != app->index) {
printf("Updating slider for '%s': index %u -> %u\n",
stored_app_name, *stored_index, app->index);
if (*stored_index != app->index) {
#ifdef DEBUG
printf("Updating slider for '%s': index %u -> %u\n",
stored_app_name, *stored_index, app->index);
#endif

Copilot uses AI. Check for mistakes.
PA_SUBSCRIPTION_MASK_SINK_INPUT,
NULL, NULL);
if (!client->operation) {
printf("Failed to subscribe to PulseAudio events\n");
Copy link

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is unclear about the consequences of the subscription failure. Consider providing more context about what this means for the application's functionality.

Suggested change
printf("Failed to subscribe to PulseAudio events\n");
printf("Failed to subscribe to PulseAudio events. Audio application monitoring will be disabled and the client will not detect when applications start or stop audio playback.\n");

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Application volume sliders stop working after running for a while

2 participants

Comments