Files
infrastructure/docs/wip/KVM-SWITCH-MAC-NOBARA.md
Kaloyan Danchev 2a3bdb9934
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Fix KVM switch: working Nobara → Mac with correct HID++ commands
- Discovered correct HID++ feature indices per device
- Updated to_mac.sh with working hidapitester commands
- Updated docs with complete setup instructions
- Mac → Nobara direction still needs work (TODO)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:38:17 +02:00

8.0 KiB

One-Key KVM: Mac ↔ Nobara

Status: WIP - Nobara → Mac working, Mac → Nobara needs work Hardware: Dell U3821DW, MX Keys S, MX Master 4 for Mac Updated: 2026-02-01

Overview

Software KVM solution to switch the Dell U3821DW ultrawide monitor and Logitech MX peripherals between Mac (MacBook Air M3) and Nobara Linux using DDC/CI and HID++ commands.

Hardware Mapping

Monitor Inputs

Input Code Port Computer
USB-C 27 USB-C Mac
HDMI 2 18 HDMI 2 Nobara

Peripheral Hosts (Logi Bolt)

Host Index (HID++) Connection Computer
1 0x00 Bolt #1 MacBook Air (Bluetooth?)
2 0x01 Bolt #1 Nobara (xtrm-pc)
3 0x02 Bolt #2 MacBook Air (via monitor hub)

Devices

  • Monitor: Dell U3821DW (38" Ultrawide, DDC/CI enabled)
  • Keyboard: Logitech MX Keys S (Easy-Switch capable)
  • Mouse: Logitech MX Master 4 for Mac (Easy-Switch capable)
  • Receiver: Logi Bolt USB (PID: 046d:c548)

Nobara Setup

1. Install dependencies

sudo dnf install ddcutil

2. Add user to i2c group (requires reboot)

sudo usermod -aG i2c $USER

3. Install hidapitester

curl -sL https://github.com/todbot/hidapitester/releases/latest/download/hidapitester-linux-amd64.zip -o /tmp/hidapitester.zip
unzip -o /tmp/hidapitester.zip -d ~/bin/
chmod +x ~/bin/hidapitester

4. Udev rule for non-root HID access

echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c548", MODE="0666"' | \
  sudo tee /etc/udev/rules.d/99-logitech-bolt.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

5. Reboot

sudo reboot

6. Verify setup

# Check i2c group membership
groups | grep i2c

# Check monitor detection
ddcutil detect

# Check Bolt receiver
~/bin/hidapitester --vidpid 046d/c548 --list-detail

7. Copy script and set up shortcut

# Copy script
mkdir -p ~/scripts
cp /path/to/xtrm/infrastructure/scripts/kvm/to_mac.sh ~/scripts/
chmod +x ~/scripts/to_mac.sh

# Set up keyboard shortcut (Ctrl+Shift+Up)
gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings \
  "$(gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings | sed "s/]$/, '\/org\/gnome\/settings-daemon\/plugins\/media-keys\/custom-keybindings\/custom-kvm\/']/")"

gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom-kvm/ name 'KVM Switch to Mac'
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom-kvm/ command '/home/jazzymc/scripts/to_mac.sh'
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom-kvm/ binding '<Shift><Control>Up'

Mac Setup

1. Install dependencies

# Install m1ddc (DDC control for Apple Silicon)
brew install m1ddc

# Install hidapitester
curl -sL https://github.com/todbot/hidapitester/releases/latest/download/hidapitester-macos-arm64.zip -o /tmp/hidapitester.zip
unzip -o /tmp/hidapitester.zip -d ~/bin/
chmod +x ~/bin/hidapitester

2. Copy script

mkdir -p ~/scripts
cp /path/to/xtrm/infrastructure/scripts/kvm/to_nobara.sh ~/scripts/
chmod +x ~/scripts/to_nobara.sh

3. Set up keyboard shortcut

TODO: Configure via Logi Options+ or macOS Shortcuts app

Scripts

Switch to Mac (Run on Nobara) - WORKING

Location: ~/scripts/to_mac.sh

#!/bin/bash
# KVM Switch: Nobara → Mac
# Switches monitor to USB-C and peripherals to Host 3 (Mac)
#
# Host mapping (0-indexed in HID++):
#   Host 1 (0x01): Nobara (xtrm-pc)
#   Host 3 (0x02): Mac (Kaloyan's MacBook Air)
#
# HID++ command format: ReportID, DeviceIdx, FeatureIdx, Function, HostIdx, 0, 0
#   Mouse:    device 0x03, feature 0x0E (CHANGE_HOST)
#   Keyboard: device 0x02, feature 0x0A (CHANGE_HOST)
#   Function 0x10 = setCurrentHost (function 0 << 4)

HIDAPITESTER="$HOME/bin/hidapitester"

echo "Switching to Mac..."

# 1. Switch Mouse (MX Master 4) to Host 3 (Mac)
echo "  Mouse -> Mac..."
"$HIDAPITESTER" --vidpid 046d/c548 --usage 0x0001 --usagePage 0xff00 \
    --open --length 7 --send-output 0x10,0x03,0x0E,0x10,0x02,0x00,0x00 2>/dev/null || \
    echo "  [WARN] Mouse switch failed"

# 2. Switch Keyboard (MX Keys S) to Host 3 (Mac)
echo "  Keyboard -> Mac..."
"$HIDAPITESTER" --vidpid 046d/c548 --usage 0x0001 --usagePage 0xff00 \
    --open --length 7 --send-output 0x10,0x02,0x0A,0x10,0x02,0x00,0x00 2>/dev/null || \
    echo "  [WARN] Keyboard switch failed"

# 3. Switch Monitor to USB-C (Dell U3821DW input code: 27)
echo "  Monitor -> USB-C..."
if command -v ddcutil &>/dev/null; then
    ddcutil setvcp 60 27 2>/dev/null || \
        echo "  [WARN] Monitor switch failed (DDC/CI disabled or permissions issue)"
else
    echo "  [WARN] ddcutil not installed"
fi

echo "Done!"

Switch to Nobara (Run on Mac) - NEEDS WORK

Location: ~/scripts/to_nobara.sh

#!/bin/bash
# KVM Switch: Mac → Nobara
# TODO: Needs correct HID++ feature indices for Mac's Bolt receiver

echo "Switching to Nobara..."

# Switch Monitor to HDMI 2
m1ddc set input 18

# TODO: Find correct HID++ commands for Mac
# The feature indices may differ on Mac's Bolt receiver
# Use: hidapitester --vidpid 046d/c548 --list-detail
# Then use solaar (if available) or HID++ protocol to find feature indices

echo "Done!"

HID++ Command Reference

Command Format

Byte Purpose Description
0 Report ID 0x10 (short report)
1 Device Index Device slot on Bolt receiver (0x01-0x06)
2 Feature Index Device-specific - must be discovered per device
3 Function 0x10 = setCurrentHost (function 0 << 4)
4 Host Index 0x00=Host1, 0x01=Host2, 0x02=Host3
5-6 Padding 0x00, 0x00

Current Device Configuration (Nobara Bolt Receiver)

Device Solaar Index HID++ Device Index CHANGE_HOST Feature Index
MX Keys S 2 0x02 0x0A (10)
MX Master 4 for Mac 3 0x03 0x0E (14)

Finding Feature Indices

The CHANGE_HOST feature index varies per device. To find it:

# On Linux with solaar
solaar show <device_number> 2>&1 | strings | grep "CHANGE HOST"
# Look for: "14: CHANGE HOST {1814}" - the number before the colon is the feature index

DDC Input Codes (Dell U3821DW)

Input Code Hex
DisplayPort 1 15 0x0F
DisplayPort 2 16 0x10
HDMI 1 17 0x11
HDMI 2 18 0x12
USB-C 27 0x1B

Troubleshooting

Monitor doesn't switch

  • DDC/CI disabled: Monitor Menu → Others → DDC/CI → On
  • Linux permissions: Ensure user in i2c group, reboot after adding
  • Verify: ddcutil detect should show monitor

Peripherals don't switch

  • Wrong feature index: Feature indices are device-specific and must be discovered
  • Device offline: Move mouse/press key to wake device before switching
  • Wrong device index: Check solaar show for correct device numbers

Solaar vs hidapitester

  • solaar config doesn't reliably switch hosts on some devices
  • Use hidapitester with correct HID++ commands instead
  • Solaar is useful for discovering device info and feature indices

Files Location

Nobara:

  • ~/scripts/to_mac.sh - Switch to Mac (working)
  • ~/bin/hidapitester - HID control tool

Mac:

  • ~/scripts/to_nobara.sh - Switch to Nobara (needs work)
  • ~/bin/hidapitester - HID control tool

Repository:

  • infrastructure/scripts/kvm/to_mac.sh
  • infrastructure/scripts/kvm/to_nobara.sh

TODO

  • Nobara → Mac switching (working)
  • Set up keyboard shortcut on Nobara (Ctrl+Shift+Up)
  • Mac → Nobara switching - needs correct HID++ feature indices for Mac's Bolt receiver
  • Set up keyboard shortcut on Mac
  • Test monitor switching from Mac side