3.3 KiB
3.3 KiB
title, created, updated, type, namespace, tags, sources, confidence, related
| title | created | updated | type | namespace | tags | sources | confidence | related | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| HTPC — magic4pc (LG Magic Remote) | 2026-05-28 | 2026-05-28 | tech | family |
|
|
medium |
|
HTPC — magic4pc (LG Magic Remote)
Go-client for using the LG Magic Remote (webOS TV app) as HTPC
mouse/keyboard input. Fork: mallexxx/magic4pc_altclient branch
bazzite-linux.
LG TV: 192.168.1.75, HTPC: 192.168.1.86.
Architecture
- TV server: webOS app on LG TV → sends UDP to fixed source port 9106
- HTPC client:
/usr/local/bin/magic4pc, UDP listener - xdotool: single persistent process via stdin pipe (mouse + keyboard)
- ydotool: gamescope-specific keys (Ctrl+1, Ctrl+2) via
/run/user/1000/.ydotool_socket
Session detection:
isGamescopeSession()— scans/proc/*/cmdlineforkwin_wayland; if absent → gamescope (Steam Big Picture mode)activeDisplay()— KDE uses Xwayland display from kwin args; gamescope uses:1(game) if visible windows present, else:0(Steam BP)
Button Mapping
| Button | Keycode | Gamescope | KDE Desktop |
|---|---|---|---|
| Red | 403 | Ctrl+1 (Steam menu) | Super |
| Green | 404 | Escape | Escape |
| Yellow | 405 | Ctrl+2 (Steam QAM) | Middle click |
| Blue | 406 | Right click | Right click |
| Back | 461 | Mouse X1 | Mouse X1 |
| D-pad | 37-40 | Arrow keys | Arrow keys |
| Ch+/Ch- | 33/34 | PageUp/Down | PageUp/Down |
| Play/Stop/Pause | 415/413/19 | XF86Audio* | XF86Audio* |
| Touch (swipe) | — | mousemove (scaled) | mousemove |
| Tap | — | Left click | Left click |
Mouse Coordinate Mapping
TV sends coordinates in 0–1920 × 0–1080 space.
In gamescope: uses letterbox algorithm.
- Find active window: (a) under cursor via
getmouselocation, or (b) largest bounding-box window (non-popup, highest ID) - Compute 16:9 letterbox viewport from window width:
lb_h = win_w * 9/16 - Compute offset:
off_y = -(lb_h - win_h) / 2 - Map:
x11_x = tv_x * scale + off_x; clip negatives to 0
In KDE: getdisplaygeometry → scale = display / 1920×1080.
Key Pitfalls
| Problem | Fix |
|---|---|
| TV "service error" / won't reconnect | Fixed source UDP port 9106 |
| TV stuck "waiting for client" | Server keepalive timeout 10s |
| KDE XTest prompt on every click | Single persistent xdotool process |
| KDE XTest prompt after xdotool restart | XwaylandEisNoPrompt=true in kwinrc |
| Wrong mouse coordinates | Dynamic scale via xdotool getdisplaygeometry |
Binary lost after rpm-ostree upgrade |
Rebuild and redeploy |
Deploy
# Build on Mac
cd ~/Developer/magic4pc_altclient
GOOS=linux GOARCH=amd64 go build -o magic4pc .
# Copy + restart on HTPC
scp magic4pc htpc:/home/bazzite/magic4pc/magic4pc
echo bazzite | sudo -S systemctl stop magic4pc.service
echo bazzite | sudo -S cp /home/bazzite/magic4pc/magic4pc \
/usr/local/bin/magic4pc
echo bazzite | sudo -S systemctl start magic4pc.service
Sudoers rule (no-password systemctl):
bazzite ALL=(ALL) NOPASSWD: /usr/bin/systemctl
See Also
- htpc-bazzite-proton — Proton game compatibility on this HTPC
- tech/htpc-steam-emulators — Steam, emulators, gamepad config