Skip to content

fix(bluetooth): unblock rfkill when enabling a blocked adapter#2520

Closed
Mic92 wants to merge 1 commit into
noctalia-dev:mainfrom
Mic92:bluetooth-rfkill-unblock
Closed

fix(bluetooth): unblock rfkill when enabling a blocked adapter#2520
Mic92 wants to merge 1 commit into
noctalia-dev:mainfrom
Mic92:bluetooth-rfkill-unblock

Conversation

@Mic92

@Mic92 Mic92 commented Apr 21, 2026

Copy link
Copy Markdown

Motivation

quickshell's BluetoothAdapter.setEnabled() early-returns with Cannot enable adapter because it is blocked by rfkill and never writes the Powered property when the adapter is in the Blocked state. That leaves the bluetooth toggle dead after a partial airplane-mode exit — e.g. the laptop's airplane Fn key (kernel rfkill block all), then wifi is re-enabled via NetworkManager while bluetooth stays soft-blocked. systemd-rfkill persists that block across reboots, so the toggle stays broken until the user runs rfkill unblock bluetooth by hand.

logind grants the active seat user rw on /dev/rfkill (uaccess), so the shell can lift the soft block itself — same mechanism setAirplaneMode() already relies on. When the adapter is blocked and the user asks to enable it, run rfkill unblock bluetooth && bluetoothctl power on and let the resulting state change propagate back through quickshell.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring

Related Issue

  • n/a

Testing

  • Tested on niri
  • Tested on Hyprland
  • Tested on sway
  • Tested with different bar positions and density settings
  • Tested at different interface scaling values
  • Tested with multiple monitors (if applicable)

Steps:

  1. rfkill block bluetoothbluetoothctl show reports PowerState: off-blocked
  2. Click the bluetooth toggle in the bar / control center
  3. Before: log spams Cannot enable adapter because it is blocked by rfkill, toggle does nothing
  4. After: log shows Bluetooth Adapter rfkill-blocked, unblocking, adapter ends up Powered: yes

Screenshots / Videos

n/a (no visual change)

Checklist

  • Code follows project style guidelines
  • Self-reviewed my code
  • No new warnings or errors
  • Documentation or comments updated (if relevant)

Additional Notes

bluetoothctl power on is chained after the unblock because quickshell's setEnabled would still see the stale Blocked state if called synchronously; going through bluetoothctl avoids the race without adding a timer.

quickshell's BluetoothAdapter.setEnabled() bails out with "Cannot enable
adapter because it is blocked by rfkill" and never writes the Powered
property when the adapter is in the Blocked state. This leaves the
bluetooth toggle dead after a partial airplane-mode exit (e.g. the user
re-enables wifi via NetworkManager but bluetooth stays soft-blocked, and
systemd-rfkill happily persists that across reboots).

logind hands the active seat user rw on /dev/rfkill, so we can lift the
soft block ourselves and power the adapter via bluetoothctl without any
privilege escalation.
@notiant

notiant commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

I've changed the Bluetooth toggle to be disabled when Bluetooth is blocked a couple of days ago, so it would be great if you can revert this change in your PR (in BluetoothSubTab).
What do you mean by "quickshell's setEnabled would still see the stale Blocked state if called synchronously"? I can't see any difference in behavior when testing with and without bluetoothctl power on (unblocking alone powers on Bluetooth for me).

Mic92 added a commit to Mic92/dotfiles that referenced this pull request Apr 24, 2026
The Framework airplane Fn key issues a kernel rfkill block all. Re-enabling
wifi via NetworkManager leaves bluetooth soft-blocked, and quickshell's
BluetoothAdapter.setEnabled() refuses to write Powered in that state, so
the noctalia toggle goes dead and systemd-rfkill persists the block across
reboots. Patch noctalia to lift the soft block itself when the user asks
to enable a blocked adapter.

While at it, also carry the plugin-fetch dead-cwd fix locally so we no
longer depend on running from the fork branch.

Upstream:
  noctalia-dev/noctalia#2520
  noctalia-dev/noctalia#2343
@Mic92

Mic92 commented Apr 26, 2026

Copy link
Copy Markdown
Author

The actual bug is in quickshell actually... Let me move the patch to this layer. Here is the quickshell upstream project: quickshell-mirror/quickshell#765

will apply the same to the noctalia fork.

@Mic92

Mic92 commented Apr 26, 2026

Copy link
Copy Markdown
Author

That's the better fix: https://github.com/noctalia-dev/noctalia-qs/pull/37

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.

2 participants