Skip to content

Conversation

@hazzsaeedharis
Copy link

@hazzsaeedharis hazzsaeedharis commented Jan 8, 2026

  • Remove isActiveOutputDeviceAirPods() check from pause/resume logic as it fails on some systems where PulseAudio can't detect the Bluetooth card properly

  • Add playerctl as fallback when DBus MPRIS doesn't find playing media players. This fixes compatibility with browsers and players that don't register properly with DBus on certain systems

  • Resume logic now correctly uses playerctl if that's how media was paused

Fixes ear detection not pausing media on aarch64 Ubuntu systems.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed media pause and resume functionality to work reliably on all audio devices
    • Enhanced reliability of pause and resume operations with improved fallback handling

✏️ Tip: You can customize this high-level summary in your review settings.

- Remove isActiveOutputDeviceAirPods() check from pause/resume logic
  as it fails on some systems where PulseAudio can't detect the
  Bluetooth card properly

- Add playerctl as fallback when DBus MPRIS doesn't find playing
  media players. This fixes compatibility with browsers and players
  that don't register properly with DBus on certain systems

- Resume logic now correctly uses playerctl if that's how media
  was paused

Fixes ear detection not pausing media on aarch64 Ubuntu systems.
@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

Modified pause and resume logic in the media controller to remove AirPods-specific device checks and implement playerctl-based fallback paths. The play() function now attempts playerctl-based resume first if paused by app services, while pause() adds a playerctl fallback when DBus-based pausing fails.

Changes

Cohort / File(s) Summary
Media Controller Pause/Resume Logic
linux/media/mediacontroller.cpp
Removed isActiveOutputDeviceAirPods requirement from pause and resume paths; added playerctl-based resume in play() as preliminary attempt with state tracking; added playerctl fallback in pause() when no DBus-based pause target exists; expanded logging throughout
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: removing restrictive ear detection logic and adding playerctl fallback for pause/resume functionality on Linux systems.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @linux/media/mediacontroller.cpp:
- Around line 310-325: The current early return after
QProcess::execute("playerctl", ...) leaves pausedByAppServices containing
"playerctl" on failure and causes repeated failed attempts; update the playerctl
branch in resume logic (the block that checks
pausedByAppServices.contains("playerctl") and calls QProcess::execute) to clear
or remove the "playerctl" entry from pausedByAppServices on both success and
failure before returning, and on failure additionally attempt the DBus fallback
path (same code used by the non-playerctl path) or log a clear error and
continue to other resume mechanisms; ensure you reference pausedByAppServices,
QProcess::execute, LOG_WARN/LOG_INFO and the surrounding resume method so the
state is always cleared on failure to avoid repeated retries.
🧹 Nitpick comments (1)
linux/media/mediacontroller.cpp (1)

421-432: Consider WARN level when playerctl fallback fails.

When both DBus and playerctl fail to pause media, logging at DEBUG level may make issues hard to diagnose. Since this is the last-resort fallback, a WARN would be more appropriate:

Suggested change
     else
     {
-      LOG_DEBUG("playerctl fallback returned: " << result);
+      LOG_WARN("playerctl fallback failed with code: " << result);
     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 339c478 and 0d36ee1.

📒 Files selected for processing (1)
  • linux/media/mediacontroller.cpp
🔇 Additional comments (2)
linux/media/mediacontroller.cpp (2)

52-58: Reasonable fix for PulseAudio compatibility issues.

Removing the isActiveOutputDeviceAirPods() check broadens the pause trigger to work regardless of whether PulseAudio can detect the Bluetooth card. This is a sensible trade-off for systems where the detection fails.

Note: This means ear detection will pause media even when audio output is routed elsewhere (e.g., speakers). If this becomes an issue, consider logging a warning when the active device check fails rather than skipping it entirely.


67-70: LGTM!

Consistent with the pause logic change. The added logging will help with debugging resume events.

Comment on lines +310 to +325
// If we paused via playerctl fallback, resume via playerctl
if (pausedByAppServices.contains("playerctl"))
{
LOG_INFO("Resuming media via playerctl");
int result = QProcess::execute("playerctl", QStringList() << "play");
if (result == 0)
{
LOG_INFO("Resumed media via playerctl");
pausedByAppServices.clear();
}
else
{
LOG_WARN("playerctl play returned: " << result);
}
return;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Failure path leaves stale state, causing repeated failures.

If playerctl play fails (e.g., playerctl not installed, no player available), pausedByAppServices is not cleared and the function returns early. Subsequent resume attempts will keep trying playerctl and failing indefinitely.

Consider clearing the state on failure or falling back to DBus:

Suggested fix
     int result = QProcess::execute("playerctl", QStringList() << "play");
     if (result == 0)
     {
       LOG_INFO("Resumed media via playerctl");
-      pausedByAppServices.clear();
     }
     else
     {
       LOG_WARN("playerctl play returned: " << result);
     }
+    pausedByAppServices.clear();  // Clear regardless to avoid infinite retry loop
     return;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If we paused via playerctl fallback, resume via playerctl
if (pausedByAppServices.contains("playerctl"))
{
LOG_INFO("Resuming media via playerctl");
int result = QProcess::execute("playerctl", QStringList() << "play");
if (result == 0)
{
LOG_INFO("Resumed media via playerctl");
pausedByAppServices.clear();
}
else
{
LOG_WARN("playerctl play returned: " << result);
}
return;
}
// If we paused via playerctl fallback, resume via playerctl
if (pausedByAppServices.contains("playerctl"))
{
LOG_INFO("Resuming media via playerctl");
int result = QProcess::execute("playerctl", QStringList() << "play");
if (result == 0)
{
LOG_INFO("Resumed media via playerctl");
}
else
{
LOG_WARN("playerctl play returned: " << result);
}
pausedByAppServices.clear(); // Clear regardless to avoid infinite retry loop
return;
}
🤖 Prompt for AI Agents
In @linux/media/mediacontroller.cpp around lines 310 - 325, The current early
return after QProcess::execute("playerctl", ...) leaves pausedByAppServices
containing "playerctl" on failure and causes repeated failed attempts; update
the playerctl branch in resume logic (the block that checks
pausedByAppServices.contains("playerctl") and calls QProcess::execute) to clear
or remove the "playerctl" entry from pausedByAppServices on both success and
failure before returning, and on failure additionally attempt the DBus fallback
path (same code used by the non-playerctl path) or log a clear error and
continue to other resume mechanisms; ensure you reference pausedByAppServices,
QProcess::execute, LOG_WARN/LOG_INFO and the surrounding resume method so the
state is always cleared on failure to avoid repeated retries.

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.

1 participant