fix(docking): dock automatically; repair cards parked on pro-audio
All checks were successful
Check / eval (push) Successful in 3m9s
All checks were successful
Check / eval (push) Successful in 3m9s
Bernardo's retest on the AMD dev box. Two of the four reports were never running the new code — both watchers are Hyprland `exec-once`, so a `nomarchy-home` switch leaves the old processes alive until relogin; only `nomarchy-dock-audio`, a user service, had picked the fix up. The journal showed the old watcher's `event=monitoradded` next to the new audio tool's `result=no-available-sink`, which is what gave it away. The other two were real. Automatic dock mode did not exist. The watcher auto-*undocked* when the last external left, but on plug it only ever matched a display profile — and with no profile saved and displayProfileAuto unset it did nothing at all, while `Dock mode` was reachable only from the menu. Half the pair being automatic is what made the dock feel broken: the session came home by itself but never left. Mirror it, letting a matched profile win as the more specific layout. The BenQ's audio was unreachable by any means because WirePlumber had the GPU's DisplayPort card pinned to `pro-audio`, whose raw `pro-output-N` sinks carry no ports, no routing and no volume — so no sink matched, nothing was selectable, and the profile is stored per card and so survived forever. The monitor's own USB card is input-only (every profile has sinks: 0), leaving DisplayPort as the only path to its speakers. Repair the card when a plug finds nothing routable, which is both the symptom and the only moment worth touching profiles: narrow to cards carrying an *available* HDMI/DP port — the monitor asking for audio over the cable — so the internal analog card is never touched and a considered pro-audio setup elsewhere survives. Verified V2: checks.docking-ux and checks.dock-audio pass with guards for both; the repair filter picks exactly the GPU card → HiFi against the dev box's live graph, leaving the BenQ USB, internal analog and Bluetooth cards alone. Hotplug itself still needs hardware — HARDWARE-QUEUE round 6, which now leads with the relogin requirement that invalidated round 5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -454,6 +454,31 @@ ${lib.concatStringsSep "\n" (lib.mapAttrsToList
|
||||
fi
|
||||
}
|
||||
|
||||
# Entering dock mode is the mirror of the automatic undock below: the
|
||||
# session already comes back to the panel by itself when the last
|
||||
# external leaves, so an arriving external has to take it the other way
|
||||
# or the pair is only half-automatic and the menu has to finish the job.
|
||||
# A display profile is a deliberate, more specific layout, so it wins —
|
||||
# the caller only reaches here when none is in effect.
|
||||
auto_dock() {
|
||||
internal=$(internal_output)
|
||||
target=$(external_outputs | ${pkgs.coreutils}/bin/head -n 1)
|
||||
[ -n "$internal" ] && [ -n "$target" ] || return
|
||||
# `monitors` (unlike `monitors all`) lists only enabled outputs, so the
|
||||
# panel still being there is what "not docked yet" means. Re-docking
|
||||
# an already-docked session would move nothing and disable nothing.
|
||||
hyprctl monitors -j 2>/dev/null \
|
||||
| jq -e --arg m "$internal" 'any(.[]; .name == $m)' >/dev/null || return
|
||||
if "$TRANSITION" dock "$internal" "$target" "$target, preferred, auto, 1"; then
|
||||
log "auto-dock internal=$internal target=$target result=ok"
|
||||
${pkgs.libnotify}/bin/notify-send -a Nomarchy "Display" \
|
||||
"Docked — every laptop workspace moved to $target; laptop panel off." \
|
||||
2>/dev/null || true
|
||||
else
|
||||
log "auto-dock internal=$internal target=$target result=failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# The set of connected outputs — not the IPC event stream — is the source
|
||||
# of truth. Hyprland's socket can miss or drop events (see the loop
|
||||
# below), and a lost monitoradded used to mean no docking profile, no
|
||||
@@ -506,6 +531,10 @@ ${lib.concatStringsSep "\n" (lib.mapAttrsToList
|
||||
log "outputs-changed removed=$gone transition=undock"
|
||||
fi
|
||||
check_monitors
|
||||
if [ -n "$added_ext" ] \
|
||||
&& [ "$(nomarchy-display-profile active 2>/dev/null || echo none)" = "none" ]; then
|
||||
auto_dock
|
||||
fi
|
||||
fi
|
||||
|
||||
# Safety invariants, re-checked regardless of whether the set moved.
|
||||
|
||||
Reference in New Issue
Block a user