Repository navigation
Conversation
The bundled externals are built for x86_64 only. On aarch64 hosts (e.g. Armada on the AYN Odin 2 Portal) the runner runs under native Python, and psutil fails to import because its extension has no pure-Python fallback. Every other native dependency falls back to pure Python. Add externals-aarch64 with psutil's abi3 aarch64 wheel and put externals-<machine> on sys.path ahead of externals. On x86_64 that directory doesn't exist, so behavior there is unchanged.
The flatpak was always started with --arch=x86_64, which fails immediately on aarch64 hosts where only the aarch64 build of Moonlight is installed. Use the host arch instead, and omit --arch for arches Moonlight is not published for. x86_64 hosts get exactly the same arguments as before.
The automatic resolution is screen size times devicePixelRatio, which can be odd with fractional scaling (1919x1078 on the AYN Odin 2 Portal). Host video encoders reject odd sizes, so Moonlight gets audio but never any video and ends the stream with "No video received from host". Even sizes are unchanged.
scripts/check-externals.py fails when requirements-<arch>.txt drifts from requirements.txt or externals-<arch> lacks the pinned version, and with --smoke imports every bundled package using moondeckrun.py's path order. CI runs both on ubuntu-latest and ubuntu-24.04-arm, and the nightly release waits for them. Also run pip via python3 -m in update-arch-externals.sh and mark the vendored aarch64 externals as generated so GitHub collapses them.
8205a64 to
6f77c57
Compare
| @@ -116,7 +116,12 @@ def update_dimensions(dimension: Dimension): | |||
|
|
|||
| logger.info(f"Using auto resolution from MoonDeck: {auto_resolution}") | |||
| if auto_resolution: | |||
| dimensions["size"] = { "width": auto_resolution["width"], "height": auto_resolution["height"] } | |||
| # Fractional display scaling can yield odd sizes (e.g. 1919x1078), which host video encoders reject | |||
There was a problem hiding this comment.
Shouldn't we go the other way? If the resolution is 1919x1078, due to fractional scaling it should have lost 1 pixel, so it should be 1920x1078, no?
Could you please play around with the manual resolution and see which variant works the best or fractional displays? Adding 1px or subtracting 1px.
| def __get_exec_with_args(self): | ||
| if self.exec_path is None: | ||
| exec = self.__get_flatpak_exec() | ||
| args = ["run", "--arch=x86_64", "--command=moonlight", self.flatpak_moonlight] | ||
| args = ["run", *self.__get_flatpak_arch_args(), "--command=moonlight", self.flatpak_moonlight] |
There was a problem hiding this comment.
| args = ["run", *self.__get_flatpak_arch_args(), "--command=moonlight", self.flatpak_moonlight] | |
| args = ["run", self.flatpak_moonlight] |
I think we should get rid o the arch and command args altogether and just let flatpak use defaults or user overrides.
| script_dir = Path(__file__).parent.resolve() | ||
| directories = [["lib"], ["externals"]] | ||
| # Arch-specific externals (e.g. aarch64 psutil) must shadow the default x86_64 ones; the dir only exists where needed | ||
| directories = [["lib"], [f"externals-{platform.machine()}"], ["externals"]] |
There was a problem hiding this comment.
I'm not a fan of this at all :/
Since it's only needed for psutils, I want to play around a little and see what other options are. I'll get back to you on this point later.
There was a problem hiding this comment.
I've removed psutil, please rebase.
Add ARM64 (aarch64) support
Most of the ~23k-line diff is vendored psutil. The real code change is about 160 lines.
This makes the same
moondeck.zipwork on aarch64 handhelds running Decky Loader. I tested it on an AYN Odin 2 Portal with Armada OS. There's no second build. The plugin picks the right dependencies when it starts, and on x86_64 the only behavior change is the resolution rounding below.What changed
The runner now puts
externals-<arch>on the path ahead ofexternals(inmain.py,moondeckrun.pyandcli.py). psutil is the only package that needs this. Its C extension is named.abi3.so, so an aarch64 Python tries to load the x86_64 copy and the import fails. Every other bundled package shipscpython-313-x86_64extensions, which aarch64 skips, and falls back to pure Python.externals-aarch64holds the psutil 7.0.0 aarch64 wheel. Its.pyfiles are identical to the copy already inexternals. Only the two.sofiles differ. On x86_64 the directory doesn't exist, so the extra path entry does nothing.moonlightproxy.pyruns the Moonlight flatpak for the host architecture instead of hardcoding--arch=x86_64. On x86_64 the arguments are the same as before.settingsparser.pyrounds the automatic resolution down to even dimensions. This one applies on every platform, and I think it's a fix everywhere. Fractional display scaling can report odd sizes (the Portal reports 1919×1078), and host video encoders refuse them. Even sizes like the Deck's 1280×800 don't change, and custom resolutions are left alone.A new
check-externalsCI job runs onubuntu-latestandubuntu-24.04-arm. It fails ifrequirements-aarch64.txtdrifts fromrequirements.txt, and it imports every bundled package using the runner's path order. The nightly release now waits for it.scripts/update-arch-externals.shregenerates the aarch64 copy. The README gets a short ARM64 section and a note on keeping dependencies in sync, and.gitattributescollapses the vendored directory in diffs.Keeping it in sync
When psutil is bumped in
requirements.txt, bumprequirements-aarch64.txtto the same version and runscripts/update-arch-externals.sh. CI fails if you forget. No other dependency needs this.Known limitations on ARM
SteamClient.System.DisplayManager. The existing try/catch handles it, so it only logs errors.Testing
check-externalspasses on x86_64 and arm64:psutil-7.0.0-cp36-abi3-manylinux2014_aarch64wheel, regenerated with the script.