Skip to content

BluezAgent: Keep pairing confirmations actionable - #3393

Open
Th0masL wants to merge 1 commit into
blueman-project:mainfrom
Th0masL:fix/pairing-confirmation-dialog
Open

BluezAgent: Keep pairing confirmations actionable#3393
Th0masL wants to merge 1 commit into
blueman-project:mainfrom
Th0masL:fix/pairing-confirmation-dialog

Conversation

@Th0masL

@Th0masL Th0masL commented Aug 30, 2026

Copy link
Copy Markdown

Summary

  • add an opt-in persistent dialog path to the notification factory
  • use it for BlueZ RequestConfirmation callbacks, which block pairing until the user responds
  • preserve notification-daemon behavior for all other notifications
  • add regression tests for both the factory selection and BlueZ agent call site

Problem

RequestConfirmation currently uses a desktop notification when the notification
server advertises action support. An action-capable server may still hide its
banner before BlueZ's authentication request expires, leaving no visible way to
confirm pairing.

This was reproduced with an Apple Magic Keyboard on:

  • Linux Mint 22.3, X11 Cinnamon
  • Blueman 2.4.4+mint2+xia
  • BlueZ 5.72-0ubuntu5.5
  • Cinnamon 6.6.9+zena
  • Cinnamon notification duration: 4 seconds

Cinnamon advertised actions and persistence. Blueman therefore used a
notification bubble. The preceding Connected notification and pairing
notification were submitted 0.428 seconds apart and displayed sequentially.
The pairing notification became visible about 4.1 seconds later, remained
visible for 4.323 seconds, and then disappeared. BlueZ eventually sent
Agent.Cancel; the keyboard remained unpaired and unbonded.

Fix

Add a force_dialog option to the notification factory and enable it only for
RequestConfirmation. The GTK dialog remains actionable until the user
confirms, denies, closes it, or BlueZ cancels the request.

Manual verification

The installed Blueman Python files were backed up, patched with the exact diff
from this branch, and identified by SHA-256 during the second capture. The
package version and all other environment details remained unchanged.

Result Stock Patched
Confirmation remained visible for at least 10 seconds No Yes
BlueZ sent Agent.Cancel Yes No
Paired No Yes
Bonded No Yes
Connected at capture completion No Yes

The patched confirmation dialog was deliberately left untouched for 10 seconds
before clicking Confirm. Pairing then completed successfully.

Automated tests

python3 -m unittest -v test.gui.test_notification test.main.applet.test_bluez_agent

Ran 3 tests in 0.004s
OK

The full local suite ran 297 tests. All 293 tests supported by the local test
environment passed; four unrelated tests could not run because python-dbusmock,
a writable /var/run, and a test /dev/rfkill device were unavailable. CI
provides those prerequisites.

Related reports include #669, #1525, and #2477.

@sonarqubecloud

Copy link
Copy Markdown

@infirit

infirit commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

This is a design decision by cinnamon to move/hide notifications to the applet after a fixed time. It's still there and actionable if you click on it in the tray.

@Th0masL

Th0masL commented Aug 30, 2026

Copy link
Copy Markdown
Author

Hmm I see, that was far from clear to me that I could still access the notification somewhere.
I guess that means that you will not want to merge that change (which I understand).
Do you suggest I propose a fix on the cinnamon's side ?

@infirit

infirit commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

I don't see this being merged and I also doubt Cinnamon will change this behaviour.

Pairing/adding new devices should be done in a dedicated wizard, like blueman did before. Then you can show all the relevant details, choices etc in a single window. I wanted to bring it back for a while but if someone want to work on this that would be great.

@Th0masL

Th0masL commented Aug 30, 2026

Copy link
Copy Markdown
Author

After investigating Cinnamon’s notification handling, I think there may be a smaller Blueman-side solution than introducing a persistent GTK dialog.

Blueman first displays a “Connected” notification for the temporary pairing connection. The actionable confirmation is queued behind it:

Connection → confirmation request: 0.754 seconds
Connection → “Connected” marker: 0.739 seconds
“Connected” marker → six-digit marker: 4.127 seconds
Six-digit popup visible: 4.323 seconds
Outcome: authentication-cancelled

The non-actionable banner delays the confirmation by about four seconds. Cinnamon then shows the confirmation for only about four seconds before moving it into the notification tray.

A focused solution could be:

  • Suppress “Connected” notifications for devices that are not yet paired or bonded. This message is misleading during pairing and delays the actionable notification.
  • Give RequestConfirmation notifications critical/action-required urgency so notification daemons can keep them visible appropriately.

This should address the main usability problem with a small, standards-based Blueman change. I can revise and test the PR using this approach if the maintainers prefer it.

@infirit

infirit commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

You can disable the ConnectionNotifier plugin in the plugin-dialog. Does this make things work better?

edit: you can set the urgency hint on the Notification class, set_hint("urgency", 2), iirc 2 is urgent.

@Th0masL

Th0masL commented Aug 31, 2026

Copy link
Copy Markdown
Author

Yeah, but my point is to try to make the user experience easier out of the box for everybody without having to change settings.

I'm an IT guy and it still took me couple of minutes to understand why I couldn't get my keyboard pair easily.
So I'm assuming other people might have similar frustrating experience.

@cschramm

Copy link
Copy Markdown
Member
  • Suppress “Connected” notifications for devices that are not yet paired or bonded. This message is misleading during pairing and delays the actionable notification.

Connected && !Paired is a legitimate steady state, not just a pairing transient. Pairing is only required for services that demand authentication. Peripherals frequently never pair at all. They sit at Connected=True, Paired=False for their whole lifetime. Classic profiles that don't require authentication include receiving a file via OBEX push from an unpaired phone or various SPP adapters (OBD dongles etc.).

Also, suppressing would mean losing the notification as of now, as there is no other trigger than the Connected transition

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.

3 participants