From 771895d839e9570ba8d586d8d36c2dd925e47a8e Mon Sep 17 00:00:00 2001 From: SirBlob Date: Sun, 1 Nov 2026 19:40:39 -0500 Subject: [PATCH] Prefer 5GHz Wi-Fi and rename the repo to dotfiles --- README.md | 4 +- bootstrap.sh | 2 +- .../dispatcher.d/90-blob-wifi-prefer-5ghz | 108 ++++++++++++++++++ docs/install.md | 8 +- install/steps/services.sh | 4 + 5 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 default/networkmanager/dispatcher.d/90-blob-wifi-prefer-5ghz diff --git a/README.md b/README.md index 900fed8..4c032f8 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ On a fresh Arch install, logged in as your own user with sudo and a network connection: ```bash -curl -fsSL https://git.sirblob.co/SirBlob/blomarchy/raw/branch/main/bootstrap.sh | bash +curl -fsSL https://git.sirblob.co/SirBlob/dotfiles/raw/branch/main/bootstrap.sh | bash ``` `bootstrap.sh` installs `git`, clones this repository to `~/dotfiles` (or @@ -93,7 +93,7 @@ It runs these steps, in this order, and every one of them is idempotent: | 4. Config | copies `hypr/`, the themed app configs, `blob/shell.json`, and the uwsm environment into `~/.config`, sets the default apps for images, video, PDFs, office files, text and archives, and writes `/etc/profile.d/blob.sh` so a login shell finds the `blob` command | | 5. First theme | links `~/wallpapers` to the checkout, applies `flats` headless, picks a background, and links the btop and Neovim theme files, so the first login is not a blank desktop | | 6. User units | installs the session services into `~/.config/systemd/user` and enables them | -| 7. systemd drop-ins | writes the shutdown timeouts, oomd thresholds, plocate prune paths, and sleep hooks under `/etc`, and turns Wi-Fi power saving off in NetworkManager | +| 7. systemd drop-ins | writes the shutdown timeouts, oomd thresholds, plocate prune paths, and sleep hooks under `/etc`, turns Wi-Fi power saving off in NetworkManager, and has it prefer 5GHz over 2.4GHz | | 8. System services | enables NetworkManager, resolved, bluetooth, cups, avahi, docker, power-profiles-daemon, and oomd, masks `NetworkManager-wait-online`, sets the boot splash to `branding/blob_boot.png`, and sets GRUB up with every other installed OS in its menu | | 9. Login screen | installs the session entry, the SDDM config and the Blob login theme, enables `sddm.service`, and sets the default target to `graphical.target` | | 10. Reload | reloads systemd, restarts the running user services, and in a running session re-renders the theme, reloads Hyprland, and restarts the Blob shell | diff --git a/bootstrap.sh b/bootstrap.sh index d7ee853..42948ca 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,7 +2,7 @@ set -e -repo_url="${BLOB_REPO_URL:-https://git.sirblob.co/SirBlob/blomarchy.git}" +repo_url="${BLOB_REPO_URL:-https://git.sirblob.co/SirBlob/dotfiles.git}" repo_branch="${BLOB_REPO_BRANCH:-main}" checkout_dir="${BLOB_CHECKOUT_DIR:-$HOME/dotfiles}" diff --git a/default/networkmanager/dispatcher.d/90-blob-wifi-prefer-5ghz b/default/networkmanager/dispatcher.d/90-blob-wifi-prefer-5ghz new file mode 100644 index 0000000..304dd35 --- /dev/null +++ b/default/networkmanager/dispatcher.d/90-blob-wifi-prefer-5ghz @@ -0,0 +1,108 @@ +#!/bin/bash + +interface=$1 +action=$2 +connection_uuid=${CONNECTION_UUID:-} + +minimum_signal=40 +signal_margin=20 +retry_seconds=600 +settle_seconds=5 +state_dir=/run/blob-wifi-band +field_separator=$'\x1f' + +nm_get() { + LC_ALL=C nmcli -g "$@" 2>/dev/null +} + +frequency_band() { + local mhz=${1%%[!0-9]*} + [[ -n $mhz ]] || return 1 + + if ((mhz >= 2400 && mhz < 2500)); then + echo "2.4" + elif ((mhz >= 4900 && mhz < 7125)); then + echo "5" + else + return 1 + fi +} + +should_run() { + [[ $action == up && -n $interface && -n $connection_uuid ]] || return 1 + [[ $(nm_get GENERAL.TYPE device show "$interface") == wifi ]] || return 1 + [[ -z $(nm_get 802-11-wireless.band connection show "$connection_uuid") ]] || return 1 + [[ -z $(nm_get 802-11-wireless.bssid connection show "$connection_uuid") ]] || return 1 +} + +attempted_recently() { + local marker="$state_dir/$connection_uuid" + [[ -e $marker ]] || return 1 + (($(date +%s) - $(stat -c %Y "$marker") < retry_seconds)) +} + +mark_attempt() { + mkdir -p "$state_dir" + touch "$state_dir/$connection_uuid" +} + +list_access_points() { + nm_get IN-USE,FREQ,SIGNAL,BSSID,SSID device wifi list ifname "$interface" --rescan no | + sed "s/\\\\:/$field_separator/g" +} + +find_better_access_point() { + local in_use frequency signal bssid ssid + local current_ssid="" current_signal=0 current_band="" + local best_bssid="" best_signal=0 + local access_points + + access_points=$(list_access_points) + + while IFS=: read -r in_use frequency signal bssid ssid; do + [[ $in_use == "*" ]] || continue + current_ssid=${ssid//$field_separator/:} + current_signal=$signal + current_band=$(frequency_band "$frequency") + done <<<"$access_points" + + [[ $current_band == "2.4" && -n $current_ssid ]] || return 1 + + while IFS=: read -r in_use frequency signal bssid ssid; do + [[ ${ssid//$field_separator/:} == "$current_ssid" ]] || continue + [[ $(frequency_band "$frequency") == "5" ]] || continue + ((signal > best_signal)) || continue + best_signal=$signal + best_bssid=${bssid//$field_separator/:} + done <<<"$access_points" + + [[ -n $best_bssid ]] || return 1 + ((best_signal >= minimum_signal)) || return 1 + ((best_signal + signal_margin >= current_signal)) || return 1 + + echo "$best_bssid" +} + +switch_to_faster_band() { + local target_bssid + + nmcli device wifi rescan ifname "$interface" &>/dev/null + sleep "$settle_seconds" + + [[ $(nm_get GENERAL.CONNECTION device show "$interface") == "$(nm_get connection.id connection show "$connection_uuid")" ]] || return 0 + + target_bssid=$(find_better_access_point) || return 0 + + mark_attempt + nmcli connection up uuid "$connection_uuid" ifname "$interface" ap "$target_bssid" &>/dev/null +} + +should_run || exit 0 +attempted_recently && exit 0 + +if [[ -z ${BLOB_WIFI_BAND_DETACHED:-} ]]; then + BLOB_WIFI_BAND_DETACHED=1 setsid -f "$0" "$@" &>/dev/null + exit 0 +fi + +switch_to_faster_band diff --git a/docs/install.md b/docs/install.md index 5fd2ed6..392badf 100644 --- a/docs/install.md +++ b/docs/install.md @@ -112,7 +112,11 @@ with `--check`. oomd pressure thresholds, the plocate prune paths, and the sleep hooks. `/etc/NetworkManager/conf.d/10-blob-wifi-powersave.conf` turns Wi-Fi power saving off, and NetworkManager is reloaded when it changes. -8. **System services** are enabled: NetworkManager, resolved, bluetooth, cups, + `/etc/NetworkManager/dispatcher.d/90-blob-wifi-prefer-5ghz` moves a Wi-Fi + connection that comes up on 2.4GHz to the same network on 5GHz or 6GHz when + that band has a usable signal. It skips profiles that have a band or BSSID + pinned with `blob network band`. +8. **System services** are enabled: NetworkManager and its dispatcher, resolved, bluetooth, cups, avahi, docker, power-profiles-daemon, and oomd. `NetworkManager-wait-online.service` is masked so a slow DHCP lease cannot hold up the login screen, and `plymouth-start.service` and @@ -218,7 +222,7 @@ things, the first three only when the tool is installed: | `powerprofilesctl` function | runs it on `/usr/bin/python3`, since a mise Python ahead on `PATH` has no `gi` module | `--cmd cd` replaces `cd` rather than adding a `z` command, so -`cd blomarchy` jumps to the last matching directory you have visited from +`cd dotfiles` jumps to the last matching directory you have visited from anywhere, while `cd ./relative/path`, `cd -` and `cd` with no argument keep behaving exactly as the builtin does. `cdi` picks from the matches interactively through `fzf`, and `zoxide query -ls` prints the database. diff --git a/install/steps/services.sh b/install/steps/services.sh index 55ec8b5..feea763 100644 --- a/install/steps/services.sh +++ b/install/steps/services.sh @@ -1,5 +1,6 @@ system_services=( NetworkManager.service + NetworkManager-dispatcher.service systemd-resolved.service bluetooth.service cups.service @@ -122,6 +123,9 @@ install_network_config() { install_root_file "$repo_dir/default/networkmanager/conf.d/10-blob-wifi-powersave.conf" \ /etc/NetworkManager/conf.d/10-blob-wifi-powersave.conf \ "NetworkManager/conf.d/10-blob-wifi-powersave.conf" + install_root_file "$repo_dir/default/networkmanager/dispatcher.d/90-blob-wifi-prefer-5ghz" \ + /etc/NetworkManager/dispatcher.d/90-blob-wifi-prefer-5ghz \ + "NetworkManager/dispatcher.d/90-blob-wifi-prefer-5ghz" 0755 [[ $check == true ]] && return 0 (( changes > changes_before )) || return 0