All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- 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>
8.0 KiB
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
i2cgroup, reboot after adding - Verify:
ddcutil detectshould 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 showfor correct device numbers
Solaar vs hidapitester
solaar configdoesn't reliably switch hosts on some devices- Use
hidapitesterwith 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.shinfrastructure/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