Files
obsidian-vault/wiki/tech/htpc-magic4pc.md
T

3.3 KiB
Raw Blame History

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
htpc
how-to
pitfalls
family/how-to/htpc-magic4pc.md
medium
htpc-bazzite-proton
tech/htpc-steam-emulators

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/*/cmdline for kwin_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 01920 × 01080 space.

In gamescope: uses letterbox algorithm.

  1. Find active window: (a) under cursor via getmouselocation, or (b) largest bounding-box window (non-popup, highest ID)
  2. Compute 16:9 letterbox viewport from window width: lb_h = win_w * 9/16
  3. Compute offset: off_y = -(lb_h - win_h) / 2
  4. 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