LizardByte / LizardByte/Sunshine

Native touch is letterbox-scaled twice when client canvas and video aspect ratios differ

Open
#5,461 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ai
Dominant language
C++
Stars
41.3k
Forks
2.1k
Avg merge
23h 47m
Merged PRs (30d)
124

Description

## Describe the bug

Native-touch coordinates that the Moonlight client already normalizes to the
visible video area are transformed through Sunshine's client touch port a
second time. With a 16:9 stream displayed inside a 4:3 client canvas, Linux
`Touch passthrough` receives full-range X but only the top 75% of Y.

I searched existing issues and read the input documentation. This is related
to, but more specific than #2166: the client coordinates are already correct,
and the additional 0.75 factor follows the client-canvas/video aspect-ratio
mismatch.

### Reproduction

Host:

- Ubuntu 26.04, x86_64
- KDE Plasma/Wayland, KMS capture
- NVIDIA RTX A4500 Laptop GPU, driver 595.84
- Sunshine deb `2026.516.143833`, commit `14ffa6f`
- captured output: 3840x2160 (16:9)

Client:

- iPad running VoidLink Extreme 3.4.5
- 4:3 client canvas
- Native Touch enabled

1. Enable `min_log_level = 0` and restart Sunshine.
2. Start the 16:9 stream.
3. Sweep native touch from the top to the bottom of the visible video.
4. Compare Sunshine's touch-packet `x`/`y` with
`EV_ABS/ABS_MT_POSITION_X/Y` from `Touch passthrough`.

Observed:

- client X: `0..0.9996`; device X spans the full axis.
- client Y: `0..0.9937`; device Y is `0.7504 * client_y`.
- mapping is top-anchored; there is no lower-letterbox offset.
- local correction: `TECHNIKA_TOUCH_CAL=0,0,65535,49484`.

The measured bottom point was client `y=0.9937`, device/game
`y=8104/10800`; expected video-bottom raw Y was 8155, and the observed
normalized-device anchor was 49484. A full-glass sweep confirmed that the
client itself sent nearly the full normalized Y range.

## Expected behavior

Native touch `(0,0)..(1,1)` is over the visible video area, so the virtual
touchscreen should receive the full selected-display range exactly once.
Client letterbox exclusion should not be reapplied by the host.

## Source evidence / latest prerelease

Sunshine passes native touch normalized to `65535 x 65535` through
`client_to_touchport()`:

- measured stable:
[`client_to_touchport()`](https://github.com/LizardByte/Sunshine/blob/14ffa6fdaa53f7b51512be2b3d24f3939695403c/src/input.cpp#L460-L505),
[native-touch caller](https://github.com/LizardByte/Sunshine/blob/14ffa6fdaa53f7b51512be2b3d24f3939695403c/src/input.cpp#L935-L978)
- latest prerelease `v2026.726.710` (`7cb9207`):
[`client_to_touchport()`](https://github.com/LizardByte/Sunshine/blob/7cb92071ac4394698e92ff6d070d310db9acc32c/src/input.cpp#L578-L623),
[native-touch caller](https://github.com/LizardByte/Sunshine/blob/7cb92071ac4394698e92ff6d070d310db9acc32c/src/input.cpp#L1120-L1163)

The mapping implementation is equivalent between the measured stable build
and latest prerelease. To be precise, the hardware measurement was made on
stable; I source-verified the latest prerelease on 2026-07-29 but did not
substitute its binary during an unrelated patched-inputtino deployment.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/input.cpp with client_to_touchport() and its native-touch caller, using the linked stable and prerelease locations as entry points. Reproduce the 16:9-to-4:3 case with verbose logging and compare the touch-packet coordinates with the Touch passthrough axis. Done means native touch over the visible video maps to the full selected-display range without applying client letterboxing twice.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, linux
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
56/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.