Compare commits

..
1406 Commits
Author SHA1 Message Date
SecularSteve 9d2078adca Added translation using Weblate (Croatian) 2026-10-01 17:20:59 +02:00
SecularSteve e876833ee3 Translated using Weblate (German)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2026-10-01 17:20:59 +02:00
Jorys Paulin 1375116b71 Translated using Weblate (French)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2026-08-25 19:57:19 +00:00
NicolasS 146797ebe4 Translated using Weblate (French)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2026-08-25 19:57:18 +00:00
Brice SOULIVONG ed219e24dc Translated using Weblate (French)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2026-08-25 19:57:17 +00:00
Jorys Paulin a19cdedaac Translated using Weblate (French)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2026-08-10 08:58:42 +00:00
Damglador 50632a1749 Translated using Weblate (Ukrainian)
Currently translated at 91.2% (229 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2026-06-30 16:01:27 +02:00
Cameron Gutman b2d77f48f8 Rerun lrelease 2026-06-28 17:00:34 -05:00
Cameron Gutman 872731ceeb Fix a few more incorrect translation strings 2026-06-28 16:59:41 -05:00
Cameron Gutman 6cad296138 Remove all vanished translations 2026-06-28 16:52:52 -05:00
Cameron Gutman 444c6ccf06 Remove the experimental tag from HDR, AV1, and YUV 4:4:4 2026-06-28 16:51:58 -05:00
Cameron Gutman d35532b03e Rerun lupdate 2026-06-28 16:51:34 -05:00
Cameron Gutman 1e0110b0f4 Fix broken translation format strings 2026-06-28 16:41:05 -05:00
Cameron Gutman e5353d9758 Remove some translations that contained typos or incorrect grammar 2026-06-28 16:37:32 -05:00
Cameron Gutman f7c660129b Merge remote-tracking branch 'origin/weblate' 2026-06-28 16:26:37 -05:00
Cameron Gutman cdacb3d28d Loosen applist XML validation to accept empty app names
This matches the behavior of the Android and iOS clients.

Fixes #1921
2026-06-28 12:18:42 -05:00
Cameron Gutman 5034a324b4 Fix manual address being clobbered when using the CLI
Fixes #1920
2026-06-28 11:48:09 -05:00
Cameron Gutman e223bf9a1b Use libplacebo renderer on macOS 2026-06-25 22:30:03 -05:00
Cameron Gutman 6e231778a2 Fix blocking during rendering rather than in waitToRender() on MoltenVK
MoltenVK does a lazy fetch of the drawable only when it's being modified, so waitToRender() is completely ineffective as is. Rendering a small empty overlay in waitToRender() forces the next drawable wait to happen in waitToRender(), before we pick the current frame to render. This removes one display refresh period of latency when using V-sync.
2026-06-25 20:01:29 -05:00
Cameron Gutman d997a0d0c8 Dynamically adjust libplacebo swapchain depth on macOS
Direct-to-display mode on some Macs (M4 Mac Mini) can retain our drawables, which cuts the frame rate in half if we're in double-buffered mode.

We don't want to use triple-buffered mode all the time because it increases latency when used if not required, so detect delayed presentation and enable it on the fly if needed.
2026-06-23 21:09:20 -05:00
Cameron Gutman 06bd8a730b Force sRGB Vulkan swapchain on macOS to fix washed out colors 2026-06-23 19:19:56 -05:00
Cameron Gutman faa39875b6 Remove outdated comment 2026-06-21 15:19:44 -05:00
Cameron Gutman 170801ba9f Send the real client UID for non-GFE hosts
This allows non-GFE hosts to perform their own custom session
management while allowing all clients to share the same session
with GFE.
2026-06-21 15:18:12 -05:00
Cameron Gutman 1be234e96a Load the UID during initialization to avoid races loading it later 2026-06-21 15:14:58 -05:00
Cameron Gutman 50364fd522 Don't set VK lock/unlock queue functions past libavutil 62
They are scheduled for removal at that ABI bump.
2026-06-21 14:01:47 -05:00
Cameron Gutman bea5355c66 Fix unused parameter warning on Windows and Linux 2026-06-21 14:01:47 -05:00
Damglador c6820d8f5d Translated using Weblate (Ukrainian)
Currently translated at 86.8% (218 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2026-06-21 03:01:18 +02:00
Damglador f58ae9cf56 Translated using Weblate (Ukrainian)
Currently translated at 54.1% (136 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2026-06-19 17:01:18 +00:00
Cameron Gutman ca7d61f528 Prefer libplacebo on macOS when available 2026-06-14 19:27:01 -05:00
Cameron Gutman 2b5388e941 Fix non-EGL frontend renderers when compiled without EGL support 2026-06-14 19:16:16 -05:00
Cameron Gutman a9ad048252 Fix HDR rendering in libplacebo on macOS 2026-06-14 18:58:22 -05:00
Cameron Gutman 51cc5a8537 Remove libplacebo workaround for FFmpeg compiled without Vulkan support 2026-06-14 18:57:46 -05:00
Cameron Gutman 8c6b422040 Implement libplacebo on MoltenVK 2026-06-14 15:45:38 -05:00
Cameron Gutman ec75f0d8de Refactor libplacebo renderer to handle non-Vulkan hwcontexts 2026-06-14 12:20:54 -05:00
Cameron Gutman f2a512d3aa Update libplacebo, sdl2-compat, OpenSSL, and SDL3 2026-06-12 00:13:18 -05:00
ssantos 6ccd91d942 Translated using Weblate (Portuguese)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2026-06-09 19:01:17 +02:00
Cameron Gutman 02004bac3f Allow toggling through combo box options using left/right on gamepads/keyboards 2026-06-07 15:14:29 -05:00
kynoptic 7c93aaf659 Force Tab focus to reach all controls on macOS
macOS defaults keyboard navigation to text fields and lists only, so Tab
(and the gamepad navigation that synthesizes it) can't move focus between
controls on the settings page. Other platforms already default to this.
2026-06-07 14:22:42 -05:00
Cameron Gutman 534ce02756 Track keyboard grab state internally rather than using SDL
Versions of sdl2-compat prior to 2.32.64 (and native SDL3) won't
set the grab flag if grabbing the keyboard fails, even though the
compositor still may be exclusively passing system keys to us via
some external configuration by the user. This causes the super key
to not be sent to the host, because we think the client OS will
consume it and don't want to duplicate the input.

Fixes #1900
2026-06-06 16:11:37 -05:00
Cameron Gutman 19d77704ba Update SDL and libplacebo 2026-06-02 02:03:10 -05:00
Cameron Gutman a2ef7a4a0c Enable LTO for FFmpeg 2026-05-27 23:21:56 -05:00
Cameron Gutman dc6c0d3315 Update prebuilts 2026-05-27 02:24:43 -05:00
Cameron Gutman cd5853c6ca Update Windows and macOS prebuilt dependencies
- Enable LTO/LTCG
- Update SDL3
2026-05-26 22:55:32 -05:00
Cameron Gutman e6da6fa11f Enable LTO for AppImage builds 2026-05-26 21:55:58 -05:00
Cameron Gutman 81f20cdb66 Move LTCG/LTO enablement into the build scripts 2026-05-26 21:46:58 -05:00
Cameron Gutman adfc972371 Enable LTCG/LTO for release builds 2026-05-26 01:23:09 -05:00
Cameron Gutman 53a14eda1c Update MSVC redistributable in installer bundle 2026-05-26 00:49:48 -05:00
Cameron Gutman 2eb6715be5 Disable WM-dependent hotkeys on LinuxFB too 2026-05-24 15:23:19 -05:00
Cameron Gutman 29294553bb Add Ctrl+Alt+Shift+K combo to toggle system key grab
Fixes #1637
2026-05-24 15:13:23 -05:00
Cameron Gutman 97240cd5f2 Add workaround for libplacebo crash with Raspbian FFmpeg
Fixes #1409
2026-05-24 14:43:02 -05:00
Cameron Gutman 8cc001768c Use UTF-16 literals for XML processing on Qt 6 2026-05-23 21:56:40 -05:00
Cameron Gutman d94b92e247 Use SDL_utf8strlcpy() to avoid MSVC secure CRT warnings 2026-05-23 19:50:32 -05:00
Cameron Gutman d9eca42311 Remove redundant QString construction 2026-05-23 19:28:28 -05:00
Cameron Gutman 63c48be6d4 Improve handling of malformed XML responses 2026-05-23 19:16:14 -05:00
Cameron Gutman 459dcd7b2c Fix incorrect error print 2026-05-16 16:10:47 -05:00
Cameron Gutman b33a252739 Fix incorrect apply() return value for legacy DRM clients 2026-05-16 16:09:57 -05:00
Cameron Gutman 1eb76bbdb0 Deep copy the BIO's backing memory for the QSslKey
This doesn't appear to be a problem in practice, but the docs don't say
that Qt couldn't retain this QByteArray for later, which would result in
a UAF with the current code.
2026-05-16 16:08:02 -05:00
Cameron Gutman bba2faa602 Fix broken horizontal scroll inversion 2026-05-16 15:45:13 -05:00
Cameron Gutman 87c3179f77 Fix incorrect failure check 2026-05-15 23:23:36 -05:00
Cameron Gutman 073f892bb1 Update Windows and macOS prebuilt dependencies
- Reverted to SDL 3.4.x to fix GCMouse issues

Fixes #1882
2026-05-15 19:16:33 -05:00
Cameron Gutman 815db2b0d7 Enable Segment Heap for improved performance and memory usage 2026-05-15 18:37:52 -05:00
Cameron Gutman a8a66bfc3d Enable Per Monitor v2 DPI awareness
Qt 6 has supported this forever, but our manifest forced PMv1.
2026-05-15 18:13:46 -05:00
Cameron Gutman 8fe279c91b Add support for controllers with dual touchpads 2026-05-14 22:14:50 -05:00
Cameron Gutman dedb0c0327 Disable text input before creating windows 2026-05-14 21:45:22 -05:00
Cameron Gutman 9cbba106ad Use the Metal renderer by default on all Macs
Whatever dGPU/eGPU rendering issues existed at the time I wrote that check seem to no longer happen on my RX 480 eGPU test setup running Ventura (our oldest supported OS).

It seems safe enough to enable now, especially since 7d6ce0b4c should catch broken systems and transparently fall back to AVSampleBufferDisplayLayer.

Fixes #1885
2026-05-14 00:45:57 -05:00
Cameron Gutman 7d6ce0b4cc Implement testRenderFrame() for the VTMetal renderer
This can be used to (hopefully) detect cases where importing the decoded frames onto the target GPU fails.

See #1885
2026-05-14 00:34:32 -05:00
Cameron Gutman 92fb7f3b71 Use the (hopefully faster) ARM64 Tahoe runner 2026-05-13 23:49:32 -05:00
Cameron Gutman b0ac3713f2 Update macOS CI runner to Tahoe 2026-05-13 23:33:30 -05:00
Cameron Gutman 96a211be11 Update Windows and macOS CI builds to Qt 6.11.1 2026-05-13 23:31:14 -05:00
Cameron Gutman 4cf498b09d Use queued audio duration instead of queued frame count to constrain latency
This avoids latency explosion when we negotiate 10 ms instead of 5 ms audio packets.
2026-05-10 21:53:09 -05:00
Cameron Gutman c21affd15a Switch to linuxdeploy for AppImages 2026-05-10 16:56:34 -05:00
dependabot[bot] 7de4e74829 Bump app/SDL_GameControllerDB from 16ac3e5 to 1fc89ca
Bumps [app/SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) from `16ac3e5` to `1fc89ca`.
- [Commits](https://github.com/gabomdq/SDL_GameControllerDB/compare/16ac3e553e23068e26819971f2cc6cd088a7f2f6...1fc89ca5787f4b8279e6c793cf3007657d9bb35c)

---
updated-dependencies:
- dependency-name: app/SDL_GameControllerDB
  dependency-version: 1fc89ca5787f4b8279e6c793cf3007657d9bb35c
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-09 13:21:38 -05:00
Cameron Gutman 9d6218d1ff Don't capture the cursor by default in windowed mode
Closes #1872
2026-05-09 13:11:45 -05:00
Cameron Gutman 8cc3b30642 Update Windows, macOS, and AppImage dependencies 2026-05-03 22:36:08 -05:00
Cameron Gutman d77e2cc913 Update upload-artifact for Node.js 24 2026-05-03 21:06:42 -05:00
Cameron Gutman 453435f916 Switch to downloading prebuilt release artifacts instead of a submodule 2026-05-03 21:04:06 -05:00
Cameron Gutman f222aa7985 Use aspect ratio preserving scaling for slow GPUs on non-KDE desktops 2026-04-26 23:15:02 -05:00
Cameron Gutman 5faa5fece8 Don't manually override v4l2m2m buffer counts
This causes POLLERR when decoding from meson-vdec on the Libre
Computer Alta (and likely other Amlogic boards). Our requried buffer
counts were already lower than the default 16/20 configuration that
FFmpeg uses, so overriding them was just a memory usage optimization.
2026-04-20 00:25:21 -05:00
Cameron Gutman 51f86caac3 Fix assert on exit using KMSDRM on AMDGPU
AMDGPU disallows commits that would leave a CRTC active without
the primary plane enabled. Instead of disabling the primary plane,
simply restore the original state of the plane to avoid this.
2026-04-19 23:17:28 -05:00
Cameron Gutman 5d813ed3df Fix clamping of signed range properties 2026-04-19 22:17:37 -05:00
Cameron Gutman d17575d47c Fix deadlock in Vulkan renderer using KMSDRM on AMDGPU 2026-04-19 21:16:45 -05:00
Cameron Gutman 0e50a9d457 Only enable D3D11/DXGI debug layer if Graphics Tools are installed
Closes #1857
2026-04-13 20:06:24 -05:00
Cameron Gutman ed029f194f Propagate CFLAGS/CXXFLAGS/LDFLAGS environment variables to QMake
Closes #1602
2026-04-12 15:51:42 -05:00
Cameron Gutman 569153220a Enable Brazilian Portuguese now that it is fully translated 2026-04-12 15:27:38 -05:00
Cameron Gutman e0367d05ae Rerun lupdate and lrelease 2026-04-12 15:21:18 -05:00
Cameron Gutman 53e0c2534d Merge remote-tracking branch 'origin/weblate' 2026-04-12 15:19:45 -05:00
Cameron Gutman a766c9cafc Disable texture sharing on Qualcomm GPUs
See #1857
2026-04-11 20:14:14 -05:00
Cameron Gutman c685021f21 Update SDL3, dav1d, FFmpeg, and OpenSSL
SDL3 -> 3.4.4 (Windows only)
dav1d -> 1.5.3
FFmpeg -> 8.1
OpenSSL -> 3.6.2

Fixes #1394
2026-04-10 20:58:23 -05:00
Cameron Gutman af03f57e08 Fix Vulkan decoder probing on Nvidia using KMSDRM 2026-04-09 22:11:08 -05:00
Cameron Gutman 1fc1122c65 Consolidate test window creation code 2026-04-09 21:43:35 -05:00
Cameron Gutman 94d47e95fe Fix non-determinism during Vulkan decoder probing on KMSDRM 2026-04-09 21:37:25 -05:00
Tak-attack 1cffa7b350 Translated using Weblate (Japanese)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2026-04-09 13:09:49 +02:00
dependabot[bot] fae1cd3dee Bump moonlight-common-c/moonlight-common-c from b187204 to 6268780
Bumps [moonlight-common-c/moonlight-common-c](https://github.com/moonlight-stream/moonlight-common-c) from `b187204` to `6268780`.
- [Commits](https://github.com/moonlight-stream/moonlight-common-c/compare/b187204769974b9af9d2a3c3bca83ad40e4f1ac9...62687809b1f7410c3db4be2527503a54ae408d70)

---
updated-dependencies:
- dependency-name: moonlight-common-c/moonlight-common-c
  dependency-version: 62687809b1f7410c3db4be2527503a54ae408d70
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-08 21:51:17 -05:00
Cameron Gutman 2160f029d2 Bump aqtinstall to a later commit to pick up Qt 6.11 deployment fix 2026-04-08 21:39:37 -05:00
Cameron Gutman 1ec1a3d7ad Move ifdef guards to fix unused variable warning 2026-04-08 21:26:33 -05:00
Cameron Gutman eb3d8ad92c Update Windows and macOS to Qt 6.11.0 2026-04-08 20:54:36 -05:00
Cameron Gutman 07b00a6987 Update to WiX v7 2026-04-08 20:49:46 -05:00
Cameron Gutman 4ec682dc72 Remove errant assert to fix software decoding on Xe 2026-04-06 21:12:00 -05:00
Cameron Gutman a9a1ea0a0b Update AppImage dependencies 2026-04-06 20:04:05 -05:00
Cameron Gutman c8d18f8a8e Bring back DRM atomic test commit using new DRM master lock
The DRM master lock avoids race conditions between Qt taking master
to draw the GUI and the DRM renderer performing a test commit.
2026-04-06 19:25:03 -05:00
Cameron Gutman 9c11dca454 Move DRM master state cleanup into cleanupRenderContext() 2026-04-06 19:24:04 -05:00
Cameron Gutman 9496c25271 Add a lock to synchronize DRM master ownership between Qt and SDL 2026-04-04 14:47:57 -05:00
Cameron Gutman 6ff3309677 Don't warn about KMSDRM atomic on unsupported platforms 2026-04-04 14:24:35 -05:00
Cameron Gutman e4c211b987 Automatically set SDL_KMSDRM_ATOMIC=0 on older SDL3 versions
Fixes #1824
2026-04-04 14:13:21 -05:00
Luís Otávio cac3bb28d7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2026-04-03 13:09:51 +00:00
Cameron Gutman 78bc2141f6 Fix getSdlFdEntryIndex() for FD 0 2026-04-02 21:20:33 -05:00
Cameron Gutman effac744c7 Fix handling close(0) in our DRM master hooks
Prior to this fix, we would become out of sync and fail to promote
Qt and SDL FDs to master when required, causing Qt's mouse to
disappear and the SDL video subsystem to fail initialization when
trying to stream.
2026-04-02 21:01:46 -05:00
Cameron Gutman 5676a076fd Fix overlay plane selection on drivers without zpos properties 2026-04-01 22:37:12 -05:00
Cameron Gutman b6407492c7 Move refreshDisplay() after test window creation
SDL invalidates cached display modes after a window creation, so this avoids paying a second mode enumeration cost when the user enters the settings page.
2026-03-28 22:01:15 -05:00
Cameron Gutman 91ce7a41e5 Cache the result of SDL_GetNumDisplayModes()
It's not free when using SDL2-compat.
2026-03-28 21:57:51 -05:00
Cameron Gutman 89c8462e9e Leave the video subsystem initialized on Windows
It significantly reduces settings page load latency.
2026-03-28 20:46:03 -05:00
Cameron Gutman 53a7680a38 Fix incorrect autoselection of SW AV1 over HW H.264 for SDR content 2026-03-28 20:19:11 -05:00
Cameron Gutman 88b4a17fe1 Use AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS for decoder probing on FFmpeg 8.1 2026-03-28 16:30:28 -05:00
Cameron Gutman 8326223220 Revert "Use EOS to force decoder test frame output"
It causes hangs on defective v4l2m2m decoders, and it's not always
well-supported by out-of-tree decoders either.

This reverts commit 66a30c66f3.
2026-03-28 16:24:20 -05:00
Cameron Gutman 4aa5ad71c0 Use av_vk_get_optional_device_extensions() on FFmpeg 8.1 2026-03-28 16:17:59 -05:00
Cameron Gutman e785be03c2 Add support for building with OpenSSL 4.0 2026-03-28 00:56:34 -05:00
தமிழ்நேரம் db294fe4ae Translated using Weblate (Tamil)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ta/
2026-03-02 10:09:47 +00:00
Cameron Gutman 2e9fbecfea Disable SDL3 raw keyboard/mouse hotplug support 2026-02-20 22:40:50 -06:00
Cameron Gutman 7c066485f3 Update SDL, sdl2-compat, and libplacebo for AppImage 2026-02-20 22:19:21 -06:00
Cameron Gutman 11d51e121a Update libplacebo and SDL3
libplacebo -> v7.360.0
SDL3 -> 3.4.2

Fixes #1661
Fixes #1617
2026-02-20 21:57:46 -06:00
Cameron Gutman 09675bf56d Update moonlight-common-c with vectorized FEC for non-ARMv8/x64 platforms
Also remove the workaround for Steam Link since vectorization is enabled by compiler flags now.
2026-02-19 20:09:38 -06:00
Cameron Gutman 8f994dd113 Enable NEON FEC optimizations on Steam Link 2026-02-19 00:54:49 -06:00
Cameron Gutman e596c2dcdc Update moonlight-common-c with SIMD acceleration for FEC 2026-02-19 00:38:52 -06:00
Cameron Gutman 209511b2dc Revert Pinyin IME workaround which is ineffective on SDL3
The underlying SDL bug is now fixed upstream for SDL 3.4.2.
2026-02-16 15:00:30 -06:00
Cameron Gutman efa67fec1e Disable VBlank virtualization with dynamic refresh rates 2026-02-14 12:39:01 -06:00
Ferrer be0aeb6cc2 Translated using Weblate (Spanish)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2026-02-11 13:09:44 +00:00
Cameron Gutman 8d5072533f Fix polish() loop in the quit dialog
Fixes #1816
2026-02-07 22:01:26 -06:00
Cameron Gutman 4c14a24960 Change nightly builds to use the non-portable profile by default
Fixes #1790
2026-02-07 17:26:23 -06:00
Cameron Gutman e3702dbab7 Don't deploy icuuc.dll into the application folder 2026-02-07 16:46:12 -06:00
Cameron Gutman e4325b8736 Update Windows ARM64 CI to Qt 6.10.2 2026-02-07 16:46:12 -06:00
Cameron Gutman eb294e63f4 Revert "Temporarily revert Windows ARM64 to Qt 6.10.0"
This reverts commit 6313129603.
2026-02-07 16:46:12 -06:00
Cameron Gutman 9d597a666b Use aqtinstall version compatible with Qt 6.10.1+ ARM64 2026-02-07 16:46:12 -06:00
Jakub SygnowskiandCameron Gutman 33e0b08699 Add Docker section to README (#1791)
* Add Docker section to README

Added information on moonlight-packaging to building section of README.

Co-authored-by: Cameron Gutman <aicommander@gmail.com>
2026-02-06 23:59:28 -06:00
Cameron Gutman 31898bbab4 Update moonlight-common-c to fix BSDs 2026-02-06 23:26:41 -06:00
Cameron Gutman 34c9e01a96 Exclude Windows and macOS systems from the slow GPU heuristic
It's targeted at SBCs, which don't run Windows or macOS.
2026-02-06 22:37:33 -06:00
Cameron Gutman ddc6675dc8 Fix macOS and Steam Link build 2026-02-06 22:27:57 -06:00
Cameron Gutman f0626e8cae Exit immediately on repeated SIGINT/SIGTERM without progress 2026-02-05 23:55:02 -06:00
Cameron Gutman 6f4ced5ed6 Assume GPUs on non-x86 platforms are slow by default
This can be overriden with GL_IS_SLOW=0 at runtime
for systems with a fast GPU, though it doesn't make
much difference either way for non-KMSDRM cases.

For slower GPUs, this enables important scaling and
rendering optimizations that can substantially
improve performance (especially on fillrate-limited
GPUs common in SBCs).
2026-02-05 23:17:23 -06:00
Cameron Gutman 0a2b134d49 Disable the DRM master hooks when EGLFS isn't used 2026-02-05 22:36:31 -06:00
Cameron Gutman f6a9e7694a Update moonlight-common-c 2026-02-05 22:33:51 -06:00
Cameron Gutman 8795fb54f4 Fix double-free in Vulkan renderer when an overlay is disabled
Also a drive-by fix to avoid pl_tex copying
2026-02-04 23:05:01 -06:00
Cameron Gutman 092eb1b117 Enable SDL3 fast parameter checks 2026-02-04 22:42:58 -06:00
Cameron Gutman 179857f17d Remove more unused Qt 6 styles 2026-01-31 17:12:29 -06:00
Cameron Gutman d878447413 Fix Windows ARM64 builds on x64 on Qt 6.10.1+ 2026-01-31 17:11:56 -06:00
Cameron Gutman 60fd840d7a Remove _USE_MATH_DEFINES workaround for SDL2 2026-01-31 13:51:59 -06:00
Cameron Gutman 5020fc6f48 Do not reset the renderer on SDL_RENDER_TARGETS_RESET
We only need to do this on a SDL_RENDER_DEVICE_RESET where we lose the whole device.

This also reverts a56efe5 since this change is not needed when handling the reset events properly.
2026-01-31 13:00:23 -06:00
Cameron Gutman a2122e17c6 Explicitly request linear sampling in StretchRect() 2026-01-31 12:48:03 -06:00
Cameron Gutman 6bb7c8bf2a Fix blurriness of DXVA2 overlay
Also make a drive-by fix for D3DTSS_COLOROP since we don't use vertex colors.
2026-01-31 12:44:50 -06:00
Cameron Gutman 2dda65078f Remove D3D9Ex focus loss hint workaround
SDL3 doesn't suffer this bug and keeping the default SDL3 auto behavior (minimize iff in exclusive mode) is a better UX.
2026-01-30 21:07:01 -06:00
Cameron Gutman 2914ff678d Update OpenSSL and libplacebo for Windows and macOS
OpenSSL -> 3.6.1
libplacebo -> 9bffcaf
2026-01-30 20:54:01 -06:00
Cameron Gutman a56efe5c36 Fix infinite renderer resets on SDL3 using direct3d renderer 2026-01-30 20:39:53 -06:00
Cameron Gutman b7a05d73b9 Update SDLRenderer capabilities to match SDL3 behavior 2026-01-30 20:38:53 -06:00
Cameron Gutman 6d5b9e4706 Remove Windows dark mode hack since SDL3 supports it natively 2026-01-30 19:57:11 -06:00
Cameron Gutman 9813932c1b Switch to SDL3+SDL2-compat 2026-01-30 19:44:29 -06:00
Cameron Gutman d4d4ab5b06 Only use the libssl.so linking hack for AppImages 2026-01-27 22:22:29 -06:00
Cameron Gutman 402ac59390 Fix forcing X11 SDL video driver on XWayland when not built with Wayland 2026-01-27 22:22:29 -06:00
Cameron Gutman c33c49e6fa Update libplacebo and drop old Gamescope workaround 2026-01-27 22:22:29 -06:00
Cameron Gutman e1bbf8144e Switch AppImage to SDL3+SDL2-compat 2026-01-27 22:22:20 -06:00
Cameron Gutman f4712718cb Allow focus to move up to the toolbar from the PC/app grid 2026-01-27 00:24:29 -06:00
Cameron Gutman d040bd24d1 Add keyboard/gamepad focus navigation to dialog buttons 2026-01-27 00:13:47 -06:00
Cameron Gutman 6d40c61850 Only set initial MenuItem focus if not activating via mouse
Having an initially highlighted item when using mouse navigation
doesn't adhere to UX norms and also can lead to a janky feeling
when the focus flip-flops from the item under the user's cursor
to the first item as the Menu opens.
2026-01-26 23:46:57 -06:00
Cameron Gutman b4a5d21f97 Fix focusing after closing a dialog 2026-01-26 23:20:38 -06:00
Cameron Gutman 792f762c15 Standardize on QString::toUtf8() 2026-01-26 21:49:08 -06:00
Cameron Gutman 8c9c799f81 Fix Clazy non-pod-global-static warnings 2026-01-26 21:49:08 -06:00
Cameron Gutman 4eaf037c75 Fix Clazy readlock-detaching warning 2026-01-26 21:49:08 -06:00
Cameron Gutman b732b58807 Fix Clazy returning-data-from-temporary warnings 2026-01-26 21:49:08 -06:00
Cameron Gutman d484ec3ac8 Fix Clazy range-loop-detach warnings 2026-01-26 21:49:08 -06:00
Cameron Gutman f5f06ae44e Remove handling for Windows versions that are no longer supported 2026-01-26 20:04:15 -06:00
Cameron Gutman d2fa488979 Move heavy SystemProperties loads to an opt-in model
This avoids heavyweight operations when we're not actually running config checks.
2026-01-26 19:46:49 -06:00
Cameron Gutman cd9aceb62c Disable D3D11VA texture sharing on known broken GPUs 2026-01-26 19:37:43 -06:00
Cameron Gutman d5b7ef0c58 Don't pump events in SdlGamepadKeyNavigation
This can cause reentrancy issues by invoking Qt-based event
processing while in the context of SDL (via libdecor's GTK loop).

Fixes #1802
2026-01-26 18:19:55 -06:00
Cameron Gutman e4be57db5d Remove superfluous Session checks in prepareToRender()
prepareToRender() is only called with a live Session.
2026-01-26 18:17:14 -06:00
Artyom Rybakov 1b0c657864 Translated using Weblate (Russian)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2026-01-26 06:53:01 +01:00
Cameron Gutman 64fea80ac9 Create the SystemProperties test window on the main thread 2026-01-25 17:10:04 -06:00
therealmate 990804fe6b Translated using Weblate (Hungarian)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2026-01-25 21:50:51 +01:00
Cameron Gutman 05ef938e2c Add support for LTR ACK control messages 2026-01-20 21:54:14 -06:00
Cameron Gutman 1e825c85e5 Optimize render to decode fence usage to reduce pipeline bubbles 2026-01-19 18:38:38 -06:00
Cameron Gutman a0a4c1ea83 Use decoder texture binding by default when using separate devices
This significantly improves performance on Ryzen 3300U and should generally perform equal or better everywhere.

This decoder->SRV path has been prone to driver bugs, so we may need to adjust this logic if driver issues crop up.
2026-01-19 16:46:50 -06:00
Cameron Gutman b5e7dec378 Fix D2R fence initial value
Fixes synchronization of the first decoded frame
2026-01-19 16:10:02 -06:00
Cameron Gutman adbd19e6fa Remove the previous frame rendered fence
- Waiting on this fence prior to rendering introduces pipeline bubbles which can impact rendering performance on low-end GPUs
- Pacer simply waiting to release the previous frame until after the current frame is rendered already means any decoder stall should be very short
2026-01-19 16:01:50 -06:00
Cameron Gutman 02a86167da Disable separate decoder devices for non-Intel FL11.0 GPUs 2026-01-19 15:08:14 -06:00
Cameron Gutman a739c1cef8 Fix D3D11 fence sharing without monitored fence support 2026-01-19 14:53:23 -06:00
Cameron Gutman f6e08f8a43 Use separate render and decode D3D11Devices
See #1424
2026-01-19 14:25:08 -06:00
Cameron Gutman 218ffc2d55 Set explicit scaling mode for all SDL textures 2026-01-17 02:34:54 -06:00
Cameron Gutman 0f49dca4c0 Use GL_NEAREST when possible without degrading quality 2026-01-17 02:23:28 -06:00
Cameron Gutman 30274f3ae8 Don't keep the dummy renderer alive for EGLRenderer's lifetime
At best, it doesn't do anything other than some queue some viewport
changes via SDL_RendererEventWatch(). At worst, it can race with
the render thread and cause trouble.
2026-01-17 01:06:41 -06:00
Jhony Minetto Araújo c696ae7a7e Translated using Weblate (Portuguese (Brazil))
Currently translated at 28.2% (71 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2026-01-16 09:01:47 +00:00
Cameron Gutman 66a30c66f3 Use EOS to force decoder test frame output 2026-01-16 01:08:51 -06:00
Cameron Gutman 198a208b44 Clamp property values when restoring them 2026-01-14 23:26:46 -06:00
Jan Astrup 21ce23e377 Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.6% (250 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2026-01-14 10:39:52 +01:00
Jhony Minetto Araújo cd4ae1c0ed Translated using Weblate (Portuguese (Brazil))
Currently translated at 27.4% (69 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2026-01-14 10:39:51 +01:00
Cameron Gutman d865c77975 Crop the incoming frames if they deviate slightly from the expected size
Fixes #1466
2026-01-11 20:58:48 -06:00
Cameron Gutman cd13910e6c Add support for YUV 4:4:4 in DXVA2
We get it basically for free now that we let FFmpeg handle the heavy lifting.
2026-01-11 20:55:46 -06:00
Cameron Gutman b8e9262b1b Replace deprecated DXVA2 initialization with standard hwaccel init
- Avoids requiring a hardcoded number of frames (and creating surfaces ourselves)
- Removes a ton of unnecessary code that's duplicated in FFmpeg
- Supports dynamic frame sizes, formats, and color conversion
- Supports frame cropping in FFmpeg
2026-01-11 17:46:13 -06:00
Cameron Gutman c14ebb1ad7 Adjust buffer count for hwaccel and v4l2m2m decoders
- For hwaccel decoders, don't depend on FFmpeg's 4 working surfaces.
  The decoders might need one or more of them internally.

- For V4L2M2M decoders, adjust the buffer counts to match our needs
  and requirements regarding Pacer-held frames.
2026-01-11 14:18:22 -06:00
Cameron Gutman d3957b3cbb Fix race condition where a separate test decoder could ingest a real frame 2026-01-11 13:41:12 -06:00
Cameron Gutman a8e8efb17b Don't blend the source surface when blitting 2026-01-11 12:35:55 -06:00
Cameron Gutman 75adc22d05 Blit the new overlay in one shot if it entirely covers the old one 2026-01-11 12:28:22 -06:00
Cameron Gutman 2549efc8b3 Fix pthread_attr leak 2026-01-11 01:47:11 -06:00
Cameron Gutman 6f8e517ce1 Remove unused field 2026-01-11 01:46:17 -06:00
Cameron Gutman 09f8e7117b Fix incorrect src pixel offset in overlay composition
Currently harmless because no overlay has a non-zero X coordinate.
2026-01-11 01:40:32 -06:00
Cameron Gutman 88719cc8bf Use FB_DAMAGE_CLIPS instead of drmModeDirtyFB() 2026-01-11 01:15:28 -06:00
Cameron Gutman 3ea62c0800 Call drmModeDirtyFB() for the modified composition regions 2026-01-10 23:53:07 -06:00
Cameron Gutman 7643cc929e Implement DRM overlay composition
This allows overlays to work on drivers that only have one usable
overlay plane and when we are using the primary plane (which often
must be exactly CRTC-sized) to overlay on top of a video underlay.
2026-01-10 23:40:12 -06:00
Cameron Gutman a58d3cfe39 Fix D3D11 copy path 2026-01-10 19:11:25 -06:00
Cameron Gutman b41c4022ea Ensure there are enough hwframes for Pacer 2026-01-10 18:13:49 -06:00
Cameron Gutman 788675ad59 Handle window size and display changes in D3D11Renderer 2026-01-10 17:48:28 -06:00
Cameron Gutman be9f465008 Remove manual hwframes creation in D3D11VARenderer
This way we aren't always allocating the worst-case possible number of frames
2026-01-10 16:36:35 -06:00
Cameron Gutman 8b6ad55c9b Enable DXGI_CREATE_FACTORY_DEBUG for debug builds 2026-01-10 16:01:03 -06:00
Cameron Gutman 92b68a40d1 Use a D3D11Fence to force sync between video and 3D engines when binding output textures 2026-01-10 14:52:27 -06:00
Cameron Gutman a931161923 Reset client caps before rendering in case SDL changed them 2026-01-08 22:03:44 -06:00
Cameron Gutman 37b9b6ed9e Don't run configuration checks for CLI launches 2026-01-08 19:10:50 -06:00
Cameron Gutman fad197fdce Move heavy SystemProperties initialization operations off the main thread
This dramatically improves startup performance on slow devices.
2026-01-08 19:09:54 -06:00
Cameron Gutman cda65ab58d Use a D3D11Fence to wait to start the next frame until the previous frame is finished 2026-01-07 19:04:15 -06:00
Cameron Gutman 9ffe5218d5 Hoist the logic to keep an AVFrame reference up to Pacer 2026-01-07 17:50:43 -06:00
Cameron Gutman ed98f256e8 Fix typo 2026-01-06 02:14:45 -06:00
Cameron Gutman 8aec35a650 Allow primary planes to be overlays for video underlays 2026-01-06 02:12:32 -06:00
Cameron Gutman a3237b741c Support underlay planes by turning off unused active planes 2026-01-06 01:59:34 -06:00
Cameron Gutman 377409f313 Fix oversized DRM dumb buffer for 4:2:0 uploads 2026-01-06 00:49:49 -06:00
Cameron Gutman 80ddd5ba13 Fix software upload for DRM renderer with non-720p resolutions
The buffer allocated for the 720p test frame was left around
and we would attempt to reuse it even if the stream had frames
of a different size.
2026-01-06 00:35:36 -06:00
Cameron Gutman 4a547eb05e Add fourcc_mod_is_vendor() definition for older headers 2026-01-05 23:00:31 -06:00
Cameron Gutman 1c6ed8f390 Remove atomic test-only commit
This is currently race-prone because nothing is synchronizing
between other Qt and SDL uses of DRM master, so it can cause
false negatives if we can't retake master ourselves.
2026-01-05 21:50:31 -06:00
Cameron Gutman 0a58af4fa1 Allow plane selection overrides using environment variables 2026-01-05 21:27:52 -06:00
Cameron Gutman 50a094c917 Fix percentage math 2026-01-05 21:01:23 -06:00
Cameron Gutman d14cf984f4 Print flip stats after the DrmRenderer is destroyed 2026-01-05 20:52:53 -06:00
Cameron Gutman 13d9d79fe3 Implement support for adjusting zpos to make planes visible 2026-01-05 20:39:12 -06:00
Cameron Gutman 70d4f24455 Fix pending frame leak on destruction 2026-01-05 19:15:58 -06:00
Cameron Gutman 705cd3ddc4 Allow rendering to a cursor plane via opt-in
This is required for some Rockchip devices running vendor kernels.
2026-01-05 19:08:22 -06:00
Cameron Gutman ea5b062da3 Set VRR, BPC, and content type properties 2026-01-05 18:58:21 -06:00
Cameron Gutman e6f41f5574 Improve DRM renderer plane compatibility testing
For atomic drivers, use a test-only commit to fully exercise the
path that we will be using when rendering.

For legacy drivers, mask the variable portion of Broadcom modifiers
before matching with IN_FORMATS.
2026-01-05 18:20:39 -06:00
Cameron Gutman 9af6222039 Update moonlight-common-c to fix leak 2026-01-05 00:24:16 -06:00
Cameron Gutman 476414ea71 Fix a rare race where an overlay surface can leak 2026-01-04 22:29:12 -06:00
Cameron Gutman 83d770cdba Prefer BT2020_YCC to allow chroma subsampling 2026-01-04 22:16:52 -06:00
Cameron Gutman 25e2d39e26 Fix copy-paste mistake in 8726c1 2026-01-04 21:52:12 -06:00
Cameron Gutman bd32370b6d Fix libdrm return value vs errno confusion
libdrm is inconsistent between returning -1 with an errno set
and just returning -errno as the return value. Figuring out which
behavior a given libdrm function has require reading the source :/
2026-01-04 21:50:40 -06:00
Cameron Gutman 8726c1c7d0 Bring back atomic async page flip support
Now that we're referencing the AVFrame to keep the buffers from
being reused during scanout, this should hopefully work better.
2026-01-04 19:34:13 -06:00
Cameron Gutman 34881599f5 Reference the AVFrame while the backing DMA-BUFs are used for scanout
This prevents tearing and other artifacts caused by the decoder
writing to a DMA-BUF that is currently being displayed.
2026-01-04 18:47:00 -06:00
Cameron Gutman de0fb72424 av_buffer_create() copies the pointer not the data 2026-01-04 18:24:20 -06:00
Cameron Gutman 46c76534bc Use AVBufferRefs to keep EGLImages and DRM FDs around for the lifetime of the frame 2026-01-04 18:06:24 -06:00
Cameron Gutman 67cba9e397 Add branding colors to appstream metadata 2026-01-04 00:38:54 -06:00
Cameron Gutman 2ab72375c6 Fix additional appstream metadata linter warnings 2026-01-04 00:16:20 -06:00
Sabri Ünal d3118bd677 metadata: Tidy up
- Drop categories that are already provided by the desktop file
- Group important information together
- Add vcs-browser URL to point to the source code repository
2026-01-03 23:56:03 -06:00
Cameron Gutman b8c3658c42 Skip modifier check if the frame doesn't have any modifiers 2026-01-03 02:53:44 -06:00
Cameron Gutman d3fb52c5a0 Check modifiers support in IN_FORMATS property
As it turns out, there *are* in fact hardware vendors dumb enough
to ship V4L2 decoders that output buffers which are unsupported by
any plane on their display hardware. By checking modifiers, we can
still fall back to GLES on GL_IS_SLOW=1 builds in this case.
2026-01-03 02:43:15 -06:00
Cameron Gutman 7924a5b6a7 Reduce mDNS log spam from hosts with many addresses 2026-01-03 01:14:50 -06:00
Cameron Gutman 2972022ced Remove async and non-blocking page flip support
It doesn't work well in practice for a few major reasons:
- It can result in the decoder writing on DMA-BUFs being used by the display
- It can generate page flip events that collide with Qt/SDL
- It can stall the decoder if the DMA-BUF has a fence on it from the display driver
2026-01-03 00:41:14 -06:00
Cameron Gutman c0846155c3 Fix page flipping bugs 2026-01-02 20:01:54 -06:00
Cameron Gutman ac6dadffc6 Use page flip events to correctly synchronize with async flips 2026-01-02 19:47:43 -06:00
Cameron Gutman 745ac34b15 Improve page flipping and modifier handling in DrmRenderer 2026-01-02 18:44:18 -06:00
Cameron Gutman 5f89636ed7 Improve robustness of DRM property value handling 2026-01-02 02:06:11 -06:00
Cameron Gutman 46d58e55a3 Add macro for printing FourCC values 2026-01-02 01:46:20 -06:00
Cameron Gutman be460970a8 Remove use of DMA_BUF_IOCTL_SYNC
It's only necessary on "real" DMA-BUFs, not dumb buffers.
2026-01-02 01:30:03 -06:00
Cameron Gutman d50ba06321 Implement DRM atomic renderer with overlay support
Fixes #1733
2026-01-02 01:24:35 -06:00
Cameron Gutman b108684edc Handle missing bitstream restrictions element in H.264 SPS fixup
NVENC on the 591.59 driver seems to not include the bitstream
restrictions element, which renders our attempt to set the
max_dec_frame_buffering value ineffective. Handle this by
providing inserting default bitstream restrictions if one
is not present.
2025-12-30 17:12:37 -06:00
Cameron Gutman b6d10a34c8 Update blocking swap buffer opt-out comment 2025-12-30 15:43:31 -06:00
Cameron Gutman 232ff0b3c6 Revert "Remove opt-out of blocking swap buffers logic for KMSDRM"
This significantly hurts performance on slower GPUs by preventing
the pipelining required when frametimes exceed the video frame
interval.

This reverts commit c26e437f40.
2025-12-30 15:39:47 -06:00
Cameron Gutman c5960c3e15 Always use display scaling with the KMSDRM video driver 2025-12-30 15:39:32 -06:00
Cameron Gutman b48cbd76f5 Fix implicit fallthrough warning 2025-12-30 15:32:15 -06:00
Cameron Gutman ceef792f04 Use display scaling to improve performance on slow GPUs
This dramatically improves performance for lower resolution
streams on slow GPUs when using the GL and Vulkan renderers.
2025-12-30 15:00:47 -06:00
Cameron Gutman f3f1d56e8d Fix EGLFS detection when a compositor is running on wayland-0 in another VT 2025-12-30 00:04:55 -06:00
Cameron Gutman 39e24e9c8c Add qt6-wayland to list of required Debian packages 2025-12-29 22:57:35 -06:00
Cameron Gutman c26e437f40 Remove opt-out of blocking swap buffers logic for KMSDRM
We don't set SDL_HINT_VIDEO_DOUBLE_BUFFER since b1c77ff.
2025-12-29 16:51:03 -06:00
Cameron Gutman e89f63b8fb Skip unnecessary glClear() on X11 2025-12-29 16:50:15 -06:00
bkpiaskun cf8251b9e6 Translated using Weblate (Polish)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2025-12-29 19:00:21 +01:00
Oğuz Ersen d6c9beffc1 Translated using Weblate (Turkish)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2025-12-29 19:00:20 +01:00
Cameron Gutman 93dc6d6b60 Convert Metal shaders to FP16 2025-12-29 01:45:49 -06:00
Cameron Gutman 8ee82421b3 Remove non-compliant float suffix in NV12 fragment shader
The 'f' suffix isn't supported until ESSL 3.0.
2025-12-28 22:58:21 -06:00
Cameron Gutman 31c65e0863 Optimize EGLRenderer overlay texture swizzle 2025-12-28 22:57:59 -06:00
Cameron Gutman 3e5aa9b127 Simplify EGLImageFactory and remove caching logic for now
The platforms that would most benefit (embedded V4L2 decoders)
either don't use frame pooling or don't synchronize with
modified DMA-BUFs unless eglCreateImage() is called each time.
2025-12-28 17:54:31 -06:00
Cameron Gutman 085480e9f4 Add EGLImage caching to improve performance 2025-12-28 17:08:45 -06:00
Cameron Gutman c3ce0918b3 Optimize blending in DXVA2 and D3D11VA renderers 2025-12-28 13:53:13 -06:00
Cameron Gutman c5b7a9c679 Optimize EGLRenderer with overlay VAOs and reduced GL_BLEND usage 2025-12-28 13:14:16 -06:00
Cameron Gutman f1451a0db3 Fix UB due to missing shader attribute location binding
Mesa drivers seem to generally bind attributes in order, but the
proprietary PowerVR driver (pvr) doesn't and renders incorrectly
as a result.
2025-12-27 23:56:17 -06:00
Cameron Gutman 8a5f34fb01 Remove logic to force the OpenGL ES library to load
This isn't necessary now that we turn on EGL everywhere,
and it breaks OpenGL ES 2.0 support too.
2025-12-27 23:11:53 -06:00
Cameron Gutman d1f43ca258 Use ESSL 1.0 for EGLRenderer shaders
We still ostensibly support GLES 2.0 GPUs.
2025-12-27 22:56:20 -06:00
Cameron Gutman 249c29b74c Allow GL_IS_SLOW and VULKAN_IS_SLOW to be overridden at runtime 2025-12-27 21:40:32 -06:00
Cameron Gutman 1cf207de07 Allow overriding FFmpeg AVOptions via environment variable 2025-12-27 21:07:04 -06:00
Cameron Gutman 4f08d52754 Enable DRM_PRIME frames for the TH1520 2025-12-27 15:40:59 -06:00
Cameron Gutman 41ad3c0938 Add environment variable override helper function
This allows FORCE_QT_GLES and SEPARATE_TEST_DECODER to override both true and false.
2025-12-27 15:33:39 -06:00
Cameron Gutman 21fb2832e1 Fix CLI exit after unexpected stream termination
Fixes #939
2025-12-27 13:33:46 -06:00
dependabot[bot] f0bb1031d8 Bump app/SDL_GameControllerDB from e40b891 to 16ac3e5
Bumps [app/SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) from `e40b891` to `16ac3e5`.
- [Commits](https://github.com/gabomdq/SDL_GameControllerDB/compare/e40b8910f859cd988124def50dcdb63b2f2ff48b...16ac3e553e23068e26819971f2cc6cd088a7f2f6)

---
updated-dependencies:
- dependency-name: app/SDL_GameControllerDB
  dependency-version: 16ac3e553e23068e26819971f2cc6cd088a7f2f6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-23 11:38:47 -06:00
Cameron Gutman b80d2a00c0 Fix SIGTERM unexpectedly quitting the host app 2025-12-23 01:09:21 -06:00
Cameron Gutman 85ea28287e Add workaround for AV1 reinit bug and quiet some debug output 2025-12-23 00:59:19 -06:00
Cameron Gutman a6f8901a18 Reuse the test decoder to improve startup performance 2025-12-23 00:32:36 -06:00
Cameron Gutman d501a627f0 Test all renderers before use
Every renderer except SDL had opted-in for testing due to various
quirks discovered over the years, so just do away with this option
and test all renderers.
2025-12-22 23:58:26 -06:00
Cameron Gutman 526d815930 Don't fall back to the generic hwaccel for DRM_PRIME formats 2025-12-22 15:06:20 -06:00
Cameron Gutman b448e5bbd7 Update AppImage dependencies 2025-12-22 10:54:50 -06:00
Cameron Gutman 741e360024 Fix GLES compatibility check on VF2 pvr driver 2025-12-21 22:15:29 -06:00
Cameron Gutman 7edbede95d Force Qt to use GLES if desktop GL is not available
Some platforms like the VisionFive 2 don't have working desktop GL,
so they must use GLES to be able to render at all. Qt doesn't try
to fall back if it fails to find a compatible EGL config, so we must
do so ourselves.
2025-12-21 21:13:22 -06:00
Cameron Gutman 7f54662160 Autoselect AV1 over H.264 on RK3588 2025-12-21 14:59:08 -06:00
Cameron Gutman f66285ddba Fix spurious HEVC software decode warning if AV1 is forced without HEVC hardware decoding 2025-12-21 14:36:22 -06:00
detiam bf250a4edb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2025-12-21 19:00:22 +00:00
Cameron Gutman bdfadb1cdc Let the streaming session handle exiting on SIGTERM 2025-12-14 19:11:13 -06:00
Cameron Gutman 63a381a882 Fix macOS build 2025-12-14 19:07:50 -06:00
Cameron Gutman 4a591069ac Add custom signal handlers to arbitrate between Qt and SDL
Fixes #1496
2025-12-14 18:57:26 -06:00
Cameron Gutman c71b513bc4 Pump the Qt event loop before creating the SDL window 2025-12-14 18:09:20 -06:00
Cameron Gutman 700655c051 Remove the fixed delay for starting the connection
The StreamSegue already handles delaying to allow the warnings to be visible.
2025-12-14 17:57:20 -06:00
Cameron Gutman 3425fec33d Use EGL+GLES workaround for Nvidia X11
We can avoid disabling EGL entirely by forcing Qt to use GLES,
which is not impacted by the black window issue. This lets us
simplify back to EGL everywhere.
2025-12-14 16:21:32 -06:00
Cameron Gutman de844f2a0c Deprioritize the Nvidia VAAPI driver if Vulkan or CUDA are available 2025-12-11 20:13:14 -06:00
Cameron Gutman 54163e30d0 Disable EGL on Nvidia XWayland environments too
It renders a black window, just like native X11.
2025-12-11 20:13:14 -06:00
Cameron Gutman bd6a1d9a9b Replace NVDEC with Vulkan Video in Flatpak metadata
NVDEC has been disabled by default since e6e91ca8
2025-12-10 21:54:07 -06:00
Cameron Gutman b25801ff7d Update VCRedist 2025-12-10 21:47:31 -06:00
Cameron Gutman bc5e9917cd Fix PS script for compatibility with KB5074596 2025-12-10 21:46:44 -06:00
Cameron Gutman d8eb817ed9 Rerun lupdate and lrelease 2025-12-09 00:47:21 -06:00
Cameron Gutman c1e5b0bf66 Merge remote-tracking branch 'origin/weblate' 2025-12-09 00:45:35 -06:00
Cameron Gutman 26f96a20a9 Fix implicit fall-through warnings 2025-12-07 18:58:25 -06:00
Cameron Gutman dbcc6a9089 Improve initialization performance when using Vulkan Video decoding 2025-12-07 17:57:22 -06:00
Cameron Gutman 9c6d2bab19 Use EGL_VENDOR instead of NV-CONTROL for Nvidia detection
The latter will still match on a hybrid system when the iGPU's EGL
implementation is in use. This scenario works properly with EGL
rendering in Qt and SDL, so we want to allow that.
2025-12-06 11:20:03 -06:00
Cameron Gutman c92dc2495e Don't use vaPutSurface() if there are no valid subpicture formats 2025-12-05 23:52:41 -06:00
Cameron Gutman 1c24aada0a Never use X11 EGL on Nvidia proprietary drivers
Fixes #1751
2025-12-05 23:10:31 -06:00
Cameron Gutman 58f9b2a83b Use opaque black in ClearRenderTargetView()
Intel's old Gen9 performance guide says it's a little faster.
2025-12-01 22:39:28 -06:00
Cameron Gutman 5feb331c46 Improve QT_QPA_EGLFS_KMS_CONFIG temporary file handling
- Close it before handing it to the QPA plugin to read
- Put the temporary file in TMPDIR instead of the current directory
2025-12-01 00:36:59 -06:00
Cameron Gutman 9d5f25f828 Don't use separate threads for querying SDL video info
This is no longer necessary now that we force Qt and SDL to use EGL.
2025-11-30 23:18:38 -06:00
Cameron Gutman d3c23b55dc Disable the VAAPI RFI latency workaround by default
I can no longer reproduce this issue on the same system running
Ubuntu 24.04 with the core22-based edge channel snap anymore.
2025-11-30 22:23:09 -06:00
Cameron Gutman 80b7a69cd2 Revert "Use the default Qt render loop"
This seems to cause 10+ second hangs at the StreamSegue spinner
when using the Qt5-based Snap on Ubuntu 24.04's Wayland session.

It's unclear if this is still an issue on Qt 6, but let's be
conservative and just revert it for now.

This reverts commit f57257cbfd.
2025-11-30 22:00:33 -06:00
dependabot[bot] 296387345d Bump moonlight-common-c/moonlight-common-c from 2d984f4 to b126e48
Bumps [moonlight-common-c/moonlight-common-c](https://github.com/moonlight-stream/moonlight-common-c) from `2d984f4` to `b126e48`.
- [Commits](https://github.com/moonlight-stream/moonlight-common-c/compare/2d984f4b0dfab5ea2cff0f262abe1a056946a7c1...b126e481a195fdc7152d211def17190e3434bcce)

---
updated-dependencies:
- dependency-name: moonlight-common-c/moonlight-common-c
  dependency-version: b126e481a195fdc7152d211def17190e3434bcce
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-26 21:06:38 -06:00
Cameron Gutman 42bf87753f Remove the installer check for MpsSvc
The firewall custom action has ignored failures since a6e549471c, so this pre-check is no longer necessary.

Fixes #1736
2025-11-26 21:06:06 -06:00
Cameron Gutman d262e5d1f6 Recompile D3D11 shaders for Shader Model 5.0
We already require FL 11.0+ GPUs anyway, so compiling them for an older shader model didn't provide any benefit.
2025-11-24 19:02:20 -06:00
Cameron Gutman f0821d9543 Use D3D11_COPY_DISCARD when updating our video texture
This ensures the driver knows it doesn't have to synchronize with the previous texture data.
2025-11-24 18:49:19 -06:00
Cameron Gutman 4164a222ae Consolidate D3D11 constant buffers now that all shaders need a CSC constant buffer 2025-11-24 18:47:14 -06:00
Cameron Gutman 245cd7f1a8 Don't trim the alignment padding with CopySubresourceRegion()
The shader already handles trimming for the bound output texture case.
2025-11-24 01:44:51 -06:00
Cameron Gutman 62816a6b2a Prioritize AV1 over H.264 if HEVC is unavailable on Windows
Some Windows PCs are shipping with HEVC disabled in firmware, even though they support AV1.
2025-11-24 00:06:40 -06:00
Cameron Gutman f5ef201905 Create a separate X11 Display object for libva
Sharing these directly is fraught with concurrency issues that
require extreme care on both sides to avoid spurious X11 errors,
hangs, and other nasty stuff. We can't necessarily depend on SDL,
libva, or the underlying VA drivers to do the right thing here.

Using a new Display (as FFmpeg does for VAAPI and VDPAU) avoids
all these problems.
2025-11-23 13:26:46 -06:00
Cameron Gutman 01288be937 Use the same X display name for VDPAU that SDL is using 2025-11-23 13:20:36 -06:00
Cameron Gutman f57257cbfd Use the default Qt render loop
Since we stopped pumping the event loop manually and switched to EGL
on X11, the default threaded render loop seems to work fine now.
2025-11-22 20:12:46 -06:00
Cameron Gutman d40999ce06 Don't reset Qt's OpenGL state
We're using a different EGL context for SDL, so it's unnecessary.
2025-11-22 19:47:52 -06:00
Cameron Gutman cb6d770b92 Restore the tooltip timeout-based hiding
The fade-out animation doesn't run on Linux when the window is
hidden, so the tooltips will reappear and fade on the app grid
which is ugly.
2025-11-22 19:35:23 -06:00
Cameron Gutman 4d6196c3d3 Use EGL for all X11 GL context creation in Qt and SDL
Using a mix of GLX and EGL can cause interoperability issues when
our EGLRenderer tries to bind an EGL context while Qt already has
a GLX context bound on the same thread. This was the source of a
number of confusing EGLRenderer failures over the years.
2025-11-22 18:51:32 -06:00
Cameron Gutman 54283ce0a1 Rework session initialization to return to the Qt event loop while connecting
We also display multiple launch warnings at the same time
2025-11-22 17:09:16 -06:00
Cameron Gutman 6313129603 Temporarily revert Windows ARM64 to Qt 6.10.0
aqtinstall needs a fix to handle Qt 6.10.1's new host/target qmake split.
2025-11-20 00:55:24 -06:00
Cameron Gutman 84d7a22638 Update CI builds to Qt 6.10.1 2025-11-20 00:22:22 -06:00
Cameron Gutman f0aff0b0fb Update VCRedist for VS 2026 2025-11-20 00:02:05 -06:00
Cameron Gutman be358e9503 Update common-c with rewritten gamepad batching logic 2025-11-15 13:35:23 -06:00
Cameron Gutman 379d5ca376 Fix some compiler warnings 2025-11-15 13:34:11 -06:00
Cameron Gutman 8ed7144751 Disable bitrate reporting until FEC accuracy issues are resolved 2025-11-15 12:22:51 -06:00
Andy Grundman 66b96e75af Convert all time-based stats to be microsecond-based, improving accuracy of very fast events. Add bitrate average/peak. 2025-11-15 12:17:59 -06:00
Cameron Gutman 1160f40655 Recombine the YUV420 shader source
We don't build shaders with hardcoded CSC constants anymore.
2025-11-08 11:40:06 -06:00
dependabot[bot] d5abf568c6 Bump moonlight-common-c/moonlight-common-c from e95feaf to 5f22801
Bumps [moonlight-common-c/moonlight-common-c](https://github.com/moonlight-stream/moonlight-common-c) from `e95feaf` to `5f22801`.
- [Commits](https://github.com/moonlight-stream/moonlight-common-c/compare/e95feaf4951b8dc774671a5d6a1c31d76d78e3ac...5f2280183cb62cba1052894d76e64e5f4153377d)

---
updated-dependencies:
- dependency-name: moonlight-common-c/moonlight-common-c
  dependency-version: 5f2280183cb62cba1052894d76e64e5f4153377d
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-06 20:53:50 -06:00
Cameron Gutman 8324f61db0 Reduce per-frame GL calls in EGLRenderer
Uniforms are attached to the program object, so they don't need to
be set each time we swap between the YUV shader and the overlay
shader.

Since 0 overlays is by far the most common case and > 1 is highly
unlikely, move the glViewport() call into renderOverlay() to let
us skip it in the common case (and be no worse than today in the
2nd most common case of 1 overlay).
2025-11-06 17:52:30 -06:00
Cameron Gutman 9106f2c420 Disable the depth and stencil buffers
We don't have any need for either in our renderers.
2025-11-06 17:44:01 -06:00
Cameron Gutman a2670dd568 Use hasFrameFormatChanged() in DRMRenderer 2025-11-06 00:04:08 -06:00
Cameron Gutman c54e6e4459 Use hasFrameFormatChanged() in VDPAU 2025-11-05 23:58:51 -06:00
Cameron Gutman dd6f1c5873 Use hasFrameFormatChanged() in SDLRenderer 2025-11-05 23:51:51 -06:00
Cameron Gutman 7fab5007a8 Switch Metal to the shared functions for CSC matrix generation and chroma co-siting 2025-11-05 23:22:15 -06:00
Cameron Gutman 7f7cc89e61 Switch EGLRenderer to the shared functions for CSC matrix generation and chroma co-siting 2025-11-05 22:27:31 -06:00
Cameron Gutman 7116efd8de Switch D3D11VA to the shared functions for CSC matrix generation and chroma co-siting 2025-11-05 22:26:27 -06:00
Cameron Gutman 229f5e4cea Add functions for color matrix generation and chroma co-siting in the renderer interface 2025-11-05 21:59:13 -06:00
ns6089 af37002a60 Select correct color matrix for 10-bit SDR 2025-11-05 00:13:25 -06:00
Cameron Gutman 181dba5864 Use correct chroma co-siting offsets in Metal 2025-11-04 23:51:39 -06:00
ns6089 fd314db27e Use correct chroma co-siting offsets in D3D11
Introduced in f67272b153
2025-11-04 23:50:27 -06:00
Cameron Gutman f67272b153 Handle chroma co-siting in the D3D11 shaders 2025-11-01 22:42:51 -05:00
Cameron Gutman 9b3050514b Handle chroma co-siting in the Metal shaders 2025-11-01 21:57:13 -05:00
Cameron Gutman 2c12ad297f Fix accuracy issues in YUV to RGB conversion of 10-bit content in Metal
See #1667 for details.
2025-11-01 19:19:19 -05:00
Cameron Gutman 50223dbdb8 Fix accuracy issues in YUV to RGB conversion of 10-bit content in D3D11VA
See #1667 for details.
2025-11-01 18:45:02 -05:00
dependabot[bot] beadf7819b Bump app/SDL_GameControllerDB from 38fc811 to e40b891
Bumps [app/SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) from `38fc811` to `e40b891`.
- [Commits](https://github.com/gabomdq/SDL_GameControllerDB/compare/38fc811c715365e963a6942092cae147eddddc90...e40b8910f859cd988124def50dcdb63b2f2ff48b)

---
updated-dependencies:
- dependency-name: app/SDL_GameControllerDB
  dependency-version: e40b8910f859cd988124def50dcdb63b2f2ff48b
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 22:11:10 -05:00
ReenigneArcher 7d829ac0c4 ci: refactor workflows to use reusable workflow calls
Updated build workflows to use workflow_call triggers and accept ci_version as input, removing inline CI version generation. Upgraded all actions to v5 and added a new build.yml workflow to orchestrate builds for AppImage, Steam Link, and Windows/macOS using reusable workflows. This improves maintainability and consistency across CI jobs.
2025-10-27 21:54:59 -05:00
arrhteeime 2f6e7608f8 Translated using Weblate (Russian)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2025-10-27 17:02:42 +00:00
Cameron Gutman 5244313b30 Improve archiving of Windows CI builds 2025-10-26 22:17:21 -05:00
Cameron Gutman c13e6b08c1 Remove unused AppVeyor CI files 2025-10-26 21:55:58 -05:00
Cameron Gutman 151f5dd678 Switch to GitHub Actions for AppImage builds 2025-10-26 21:15:41 -05:00
Cameron Gutman a34d40e3ee Switch to GitHub Actions for Steam Link builds 2025-10-26 16:06:09 -05:00
Cameron Gutman 68aa04926e Switch to GitHub Actions for Windows and macOS builds 2025-10-26 15:09:57 -05:00
Cameron Gutman 7d544c1ce4 Move audio capabilities out of the renderer classes
Since the removal of libsoundio, all renderers support arbitrary audio duration, so we can avoid having to start an audio session just to query capabilities.
2025-10-25 19:17:38 -05:00
Cameron Gutman ac7696ea8f Rebuild FFmpeg for macOS and OpenSSL for Windows
- Fixes unexpected Homebrew library dependency in macOS FFmpeg build
- Adds CFG and EHCont mitigations in Windows OpenSSL build
- Remove unused Windows avformat binaries

https://github.com/cgutman/moonlight-deps/commit/d3a3222573f1deefa175ade600702f17f56192fa
2025-10-25 18:13:13 -05:00
Daniel Nylander e79bf664dd Translated using Weblate (Swedish)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2025-10-25 17:02:42 +02:00
Cameron Gutman 4d303cebee Consolidate all writes to the log stream in LoggerTask
This avoids some thread-safety issues when switching log modes or reaching the log size limit.
2025-10-25 00:33:02 -05:00
Cameron Gutman bd6235efba Use async logging while streaming only
The benefits of reliable output outweigh performance concerns during non-streaming activities.
2025-10-25 00:18:34 -05:00
Cameron Gutman b1232e0ed4 Fix memory corruption due to concurrent QString operations 2025-10-24 23:38:07 -05:00
Cameron Gutman c35f7086a0 Block the Bandicam Vulkan layer from loading into Moonlight
It installs a buggy vkDestroySwapchainKHR() hook that causes Moonlight to crash deterministically on startup.

Fixes #1425
2025-10-24 23:17:03 -05:00
Cameron Gutman c7bc76325f Revert macOS audio buffer size workaround
This causes excessive glitching and needs to be fixed by Apple (if it hasn't already in the 2 years since the report).
2025-10-23 21:42:44 -05:00
Cameron Gutman ccaca68570 Don't use CAMetalDisplayLink on Intel Macs
When in Direct mode, skipping a frame will cause the display to flash black on Tahoe.
2025-10-23 21:16:53 -05:00
Cameron Gutman 57db20016a Rewrite frame pacing mechanism for VTMetalRenderer
This should hopefully improve performance and avoid performance issues on Tahoe.
2025-10-23 19:43:10 -05:00
Cameron Gutman bdb6d02dac Add (currently harmless) missing break 2025-10-22 23:21:07 -05:00
Cameron Gutman 9bcc6291be Auto-lock the cursor in single display borderless windowed scenarios 2025-10-22 23:13:03 -05:00
Brad Smith 4ec549650d Add fast AES detection for FreeBSD/OpenBSD on ARM/AArch64 using elf_aux_info() 2025-10-22 18:40:20 -05:00
Cameron Gutman 14027f3c74 Limit the IME workaround to Windows only 2025-10-20 23:37:31 -05:00
Qian23333 fb9a164111 feat: disable text input when window gains focus 2025-10-20 23:33:10 -05:00
Cameron Gutman 200cab9d17 Attach EDR metadata to Metal layer
This improves the accuracy of HDR streaming and enables HDR->SDR tonemapping.
2025-10-20 22:28:27 -05:00
Brad Smith c52a57f0ec build: Fix building on *BSD/riscv64 2025-10-20 21:21:00 -05:00
Cameron Gutman b4dc7ca7cb Build AppImage with Qt 6 2025-10-20 20:51:51 -05:00
Cameron Gutman 00c1dd0d0d Fix missing svg module in AppImage 2025-10-20 01:01:25 -05:00
therealmate ecfc24c5d4 Translated using Weblate (Hungarian)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2025-10-20 06:50:44 +02:00
Cameron Gutman e6e91ca88b Disable CUDA by default in favor of Vulkan and VDPAU
All of our official releases (Flatpak and AppImage) already do this, so this just makes it official.

This can be overridden by running qmake with CONFIG+=enable-cuda.
2025-10-19 21:24:29 -05:00
Cameron Gutman 260a0e0ae2 Use Ubuntu Jammy base OS for AppImage 2025-10-19 21:11:34 -05:00
Cameron Gutman 3f8f4744c5 Reduce CPU usage from background PC polling 2025-10-19 20:50:29 -05:00
Cameron Gutman 4bbd02fb2d Reduce the priority of background polling threads 2025-10-19 17:31:33 -05:00
Cameron Gutman c5ca672865 Don't set pix_fmt for hwaccel decoders
This works around a bug in the AV1 Vulkan decoding code in FFmpeg
that causes it to incorrectly skip hwaccel init.

Fixes #1511
2025-10-19 16:16:06 -05:00
Cameron Gutman 4688f3650c Handle IPv6 literals without URL escaping too
Fixes #1547
2025-10-19 13:31:27 -05:00
celeresxandCameron Gutman 2550f416f4 Clarify Steam Link hardware limitations in README (fixes #1558) (#1612)
Co-authored-by: Cameron Gutman <aicommander@gmail.com>
2025-10-19 12:58:16 -05:00
Cameron Gutman 579ad25a01 Add CONFIG+=disable-masterhooks QMake option
This allows disabling the DRM master hooks for environments where
getting DRM master is impossible (such as sandboxes like Flatpak),
but leave the DRM renderer itself enabled for usecases like V4L2
which require the DRM renderer to export DMA-BUFs to EGL.
2025-10-12 23:03:53 -05:00
Cameron Gutman 1144dbccb3 Don't call dlsym() in our DRM master hooks
Not only is it faster to cache the function pointers, calling
dlsym() inside open()/close() can lead to deadlocks when using
Vulkan Video decoding on top of the Nvidia driver.
2025-10-12 22:49:29 -05:00
Cameron Gutman ff81f74391 Enable D3D12VA hwaccels in FFmpeg 2025-10-12 15:56:10 -05:00
Cameron Gutman c0d38ee78f Switch the decoder lock to a mutex
It can be held for non-trivial amounts of time.
2025-10-12 15:47:09 -05:00
Cameron Gutman c9cb64f90b Fix StreamSegue BusyIndicator running after streaming
See #1695
2025-10-11 15:50:45 -05:00
Eval EXEC 93e597a93f Stop hidden BusyIndicators from burning CPU 2025-10-11 15:34:55 -05:00
Cameron Gutman 82b33c033a Update and rebuild all prebuilt libraries 2025-10-11 14:41:03 -05:00
Cameron Gutman be266d3349 Disable toolbar icon scaling
Closes #1192
2025-10-11 12:55:54 -05:00
Cameron Gutman c618a0b5df Use native QML icon support 2025-10-11 12:52:37 -05:00
Cameron Gutman a20d429bc1 Remove usage of deprecated Metal API 2025-10-11 11:41:28 -05:00
Cameron Gutman 2b3e0803de Increase Qt requirement to 5.12 and remove pre-5.12 workarounds 2025-10-11 11:03:33 -05:00
Cameron Gutman 4189903233 Remove libsoundio audio backend
SDL has been the default audio backend for years now, and libsoundio has
not been well-maintained upstream.
2025-10-11 10:35:31 -05:00
Любомир Василев 1a0dd56bb9 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2025-10-11 16:07:31 +02:00
Philip Goto 3aa3bfa403 Translated using Weblate (Dutch)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2025-10-11 16:07:30 +02:00
sanhoe aa9a716bd5 Translated using Weblate (Korean)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2025-10-11 16:07:28 +02:00
Jorys Paulin 6fd2b73e6b Translated using Weblate (French)
Currently translated at 100.0% (251 of 251 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2025-10-11 16:07:25 +02:00
Cameron Gutman 06b5c4631f Fix warning for unnecessary .desktop suffix passed to setDesktopFileName() 2025-10-11 00:36:54 -05:00
Cameron Gutman 997c4aa0ae Fix unchecked return value warnings using QIODevice::Open() 2025-10-11 00:24:02 -05:00
dependabot[bot] f4343c5f29 Bump app/SDL_GameControllerDB from 7979e7b to 38fc811
Bumps [app/SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) from `7979e7b` to `38fc811`.
- [Commits](https://github.com/gabomdq/SDL_GameControllerDB/compare/7979e7b29261c11ebce2deabc41ed081b6691398...38fc811c715365e963a6942092cae147eddddc90)

---
updated-dependencies:
- dependency-name: app/SDL_GameControllerDB
  dependency-version: 38fc811c715365e963a6942092cae147eddddc90
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-11 00:13:38 -05:00
Cameron Gutman 3cdea6b039 Update VC redistributable in installer bundle 2025-10-11 00:12:19 -05:00
Cameron Gutman ac2e10c712 Update to WiX v6.0.2 2025-10-11 00:11:09 -05:00
Simon Pawlowski 61fa45ad21 Fixed translation (#1669)
MBps is used for megabytes, even in German. Mbps is the correct translation.
2025-10-10 00:49:25 -05:00
Cameron Gutman f362e76127 Sync AppImage dependency versions with moonlight-deps 2025-10-10 00:45:58 -05:00
Cameron Gutman 749c69fc76 Build Windows against Qt 6.9 in CI 2025-10-10 00:41:48 -05:00
Cameron Gutman 5dca30def1 Rerun lupdate and lrelease 2025-10-10 00:35:37 -05:00
Cameron Gutman 502783a86b Merge remote-tracking branch 'origin/weblate' 2025-10-10 00:33:55 -05:00
Cameron Gutman 45989fdd6e Fix incorrect toolbar color on Qt 6.9+
Fixes #1685
2025-10-09 20:47:58 -05:00
Cameron Gutman 490aa5082f Don't use SDL locking functions in our open()/close() hooks
Other shared library constructors can invoke open()/close() before
SDL2-compat's constructor runs to load SDL3 and populate the SDL3
function table. This causes SDL_AtomicLock()/SDL_AtomicUnlock()
to jump to 0.

See #1707
2025-10-09 20:03:19 -05:00
Taylor Lineman ae1c65805c Enable Game Mode on Apple Platforms (#1709) 2025-10-09 18:10:44 -05:00
Cameron Gutman 9cb4105aec Fix incorrect getToggleOptionValue behavior 2025-08-31 15:15:24 -05:00
armin-25689 1fd545ae1f build: fix no <linux/dma-buf.h> for BSDs 2025-08-31 15:05:03 -05:00
Daniel Nylander 3194cb09d8 Translated using Weblate (Swedish)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2025-08-31 08:05:47 +02:00
Cameron Gutman f9bb45579b Enable CFG, EHCont, and CET for Windows builds 2025-08-24 20:42:37 -05:00
grgergo f7b2edc8e3 Translated using Weblate (Hungarian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2025-08-13 20:02:11 +02:00
veldenb c9a3946d80 Translated using Weblate (Dutch)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2025-07-29 01:43:50 +02:00
Laszlo Racz 0c8354336b Fix: Improve stream window resizing logic 2025-07-27 14:23:12 -05:00
Cameron Gutman 1bf86f52d3 Deregister logging callbacks before destroying the logger 2025-07-04 15:56:11 -05:00
dependabot[bot] 504d42865d Bump app/SDL_GameControllerDB from e5a5fa2 to 7979e7b
Bumps [app/SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) from `e5a5fa2` to `7979e7b`.
- [Commits](https://github.com/gabomdq/SDL_GameControllerDB/compare/e5a5fa2ac6e645d72c619ea99520a3a4586ee005...7979e7b29261c11ebce2deabc41ed081b6691398)

---
updated-dependencies:
- dependency-name: app/SDL_GameControllerDB
  dependency-version: 7979e7b29261c11ebce2deabc41ed081b6691398
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-04 15:05:05 -05:00
Odizinne 65c04fd560 Added option to disable pre launch warning and delay 2025-07-04 15:04:10 -05:00
Cameron Gutman 11dc244857 Create dependabot.yml for submodule updates 2025-07-04 14:46:44 -05:00
FrogTheFrog b9cab4cac5 fix outdated app list printing via cli 2025-07-04 14:32:47 -05:00
6690 65647a32f4 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2025-06-26 22:59:02 +02:00
therealmate 777502b495 Translated using Weblate (Hungarian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2025-06-24 07:01:47 +00:00
தமிழ்நேரம் ce4309694f Translated using Weblate (Tamil)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ta/
2025-06-23 05:16:19 +02:00
therealmate ccc64a5629 Translated using Weblate (Hungarian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2025-06-23 05:16:19 +02:00
Batıkan Ökten 25f6c020b6 Translated using Weblate (Turkish)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2025-06-03 01:23:26 +02:00
caviaz 6a95742a92 Translated using Weblate (Dutch)
Currently translated at 84.4% (211 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2025-05-27 09:01:44 +02:00
FrogTheFrog 1dbdcb5279 Prevent double printing app list via cli 2025-05-07 18:27:00 -05:00
GOGOsu 9ce0537587 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2025-05-07 11:01:44 +02:00
arrhteeime 76d03f015d Translated using Weblate (Russian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2025-05-02 15:02:58 +02:00
aga_90 edbc24fa3e Translated using Weblate (Hungarian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2025-05-01 01:09:49 +02:00
Nicolas Xavier Herrera Medina d4fd50b973 Translated using Weblate (Spanish)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2025-04-25 10:12:30 +02:00
sanhoe d5ab795b36 Translated using Weblate (Korean)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2025-04-20 10:06:37 +02:00
Jorys Paulin c5fc5220f3 Translated using Weblate (French)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2025-04-18 13:00:11 +02:00
Alex 28dea31533 Translated using Weblate (German)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2025-04-16 02:21:21 +02:00
Любомир Василев 8ce6a9585f Translated using Weblate (Bulgarian)
Currently translated at 100.0% (250 of 250 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2025-04-08 05:36:27 +02:00
Cameron Gutman 47452371db Rerun lupdate and lrelease 2025-04-05 20:29:24 -05:00
Cameron Gutman 4001b05fca Add new languages 2025-04-05 20:29:09 -05:00
Cameron Gutman 75e917622e Merge remote-tracking branch 'origin/weblate' 2025-04-05 20:15:30 -05:00
Cameron Gutman 75359bb1c4 Fix tooltip layout with Qt 6.9 2025-04-05 00:27:50 -05:00
Cameron Gutman c93f7e7385 Output CLI error/info messages to the console on Windows
Fixes #1554
2025-04-04 22:23:17 -05:00
Cameron Gutman 48bcd725c9 Use static QRegularExpressions as recommended by Clazy 2025-04-04 22:13:45 -05:00
MoreOrLessSoftware e807a52cfa Add bitrate auto-adjustment toggle and reset button
This change adds a 'Use Default' button next to the bitrate slider that resets the bitrate to the default value for the current resolution/FPS. It also implements an autoAdjustBitrate setting that controls whether the bitrate is automatically updated when resolution/FPS/YUV444 settings change.

- When the user manually adjusts the bitrate slider, autoAdjustBitrate is set to false
- When the user clicks the 'Use Default' button, autoAdjustBitrate is set to true
- Bitrate is only updated automatically when settings change if autoAdjustBitrate is true
2025-04-02 22:02:09 -05:00
James Poje 9c9bfd8428 Add quit-app-and-exit shortcut Ctrl+Alt+Shift+E
Add a shortcut to quit the current app and exit Moonlight entirely.
2025-04-02 21:55:38 -05:00
Jorys Paulin 29b1304337 feat: hide hw acceleration warning when using forced software decoding 2025-04-02 21:46:11 -05:00
Jorys Paulin cc0b574bb1 feat: add message when host doesn't show any apps 2025-04-02 21:45:23 -05:00
Cameron Gutman 7a769172a1 Fix null window on Qt 6.9 2025-04-02 21:14:22 -05:00
ABeltramo d9c7a245ef DualSense adaptive trigger support (#1561) 2025-04-01 21:45:25 -05:00
Serdar Sağlam 469a5c78f1 Translated using Weblate (Turkish)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2025-03-27 04:15:37 +01:00
rinsuki fabb4fdadc Fix INTERNATIONAL keys wouldn't work properly
since those keys aren't exist in US keyboard, we shouldn't treat (and convert) as a US keyboard keycodes (on Sunshine).
2025-02-19 22:18:34 -06:00
rinsuki 9491884cb4 Add some key definitions to support Japanese Keyboard Layout
Tested environment:

Moonlight on macOS 15.3 w/ MacBook Pro Internal Keyboard
Sunshine 2025.122.141614 w/ Windows 11 24H2
2025-02-19 22:18:34 -06:00
Cameron Gutman bf51577787 Fix macOS build 2025-02-18 19:52:33 -06:00
Cameron Gutman 4c5bcee8dc Give up immediately if the backend fails to initialize 2025-02-18 19:46:29 -06:00
Cameron Gutman fd70865026 Avoid retrying renderer init if we know the error was not transient 2025-02-18 19:02:12 -06:00
Cameron Gutman 351aaa6759 Add an enum type for each renderer 2025-02-18 18:58:04 -06:00
Philip Goto 59bc625cc7 Translated using Weblate (Dutch)
Currently translated at 84.6% (210 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2025-02-15 23:14:56 +01:00
GOGOsu b2f765e8ef Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2025-02-11 07:01:57 +01:00
Kolja bdd9a3a994 Add Network and RemoteAccess categories 2025-02-07 20:21:56 -06:00
Philip Goto 2ecafabcab Translated using Weblate (Dutch)
Currently translated at 83.4% (207 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2025-02-05 14:01:58 +00:00
Cameron Gutman dd2a99a96b Prepare for SDL3 support 2025-01-25 16:20:20 -06:00
தமிழ்நேரம் 9ff2ac0974 Translated using Weblate (Tamil)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ta/
2025-01-19 10:34:48 +01:00
தமிழ்நேரம் 5760d08c33 Added translation using Weblate (Tamil) 2025-01-18 14:02:22 +01:00
Cameron Gutman edd7a134d8 Fix MSVC binary path in CI for Qt 6.8 2025-01-13 20:11:06 -06:00
Cameron Gutman ffa87c5f01 Update Windows AppVeyor builds to Qt 6.8 2025-01-13 19:48:47 -06:00
ZerOriSama ff7e61c6d9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2025-01-06 00:01:23 +00:00
Любомир Василев 6ad96fba42 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-30 13:18:25 +01:00
Любомир Василев 85856114b2 Translated using Weblate (Bulgarian)
Currently translated at 97.9% (243 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-23 10:43:01 +01:00
Любомир Василев 7decfae792 Translated using Weblate (Bulgarian)
Currently translated at 87.5% (217 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-22 09:00:43 +00:00
Любомир Василев b6008b15dc Translated using Weblate (Bulgarian)
Currently translated at 53.6% (133 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-21 09:00:36 +01:00
Любомир Василев 260ec3d80d Translated using Weblate (Bulgarian)
Currently translated at 38.7% (96 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-20 08:25:55 +01:00
Любомир Василев 7ec2e50334 Translated using Weblate (Bulgarian)
Currently translated at 13.7% (34 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/bg/
2024-12-15 14:06:34 +01:00
Любомир Василев e532b9167a Added translation using Weblate (Bulgarian) 2024-12-14 13:07:53 +01:00
Moritz Schirmer 52d5890372 Translated using Weblate (German)
Currently translated at 97.1% (241 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2024-12-06 06:59:09 +01:00
Dark Space f34d11994f Translated using Weblate (Italian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2024-11-23 13:00:19 +01:00
Rouvr 359c92340d Translated using Weblate (Czech)
Currently translated at 86.6% (215 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2024-11-13 20:00:25 +01:00
Cameron Gutman 15e337fff8 Only call SDL_NumJoysticks() once per loop
It does non-trivial work when using sdl2-compat.
2024-11-12 23:52:31 -06:00
Cameron Gutman 707dd3cb83 Checkout libs submodule for Steam Link too 2024-11-08 21:32:32 -06:00
Cameron Gutman 98f6a09991 Use a Ne10-optimized libopus build for Steam Link
Steam Link is an incredibly CPU-constrained platform, so it needs
all the help it can get to avoid audio underruns.
2024-11-08 21:26:45 -06:00
Jorys Paulin f1d0e97681 Translated using Weblate (French)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-11-03 12:00:23 +01:00
Cameron Gutman 103f988dbf Move logging into a separate thread 2024-10-20 21:52:15 -05:00
Cameron Gutman 2257cb0cef Update Windows, macOS, and AppImage libraries
SDL -> 86fd4ed
FFmpeg -> 7.1 (87ccf995c)
dav1d -> 1.5.0
2024-10-20 13:46:05 -05:00
Cameron Gutman b6a3369243 Rework window focus tracking for gamepad navigation 2024-10-18 21:20:56 -05:00
Cameron Gutman 4af9623727 Replace C++ VLAs with std::vector 2024-10-15 22:41:21 -05:00
Cameron Gutman 515db03fe5 Add missing stdbool.h include 2024-10-15 22:38:06 -05:00
Matthias Küch e44d097683 Add stderr log for Steam Link 2024-10-12 00:14:51 -05:00
Jorys Paulin 208d048358 Translated using Weblate (French)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-10-08 14:15:38 +02:00
Cameron Gutman 9936085aee Fix incorrect selection if pix_fmt is overridden before ffGetFormat()
The DRM renderer does this for the out-of-tree v4l2m2m patches to ensure
we get NV12 buffers, but it ends up clobbering our own preference for
DRM_PRIME frames in the process.
2024-10-03 20:28:51 -05:00
Cameron Gutman 3279d9c3f6 Fix QML component versioning error on Qt 5 2024-10-03 00:15:53 -05:00
phlostically e571d5833c Translated using Weblate (Esperanto)
Currently translated at 9.2% (23 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/eo/
2024-10-02 23:16:22 +02:00
Cameron Gutman 3531fe0a4f Fix typo in version check for new Vulkan queue API 2024-10-02 00:37:22 -05:00
phlostically 286676e5c1 Added translation using Weblate (Esperanto) 2024-10-01 22:36:26 +02:00
Cameron Gutman 6ce02616f0 Use new Vulkan queue API in FFmpeg 7.1 2024-09-29 23:04:23 -05:00
Cameron Gutman 13880353d8 Use new avcodec_get_supported_config() API in FFmpeg 7.1 2024-09-29 22:23:37 -05:00
Cameron Gutman ec69dad8d7 Fix import incorrectly removed by 2a63ad5 2024-09-28 00:09:21 -05:00
Cameron Gutman 72ae324d71 Fix unused parameter warnings 2024-09-28 00:08:35 -05:00
Cameron Gutman 901cbd255c Disable Vulkan debug layers by default
The vast majority of Vulkan code running in Moonlight
is part of FFmpeg or libplacebo, so the debug layers
really just slow things down without finding any bugs
in our code.

Additionally, there are some overzealous checks firing
constantly on libplacebo and FFmpeg with certain Vulkan
drivers that we can't do anything about.
2024-09-28 00:05:17 -05:00
Cameron Gutman 2a63ad53d7 Don't poll gamepad input when the GUI is not focused/visible 2024-09-26 19:24:29 -05:00
Cameron Gutman 9b3d4c1ad7 Free the old CRTC connectors array 2024-09-23 22:25:51 -05:00
Cameron Gutman 054e334066 Allow Qt to borrow DRM master from SDL to update the UI 2024-09-23 22:15:31 -05:00
Cameron Gutman 6d023c2dfa Defer launch warnings until after launch validation
We need to destroy the SDL window before we can be sure that Qt
can draw to the screen if we used KMSDRM.
2024-09-23 21:48:43 -05:00
Cameron Gutman 0e2d5bf441 Fix EGLFS state restoration after Vulkan rendering 2024-09-23 21:32:09 -05:00
Cameron Gutman 023b6b2772 Fix DRM FD leak with Vulkan windows 2024-09-21 21:41:43 -05:00
Cameron Gutman 6f39d120cb Unify handling of DRM devices between DRM and VAAPI
SDL may not be able to give us a DRM FD for Vulkan windows.
2024-09-21 20:46:11 -05:00
Cameron Gutman 9cf305865b Add support for managing multiple SDL DRM FDs
This is required for Vulkan+KMSDRM rendering.
2024-09-21 20:41:43 -05:00
Patrick Sletvold 6d47287b60 Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.1% (246 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2024-09-21 11:40:45 +00:00
Cameron Gutman 6b11f43302 Don't set the output rect until after modesetting
It's possible that modesetting will also change the resolution
not just the refresh rate. This can happen in cases where the
CRTC is currently set to 4K 30 Hz and we choose 1080p 60 Hz as
a better mode match for displaying a 1080p 60 FPS stream.
2024-09-19 22:43:34 -05:00
Tomonobu Terakubo 60fb6881b2 Translated using Weblate (Japanese)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2024-09-20 01:40:49 +02:00
Артём Журин b79c116bd9 Translated using Weblate (Russian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-09-20 01:40:48 +02:00
Patrick Sletvold 895d0a6bf3 Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.3% (177 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2024-09-20 01:40:48 +02:00
Cameron Gutman 5a1ef55767 Update README.md
Add note about YUV 4:4:4 and update build requirements
2024-09-18 22:16:33 -05:00
Matt Tannahill 76deafbd7b Fix build for Xcode < 14 2024-09-18 22:12:04 -05:00
Tomonobu Terakubo ae2693a860 Translated using Weblate (Japanese)
Currently translated at 95.9% (238 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2024-09-18 13:40:50 +00:00
Артём Журин 0783b28ba6 Translated using Weblate (Russian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-09-18 13:40:50 +00:00
Cameron Gutman f786e94c7b Fix excessive latency with Vulkan video decoding on Nvidia
For yet unknown reasons, high frame queue delay leads to massive decode latency.
2024-09-16 21:59:17 -05:00
Cameron Gutman 1caee721e8 Prepare for v6.1.0 2024-09-16 18:36:50 -05:00
Cameron Gutman accd30176f Rerun lupdate and lrelease 2024-09-15 23:45:27 -05:00
Cameron Gutman 7721fa6d7c Merge remote-tracking branch 'origin/weblate' 2024-09-15 23:44:31 -05:00
Cameron Gutman 8e295aab00 Update dependencies for AppImage
SDL -> 1b26b5440
2024-09-15 23:35:26 -05:00
Cameron Gutman 4838a75c58 Suppress spammy libplacebo messages
Streaming 10-bit content on Nvidia GPUs spams the log with the following for every rendered frame:
Masking `blit_src` from wrapped texture because the corresponding format 'rx10' does not support PL_FMT_CAP_BLITTABLE
Masking `blit_src` from wrapped texture because the corresponding format 'rxgx10' does not support PL_FMT_CAP_BLITTABLE
2024-09-15 22:01:39 -05:00
Cameron Gutman c5ec8c0fdb Add libplacebo prefix to log messages 2024-09-15 21:58:19 -05:00
Cameron Gutman b266f61ba6 Disable direct rendering of YUV444 using vaPutSurface()
It doesn't work as of libva 2.21 + iHD 24.2.5 despite the fact that
the VAEntrypointVideoProc advertises VA_RT_FORMAT_YUV444.
2024-09-15 21:03:00 -05:00
Cameron Gutman d1dffdc34c Prefer optimal 8-bit hardware codec if 10-bit codec is not available 2024-09-15 16:47:30 -05:00
Cameron Gutman 268f8db26b Never negotiate 10-bit profiles without a 10-bit renderer 2024-09-15 15:53:45 -05:00
Cameron Gutman de28eda266 Don't enable HDR checkbox if no HDR renderers work 2024-09-15 15:09:11 -05:00
Cameron Gutman 3e9e497203 Fix viewing apps and CLI streaming with Qt 5.11 and earlier
Arrow function expressions are not supported in QML until Qt 5.12.

Fixes #1350
Closes #1391
2024-09-15 14:39:34 -05:00
Cameron Gutman 96fb6ee5e9 Share SDL's EGL display with EGLRenderer
Fixes #1396
2024-09-12 22:37:25 -05:00
Cameron Gutman 02853e74ba Reduce the bitrate to YUV420 defaults if YUV444 was selected but not negotiated
If the user has selected a custom bitrate, we will leave it alone.
2024-09-12 21:52:27 -05:00
Cameron Gutman 46910cf774 Remove black background workaround now that SDL is fixed 2024-09-12 21:38:30 -05:00
Cameron Gutman b1c77ff80e Disable SDL double buffering
It was broken in SDL until recently and now that it works again, it causes stuttering.
2024-09-12 21:34:22 -05:00
Cameron Gutman 92ee4a3046 Don't use the bind path for UMA GPUs
It turns out to be very marginally slower on RDNA2 iGPUs.
2024-09-12 21:32:36 -05:00
Cameron Gutman 6ec0c79899 Revert "Remove FL 11.0 restriction for D3D11VA"
Even with a fix for the Intel IVB rendering issue, there are still problems on
other older cards that make it not really worth it to enable D3D11VA.

The big benefit of D3D11VA is independent flip in windowed mode using
overlays and that isn't supported on those old cards anyway.

This reverts commit 7074463d0f.
2024-09-12 21:29:40 -05:00
Артём Журин 1c281ee3fc Translated using Weblate (Russian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-09-11 11:09:10 +02:00
Jorys Paulin e2b7cbfe62 Translated using Weblate (French)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-09-07 21:09:17 +02:00
Cameron Gutman 67e89d9e16 Add workaround for incorrect color range in AMF AV1 encoding output 2024-09-04 23:13:48 -05:00
gallegonovato bbf6d9722a Translated using Weblate (Spanish)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-09-04 11:09:36 +00:00
Cameron Gutman 34549864ad Update libraries
SDL2 -> 10b4a79
OpenSSL -> 3.3.2

Should address #1081 with upstream SDL fix
2024-09-03 23:18:12 -05:00
gallegonovato 1303a700e0 Translated using Weblate (Spanish)
Currently translated at 96.7% (240 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-09-03 11:09:25 +02:00
Cameron Gutman 25132a1f7b Enable decoder texture binding for all FL11.1 iGPUs
Since those GPUs don't benefit from the fence hack, restrict that to Intel only.
2024-08-31 00:36:25 -05:00
Cameron Gutman 7074463d0f Remove FL 11.0 restriction for D3D11VA 2024-08-30 23:03:36 -05:00
Cameron Gutman 99311403fa Move dummy fence into renderVideo()
The workaround only seems to work with a new fence each time.
2024-08-30 22:42:53 -05:00
Cameron Gutman 8b50eea485 Wait on a dummy fence before using textures shared with the decoder 2024-08-30 22:22:30 -05:00
Cameron Gutman 302dca6c0c Update OpenSSL libraries for macOS with fixed library path 2024-08-30 16:32:31 -05:00
Cameron Gutman f756be87ff Fix YUV444 hardware decoding on Windows systems without an Intel GPU present 2024-08-30 16:31:58 -05:00
Cameron Gutman 9d99ecbca6 Add note about installing the Graphics Tools optional feature 2024-08-30 16:23:31 -05:00
Arda Anıl 1475bdfbba Translated using Weblate (Turkish)
Currently translated at 100.0% (248 of 248 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2024-08-30 21:09:24 +00:00
Cameron Gutman 69a3406d4a Fix broken PDBs for libplacebo.dll 2024-08-30 00:08:02 -05:00
Cameron Gutman 7e17d82ee5 Add a NSLocalNetworkUsageDescription for Sequoia 2024-08-29 23:31:55 -05:00
Cameron Gutman 153db55519 Replace OpenSSL static libs with dylibs to enable Qt OpenSSL TLS plugin
SecureTransport is deprecated, stuck on TLS 1.2, and seems prone to
random breakage in OS updates (see #1355).
2024-08-29 23:28:08 -05:00
Cameron Gutman 4290a54ffa Log the chosen Metal device 2024-08-29 23:20:52 -05:00
Cameron Gutman a6e549471c Ignore failures when registering firewall exceptions
There appear to be bugs in the WiX firewall extension that causes errors on
install/upgrade in some scenarios (seemingly where existing fw exceptions for
Moonlight exist as in #1309).

Since a firewall exception really only provides minimal benefits for us in the
default configuration of Windows Firewall (outgoing: allow, incoming: deny) due
to WFP's stateful treatment of solicited unicast/multicast UDP traffic, let's
allow it to silently fail and not abort the whole installation.
2024-08-29 02:14:04 -05:00
Cameron Gutman 04edfdc4ca Update to WiX 5.0.1 2024-08-29 01:50:53 -05:00
Cameron Gutman db30faf602 Enable Turkish language now that it's nearly completely translated 2024-08-29 01:40:13 -05:00
Cameron Gutman cdb610f121 Rerun lupdate and lrelease 2024-08-29 01:39:09 -05:00
Cameron Gutman e404722e7c Add Estonian translation 2024-08-29 01:37:09 -05:00
Cameron Gutman 1840c47751 Merge remote-tracking branch 'origin/weblate' 2024-08-29 01:24:36 -05:00
c0dE 3bd571bc90 Translated using Weblate (Portuguese (Brazil))
Currently translated at 26.6% (64 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2024-08-29 08:24:04 +02:00
G.Nakai 224153e230 Translated using Weblate (Japanese)
Currently translated at 94.1% (226 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2024-08-29 08:24:04 +02:00
Cameron Gutman ef12850867 Remove unnecessary Windows dependencies 2024-08-29 01:22:41 -05:00
Cameron Gutman caf322d934 Provide valid default preferred formats for YUV444 2024-08-29 01:03:39 -05:00
Cameron Gutman 9043e8f663 Remove hard limits for bitrate and FPS command-line options 2024-08-25 16:18:55 -05:00
Cameron Gutman 76fd502262 Reintroduce support for FFmpeg 4
Some SBCs still depend on patched FFmpeg 4.x builds for hardware acceleration.
2024-08-24 16:50:27 -05:00
Cameron Gutman 9186feca80 Slightly simplify Metal shader 2024-08-22 01:18:39 -05:00
Cameron Gutman df814fef4a Implement support for HDR with software decoding on macOS 2024-08-22 00:05:26 -05:00
Cameron Gutman d2b3bc962f Probe for a HDR-compatible software renderer 2024-08-20 23:03:41 -05:00
Cameron Gutman 876375f7e9 Add additional codec negotiation improvements
- Fix picking incompatible YUV444 codec if software decoding was forced
- Prefer AV1 over HEVC when using HDR with software decoding
- Display software decoding warning when using an HDR codec without hardware decoding
2024-08-20 23:03:09 -05:00
Cameron Gutman e662e93a53 Prioritize AV1 over HEVC for HDR with software decoding
dav1d is much faster than FFmpeg's HEVC decoder
2024-08-20 01:30:33 -05:00
Cameron Gutman 7c6954b5f6 Add HDR support with software decoding using libplacebo
Not supported on macOS yet.
2024-08-20 01:28:00 -05:00
Cameron Gutman 416003248b Enable Vulkan renderer on Windows ARM64 builds 2024-08-20 00:43:03 -05:00
Cameron Gutman 6d6cd6fc35 Improve codec autoselection logic
- Deprioritize codecs that don't have hardware decoding rather than rejecting them outright
- Allow AV1 to be negotiated with autoselection if no other codec is available
- Take into account YUV444 preference when picking an optimal codec
- Arrange codec preference in ascending order of computational complexity when hardware decoding is unavailable
2024-08-19 23:41:42 -05:00
Cameron Gutman 17448c02b0 Move host settings to the other column to balance column length 2024-08-19 21:44:52 -05:00
Cameron Gutman f3a75e8e76 Add experimental option to unlock bitrate to 500 Mbps
Fixes #1375
Fixes #1343
Closes #1377
2024-08-19 21:43:00 -05:00
Cameron Gutman 7da085480c Switch to a vanilla 7.0 branch with the Nvidia video decoding fix cherry-picked
moonlight_7_0_2 has out-of-tree V4L2 patches that fail to build with the old libdrm headers in Focal.
2024-08-19 21:03:23 -05:00
Cameron Gutman bed3a6ecd8 Print the friendly name of the unsupported AVPixelFormat in SDLRenderer 2024-08-19 20:58:45 -05:00
Cameron Gutman e01c42153c Allow software decoding if YUV444 is selected rather than falling back to YUV420 2024-08-19 20:58:16 -05:00
Cameron Gutman 9df65cb814 Allow selection of AV1 or HEVC for software decoding when HDR or YUV444 are enabled
These advanced features often/always are only supported with AV1 or HEVC.
2024-08-19 20:57:11 -05:00
Cameron Gutman fddb4881fb Use our FFmpeg fork for the AppImage to fix Nvidia Vulkan decoding crash
Hopefully the required patch will be picked to release/7.0 soon
2024-08-19 19:42:21 -05:00
Cameron Gutman 5765c254cd Add software fallback for YUV444 using libswscale 2024-08-19 19:20:17 -05:00
Cameron Gutman ea724a05a6 Fix compilation with older FFmpeg versions 2024-08-19 01:03:03 -05:00
Cameron Gutman 369f614b59 Rewrite format handling in DRM renderer 2024-08-19 00:57:07 -05:00
Cameron Gutman 8606b2c95e Add support for VUYX and XV30LE for YUV 4:4:4 2024-08-18 23:45:26 -05:00
Cameron Gutman fafddddfe0 Fix size and pitch calculation for dumb buffer uploads 2024-08-18 23:08:20 -05:00
Cameron Gutman 1bb16be183 Allow DrmRenderer to act as a non-DRM hwaccel backend
This case basically works like a degenerate case of a DRM hwaccel
without DRM master where we just provide EGL export functionality
except that we don't even need a DRM FD in this case.

There are patches floating around the FFmpeg list for this:
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=12604
2024-08-17 17:04:30 -05:00
Cameron Gutman 8e2aa87c4f Avoid using D3D11VA on very old Intel GPUs
Fixes #1348
Fixes #1381
2024-08-16 00:32:46 -05:00
ns6089 2aea070d93 Fix resetting bitrate when YUV444 is enabled 2024-08-15 22:56:46 -05:00
Mohammad 37ace0060e Update README.md
Changing package name qtbase6-dev to qt6-base-dev.
2024-08-15 22:56:30 -05:00
Cameron Gutman 28b4272123 Update Windows FFmpeg to 7.0.2 with patches
- Vulkan video decoding crash fix for Nvidia GPUs
- D3D11VA support for HEVC 4:4:4 on Intel GPUs
2024-08-15 22:55:37 -05:00
Cameron Gutman 19660174b7 Check that the new keypair is usable before persisting it 2024-08-15 22:50:49 -05:00
Ettore Atalan 2beaf10ea5 Translated using Weblate (German)
Currently translated at 99.5% (239 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2024-08-15 07:09:13 +00:00
Cameron Gutman 665352ec95 Remove support for Intel's vendor-specific HEVC RExt profiles
These aren't supported upstream (and probably never will be) and recent
Intel drivers for Tiger Lake and later support the Microsoft standard
HEVC RExt profiles now.
2024-08-13 00:50:32 -05:00
Cameron Gutman ab791cf4c8 Add support for the official DXVA HEVC Rext GUIDs defined in the Win11 24H2 SDK 2024-08-02 21:22:43 -05:00
Cameron Gutman ef7dff32aa Don't use Vulkan Video on Intel GPUs on Windows
Intel's Windows drivers are either totally broken or just don't play nicely with FFmpeg currently.
2024-08-02 21:16:52 -05:00
Cameron Gutman 9227ebfec9 Fix compiler warnings introduced by ComPtr refactoring 2024-08-02 21:15:18 -05:00
Cameron Gutman f138827cdf Add handling for AV1 High profile in D3D11VA/DXVA2
This doesn't seem to be supported by FFmpeg or any actual hardware yet
2024-07-30 23:21:49 -05:00
Cameron Gutman e25919e0f9 Use for each loop to destroy objects in arrays
Also fixes incorrect release of m_VideoPixelShaders objects
2024-07-30 22:58:59 -05:00
Cameron Gutman 99749d4730 Use ComPtr for lifetime management in DXVA2 2024-07-30 22:41:29 -05:00
Cameron Gutman 9e811f54f1 Use ComPtr for lifetime management in D3D11VA 2024-07-30 22:29:38 -05:00
Cameron Gutman 0bb0d27d64 Implement YUV 4:4:4 decoding with D3D11VA on Intel GPUs 2024-07-30 21:12:11 -05:00
Arda Anıl ede5ab8671 Translated using Weblate (Turkish)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2024-07-28 10:09:17 +00:00
Cameron Gutman 6c6f808365 Tweak the YUV444 tooltip text 2024-07-26 01:24:27 -05:00
Cameron Gutman dd9569913b Remove hardcoded block for YUV444 on non-Vulkan renderers 2024-07-26 01:20:48 -05:00
Cameron Gutman 778eb07c5f Reject YUV444 rendering using D3D11VA until it properly supported 2024-07-26 01:19:26 -05:00
Cameron Gutman e2ffeae3f6 Add YUV444 support to VT Metal renderer 2024-07-26 00:39:13 -05:00
Cameron Gutman eb6d16fdcf Remove guards for older macOS and SDK versions 2024-07-26 00:38:54 -05:00
Cameron Gutman e548697a36 Move VT decoding support detection into a single base class 2024-07-26 00:35:32 -05:00
Cameron Gutman c707dab70a Plumb YUV444 logic into additional renderers 2024-07-25 06:36:40 -05:00
ns6089 da0244c538 Support YUV 4:4:4 formats 2024-07-24 20:54:13 -05:00
Cameron Gutman ff332d45f8 Fix false compiler warnings about missing return from non-void function 2024-07-24 20:45:52 -05:00
Cameron Gutman 9e92c07cb7 Use VK_NULL_HANDLE instead of nullptr to initialize VkSurfaceKHR field
Fixes #1367
2024-07-24 20:38:36 -05:00
Cameron Gutman 7f009a4b8e Switch to 32-bit floating point audio
Excluding Steam Link due to CPU and API limitations
2024-07-17 20:37:50 -05:00
Cameron Gutman 8ac378f467 Enable libplacebo Vulkan renderer on x64 Windows builds 2024-07-16 19:12:37 -05:00
Cameron Gutman 82ec773119 Add Vulkan headers v1.3.290 for Windows 2024-07-16 19:06:43 -05:00
Cameron Gutman 3580286807 Update prebuilt libraries
SDL2 -> 3b7eafe
dav1d -> 1.4.3
openssl -> 3.3.1
libplacebo -> 7.349.0
libva -> 2.22.0
2024-07-13 17:27:03 -05:00
Cameron Gutman e226091c19 Require macOS 11 or later 2024-07-13 17:26:27 -05:00
Cameron Gutman 074b4520e5 List both Qt 5 and Qt 6 packages for Linux builds 2024-07-13 16:19:00 -05:00
Cameron Gutman de30eeaa66 Fix CI build errors 2024-07-13 13:53:43 -05:00
Cameron Gutman fe9282e7d9 Update Windows to Qt 6.7 and remove 32-bit support 2024-07-13 13:23:14 -05:00
Cameron Gutman 45ccd1a811 Add plane selection workaround for Spacemit driver bug
Expose plane bug workaround logic through new envvars:
- DRM_MIN_PLANE_ZPOS
- DRM_ALLOW_PRIMARY_PLANE
2024-07-12 19:37:56 -05:00
Cameron Gutman 52583f5c71 Consolidate decoder checks to reduce code duplication 2024-07-12 19:02:20 -05:00
Cameron Gutman 952ebcd0d2 Prefer zero-copy formats for non-hwaccel hardware decoders
SpacemiT K1's BSP has a version of FFmpeg that contains both
v4l2m2m and their own *_stcodec decoders. Not only is their
V4L2 driver for their mvx decoder seemingly totally broken
(output buffers are all zeros), but it doesn't have any of
the DRM_PRIME support work that is maintained out of tree.

The result is we use a broken copyback decoder instead of
a (mostly) working zero-copy decoder because we didn't
include any logic to rank non-hwaccel decoders by pixfmt
like we have with device type for hwaccel decoders.
2024-07-12 18:45:46 -05:00
Cameron Gutman d5a198b764 YUV420P10 is also compatible with PlVkRenderer 2024-07-06 17:24:46 -05:00
Cameron Gutman b5b2731d5f Add support for rendering software decoded frames with Vulkan 2024-07-06 16:49:35 -05:00
Cameron Gutman d085722911 Don't attempt to use mismatched 8-bit formats with 10-bit codecs
In addition to silently truncating the samples, this also tickles
some nasty bugs in the VF2's out-of-tree OMX decoder.
2024-07-06 02:27:46 -05:00
Cameron Gutman 2e29ef8d74 Simplify codec selection and prioritization logic 2024-07-06 00:50:32 -05:00
Cameron Gutman 34fa7167b1 Force AV_CODEC_CAP_HARDWARE set for OMX decoders
There are at least 2 out-of-tree OMX decoder implementations
that both lack AV_CODEC_CAP_HARDWARE, so they trick us into
thinking that neither of them is hardware accelerated.

Fixes false decoder warnings when linked against the patched
FFmpeg builds shipping on VisionFive 2 and LicheePi 4A SBCs.
2024-07-05 23:04:10 -05:00
Cameron Gutman 27b173b76b Add a GenericHwAccelRenderer for unknown hwaccels
This will get us limited hardware acceleration even for hwaccels
that we don't know about yet.
2024-07-05 22:49:52 -05:00
Cameron Gutman d73df12367 Don't precompile QML files with disable-prebuilts
This binds us against the exact compile-time version of Qt with no
forwards or backwards compatibility, so it must not be used when we
could load Qt libraries from a location outside of our app bundle.
2024-07-04 15:45:48 -05:00
Kofaone 725e51f9b3 Translated using Weblate (Estonian)
Currently translated at 10.8% (26 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/et/
2024-07-03 16:09:29 +00:00
Kofaone 0c6689a5b4 Added translation using Weblate (Estonian) 2024-07-02 18:05:23 +02:00
Артём Журин 32115c639e Translated using Weblate (Russian)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-07-01 11:09:14 +02:00
Cameron Gutman 17a2548480 Fix changelog typo 2024-06-29 19:56:31 -05:00
Cameron Gutman 753deb915f Prepare for v6.0.1 2024-06-29 19:55:10 -05:00
Cameron Gutman 7d6f4135d5 Show Hungarian in the language list
The translation is nearly complete now (89%)
2024-06-29 17:19:35 -05:00
Cameron Gutman 622ec843ff Add Lithuanian and rerun lupdate/lrelease 2024-06-29 17:17:45 -05:00
Cameron Gutman 5c18bf1608 Merge remote-tracking branch 'origin/weblate' 2024-06-29 17:07:02 -05:00
Cameron Gutman d184730a82 Switch over to the new code signing certificate 2024-06-29 17:02:33 -05:00
Cameron Gutman 335ed0e8e6 Only sample directly from the video decoder output texture on Intel GPUs
This technique seems to actually make performance worse on some AMD GPUs (RX 480)
and causes rendering errors on others (HD 5570). These might be AMD-specific bugs
but let's not risk a behavior change for AMD/NVIDIA where nobody was having perf
issues with the old copy method anyway.
2024-06-29 14:44:08 -05:00
Cameron Gutman 0abb9fd7c2 Revert "Avoid using D3D11VA on older AMD TeraScale GPUs"
This reverts commit 93408386ae.
2024-06-29 14:12:03 -05:00
Cameron Gutman 1a1ce05959 Revert "Use a Texture2DArray in HLSL to match the SRVs"
This reverts commit d389f9a6e9.
2024-06-29 14:07:41 -05:00
Cameron Gutman 93408386ae Avoid using D3D11VA on older AMD TeraScale GPUs 2024-06-28 20:24:47 -05:00
Cameron Gutman 415b512c75 Require FL 11.0 for the D3D11VA renderer
We would probably be okay with 10.0 (SM4), but let's not risk
encountering GPU driver bugs like we do on old AMD cards.
2024-06-28 19:56:00 -05:00
Cameron Gutman d389f9a6e9 Use a Texture2DArray in HLSL to match the SRVs 2024-06-27 19:46:27 -05:00
kiictus ba01558bc5 Translated using Weblate (Lithuanian)
Currently translated at 38.3% (92 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/lt/
2024-06-27 21:10:56 +02:00
Cameron Gutman dff02eab7d Fix DrmRenderer build 2024-06-25 23:29:37 -05:00
Cameron Gutman ecfcedad58 Fix window resizing on Windows with software decoding 2024-06-25 23:21:08 -05:00
Cameron Gutman e76780e105 Add a new prepareToRender() callback for renders to perform their initial window clears
This consolidates all the clearing that was strewn across the codebase.
2024-06-25 23:12:18 -05:00
Cameron Gutman 1d1fa0577b Don't flush window events after the KMSDRM modeset operation
We will flush the initial window shown event that we require to start decoding.
2024-06-25 22:28:23 -05:00
Cameron Gutman a9d7c8e495 Move forced KMSDRM modesetting operation into Session init code
Performing this each time DrmRenderer is initialized leads to long
delays when choosing a decoder on embedded platforms, particularly
those like TH1520/JH7110 which lack accelerated GL drivers.
2024-06-25 21:57:02 -05:00
Cameron Gutman ffdf683597 Output log messages to an attached debugger 2024-06-24 19:24:06 -05:00
Cameron Gutman ac0e1098b9 Take COLOR_ENCODING values into account when choosing a colorspace
Replace the generic starfive hack with proper logic to examine the
supported enum values to select a colorspace. This fixes incorrect
colors with vs-drm on the TH1520.
2024-06-23 19:33:37 -05:00
Cameron Gutman 35695642d5 Use the first available plane that meets the zpos requirement
Planes seem to be listed in descending order of capabilities
with later planes sometimes lacking scaling capabilities, which
is the case with vs-drm on the TH1520.
2024-06-23 19:03:35 -05:00
Cameron Gutman e458682a23 Refactor plane property loop to avoid leak 2024-06-23 18:13:20 -05:00
Cameron Gutman fbe5e6f01f Build Windows ARM64 with Qt 6.7 in CI 2024-06-23 17:58:22 -05:00
Cameron Gutman 52756e7f45 Update AppImage dependencies
dav1d -> 1.4.3
SDL2 -> ab5740bd
2024-06-23 17:57:42 -05:00
Cameron Gutman 0f57abf6f8 Don't select an overlay plane with a lower zpos than the primary plane 2024-06-23 17:55:27 -05:00
Cameron Gutman 94943d2865 Clamp chroma texcoords to avoid sampling alignment padding
This resolves #885 without the massive perf hit on lower end Intel GPUs.
2024-06-22 16:19:26 -05:00
Cameron Gutman c3bd7edc4e Revert "Use a separate texture for rendering to avoid blending in the alignment padding"
This kills performance on some Intel iGPUs (particularly Atom chips like N100),
so let's remove the copy and solve this issue a different way instead.

This reverts commit a6fccf93d1.
2024-06-22 12:35:00 -05:00
Cameron Gutman b6bb96223d Revert "Remove manual hwframe ctx setup for D3D11VA"
We need this back to avoid the copy that's tanking performance on Intel iGPUs.

This reverts commit 2cef09471b.
2024-06-22 12:34:10 -05:00
kiictus f07f3c843a Translated using Weblate (Lithuanian)
Currently translated at 17.0% (41 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/lt/
2024-06-22 12:09:13 +02:00
kiictus 7712a2dce4 Added translation using Weblate (Lithuanian) 2024-06-21 12:05:30 +02:00
Артём Журин d86e13a3a7 Translated using Weblate (Russian)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-06-20 08:07:54 +02:00
Cameron Gutman 3aaa09bb7d Disable CUDA/NVDEC in AppImage builds
These are only really useful for Wayland scenarios, but:
- Wayland is explicitly disabled for AppImage due to EGL issues
- VDPAU now works under XWayland with 545 and later drivers
- Moonlight now has a Vulkan Video backend which works with 535 and later drivers

Fixes #1314
2024-06-19 10:29:03 -05:00
Cameron Gutman 377abf2155 Remove verbose flag from tar invocation 2024-06-19 10:25:15 -05:00
Cameron Gutman d3219ae24a Don't use VAAPI fallback driver names on libva 2.20+
libva 2.20 is good enough at detecting driver names (even under XWayland)
that we don't need to use the fallback name list anymore. This saves time
probing drivers, avoids excessive log output from failed probes, and avoids
tickling bugs in VAAPI drivers that are installed but unused.
2024-06-18 00:31:59 -05:00
Cameron Gutman bd60b873ec Add missing check for no Vulkan devices 2024-06-18 00:12:08 -05:00
Jorys Paulin 3abf925810 Translated using Weblate (French)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-06-17 13:09:16 +00:00
Michael Freund (Ottes) d5cbcc8199 Translated using Weblate (German)
Currently translated at 97.9% (235 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2024-06-14 02:28:52 +02:00
Cameron Gutman 640ac3f9fe Don't bundle libs into the final app package if disable-prebuilts is set 2024-06-10 22:57:58 -05:00
Cameron Gutman 83811e2a07 Add 'CONFIG+=disable-prebuilts' qmake option
When specified, qmake uses pkg-config for libraries on macOS instead of the prebuilts in the libs submodule.
2024-06-10 22:51:45 -05:00
Cameron Gutman 31641f5246 Update readme with new packages and Qt 6 recommendations 2024-06-09 20:54:17 -05:00
Cameron Gutman d7bc735edc Allow use of old fullscreen mode on macOS by setting I_WANT_BUGGY_FULLSCREEN=1 2024-06-09 15:46:24 -05:00
Cameron Gutman b59de38e0b Revert "Only use SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES=0 for native notched resolution"
Users want to control when the notch is and is not included for display scaling.

Fixes #1301

This reverts commit e25d9b0da2.
2024-06-09 15:42:39 -05:00
Cameron Gutman 17af71fe7a Allow the Vulkan renderer to accept HDR input even without HDR output capability
In addition to resolving issues with mixing HDR and SDR displays and moving
between them while streaming, it also allows streaming HDR content to an SDR
display with tone mapping handled transparently by libplacebo.
2024-06-09 15:00:56 -05:00
Cameron Gutman a0c77d0ad8 Filter SDL_WINDOWEVENT_SHOWN after initial renderer creation
This case exists to handle the initial bringup of the renderer when
the window appears on screen. We can ignore these if we already
created a renderer, to avoid renderer re-creation if a spurious
SDL_WINDOWEVENT_SHOWN event arrives later.
2024-06-09 14:34:34 -05:00
Cameron Gutman ec7137e693 Flush window events in MMAL and DRM renderers 2024-06-09 14:26:26 -05:00
David King 1b56f28fd4 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2024-06-09 13:09:15 +02:00
Cameron Gutman 486c46781b Increase computer seeking timeout for 'stream' and 'list' actions
The host may take some time to wake up from sleep.
2024-06-08 16:18:06 -05:00
Cameron Gutman 6397031e46 Expand allowed range for --fps option 2024-06-08 00:17:17 -05:00
Cameron Gutman e7a2d9f44d Prepare for v6.0.0 2024-06-05 22:42:28 -05:00
Cameron Gutman ee5d0acc1f Rerun lupdate and lrelease 2024-06-05 00:28:11 -05:00
Cameron Gutman 6a5a69cabd Merge remote-tracking branch 'origin/weblate' 2024-06-05 00:26:59 -05:00
weng weng cd7391f908 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.2% (231 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2024-06-04 02:09:15 +00:00
Cameron Gutman d6d28f1afd Remove unused libplacebo libraries 2024-06-02 21:52:35 -05:00
Cameron Gutman 5a6620a9ae Fix missing installer window icon with WiX 5 2024-06-02 21:40:40 -05:00
Cameron Gutman 5a47ddca33 Use EGL on X11 for non-x86 platforms
In theory we could do this everywhere, but I'd rather not risk major behavior changes on x86 right before a release.
2024-06-02 14:01:54 -05:00
Cameron Gutman b58f021fc8 Only set QT_SSL_USE_TEMPORARY_KEYCHAIN on macOS
It's useless on other platforms.
2024-06-02 13:58:42 -05:00
Cameron Gutman 12b93337d1 Fix SDL_VIDEODRIVER override when the Qt platform plugin was manually set 2024-06-01 22:43:52 -05:00
Cameron Gutman 807fc6b31c Opt out of macOS Game Mode due to various OS bugs
Fixes #1170
Fixes #1297
2024-06-01 16:36:24 -05:00
Cameron Gutman 959080aa95 Update moonlight-common-c with higher IPv6 MTU 2024-06-01 16:30:45 -05:00
Cameron Gutman 18a772aeba Update prebuilt libraries
opus -> 1.5.2
FFmpeg -> 7.0.1
dav1d -> 1.4.2
2024-06-01 16:30:20 -05:00
Cameron Gutman 9bdd17f1c3 Properly clean libavformat files with clean-libs.sh 2024-06-01 16:25:46 -05:00
sanhoe 3d1967bd1e Translated using Weblate (Korean)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2024-06-01 16:41:32 +02:00
Cameron Gutman 469bd32bde Update AppImage to FFmpeg 7.0.1 and dav1d 1.4.2 2024-05-31 20:43:03 -05:00
comsyspro 351b4edf0c Translated using Weblate (German)
Currently translated at 95.8% (230 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2024-05-29 09:09:23 +02:00
Cameron Gutman a0a8b70bc1 Strip session keys and IVs from the logs
Logging these isn't a major issue because they change each session and
the privilege level to access the logs is the same as those to access the
private key of Moonlight client itself, but there's also no good reason to
log them either.
2024-05-27 22:02:02 -04:00
Cameron Gutman e07f069222 Always use the custom logger
It was already used everywhere except macOS Debug builds.
2024-05-27 21:40:18 -04:00
Empotik 47ccd1e481 Translated using Weblate (Thai)
Currently translated at 57.5% (138 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/th/
2024-05-27 23:09:14 +00:00
Cameron Gutman 96fba43186 Add missing AV1 option in CLI video codec options
Fixes #1290
2024-05-27 13:06:49 -04:00
Cameron Gutman 9e7c212c6d Update moonlight-common-c 2024-05-25 18:32:58 -05:00
Cameron Gutman e67d83e097 Move declaration under ifdef to eliminate unused variable warning 2024-05-25 17:01:46 -05:00
Cameron Gutman 4474f815af Only use fallback VDPAU/VAAPI driver paths on AppImages
Native packages and Flatpak/Snap packages both have properly set
driver path values embedded in libva.so/libvdpau.so. Let's not go
splunking for drivers in random folders on those systems.
2024-05-25 14:39:09 -05:00
Cameron Gutman e130a15037 Remove dependency on AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES for VDPAU wrapper identification
These quirks may be deprecated and no longer populated in an upcoming FFmpeg version.
2024-05-25 14:24:31 -05:00
Cameron Gutman 845ef147c9 Add new libva driver path values for Fedora 40 2024-05-25 14:22:43 -05:00
Cameron Gutman fb17c15cfd Update VCRedist 2024-05-25 11:54:29 -05:00
Marocco2 bb74cedf59 Translated using Weblate (Italian)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2024-05-25 15:09:12 +02:00
Mike 9af6906380 Translated using Weblate (Polish)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2024-05-24 08:09:10 +00:00
gallegonovato c1ae3cceda Translated using Weblate (Spanish)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-05-24 08:09:10 +00:00
Loïc Hesling e1e3bd512f Translated using Weblate (French)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-05-24 08:09:09 +00:00
Cameron Gutman cf3ff32340 Rerun lupdate and lrelease 2024-05-23 00:28:10 -07:00
Cameron Gutman 2c98deeae3 Merge remote-tracking branch 'origin/weblate' 2024-05-23 00:26:16 -07:00
Cameron Gutman a572681737 Add --hdr and --no-hdr command-line arguments
Fixes #1287
2024-05-22 23:28:14 -07:00
Cameron Gutman e78b389bc0 Fix passing incorrect 'this' pointer to quitRunningApp()
This worked before due to Qt behavior that was changed in https://codereview.qt-project.org/c/qt/qtdeclarative/+/450393
to generate a warning in this situation. The old behavior remains the default, but this change avoids a warning in the logs.
2024-05-22 23:11:52 -07:00
Роман 83ec929758 Translated using Weblate (Russian)
Currently translated at 83.6% (199 of 238 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-05-21 20:02:01 +02:00
Cameron Gutman 9117f6565e Don't clobber existing std handles when attaching to the parent console
Fixes #1270
2024-05-11 23:38:32 -05:00
Cameron Gutman aa33432c81 Detect whether to log to file based upon whether stderr was redirected 2024-05-11 23:24:36 -05:00
Cameron Gutman e25d9b0da2 Only use SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES=0 for native notched resolution
Full-screen and borderless windowed are now fully indistinguishable on macOS to avoid user confusion.

Fixes #861
2024-05-11 19:58:36 -05:00
Cameron Gutman 0dfa8a7b53 Override fullscreen mode if necessary for native resolutions to work as expected
Fixes #1244
2024-05-11 19:55:08 -05:00
Cameron Gutman 85a9f85c54 Add support for listing notch and notchless native resolution options 2024-05-11 19:48:01 -05:00
Cameron Gutman ed68f920f1 Avoid polluting source tree with NuGet cache files during WiX build 2024-05-11 15:08:30 -05:00
Cameron Gutman f9a4498f9b Upgrade to WiX v5.0.0 2024-05-11 15:08:10 -05:00
Cameron Gutman 4d1acf2e30 Don't invoke signal handlers directly
This generates a runtime warning on Qt 6.7
2024-05-06 19:16:10 -07:00
Cameron Gutman db4739b82d Remove warn_off configuration for moonlight-common-c subproject
We can just turn off unused parameter warnings instead of all warnings.
2024-05-05 18:52:21 -05:00
gallegonovato 38bf833708 Translated using Weblate (Spanish)
Currently translated at 100.0% (238 of 238 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-05-05 07:07:20 +02:00
Cameron Gutman 364093aef8 Prevent a deadlock if the audio device stops consuming data 2024-05-04 21:22:38 -05:00
Cameron Gutman 6d220a9062 Allow audio to recover if no audio devices were present during stream start 2024-05-04 21:13:00 -05:00
Jorys Paulin abec8b3fe1 Translated using Weblate (French)
Currently translated at 100.0% (238 of 238 strings)

Co-authored-by: Jorys Paulin <paulinjorys5@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
Translation: Moonlight Game Streaming/moonlight-qt
2024-05-02 09:07:13 +02:00
Cameron Gutman 93ed985043 Rerun lupdate and lrelease 2024-04-30 22:53:23 -05:00
Cameron Gutman 23c737cab9 Split details dialog into multiple lines for easier translation 2024-04-30 22:53:23 -05:00
Cameron Gutman cb850f013a Add Central Kurdish language (disabled until it's completed) 2024-04-30 22:53:15 -05:00
Cameron Gutman 6bd964a094 Merge remote-tracking branch 'origin/weblate' 2024-04-30 22:27:09 -05:00
Cameron Gutman 419c788ab5 Remove save() call that is no longer necessary since d1ccd19 2024-04-30 21:42:38 -05:00
Jorys Paulin a412100a11 feat: added show performance overlay preference (#1209) 2024-04-30 21:37:52 -05:00
Cameron Gutman 0531666f38 Apply some minor cosmetic improvements to the details dialog 2024-04-30 21:36:59 -05:00
Jorys Paulin c096238998 Add "View details" to PC list (#1221)
* feat: add view pc details menu item

* feat: show mac address

* fix: cast mac byte array to string
2024-04-30 21:23:25 -05:00
Hans Gaiser 211fec0ff0 Send WOL packet when seeking a computer. 2024-04-30 21:05:33 -05:00
Dylan Frankcom 58e27875ae Fix Raised Black Levels on Steam Deck OLED (#1265)
Add getDecoderColorRange to plvk
2024-04-30 20:31:00 -05:00
Ahmed kurdish 954e6608a1 Added translation using Weblate (Kurdish (Central))
Co-authored-by: Ahmed kurdish <nikogaming500@gmail.com>
2024-04-29 21:06:00 +02:00
Cameron Gutman 1cd588f25c Don't set relative warp mode based on absolute/relative mouse mode
This breaks pointer capture on Wayland when we start in absolute mouse
mode (since warp is not supported on Wayland). It's also confusing to
users because it leads to different relative mouse acceleration curves
based on whether you start a stream in relative mode or not.
2024-04-27 17:13:02 -05:00
Cameron Gutman ebfe035a18 Set SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP=0 to resolve pointer lock issue on Wayland
SDL will try to lock the mouse cursor on Wayland if it's not visible in order to
support applications that assume they can warp the cursor (which isn't possible on
Wayland). We don't want this behavior because it interferes with seamless mouse
mode when toggling between windowed and fullscreen modes by unexpectedly locking
the mouse cursor.
2024-04-27 16:49:51 -05:00
Yutaro Urata 6f22ed13c1 Translated using Weblate (Japanese)
Currently translated at 86.0% (185 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2024-04-24 21:07:16 +02:00
Cameron Gutman 4aa2b8570c Autorelease the system default Metal device 2024-04-19 00:29:51 -05:00
Cameron Gutman fe6562e31c Allow forcing Metal renderer on or off via VT_FORCE_METAL=1 and VT_FORCE_METAL=0 respectively 2024-04-19 00:27:45 -05:00
Cameron Gutman 654e386263 Only pace presentation if display sync is enabled 2024-04-19 00:17:13 -05:00
Cameron Gutman 76d0eb6b63 Avoid trying VDPAU when Vulkan is preferred
The VDPAU renderer causes interoperability issues with Vulkan.
2024-04-18 00:41:24 -05:00
Hans Gaiser 02d867fe09 Log to stderr instead of stdout. 2024-04-17 23:55:38 -05:00
Cameron Gutman 76ff53f09f Move warning dialog checks into the Window's onCompleted() function
The old issue with dialogs appearing behind the main window only impacts the old non-QC2 dialogs,
which we haven't used for several years.
2024-04-14 14:49:35 -05:00
Cameron Gutman 37d92dee16 Revert "Fix hiding the main UI window while streaming on Qt 6.7"
The original issue on Qt 6.7 was caused by conflicts with the window state set in main.qml
which was addressed by afbc49e39a.

The remaining issue with Qt 6.7 clobbering window state and position when hiding a window
looks like a legitimate Qt bug.

This reverts commit ebe270bec5.
2024-04-14 14:08:53 -05:00
Cameron Gutman afbc49e39a Apply the main window visibility property only at startup
Otherwise it can affect the state of the window when showing again streaming
2024-04-14 13:35:41 -05:00
Cameron Gutman d1ccd19fcc Make StreamingPreferences a proper singleton
This removes the need for several hacks in SettingsView to force updates and improves performance by not reloading preferences all over the place.
2024-04-14 13:01:30 -05:00
Cameron Gutman ebe270bec5 Fix hiding the main UI window while streaming on Qt 6.7 2024-04-13 00:05:49 -05:00
Cameron Gutman 784234c857 Fix updating bitrate text upon language change on Qt 6.7 2024-04-13 00:05:11 -05:00
Cameron Gutman 6a85996b4a Clear the minimized state on the Qt window if the SDL window is not minimized 2024-04-07 00:42:51 -05:00
Cameron Gutman c6710f93dc Enable Steam Controller detection on Steam Link
Fixes #697
2024-04-06 20:03:54 -05:00
Cameron Gutman 5e46c4ec2b Update Windows and Mac prebuilt libraries
SDL2 -> 1fa6142
FFmpeg -> 7.0
opus -> 1.5.1
dav1d -> 1.4.1
2024-04-06 19:56:38 -05:00
Cameron Gutman 011feab6ce Add workaround for broken Qt EGLFS card selection logic 2024-04-06 14:35:34 -05:00
Cameron Gutman f8c5d3c0ce Update AppImage libraries
FFmpeg -> 7.0
SDL2 -> 1fa61429
libplacebo -> 7b294350
2024-04-06 12:44:50 -05:00
Cameron Gutman 74d452bf35 Limit mDNS resolution retry count 2024-04-06 12:40:32 -05:00
Cameron Gutman fd2ff61a40 Support Vulkan AV1 decoding with FFmpeg 7.0 2024-04-06 12:31:14 -05:00
Cameron Gutman 8a87a09947 Flush stale gamepad events after checking for unmapped gamepads 2024-03-31 14:56:46 -05:00
Cameron Gutman cf544a8703 Don't reload preferences every time we poll for GUI gamepad input 2024-03-31 14:54:36 -05:00
Cameron Gutman 0e1190a059 Remove Optimus block for modern Nvidia drivers
Now that we use D3D11 and don't fall back to D3D9, it should be safe to allow Optimus again.

This will re-enable Optimus for D3D9 on Windows 8.1, but all of the reported problems were on Windows 10 so it will hopefully be a non-issue.

Fixes #1241
2024-03-28 21:06:15 -05:00
Cameron Gutman f2535f1e6e Avoid D3D9 fallback on lack of codec support unless a D3D11 FL11.0 GPU wasn't found
We'd rather not waste time (and risk crashes) loading the D3D9 driver if the GPU doesn't have the physical decoding hardware at all.
2024-03-26 23:59:18 -05:00
Cameron Gutman cefa567f95 Demote DXVA2 renderer to second pass of hwaccels 2024-03-26 23:04:54 -05:00
Cameron Gutman 9be782ae8e Fix some harmless compiler warnings 2024-03-26 21:59:39 -05:00
Cameron Gutman 610e07d4bd Improve state propagation between Qt and SDL windows 2024-03-26 21:42:13 -05:00
Marcos Del Sol Vives 75eb921a04 Improve VPN heuristics under Windows
The NDIS interface type will now be used also for matching, improving the
heuristics for multiple popular VPN implementations.

Fixes #1233
2024-03-26 01:20:53 -05:00
Cameron Gutman 97bd515b11 Remove leftover preferred Metal device logic 2024-03-26 01:16:57 -05:00
Cameron Gutman a45695a22a Rework Qt window handling during SDL window creation
- Avoids blindly enumeration all top-level windows
- Properly tracks screen changes during the connection process
- Starts stream window minimized if the Qt window was minimized

Fixes #1231
2024-03-24 21:38:54 -05:00
Cameron Gutman 0d67fd1ff0 Batch mouse motion events on the SDL side 2024-03-24 20:35:23 -05:00
Cameron Gutman a093a0ae59 Restore AVSampleDisplayLayer renderer for dGPU/eGPU systems
These sometimes have issues importing decoded frames for Metal rendering.
2024-03-24 17:47:29 -05:00
Cameron Gutman c9ad8ffa69 Stop using true fullscreen mode on Mac
It has numerous issues on modern Macs and seems to get worse every macOS release.
2024-03-24 13:55:43 -05:00
Cameron Gutman 9987914ebb Update SDL_GameControllerDB 2024-03-20 02:04:01 -05:00
Lukas Senionis fbfd6fb462 Update 0001-Vulkan-Don-t-try-to-reuse-old-swapchain.patch to compile with latest changes 2024-03-18 21:54:28 -05:00
Cameron Gutman bec053e3cf Update AppImage dependencies 2024-03-18 01:44:08 -05:00
Cameron Gutman d364b24378 Fix broken on-link detection that caused non-VPN WAN connections to use LAN MTU
Fixes #1101
2024-03-15 20:04:51 -05:00
Jorys Paulin 8c67586cd0 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-03-11 20:01:49 +01:00
Cameron Gutman 89a628a0dd Use 'git apply' instead of 'git am' 2024-03-02 12:18:14 -06:00
Cameron Gutman 4fb9681b7f Update moonlight-common-c 2024-03-02 11:26:54 -06:00
Cameron Gutman c13128ca1d Add libplacebo patch from Chiaki4Deck to resolve AppImage hangs on Steam Deck 2024-03-02 11:25:53 -06:00
Cameron Gutman ceca83346b Use FIFO present mode for VSync 2024-03-02 11:19:52 -06:00
Jorys Paulin fc6c51c75a fix: add explicit width and height to discord icon 2024-02-18 15:28:47 -06:00
Jorys Paulin 161d91acf8 fix: fix discord icon on qt 5 2024-02-18 15:28:47 -06:00
Cameron Gutman 06ef10a2ad Update README to clarify requirements for Vulkan video
See #1186
2024-02-18 15:23:35 -06:00
Cameron Gutman 7b29b22192 Update dependencies
SDL -> df00a7dd4
SDL_ttf -> 2.22.0
FFmpeg -> 3e79074c4 (n6.1)
dav1d -> 1.4.0
libplacebo -> 3ba18d
2024-02-17 16:14:39 -06:00
Cameron Gutman 289a7165b3 Remove dSYM files from macOS app bundle
macdeployqt incorrectly copies these if they are installed, which bloats the final DMG significantly.

See https://bugreports.qt.io/browse/QTBUG-56590
2024-02-17 14:19:05 -06:00
Cameron Gutman 62011c37f4 Fix build with SDL 2.0.20 and earlier
Fixes #1186
2024-02-17 13:31:53 -06:00
Cameron Gutman 919e44b29b Fix __builtin_cpu_supports(aes) for GCC 6-9 2024-02-17 13:28:32 -06:00
Cameron Gutman 32be1b158b Update VCRedist 2024-02-16 23:06:52 -06:00
Cameron Gutman f635860afd Update to WiX 4.0.4 2024-02-16 23:05:58 -06:00
Cameron Gutman 3b078f095b Update AppVeyor image for macOS 2024-02-16 23:01:44 -06:00
Jorys Paulin 72fc7ea31a feat: update discord icon 2024-02-16 22:36:26 -06:00
Vag Ko f4edd1e63a Translated using Weblate (Greek)
Currently translated at 79.5% (171 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/el/
2024-02-12 22:02:05 +01:00
Jorys Paulin 6011384afe Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-02-11 10:01:59 +01:00
Cameron Gutman 896456a8ac Wait for command buffer completion before returning from renderFrame() 2024-02-11 00:15:32 -06:00
Cameron Gutman 8959ddbeb6 Rewrite overlay support in Metal renderer to avoid additional subviews
Subviews cause our Metal layer to fall out of the direct composition path on Intel hardware
2024-02-11 00:15:07 -06:00
Cameron Gutman 767215fce5 Rewrite old frame pacing logic for Metal renderer 2024-02-10 22:49:13 -06:00
Cameron Gutman 3ef05f3a35 Completely switch to D3D11VA over DXVA2 for supported GPUs in all scenarios
Fixes #1179
2024-02-09 01:24:03 -06:00
Cameron Gutman 12624bc5c4 Avoid the composited display path for our Metal layer 2024-02-08 18:19:01 -06:00
Cameron Gutman 5bd0dea85d Enable Metal validation in debug builds 2024-02-08 18:07:43 -06:00
Cameron Gutman 80242f2e90 Fix Metal debug layer validation errors 2024-02-08 18:06:46 -06:00
Cameron Gutman cf3e328f9d Add seamless resize support for Metal renderer 2024-02-08 18:05:47 -06:00
Bàn Hải Dương 150002d4d4 Translated using Weblate (Vietnamese)
Currently translated at 90.2% (194 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2024-02-08 16:01:48 +01:00
Cameron Gutman b972a22459 Use SDL helpers to create Metal view 2024-02-07 03:26:09 -06:00
Cameron Gutman db06239018 Rewrite the macOS renderer using CAMetalLayer
This allows v-sync to be disabled on macOS and lets us remove a whole bunch of old hacks.

Further optimizations of the new renderer are still needed.
2024-02-07 02:40:35 -06:00
boogie bdc7d53515 Only give "pixel_format=nv12" option to v4l2m2m or v4l2requests decoders
pixel_format is a global option which changes avctx->pix_fmt to the
given format, and overrides the AV_PIX_FMT_DRM_PRIME requirement of a
decoder. So v4l2 out of tree patches has done some exception which is
not perfectly nice, therefore limit this option only if the given
decoder is v4l2 decoder. Otherwise rockchip mpp based ffmpeg decoders
can not work properly
2024-02-06 00:09:34 -06:00
Cameron Gutman 7f83b79c19 Update AppImage dependencies 2024-02-05 23:11:02 -06:00
Cameron Gutman 47b3aff352 Update moonlight-common-c with RTSP encryption 2024-02-05 23:01:25 -06:00
Cameron Gutman 679f237c1b Update bug report template 2024-02-05 22:16:49 -06:00
Cameron Gutman 3d8de56f25 Add fast AES detection for RISC-V using hwprobe() syscall 2024-01-23 02:28:28 -06:00
Vadym Nekhai 801cebbbc7 Translated using Weblate (Ukrainian)
Currently translated at 35.8% (77 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2024-01-22 06:01:48 +01:00
Cameron Gutman 66fb0465c4 Update moonlight-common-c with finalized encryption changes 2024-01-19 19:05:59 -06:00
Cameron Gutman 8bbc9b2c57 Fix build with old ARM headers and opt-out of fast AES on RISC-V for now 2024-01-15 17:36:57 -06:00
Cameron Gutman be7694dd8b Improve fast AES heuristic for Linux ARM and unknown platforms 2024-01-15 14:16:56 -06:00
Cameron Gutman ce8b24dfa7 Implement fast AES detection logic for Windows and macOS 2024-01-15 13:40:13 -06:00
Cameron Gutman 75ddac54c5 Update moonlight-common-c with new encryption features 2024-01-15 13:35:39 -06:00
Cameron Gutman b01a83ff39 Send pen input as pen events on Windows 2024-01-12 23:40:24 -06:00
Cameron Gutman c3e886fbcc Use drmIoctl() instead of bare ioctl() to handle EINTR/EAGAIN 2024-01-05 18:33:17 -06:00
Cameron Gutman e20d56041e Fix rare race condition in overlay update code 2023-12-31 15:21:18 -06:00
Cameron Gutman 114074bfd8 Don't set HDR metadata on the DXGI swapchain
This is no longer recommended by Microsoft due inconsistencies with display support for HDR metadata.
2023-12-31 15:15:06 -06:00
Cameron Gutman e44e29e7eb Update moonlight-common-c with X-SS-Connect-Data support 2023-12-29 23:15:41 -06:00
Cameron Gutman 03663d5552 Fix integer promotion issue in gamepad state merging 2023-12-29 16:06:53 -06:00
Cameron Gutman dce2a857f7 Merge all gamepad state when in single controller mode 2023-12-28 16:28:40 -06:00
Cameron Gutman 61f71a318e Expose PLVK_DEBUG_EXTRA for enabling extra debug layers 2023-12-27 15:40:01 -06:00
Cameron Gutman 646ce2bf66 Handle occlusion of the Vulkan window without recreating the renderer over and over 2023-12-27 15:36:59 -06:00
Cameron Gutman 2bbae90e2c Revert "Unconditionally override host-reported minimum luminance value"
This reverts commit 770872238d.
2023-12-26 15:46:25 -06:00
Cameron Gutman bb8e229814 Swap buffers in waitToRender() instead of renderFrame() 2023-12-26 15:45:31 -06:00
Cameron Gutman 9ed8252cc6 Display error codes when the connection is terminated 2023-12-22 14:12:59 -06:00
Cameron Gutman 2cef09471b Remove manual hwframe ctx setup for D3D11VA
It was apparently never necessary, since FFmpeg's default behavior of
avcodec_get_hw_frames_parameters() + av_hwframe_ctx_init() makes a
context that exactly matches the one we constructed manually.
2023-12-22 02:45:11 -06:00
Cameron Gutman 2d15382e31 Fix libplacebo renderer build on Windows 2023-12-21 18:12:19 -06:00
Cameron Gutman 770872238d Unconditionally override host-reported minimum luminance value 2023-12-18 16:43:17 -06:00
Cameron Gutman 2a05b890d8 Enable transparent resizing and display changes for supported renderers 2023-12-17 21:15:40 -06:00
Cameron Gutman 481f23b6e9 Remove some dependencies on fixed window and frame sizes 2023-12-17 20:39:26 -06:00
Cameron Gutman 4e7107a09e Use the crop rect from the pl_frame instead of the raw AVFrame dimensions 2023-12-17 19:06:56 -06:00
Cameron Gutman 0223394725 Fix manual codec options when using Vulkan for HDR
For now, we can't switch between GL and Vulkan on a single window, so performing decoder
probes with 8-bit formats may activate EGLRenderer which breaks Vulkan on our window.

It also speeds up stream launch validation for HDR cases in general, since we don't
perform unnecessary decoder probes for 8-bit profiles when the user wanted 10-bit.
2023-12-17 18:53:13 -06:00
Cameron Gutman 058739321c Move vkAcquireNextImageKHR() into waitToRender() so it can overlap with new frame arrival 2023-12-17 16:47:38 -06:00
Cameron Gutman 708bec2937 Rewrite Vulkan device selection logic to handle multi-GPU systems better 2023-12-17 15:46:10 -06:00
Cameron Gutman c939537c5c Synchronize swapchain and pl_frame colorspace values 2023-12-16 17:36:02 -06:00
Cameron Gutman 9497657c83 Fix handling of zero minimum HDR luminance 2023-12-16 17:28:35 -06:00
Cameron Gutman d4050f3a4f Add HDR metadata to each AVFrame 2023-12-16 17:02:53 -06:00
Cameron Gutman c74c4ef041 Fix native Vulkan video decoding (non-imported frames) 2023-12-16 16:21:54 -06:00
Cameron Gutman d75663052d Fix a few minor Vulkan renderer bugs 2023-12-16 16:18:19 -06:00
Cameron Gutman 8f2db99406 Enable libdrm in AppImage FFmpeg build to support DRM-PRIME to Vulkan hwframe mapping 2023-12-14 17:48:45 -06:00
Cameron Gutman 6a58dbb05e Disable 10-bit SDR swapchains on Vulkan due to inconsistent dithering behavior 2023-12-14 17:46:06 -06:00
Cameron Gutman 8aeb976128 Require a test frame for Vulkan video decoding 2023-12-14 17:44:58 -06:00
Cameron Gutman 7d51a4b67d Fix incorrect overlay colors in Vulkan renderer 2023-12-14 17:43:54 -06:00
Cameron Gutman f7d412e3bf Fix FFmpeg configure args 2023-12-14 00:21:39 -06:00
Cameron Gutman 4469c7fae3 Build AppImage with libplacebo and Vulkan video support 2023-12-13 18:26:00 -06:00
Cameron Gutman ee95efc0f1 Improve Vulkan renderer debuggability 2023-12-13 01:08:32 -06:00
Cameron Gutman 3ddc8ad68a Fix crash if pl_vulkan_create() fails 2023-12-13 01:04:54 -06:00
Cameron Gutman 333d97160e Add opt-in for Vulkan rendering for SDR content with PREFER_VULKAN=1 2023-12-13 01:03:27 -06:00
Cameron Gutman aac5ad3fd0 Add a libplacebo-based Vulkan renderer for HDR and Vulkan video decoding support
Vulkan H.264/HEVC video decoding isn't supported with Fedora's Mesa binaries due to
patent issues, so only the VAAPI/DRM-PRIME import path was tested locally with ANV.

HDR video is getting tonemapped to my SDR monitor reasonably, so HDR output probably
works with GameScope but I haven't confirmed yet.

See #1117
2023-12-12 23:54:23 -06:00
Cameron Gutman 1ef083c952 Update moonlight-common-c to remove per-codec bitrate adjustments 2023-12-03 22:21:10 -06:00
Cameron Gutman c63b918bb2 Don't hardcode the server signature length 2023-11-29 21:53:49 -06:00
Jorys Paulin 4dba4ad538 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-04 14:32:16 +01:00
NicolasS 83fcad6bd1 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-03 13:43:42 +01:00
Jorys Paulin e08178474d Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-03 13:43:42 +01:00
Cameron Gutman f374e88bac Update README.md
Added new SBC packages and updated build requirements
2023-11-03 00:13:50 -05:00
Cameron Gutman 3cb169ea26 Fix CUDA build without KMSDRM enabled 2023-11-01 22:49:18 -05:00
Cameron Gutman 58f87e39a9 Prepare for v5.0.1 2023-11-01 21:49:03 -05:00
Cameron Gutman b1c8005d1a Disable libdrm in AppImage build 2023-11-01 21:44:44 -05:00
Cathy J. Fitzpatrick f8a2e22a18 Update moonlight-common-c to eb67a2fd (2023-10-26) 2023-11-01 20:31:19 -05:00
Cameron Gutman 7ea118fbae Fix dark mode on Windows with Qt 6.5+ 2023-11-01 20:30:34 -05:00
Cameron Gutman 2149024c35 Rerun lupdate and lrelease 2023-11-01 20:02:40 -05:00
Cameron Gutman f5d71c8c9a Merge remote-tracking branch 'origin/weblate' 2023-11-01 20:01:25 -05:00
Cameron Gutman e108a05895 Bump WiX SDK to 4.0.2 2023-11-01 19:58:29 -05:00
Cameron Gutman ea8bccd508 Fix typo causing libva-drm only to be enabled if libva-wayland is present 2023-11-01 17:39:24 -05:00
maicolbattistini bca919c48c Translated using Weblate (Italian)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2023-10-21 04:13:46 +00:00
Jorys Paulin 511ffe03b5 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-21 04:13:45 +00:00
Cameron Gutman 413993ab6f Bump release date in appstream 2023-10-18 00:45:10 -05:00
Cameron Gutman 948b9c818a Add workarounds for some SDL joystick index issues 2023-10-18 00:42:59 -05:00
Cameron Gutman cf615ea88d Update SDL2 to fix HIDAPI joystick crash 2023-10-18 00:41:53 -05:00
Cameron Gutman 2d1e16fe50 Update moonlight-common-c 2023-10-16 22:42:46 -05:00
Cameron Gutman 089c3d3ad3 Prepare for v5.0.0 2023-10-16 19:04:40 -05:00
Cameron Gutman 63e3fa6609 Disable ATS 2023-10-16 18:13:13 -05:00
Cameron Gutman 8a7fa7e559 Update moonlight-common-c 2023-10-16 18:06:45 -05:00
Cameron Gutman 989a90a0f7 Rerun lupdate and lrelease 2023-10-15 20:30:46 -05:00
Cameron Gutman a707720577 Merge remote-tracking branch 'origin/weblate' 2023-10-15 20:28:04 -05:00
Cameron Gutman eef270de26 Fix HDR with external displays on macOS Sonoma
Fixes #1079
2023-10-15 15:30:41 -05:00
Cameron Gutman 0ac765bc32 Revert SDL audio buffer size on macOS to v4.3.1 value
Fixes #1071
2023-10-15 13:17:00 -05:00
Cameron Gutman e76551cb64 Use the PC name alone as the streaming window title on macOS 2023-10-15 13:15:38 -05:00
Cameron Gutman 4fd902a0d3 Update moonlight-common-c 2023-10-15 13:04:31 -05:00
Cameron Gutman 9cba449092 Add config option to allow EGL usage when built with MMAL 2023-10-15 13:03:47 -05:00
Cameron Gutman 905b2ecf9e Change AV1 bitrate multiplier to match HEVC 2023-10-15 12:51:23 -05:00
Cameron Gutman 53c2c612c9 Add Share+PS combo for clickpad button emulation on PS4/5 controllers 2023-10-14 01:46:50 -05:00
Cameron Gutman 8ffadde9cc Update SDL2 in AppImage for PulseAudio fix and gamepad sensor support 2023-10-14 00:39:42 -05:00
Jorys Paulin f569bf633c Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-13 12:01:28 +02:00
Cameron Gutman 6eb5e07007 Fix warnings in 32-bit builds 2023-10-12 19:05:52 -05:00
Cameron Gutman f07201baa9 Update moonlight-common-c 2023-10-12 18:46:35 -05:00
Cameron Gutman 9120fd01a8 Adjust MMAL and RPi workarounds for Pi 5 and Bookworm support 2023-10-12 18:46:11 -05:00
Cameron Gutman c14cc70a6a Also check for V3D compatible IDs 2023-10-08 16:52:54 -05:00
Cameron Gutman a66f91ae3c Update moonlight-common-c 2023-10-08 16:29:59 -05:00
Cameron Gutman 7e4fddbe62 Only block EGL rendering on Pi 4 and earlier
Hopefully Pi 5 is powerful enough to at least render 1080p 60 FPS.
2023-10-08 16:16:33 -05:00
Cameron Gutman 0ff9f8c55a Update dav1d to 1.3.0 2023-10-06 00:26:44 -05:00
Cameron Gutman 6f710faa8e Fix EGL loading in the AppImage 2023-10-05 23:05:07 -05:00
Cameron Gutman 2127e1d90b Allow h264_v4l2m2m to be used in RPi builds if manually specified 2023-10-05 18:37:14 -05:00
Cameron Gutman 9d73aa6b4a Fix DrmRenderer not falling back to swframes if DRM PRIME is available 2023-10-05 18:13:52 -05:00
Cameron Gutman a2f23b7053 Fix automatic VA DRM driver selection with libva 2.20 2023-10-05 18:12:12 -05:00
Cameron Gutman 5974980aff Use BT.709 in DrmRenderer only on Starfive devices 2023-10-05 18:10:36 -05:00
Cameron Gutman 6fa53691aa Fix implicit default constructor warning 2023-10-02 17:42:35 -05:00
Cameron Gutman 49e0679864 Synchronize with possible concurrent writers to the NvComputer object 2023-10-01 17:46:27 -05:00
Cameron Gutman 0976bc39b3 Only reserialize hosts if a serializable attribute changed 2023-10-01 17:28:06 -05:00
Cameron Gutman facd6e4e56 Revert "Batch delayed flushes to improve performance on macOS"
This reverts commit aa74e6930b.
2023-10-01 16:33:14 -05:00
Cameron Gutman d2dc0aa1b1 Don't serialize apps for the host backup
This takes a ton of time on macOS and most of the data is just a local cache anyway
2023-10-01 16:13:22 -05:00
Cameron Gutman aa74e6930b Batch delayed flushes to improve performance on macOS 2023-10-01 15:26:28 -05:00
Jorys Paulin b7811bf196 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-01 10:59:44 +00:00
Cameron Gutman 18130fd8de Use BT.601 for planes that lack COLOR_ENCODING properties 2023-09-29 18:30:39 -05:00
Cameron Gutman b6d4f97e96 Check that the chosen plane supports the decoded frame pixel format 2023-09-29 17:22:49 -05:00
Cameron Gutman 0dd0112518 Don't export EGLImages for software frames 2023-09-29 17:20:50 -05:00
Cameron Gutman 5711e6064e Allow reuse of an active plane for devices with only one usable plane per CRTC 2023-09-29 17:19:44 -05:00
Cameron Gutman 517b684f85 Handle EGL driver returning no supported formats or modifiers for DMA-BUF import 2023-09-27 01:31:01 -05:00
Cameron Gutman 39465f6d8a Override some Material 3 colors to improve contrast 2023-09-27 00:51:51 -05:00
Cameron Gutman 738813cbac Add fallback definition for EGLuint64KHR 2023-09-26 23:22:25 -05:00
Cameron Gutman c2778e040a Build fix for old EGL headers 2023-09-26 23:16:22 -05:00
Cameron Gutman 1efdeeb9dc Export composed VA surface layers for EGL import if supported
Importing composed formats is more efficient and performant because it allows
tiled and/or compressed surfaces to be directly sampled by shaders without
requiring a conversion to a linear planar format first.
2023-09-26 22:58:13 -05:00
Cameron Gutman b01dfea343 Refactor EGLImage creation into a separate shared class 2023-09-26 21:03:19 -05:00
Cameron Gutman e143293e91 Update our plist to activate Game Mode on Sonoma 2023-09-26 18:28:14 -05:00
Cameron Gutman f420dc740a Set EGL_IMAGE_PRESERVED_KHR=EGL_TRUE on our EGLImages
They're mapped read-only and may be saved internally as reference frames,
so they must not be modified by the EGL implementation.
2023-09-26 02:38:46 -05:00
Jen Kung-chih 2e532224b7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-09-24 19:59:50 +00:00
Jorys Paulin cb8366a7e5 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-09-24 19:59:49 +00:00
Cameron Gutman fee54a9d76 Update moonlight-common-c to pick up various fixes 2023-09-23 13:33:54 -04:00
Cameron Gutman dc556d3c9b Try to fix Windows build 2023-09-23 13:33:21 -04:00
Cameron Gutman 4fed3802aa Fix signed vs unsigned comparison warning 2023-09-23 11:15:41 -04:00
Cameron Gutman f7bb4611e9 Replace uses of strcpy() and sprintf() 2023-09-23 11:15:21 -04:00
Artur Szulc 57791eec62 Translated using Weblate (Polish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2023-09-22 20:59:07 +00:00
Cameron Gutman e1e3d8e710 Update AppImage to libva 2.20.0 2023-09-20 19:29:43 -05:00
Cameron Gutman 654be492a0 Avoid using LFS64 interfaces with Musl 2023-09-18 20:07:56 -05:00
Cameron Gutman 1df0da4d4a Also use test frame decoding parameters when creating a test renderer 2023-09-14 18:21:53 -05:00
Cameron Gutman 1dd6cdb567 Use the correct width and height of the test frame when performing the test decode
Using the stream resolution instead of the test frame resolution was causing all non-720p streams to fail on the VisionFive 2 board with the wave5 driver.

It also likely fixes a similar interoperability issue with the qcom-venus driver that was reported in #1042
2023-09-14 18:16:45 -05:00
Cameron Gutman edfb3cfdc8 Update OpenSSL to 1.1.1w for Windows and Mac builds 2023-09-12 19:36:48 -05:00
Cameron Gutman c6a8f44640 Don't set currentIndex to -1 while reinitializing
It causes warnings in other code that have property bindings to currentIndex
2023-09-12 19:28:33 -05:00
Cameron Gutman b7301d4415 Rerun lupdate and lrelease 2023-09-12 19:19:31 -05:00
Cameron Gutman 4d668702b5 Merge remote-tracking branch 'origin/weblate' 2023-09-12 19:18:14 -05:00
Cameron Gutman f4b0f4d78f Functionally revert f60e7241
Switching to indirect rendering has a high risk of performance and functionality regressions,
so let's just continue using AVSampleBufferDisplayLayer until we have a Metal renderer
since #973 is fixed.

This isn't an actual revert because we want to still keep the indirect override around.
2023-09-12 18:36:53 -05:00
Cameron Gutman 7100262e09 Update build requirements 2023-09-12 18:26:03 -05:00
Cameron Gutman e516943d53 Guard SDL_ControllerSensorEvent usage by SDL version check 2023-09-12 18:10:06 -05:00
Cameron Gutman fd41226cdd Support fully-planar output in DrmRenderer 2023-09-12 18:08:48 -05:00
Cameron Gutman 47b04eee3e Remove use of deprecated QByteArray::count() 2023-09-12 18:07:44 -05:00
Cameron Gutman 24ee6f96e1 Don't filter SOPS option by active resolutions with Sunshine 2023-09-11 21:25:29 -05:00
Cameron Gutman 6e34c21175 Fix signed integer overflow found by UBSan 2023-09-11 21:23:39 -05:00
Cameron Gutman 64789ea8bc Destroy the VTRenderer before leaving fullscreen
Fixes #973
2023-09-11 21:07:54 -05:00
Cameron Gutman 2ac7176787 Fix a bunch of memory leaks in the VTRenderer
It appears the leaked AVSampleBufferDisplayLayer may be causing the hang in #973
2023-09-11 20:49:35 -05:00
Cameron Gutman b968886594 Round default bitrates to the nearest megabit 2023-09-11 01:18:52 -05:00
Cameron Gutman 2f9c44103b Automatically scroll the SettingsView to ensure the focused item is visible
Also removed old manual scrolling code from SdlGamepadKeyNavigation as it was broken on Qt 6 anyway.
2023-09-11 00:08:20 -05:00
Cameron Gutman e9ed4940cd Interpolate between entries in our default bitrate table 2023-09-10 22:34:20 -05:00
Cameron Gutman 85b5845ebb Switch to Qt 6.5 for Windows ARM64 build 2023-09-10 18:43:51 -05:00
Cameron Gutman 6f4db913aa Update jom and vswhere
jom -> 1.1.4
vswhere -> 3.1.7
2023-09-10 16:55:19 -05:00
Cameron Gutman 2d20c711a6 Move Qt ARM64 patching into the install section 2023-09-10 16:50:41 -05:00
Cameron Gutman 2e829bc85f Fix corecrt_math_defines.h macro redefinition warnings with MSVC Qt 6 builds 2023-09-10 16:48:24 -05:00
Cameron Gutman acddc3cabd Fix ARM64 builds in AppVeyor
We have to replace some files that were built with incorrect paths
2023-09-10 16:32:42 -05:00
Cameron Gutman a16647f16c Always include ARM64 in the installer bundle 2023-09-10 15:16:02 -05:00
Cameron Gutman 3e3f384218 Fix indentation after WiX v4 autoconversion 2023-09-10 15:16:02 -05:00
Cameron Gutman 45a98a391a Produce Windows ARM64 binaries in CI 2023-09-10 15:15:53 -05:00
Cameron Gutman c9992201ce Support building with Qt 6's official ARM64 SDK binaries 2023-09-10 15:06:42 -05:00
Cameron Gutman 80062d262e Remove manual qmlcachegen invocation for internal Qt QML files
It's not safe to always assume we can always precompile everything.
Instead set QML_CACHE_DIR to ensure the files go to our desired location.
2023-09-10 15:03:53 -05:00
Zan 1456 652f7a7710 Translated using Weblate (Hungarian)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2023-09-09 21:55:43 +02:00
gallegonovato 7e7e50ada2 Translated using Weblate (Spanish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-09-09 21:55:42 +02:00
Cameron Gutman 87eba9bb89 Fix build on Qt 5.13 and earlier 2023-09-09 14:22:47 -05:00
Cameron Gutman da1fcd49fc Increase audio buffer size to reduce the chance of underruns 2023-09-09 12:56:05 -05:00
Cameron Gutman c98289a9e7 Use DMA_BUF_IOCTL_SYNC to synchronize swframe copies 2023-09-09 12:19:40 -05:00
Cameron Gutman 1d0b65f798 Log the active SDL audio driver 2023-09-09 11:46:06 -05:00
Cameron Gutman 3094185cd6 Also skip SDL_RENDERER_PRESENTVSYNC on Wayland 2023-09-09 10:41:33 -05:00
Cameron Gutman aaff04167b Only skip SDL_RENDERER_PRESENTVSYNC on Windows
macOS can still tear when using the Metal renderer backend.
2023-09-09 08:00:13 -05:00
Cameron Gutman 21bba02e6f Allow render thread usage with Metal 2023-09-09 07:45:42 -05:00
Cameron Gutman f60e724167 Default to indirect rendering on Apple Silicon
Hopefully the UMA makes the performance impact of reimporting frames negligible
until we can get a proper Metal renderer to replace AVSampleBufferDisplayLayer.
2023-09-09 07:44:11 -05:00
Cameron Gutman 7551e90899 Adjust AV1 surface alignment to match FFmpeg behavior 2023-09-08 23:13:29 -05:00
Cameron Gutman 715429c13c Print error dialogs and warning toasts to the log 2023-09-08 23:00:00 -05:00
Cameron Gutman 7976189d56 Bump macOS nightlies to Qt 6.4 2023-09-08 19:54:58 -05:00
Cameron Gutman 47d1eff45d Don't rasterize layers in fullscreen
The original artifacting bug didn't manifest in fullscreen anyway.
2023-09-08 19:53:01 -05:00
bittin1ddc447d824349b2 073df32b01 Translated using Weblate (Swedish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-09-08 11:59:30 +02:00
Zan 1456 e8ec7efa5c Translated using Weblate (Hungarian)
Currently translated at 33.4% (72 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2023-09-08 11:59:29 +02:00
sanhoe f08cdae2b4 Translated using Weblate (Korean)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-09-08 11:59:29 +02:00
weng weng 1389d29d8c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-09-08 11:59:28 +02:00
Jorys Paulin d4bfde7906 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-09-08 11:59:28 +02:00
reloxx13 fe73c36958 Translated using Weblate (German)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2023-09-08 11:59:28 +02:00
Cameron Gutman a97f6d90f4 Fix Linux build break 2023-09-08 02:04:15 -05:00
Cameron Gutman 0735f164a8 Revert back to model reset for updating the computer list
It's possible that multiple changes occur in parallel, so we can't rely on receiving them one at a time
even if the callbacks are synchronized. Handling this substantially complicates the logic such that
it's not really worth doing individual insertions and deletions anymore.

This reverts 94d821a4a9 and replaces it with a solution
that is basically the old code except that it properly handles changes to the structure of the list.
2023-09-08 02:02:21 -05:00
Cameron Gutman 9de0c215ba Don't allow custom frame rates below 10 FPS 2023-09-08 00:59:56 -05:00
Cameron Gutman 56474822f7 Don't scale bitrate linearly with frame rate beyond 60 FPS 2023-09-08 00:59:33 -05:00
Cameron Gutman 98b18d89eb Fix libva-x11 build in AppImage 2023-09-06 19:25:42 -05:00
Cameron Gutman 78ea79b95a Quiet new -Wswitch warnings 2023-09-05 22:51:08 -05:00
Cameron Gutman acbe503c12 Fix NVIDIA VAAPI X11 deprioritization check to actually check for X11 2023-09-05 20:46:43 -05:00
Cameron Gutman 0261c41574 Revert "Prefer nvidia-vaapi-driver over VDPAU for AV1"
libvdpau 1.5 has supported this for a while and we'll fall
back to VAAPI if VDPAU doesn't work.

This reverts commit 42960b7bf1.
2023-09-05 20:39:28 -05:00
Cameron Gutman c8182dfab3 Use BT.709 for DrmRenderer 2023-09-05 19:28:22 -05:00
Cameron Gutman 2eee9c019f Force the Material theme since our UI relies on it 2023-09-05 19:25:09 -05:00
Cameron Gutman 9ed40b5d9f Add chroma siting metadata to EGL exported frames 2023-09-05 18:30:01 -05:00
Cameron Gutman ebc4c71c72 Fix handling of non-standard hwaccel decoders that also set AV_CODEC_CAP_HARDWARE 2023-09-04 23:40:59 -05:00
Cameron Gutman dec5a6370e Fix build with Qt 5 2023-09-03 19:42:19 -05:00
Cameron Gutman 519858b708 Link to Sunshine 2023-09-03 18:04:31 -05:00
Cameron Gutman 8fcc4cf7fe Update readme and metadata with new features 2023-09-03 18:03:34 -05:00
Cameron Gutman 2f78350696 Change PC offline overlay to match new Play and Stop icons 2023-09-03 17:44:15 -05:00
FrogTheFrog 85d4037a89 Allow to specify gamepad GUIDs to be ignored when streaming 2023-09-03 16:24:05 -05:00
Cameron Gutman d165bf7498 Sort the host list 2023-09-03 16:20:29 -05:00
Cameron Gutman 94d821a4a9 Process insertions and moves in the ComputerModel without resetting 2023-09-03 16:19:24 -05:00
Cameron Gutman 6a854f7a64 Limit default bitrate to one decimal place 2023-09-02 20:15:18 -05:00
Cameron Gutman d76675f4b1 Fix handling of frame rates below 30 FPS 2023-09-02 20:05:27 -05:00
Cameron Gutman 4a7e43ccb6 Improve play and quit button visibility 2023-09-02 19:57:08 -05:00
Cameron Gutman b53333d1ba Refresh the bitrate text when the language changes 2023-09-02 18:47:42 -05:00
Cameron Gutman f1f3c8bfb9 Rerun lrelease 2023-09-02 18:42:39 -05:00
Cameron Gutman e580e7c672 Prune obsolete strings 2023-09-02 18:42:01 -05:00
Cameron Gutman a62fd96269 Rerun lupdate 2023-09-02 18:41:27 -05:00
Cameron Gutman a1d592bb87 Fix loss of all paired computers if Moonlight is terminated while writing the computer list 2023-09-02 16:43:25 -05:00
Cameron Gutman 83f5f6cefc Don't scale default bitrate further beyond 90 FPS 2023-09-02 15:54:12 -05:00
Cameron Gutman 9166e70524 Replace fixed "unsupported FPS" options with fully custom FPS option
Fixes #1003
2023-09-02 15:53:30 -05:00
Cameron Gutman 41f8fa95fe Rerun lupdate and lrelease 2023-08-29 23:46:18 -05:00
Cameron Gutman b140c21ed9 Merge remote-tracking branch 'origin/weblate' 2023-08-29 23:44:30 -05:00
Cameron Gutman 863712cb6e Update SDL2 to f032e8c1 2023-08-29 23:43:27 -05:00
Cameron Gutman 43f0aa7f06 Update moonlight-common-c 2023-08-29 23:41:56 -05:00
Cameron Gutman 12535d8142 Fix warning when quitting app after streaming is enabled 2023-08-29 18:19:43 -05:00
Cameron Gutman 8cf6a8bc98 Clean up old log files if more than 10 exist 2023-08-29 18:11:27 -05:00
Cameron Gutman 7073dd26de Fix race condition that could cause quit segue to never dismiss
Fixes #1060
2023-08-29 18:10:16 -05:00
Jorys Paulin 66bfd2fad8 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-08-22 14:52:37 +02:00
Cameron Gutman bb444f306a Update SDL_GameControllerDB 2023-08-21 21:58:12 -05:00
Cameron Gutman 626fba4a8f Fix DXVA2 chroma subsampling assuming interlaced content 2023-08-19 18:09:07 -05:00
Cameron Gutman 9dc96bda58 Update moonlight-common-c 2023-08-19 18:08:57 -05:00
Cameron Gutman 1a2f1ed620 Enable AV1 RFI on all decoders capable of HEVC RFI 2023-08-13 16:41:48 -05:00
Cameron Gutman 50255dd896 Set Colorspace connector property when streaming HDR 2023-08-09 23:02:43 -05:00
Cameron Gutman c8b9fda258 Fall back to HEVC if AV1 is forced and unavailable
Fixes #1053
2023-08-05 22:56:12 -05:00
sanhoe bb41732e59 Translated using Weblate (Korean)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-08-04 17:06:03 +02:00
ld892012 7d9b984747 Translated using Weblate (French)
Currently translated at 96.7% (208 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-08-04 17:06:03 +02:00
Cameron Gutman 7404e5fce2 Prefer D3D11VA for FSE V-Sync off 2023-08-03 19:41:35 -05:00
Cameron Gutman dc5414bd0d Force immediate destruction of the D3D11 swapchain
Possible fix for #959
2023-08-03 19:18:07 -05:00
Cameron Gutman d147d36867 Fix leaking /dev/dri fds on each vaInitialize() failure 2023-08-01 22:53:22 -05:00
Cameron Gutman 7763ec3c5c Fix mapping frames on RPi with 64-bit kernel and 32-bit userland 2023-08-01 22:01:34 -05:00
weng weng c61083ccd9 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-07-26 12:06:20 +02:00
Cameron Gutman 841aeccd6b Don't call QHostInfo::fromName() to "resolve" an IP address literal
Fixes #1037
2023-07-26 01:59:00 -05:00
Cameron Gutman bfcd373eec Add PC name to streaming window title
Fixes #1039
2023-07-23 01:16:24 -05:00
Cameron Gutman 202ef41894 Fix scaling of touch coordinates 2023-07-23 01:13:54 -05:00
Cameron Gutman f112edc3c3 Disable touch feedback when sending touch natively 2023-07-23 00:17:58 -05:00
Cameron Gutman 05fd7b18b9 Update touch API 2023-07-22 17:23:09 -05:00
ns6089 9764174070 Add host processing latency to ffmpeg stats overlay 2023-07-20 22:30:26 -05:00
Luna Jernberg 6b0370f0bc Translated using Weblate (Swedish)
Currently translated at 96.7% (208 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-07-19 22:04:39 +02:00
gallegonovato 2e4313e7c3 Translated using Weblate (Spanish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-07-19 22:04:39 +02:00
Jen Kung-chih 2684d1874a Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-18 07:04:33 +02:00
Jen Kung-chih 882539a700 Translated using Weblate (Chinese (Traditional))
Currently translated at 97.2% (209 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-18 03:06:10 +02:00
Cameron Gutman 42960b7bf1 Prefer nvidia-vaapi-driver over VDPAU for AV1 2023-07-16 16:54:13 -05:00
Cameron Gutman 333f978186 Add dav1d software AV1 decoder to FFmpeg libraries 2023-07-16 16:41:55 -05:00
Cameron Gutman e7e9df3261 Populate AV1 bitrate multiplier 2023-07-16 15:54:58 -05:00
Cameron Gutman 24dbc96fe5 Regenerate translations 2023-07-16 15:47:31 -05:00
Cameron Gutman abc391f32a Improve AV1 support 2023-07-16 15:38:58 -05:00
Cameron Gutman a589e8e3de Merge remote-tracking branch 'origin/weblate' 2023-07-16 12:31:52 -05:00
Fernando Lopes 39fa9a91b8 Translated using Weblate (Portuguese (Brazil))
Currently translated at 19.6% (41 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2023-07-16 16:02:55 +02:00
Angus Wan e10d98fb79 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-16 16:02:55 +02:00
Cameron Gutman d17cdbda93 Replace another QSharedPointer::get() call with Qt 5.10 alternative 2023-07-16 00:18:17 -05:00
Cameron Gutman 2252abefbf Fix build break on Qt 5.10 and earlier 2023-07-16 00:13:09 -05:00
Cameron Gutman ce60a146dc Move RPi decoder hacks to correct location for new selection logic 2023-07-15 15:22:02 -05:00
Cameron Gutman cd4a6f3e17 Rewrite FFmpeg decoder selection logic to dynamically discover compatible decoders
This avoids having to maintain a hardcoded list of all known H.264/HEVC/AV1 decoders
and ensures new/unknown decoders will just work automatically (assuming we have
a renderer that can process their output pixel format).
2023-07-15 15:12:58 -05:00
Cameron Gutman fc5e1ed5d8 Work around broken APT config on AppVeyor Ubuntu2004 image 2023-07-15 01:20:26 -05:00
Cameron Gutman d70b98075e Upgrade AppImage to Ubuntu 20.04 base 2023-07-15 00:47:26 -05:00
Cameron Gutman a4d9952061 Migrate from altool to notarytool for notarization 2023-07-14 21:44:14 -05:00
Cameron Gutman 45e4dfe09c Don't globally install wix.exe in CI anymore 2023-07-14 20:32:18 -05:00
Cameron Gutman 34ba9063ad Move installer signing into MSBuild 2023-07-14 20:31:32 -05:00
Cameron Gutman d5e2d59fe9 Fixes for WiX v4 migration 2023-07-14 20:05:49 -05:00
Cameron Gutman d39bdb28d6 Update AppImage to libva 2.19 2023-07-14 19:55:44 -05:00
Cameron Gutman 8bf5622d21 Upgrade installer to WiX v4 2023-07-14 19:55:00 -05:00
Maciej Błędkowski 9cafd5e099 Translated using Weblate (Polish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2023-07-11 17:50:13 +02:00
gallegonovato d1b3bfd700 Translated using Weblate (Spanish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-07-11 17:50:12 +02:00
Cameron Gutman e60caf06f9 Update libraries
OpenSSL -> 1.1.1u
SDL -> 156c7ba
2023-07-09 17:49:04 -05:00
Cameron Gutman a243c6bb90 Don't build unneeded sources
Fixes #1010
2023-07-09 17:23:21 -05:00
Cameron Gutman 10523a7e27 Correct guards around newer SDL functionality 2023-07-09 16:36:41 -05:00
Casey Korver ea06ec0133 Correct spelling mistakes found with Codespell 2023-07-09 13:21:18 -05:00
jcj83429 e287ebcded Add support for Applications (context menu) key
I'm adding corresponding support in Sunshine
2023-07-08 20:08:02 -05:00
Cameron Gutman 2ee90289a1 Update moonlight-common-c 2023-07-08 19:17:22 -05:00
Cameron Gutman 193df861d1 Update moonlight-common-c 2023-07-05 19:48:25 -05:00
Cameron Gutman 9055496a19 Add AV1 test frames 2023-07-05 19:47:45 -05:00
Cameron Gutman 5424576f73 Ensure serverCodecModeSupport is always non-zero 2023-07-05 19:46:30 -05:00
Cameron Gutman a81c6a1c5e Initial work on AV1 support 2023-07-03 00:45:36 -05:00
Cameron Gutman 53a572a4a4 Add controller motion deduplication and fix gyro units 2023-07-02 19:22:00 -05:00
Cameron Gutman df283d80c6 Implement controller LED and battery protocol extensions 2023-07-02 16:44:41 -05:00
Cameron Gutman b6d203b6dd Pull latest protocol extension changes 2023-06-27 22:51:50 -05:00
Cameron Gutman ef988cc8af Destroy the QMdnsEngine Server and Cache when not polling
These set background timers to refresh state, rebind sockets,
and refresh the cache. This is all stuff that we don't want to
be doing while streaming.
2023-06-21 00:54:11 -05:00
Kung-chih ba46905243 Update SettingsView.qml 2023-06-20 21:58:10 -05:00
Cameron Gutman df0c4c8208 Delete the QNetworkAccessManager when we're done with it
Apparently having this object around can lead to background
network scans happening that cause WiFi perf degradation.
2023-06-20 21:51:28 -05:00
Cameron Gutman e5aaa1fc53 Implement controller arrival events using Sunshine protocol extension 2023-06-18 23:34:28 -05:00
James Le Cuirot 8b6df34d8b Allow forced disabling of features instead of relying on pkg-config
So-called "automagic" behaviour is considered unhelpful by
distributions. A user may unintentionally build Moonlight with VDPAU
support simply because they had that library installed, only for the
whole application to break when they uninstall the library later. This
could happen on any distribution, but it should especially be avoided on
source-based distributions, where the user would not expect the package
manager to encounter such issues.

This commit is best viewed without whitespace changes.
2023-06-18 16:43:16 -05:00
Cameron Gutman 7a719aa886 Allow up to 16 gamepads with Sunshine hosts 2023-06-18 16:39:24 -05:00
Cameron Gutman 9af58af5e4 Implement gyro/accel and touchpad input using Sunshine extension 2023-06-18 16:08:32 -05:00
Cameron Gutman b945c8c2dc Implement trigger rumble using Sunshine protocol extension 2023-06-18 16:04:49 -05:00
Cameron Gutman 2165f56aee Implement full multi-touch support using Sunshine protocol extension 2023-06-18 16:02:21 -05:00
Cameron Gutman e42de9d155 Add extended button support with Sunshine 2023-06-18 16:00:51 -05:00
sanhoe 7fd95b9de2 Translated using Weblate (Korean)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-05-22 11:50:36 +02:00
Jorys Paulin a42c85802e Translated using Weblate (French)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-05-22 11:50:36 +02:00
shakedex cb3730100d Translated using Weblate (Hebrew)
Currently translated at 2.8% (6 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/he/
2023-04-29 18:51:13 +02:00
Yutaro Urata 7a04d2ad2c Translated using Weblate (Japanese)
Currently translated at 89.4% (187 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2023-04-29 18:51:12 +02:00
shakedex 1f93976919 Translated using Weblate (Hebrew)
Currently translated at 1.4% (3 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/he/
2023-04-27 20:48:43 +02:00
shakedex 0b7505f109 Added translation using Weblate (Hebrew) 2023-04-26 00:54:28 +02:00
Jen Kung-chih 392ca2d8b7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-04-14 18:48:56 +02:00
Cameron Gutman 68daa90b7e Refactor non-hwaccel decoders to use a single list of known codec names 2023-04-02 17:31:31 -05:00
Cameron Gutman fb39ad896e Add h264_omx and hevc_omx decoders used by the Vision Five 2 2023-04-02 17:17:25 -05:00
Simon Nilsson cb199054e3 Translated using Weblate (Swedish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-04-01 20:38:06 +02:00
Cameron Gutman 7cf77211b0 Update AppImage to libva 2.18.0 2023-03-28 20:06:09 -05:00
Cameron Gutman a3d1e9a117 Allow negotation of 36 and 48 bit deep color modes 2023-03-27 01:02:50 -05:00
Cameron Gutman 755c7c9895 Set max BPC property when streaming in 10-bit color modes 2023-03-27 00:44:02 -05:00
Cameron Gutman 45b5136233 Update libs for Windows, macOS, and AppImage
SDL2_ttf -> 2.20.2
SDL2 -> b57a6a1a
OpenSSL -> 1.1.1t (eec3403 for WinARM64)
opus -> 8cf872a1
FFmpeg -> 6.0 (with DXVA2/D3D11VA AV1 decoders enabled)
2023-03-26 20:49:25 -05:00
Cameron Gutman f16b5cd337 Expose glslow config option 2023-03-26 20:27:03 -05:00
Cameron Gutman 21cda8141d Always request AV_PIX_FMT_DRM_PRIME to ensure we get it if available 2023-03-26 19:59:12 -05:00
Cameron Gutman 90f26dfa45 Support direct KMSDRM output for platforms with slow GL implementations 2023-03-26 19:46:22 -05:00
Cameron Gutman ba507d8046 Move hw->sw frame mapping into a separate class 2023-03-26 14:41:02 -05:00
Cameron Gutman 5639bcc0f5 Default SDL render driver to GLES2 when using EGLFS
Fixes #868
2023-03-26 13:43:09 -05:00
Cameron Gutman 4cd030582d Allow matching primary planes for direct rendering 2023-03-26 13:28:26 -05:00
Jen Kung-chih 7908076b39 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-03-26 10:40:35 +02:00
Cameron Gutman ca91f9b702 Allow use of the delete key to delete PCs 2023-03-25 16:33:16 -05:00
Jen Kung-chih 0e86af1c9b Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-03-22 09:37:22 +01:00
weng weng c5ad84e2ee Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-03-22 09:37:21 +01:00
gallegonovato bfb5d6e8fe Translated using Weblate (Spanish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-03-20 18:41:02 +01:00
weng weng d63b0b5978 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.6% (202 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-03-20 18:41:02 +01:00
Cameron Gutman 5e6b60bae0 Fix handling of IPv6 literals with port numbers 2023-03-18 14:47:23 -05:00
Cameron Gutman 65b6885c61 Update VCRedist 2023-03-18 14:36:01 -05:00
Cameron Gutman e8ceaa4085 Update SDL_GameControllerDB 2023-03-18 14:34:13 -05:00
Cameron Gutman db2b120b68 Remove unused variable 2023-03-18 14:29:45 -05:00
Cameron Gutman 5f315d0093 Rerun lupdate and lrelease 2023-03-18 14:24:29 -05:00
Cameron Gutman 016b212ff7 Merge remote-tracking branch 'origin/weblate' 2023-03-18 14:22:11 -05:00
Cameron Gutman bccffe09e2 Purge NVIDIA-specific strings 2023-03-18 14:20:51 -05:00
Cameron Gutman a0365c8e1c Evaluate D3D9 quirks before calling CreateDeviceEx() 2023-03-17 00:53:47 -05:00
Cameron Gutman 38156c9f7f Default to D3D11VA on multi-GPU systems 2023-03-13 22:56:28 -05:00
Cameron Gutman 640db09a64 Update moonlight-common-c 2023-03-11 11:45:07 -06:00
Cameron Gutman 5baa8c680a Add upstreamed NV15 format used by Rockchip devices 2023-03-11 11:44:36 -06:00
Cameron Gutman e1c4a488ed Remove mouse throttling code
This should be managed inside moonlight-common-c instead.
2023-03-11 11:40:37 -06:00
Cameron Gutman 332d4433c4 Add horizontal scrolling in mouse emulation mode 2023-03-04 12:28:53 -06:00
Karnosio f5d535b1ef Translated using Weblate (Ukrainian)
Currently translated at 34.1% (71 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2023-02-21 19:36:41 +01:00
Cameron Gutman 35e226273c Tell the host if we want gamepads to persist after disconnection 2023-02-20 16:52:28 -06:00
Cameron Gutman 90e25e60d6 Add FPS values for all attached displays and support custom FPS values
Fixes #926
2023-02-03 00:45:27 -06:00
Cameron Gutman 80659160d3 Consolidate launch and resume and skip FPS hack for Sunshine 2023-02-03 00:36:30 -06:00
Cameron Gutman 5de29928cd Plumb HDR metadata for VideoToolbox 2023-02-02 19:16:18 -06:00
Cameron Gutman c65cea0f66 Update AppImage to libva 2.17 2023-01-17 21:45:29 -06:00
Cameron Gutman b3cfdbb835 Fix DRM renderer build 2023-01-17 21:45:02 -06:00
Cameron Gutman 9c15cceee7 Don't batch mouse motion for Sunshine 2023-01-16 22:01:34 -06:00
Cameron Gutman 8a0142bd0f Plumb HDR metadata and horizontal scrolling with Sunshine 2023-01-16 21:51:18 -06:00
ssantos 3d6e05d8c0 Translated using Weblate (Portuguese)
Currently translated at 94.2% (196 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2023-01-11 16:51:06 +01:00
Jen Kung-chih ddf0e6a935 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-01-02 07:47:19 +01:00
Dan 51852f044e Translated using Weblate (Ukrainian)
Currently translated at 32.6% (68 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-12-21 01:50:35 +01:00
Cameron Gutman 17cad6b3ca Fix a missed ZH_TW rename
Fixes #906
2022-12-15 22:48:44 -06:00
Jen Kung-chih 8912869077 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-12-07 11:48:30 +01:00
Zaraza225 a2697634ba Translated using Weblate (Ukrainian)
Currently translated at 32.6% (68 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-12-02 21:48:32 +01:00
Cameron Gutman 1bfb798107 Update SDL_GameControllerDB 2022-11-29 19:22:39 -06:00
Suzuran cf60568f53 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-11-29 11:47:36 +01:00
Cameron Gutman ddd18fdaf6 Rerun lupdate and lrelease 2022-11-25 14:18:44 -06:00
Cameron Gutman b04bb30930 Rename zh_Hant to zh_TW to match Qt's expected name 2022-11-25 14:18:06 -06:00
Cameron Gutman e41aaf980b Merge remote-tracking branch 'origin/weblate' 2022-11-25 14:06:13 -06:00
happyharryh 46df6601a1 Update translation for dialog buttons
Reference: https://github.com/qt/qttranslations/tree/dev/translations
2022-11-25 14:05:41 -06:00
happyharryh 5eb8b97469 Fix LANG_AUTO for Simplified Chinese 2022-11-25 14:05:41 -06:00
happyharryh 8cd0536fb1 Fix the translation of standard buttons in Dialogs 2022-11-25 14:05:41 -06:00
Zaraza225 99a6789720 Translated using Weblate (Ukrainian)
Currently translated at 30.0% (61 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-11-24 07:47:40 +01:00
Cameron Gutman 92670cc051 Add support for Qt 6's ARM64 qmake.bat 2022-11-21 21:37:16 -06:00
Cameron Gutman 89cbbfc291 Derive target architecture based on Qt path 2022-11-21 21:30:24 -06:00
Cameron Gutman 31869a7da2 Update to SDL 2.26.0 2022-11-21 20:50:44 -06:00
Cameron Gutman 68c6d6c932 Attempt to fix build with SDL 2.26 on systems with old GL headers 2022-11-21 20:32:10 -06:00
Loïc Hesling e4e140fa53 Translated using Weblate (French)
Currently translated at 97.0% (197 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-11-17 12:47:09 +01:00
Cameron Gutman b9709d0825 Fix build without SDL_VIDEO_DRIVER_WAYLAND 2022-11-14 21:11:26 -06:00
Cameron Gutman 324e3dffa0 Update MSVC Redist 2022-11-13 11:41:03 -06:00
Cameron Gutman dd9de3fcb4 Offset the ports used for WOL if the host is using alternate ports 2022-11-13 11:39:28 -06:00
Cameron Gutman 6710d0561a Use current HTTP port if ExternalPort is not present 2022-11-13 11:35:47 -06:00
Translator-3000 a30f97db0d Translated using Weblate (Italian)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-11-13 13:49:04 +01:00
Cameron Gutman cae666b834 Wake pacing queue waiters when Pacer is being destroyed 2022-11-12 15:55:36 -06:00
Cameron Gutman 5970ca49e9 Don't use swap interval on Wayland 2022-11-12 15:45:54 -06:00
Cameron Gutman 6ae6218043 Refactor Pacer to handle both blocking and non-blocking VsyncSources 2022-11-12 15:08:50 -06:00
Cameron Gutman 8e3e19a7f7 Removed unused NullThreadedVsyncSource 2022-11-12 14:30:38 -06:00
Cameron Gutman e3d51fd7f7 Implement a Wayland Vsync source using frame callbacks 2022-11-12 13:03:42 -06:00
Brandon Goldberg 95f5c1d104 Translated using Weblate (Spanish)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-11-09 16:47:06 +01:00
Jen Kung-chih 02a14069a3 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-11-05 14:04:04 +01:00
Cameron Gutman 394f28339e Update v4.3.1 changelog 2022-11-02 20:43:25 -05:00
Cameron Gutman 411998d4e3 Implement detection of local IPv6 addresses 2022-11-02 20:35:41 -05:00
Cameron Gutman 371906445e Prepare for v4.3.1 2022-11-02 19:44:44 -05:00
Cameron Gutman 34d91e58c0 Rerun lupdate and lrelease 2022-11-02 19:34:47 -05:00
Cameron Gutman f3f25bec7a Mark unfinished translation in zh_cn 2022-11-02 19:34:14 -05:00
Cameron Gutman 08d74bea75 Merge remote-tracking branch 'origin/weblate' 2022-11-02 19:30:25 -05:00
Dominik Chrástecký 63f917b317 Translated using Weblate (Czech)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-11-03 01:28:51 +01:00
Cameron Gutman 448633ec3c Fix some log messages with extra spaces 2022-11-02 19:25:44 -05:00
Cameron Gutman 09ce3c9ce4 Use CRLF line endings for the log file on Windows 2022-11-02 19:19:00 -05:00
Cameron Gutman 8fcc98102b Limit log by size rather than line count 2022-11-02 19:18:22 -05:00
Cameron Gutman e14075b464 Update moonlight-common-c to fix audio FEC OOS bug 2022-11-01 23:47:51 -05:00
Howard Wu ca89d14ec8 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.5% (202 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-11-02 03:03:38 +01:00
Cameron Gutman 3f51998065 Start the streaming window maximized if the GUI was maximized
Fixes #889
2022-10-30 11:56:15 -05:00
이정희 6e5b6a1a5c Translated using Weblate (Korean)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-10-30 15:02:46 +01:00
sanhoe 660f6c5bbf Translated using Weblate (Korean)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-10-29 06:02:07 +02:00
Cameron Gutman 5034bd72ed Bump v4.3.0 release date 2022-10-27 19:44:58 -05:00
Cameron Gutman 5b7c144796 Add workaround for DWM dark mode bug on Win10 2022-10-27 19:26:51 -05:00
Cameron Gutman e45b6b9b85 Avoid white flash when starting streaming on Windows 2022-10-27 18:18:47 -05:00
Cameron Gutman 245f242fb8 Add support for dark mode on Windows
Fixes #886
2022-10-27 18:12:26 -05:00
Cameron Gutman a6fccf93d1 Use a separate texture for rendering to avoid blending in the alignment padding
Fixes #885
2022-10-26 21:48:55 -05:00
Cameron Gutman 3dcab90752 Fix appdata for v4.3.0 2022-10-25 23:50:33 -05:00
Cameron Gutman 30a5f405f5 Enable HEVC RFI for the FFmpeg software decoder 2022-10-25 23:19:19 -05:00
Cameron Gutman bad1c9628e Prepare for v4.3.0 2022-10-25 23:11:12 -05:00
Cameron Gutman 1ab7bca43f Update SDL in AppImage 2022-10-25 22:47:29 -05:00
Cameron Gutman 7d0a53773c Rerun lupdate and lrelease 2022-10-25 22:45:03 -05:00
Cameron Gutman 789236ee8f Merge remote-tracking branch 'origin/weblate' 2022-10-25 22:44:21 -05:00
weng weng 21cba0b080 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-26 05:43:12 +02:00
Cameron Gutman 31eb0891e5 Update moonlight-common-c for improved audio FEC recovery 2022-10-25 22:42:12 -05:00
Cameron Gutman a13f8e7937 Ensure delayed flushes complete during shutdown 2022-10-25 02:43:55 -05:00
Cameron Gutman 5bfe56472f Fix build 2022-10-25 02:08:46 -05:00
Cameron Gutman 16a9ed682e Use a single flush thread for ComputerManager
Some QSettings backends don't like concurrent writes and using a
single thread improves write batching behavior.
2022-10-25 02:07:16 -05:00
Cameron Gutman 59cae610d2 Clarify encoding resolution limit comment 2022-10-25 01:24:57 -05:00
Cameron Gutman 29ac7893d7 Don't enforce the NVENC H.264 resolution limit on Sunshine hosts
Closes #882
2022-10-25 01:18:10 -05:00
Cameron Gutman c8aeca8ace Add an environment variable opt-out for the gamepad quit combo
See #870
2022-10-25 00:27:40 -05:00
Cameron Gutman 3da505c4c6 Minor perf optimization suggested by Clazy 2022-10-25 00:26:03 -05:00
Cameron Gutman 06bc05b708 Rerun lupdate and lrelease 2022-10-25 00:14:22 -05:00
Cameron Gutman a3dc9593c2 Merge remote-tracking branch 'origin/weblate' 2022-10-25 00:10:40 -05:00
Cameron Gutman 18a271a0ec Update moonlight-common-c for improved audio FEC recovery 2022-10-25 00:10:29 -05:00
Cameron Gutman cebd3bf751 Save hosts on a separate thread
QSettings on macOS Ventura performs horribly when saving a lot of values
(like several hosts or a host with a large app list). This change considerably
improves UI performance by moving the long operation off the main thread.
2022-10-25 00:07:07 -05:00
Cameron Gutman cb04925c6e Optimize locking in ComputerManager to reduce reader contention 2022-10-25 00:07:07 -05:00
Cameron Gutman b7a340bd00 Improve locking in NvComputer class 2022-10-24 23:53:02 -05:00
Cameron Gutman 2a0f837120 Stop issuing further HTTP requests when quitting 2022-10-24 23:46:57 -05:00
Cameron Gutman d00bdff495 Update SDL and FFmpeg for AppImage 2022-10-23 16:59:54 -05:00
Cameron Gutman 7e9c977b3d Update moonlight-common-c 2022-10-23 16:55:52 -05:00
reloxx13 1629151528 Translated using Weblate (German)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-21 20:05:49 +02:00
reloxx13 24295197bd Translated using Weblate (German)
Currently translated at 98.0% (199 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-20 19:02:35 +02:00
Eric 807dd84daa Translated using Weblate (Chinese (Simplified))
Currently translated at 98.5% (200 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-18 13:05:01 +02:00
Cameron Gutman 17848c097c Don't switch between GLX and EGL if EGL worked 2022-10-16 22:57:08 -05:00
Cameron Gutman 563b760d31 Update packages for recent versions of Ubuntu 2022-10-16 22:23:27 -05:00
Cameron Gutman 8465a27a97 Deprioritize VAAPI for Gallium and Nvidia drivers and work around RFI latency bug 2022-10-16 21:51:10 -05:00
Cameron Gutman 255cbd1e7e Fix building with SDL 2.0.20 or earlier 2022-10-15 15:36:09 -05:00
Cameron Gutman 7717749b72 Reduce max queued frames to avoid exhausting the decoder buffer pool 2022-10-15 14:34:42 -05:00
Cameron Gutman 9e4337babf Revert "Increase the number of decoder surfaces for DXVA2/D3D11VA"
This reverts commit 02c781b8f4.
2022-10-15 14:32:12 -05:00
Cameron Gutman 6771877a84 Make scaleSourceToDestinationSurface() idempotent
Deviation between scaling done during window sizing and renderer
viewport configuration can lead to small errors that create visible
artifacts such as a single pixel pillarbox/letterbox on one side.
2022-10-15 13:12:18 -05:00
Cameron Gutman a860bd8dd5 Enable HEVC RFI on Tegra 2022-10-14 23:41:09 -05:00
Cameron Gutman 704ce4ff0c Add environment variable for overriding decoder capabilities 2022-10-14 23:39:49 -05:00
Cameron Gutman 21edcc8113 Add workaround for macOS fullscreen exit bug 2022-10-14 23:01:55 -05:00
Cameron Gutman 125738f13d Cancel overlay update callbacks before destroying VTRenderer 2022-10-14 22:49:33 -05:00
Cameron Gutman 02c781b8f4 Increase the number of decoder surfaces for DXVA2/D3D11VA
We forgot to take into account frames buffered within Moonlight itself
2022-10-14 21:20:35 -05:00
Cameron Gutman 453fe6aea0 Ensure the target window size is always even 2022-10-14 21:09:32 -05:00
Cameron Gutman e0fb7dfd14 Rework window creation, sizing, and fullscreen transition logic
- Fixes window position/size being lost when toggling full-screen
- Fixes initial window size not respecting stream aspect ratio
2022-10-14 20:24:12 -05:00
Cameron Gutman c4012225c2 Rerun lupdate and lrelease 2022-10-14 19:27:04 -05:00
Cameron Gutman 1750243537 Merge remote-tracking branch 'origin/weblate' 2022-10-14 19:26:38 -05:00
Cameron Gutman 84fc5f3008 Use colorspace helper with VAAPI direct rendering 2022-10-14 19:23:51 -05:00
Cameron Gutman 8a224fbae4 Revert "Fix macOS build"
This reverts commit 0928d1fab2.
2022-10-13 01:19:56 -05:00
Cameron Gutman e6c4332445 Revert "Use Rec 2020 colorspace for WCG support even if HDR is off on the host"
Rec 2020 conversion causes colors to be blown out in SDR

This reverts commit 472e8ee92e.
2022-10-13 01:19:49 -05:00
Cameron Gutman 0928d1fab2 Fix macOS build 2022-10-13 01:11:04 -05:00
Cameron Gutman 40dd588bef Use 10-bit format mask instead of hardcoding specific formats 2022-10-13 00:17:05 -05:00
Cameron Gutman 472e8ee92e Use Rec 2020 colorspace for WCG support even if HDR is off on the host 2022-10-13 00:14:10 -05:00
Cameron Gutman c55af7fff3 Add a decoder/renderer callback to specify the desired color range 2022-10-12 23:59:01 -05:00
Cameron Gutman 7a39daf179 Implement Rec 601 Full Range support in SDLRenderer 2022-10-12 23:52:29 -05:00
Cameron Gutman 8d087ba5b1 Allow localization of pairing error strings 2022-10-12 22:20:15 -05:00
Cameron Gutman c7a30d8728 Allow a pairing attempt even if the PC is busy
Pairing while busy doesn't work with GFE but works with Sunshine
2022-10-12 22:15:58 -05:00
LedyBacer 1f678cafba Translated using Weblate (Russian)
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-10-12 10:23:12 +02:00
Jen Kung-chih 579e0bc464 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-10-10 19:59:11 +02:00
Nikita Epifanov 7f36dc5aad Translated using Weblate (Russian)
Currently translated at 97.0% (194 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-10-10 19:59:11 +02:00
Eric a7c2026128 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-10 19:59:11 +02:00
Sargon-Isa 7b0d67ebbe Translated using Weblate (German)
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-10 19:59:10 +02:00
Cameron Gutman 63f0910eac Update AppImage to libva 2.16.0 2022-10-07 22:22:13 -05:00
Cameron Gutman b16cf9fcc5 Update moonlight-common-c with speculative RFI support 2022-10-07 22:21:16 -05:00
Cameron Gutman 5501d7bc6b Include opt-out variable in VAAPI avoidance log output 2022-10-05 18:50:53 -05:00
Cameron Gutman 413ef42a34 Enable HEVC RFI for CUDA, VAAPI, and VDPAU decoders 2022-10-05 18:47:43 -05:00
Cameron Gutman a1694ab951 Use nvidia-vaapi-driver on Wayland systems if available 2022-10-05 18:44:11 -05:00
Cameron Gutman fbbbd5e0b8 Use new LiRequestIdrFrame() API 2022-10-05 00:53:31 -05:00
Cameron Gutman f8c7e2ee41 Enable HEVC RFI for VideoToolbox 2022-10-05 00:25:59 -05:00
Cameron Gutman 2a4af0bc2c Use colorspace helpers for DRM EGL export 2022-10-05 00:20:33 -05:00
Cameron Gutman d24db13e9d Update SDL_GameControllerDB 2022-10-05 00:00:39 -05:00
Cameron Gutman bc68aad67b Print the frame number if decoding fails 2022-10-04 23:38:54 -05:00
Cameron Gutman 9e8a4cab7b Enable HEVC RFI for DXVA2 and D3D11VA 2022-10-04 22:56:21 -05:00
Cameron Gutman 3679964cf8 Rerun lupdate and lrelease 2022-10-04 22:06:57 -05:00
Cameron Gutman 225ec1a87f Merge remote-tracking branch 'origin/weblate' 2022-10-04 22:05:48 -05:00
Cameron Gutman 071c76c06a Add error text for ML_ERROR_FRAME_CONVERSION 2022-10-04 22:05:18 -05:00
Cameron Gutman d77a255721 Update moonlight-common-c with GFE 3.26 and HEVC RFI fixes 2022-10-04 22:03:27 -05:00
Cameron Gutman 26ee1aee25 Fix protected content error on GFE 3.22+ 2022-10-04 22:02:44 -05:00
Jen Kung-chih b047395938 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-09-29 15:16:28 +02:00
Cameron Gutman 483a601867 Display SDR/HDR status in performance overlay 2022-09-28 17:44:22 -05:00
bruh c4bc2f6adf Translated using Weblate (Vietnamese)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2022-09-25 17:18:44 +02:00
Cameron Gutman 439e8fe33f Constify frame colorspace helper functions 2022-09-24 18:37:51 -05:00
Cameron Gutman 99885f5b4b Centralize colorspace and color range handling 2022-09-24 12:28:23 -05:00
Cameron Gutman 78b522ec1d Fix large frame header size for GFE 3.26 2022-09-22 23:48:41 -05:00
Jorys Paulin dbfa5a9358 Translated using Weblate (French)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-09-14 15:20:55 +02:00
Howard Wu 3910b3862a Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-09-13 07:18:54 +02:00
Cameron Gutman 3b8e3b7d5c Prepare for v4.2.1 2022-09-12 00:12:35 -05:00
Cameron Gutman 6129000dde Rerun lupdate and lrelease 2022-09-12 00:08:31 -05:00
Cameron Gutman 65b274d695 Merge remote-tracking branch 'origin/weblate' 2022-09-12 00:07:42 -05:00
reloxx13 a13dd0076b Translated using Weblate (German)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-09-12 06:41:15 +02:00
Cameron Gutman cc026c995c Fix mishandling of IDR frames with a SEI or AUD NAL
Fixes #865
2022-09-11 23:36:20 -05:00
Cameron Gutman 81cfacaa3d Add fallback logic when the host doesn't send valid colorspace data 2022-09-11 23:13:10 -05:00
Cameron Gutman fabebc05d2 Prepare for v4.2.0 2022-09-10 12:19:04 -05:00
Cameron Gutman 07a97bab03 Rerun lupdate and lrelease 2022-09-10 12:06:22 -05:00
Cameron Gutman 69ac810c82 Merge remote-tracking branch 'origin/weblate' 2022-09-10 12:05:24 -05:00
Daniel Saburi 3f4609dc6e Translated using Weblate (Portuguese (Brazil))
Currently translated at 16.1% (32 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2022-09-09 04:16:43 +02:00
Daniel Saburi 1ddb529d26 Translated using Weblate (Portuguese)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2022-09-09 04:16:42 +02:00
Cameron Gutman ab6b88073c Fix build with _FILE_OFFSET_BITS=64 2022-09-05 22:04:24 -05:00
Cameron Gutman ad3ed97472 Fix handling of 3 byte Annex B start sequences 2022-09-05 17:56:42 -05:00
Cameron Gutman 07e902fe95 Fix build with open() defined to open64() 2022-09-04 23:45:18 -05:00
Cameron Gutman eb781ce689 Use __FUNCTION__ macro instead of hardcoding 2022-09-03 18:09:01 -05:00
Cameron Gutman 555a65c8ea Add open64() hook for _FILE_OFFSET_BITS=64 2022-09-03 18:05:03 -05:00
Cameron Gutman 58429f4172 Fix handling of the optional mode argument in our open() hook 2022-09-03 17:52:54 -05:00
sanhoe e2692a0abd Translated using Weblate (Korean)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-09-03 00:21:34 +02:00
Brandon Goldberg d218c43edf Translated using Weblate (Spanish)
Currently translated at 97.4% (193 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-09-03 00:21:34 +02:00
Cameron Gutman fae9813127 Rebuild libraries built with CMake to get working PDBs and better optimizations
Additionally, disable WGI to work around an SDL bug

https://github.com/cgutman/moonlight-deps/commit/1810c6fba8b2377791e68d8829ee4c9a796788af
2022-08-28 20:34:44 -05:00
Cameron Gutman adc56d4ee5 Rerun lupdate and lrelease 2022-08-28 20:22:39 -05:00
Cameron Gutman f982e33fab Merge remote-tracking branch 'origin/weblate' 2022-08-28 20:20:53 -05:00
Cameron Gutman 9ab4479fcf Fix excessive flickering when switching between full-screen and windowed on Windows 2022-08-28 20:10:26 -05:00
Cameron Gutman 3e330b7929 Attach to the parent console to print list output on Win32 2022-08-27 14:54:45 -05:00
Cameron Gutman ecddada150 Improve verbose log suppression 2022-08-25 23:02:32 -05:00
Cameron Gutman 0c828cbb37 Suppress non-critical log output while running the list command 2022-08-25 22:45:42 -05:00
Cameron Gutman 84a32f8c16 Minor cleanup of new list code 2022-08-25 22:39:04 -05:00
Anselm Busse 4ee36fd405 Avoid GUI display for App listing 2022-08-25 22:18:05 -05:00
Anselm Busse 0802609fd8 Correcting for PR comments 2022-08-25 22:18:05 -05:00
Anselm Busse de88176995 Add a 'list' option for the CLI
This commit addresses Issue #448 by adding a command line option that allows the listing of all the Apps reported by the remote host as a CSV.
2022-08-25 22:18:00 -05:00
Cameron Gutman aca82f400a Never use fewer than 480 samples to avoid causing issues on PulseAudio systems
Fixes #830
Fixes #858
2022-08-25 21:27:05 -05:00
Brandon Goldberg 54bb6fe527 Translated using Weblate (Spanish)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-08-25 02:17:55 +02:00
Cameron Gutman c1f663cec1 Add missing files from previous commit 2022-08-24 17:31:22 -05:00
Cameron Gutman aaf59c2d01 Add CLI pairing support 2022-08-24 00:22:02 -05:00
Cameron Gutman 692942e5be Move PIN generation into ComputerManager to be shared with CLI pairing 2022-08-24 00:21:25 -05:00
Cameron Gutman f4acd629a1 Save hosts immediately after pairing concludes to ensure the server cert is persisted 2022-08-24 00:20:22 -05:00
Cameron Gutman 0ff8a44ec3 Allow 10-bit in DXVA2 as a fallback 2022-08-22 00:23:07 -05:00
Cameron Gutman c6d8f6e618 Allow D3D11VA to be disabled via environment variable 2022-08-22 00:19:46 -05:00
Cameron Gutman 1baa23cc43 Update SDL to 84004d1 for AppImage 2022-08-21 20:58:50 -05:00
Cameron Gutman 3be696e6bb Update SDL to 84004d1 2022-08-21 20:55:38 -05:00
Cameron Gutman 3cfcb01603 Add simple script to help updating libs 2022-08-21 20:55:25 -05:00
Cameron Gutman d39a29759c Don't draw with test-only renderers 2022-08-21 18:38:09 -05:00
Cameron Gutman bf4332b9e7 Prefer D3D11VA in non-FSE modes for improved performance 2022-08-21 17:50:56 -05:00
Cameron Gutman feaae7b684 Update moonlight-common-c to improve control stream failure diagnostics 2022-08-21 15:10:49 -05:00
Cameron Gutman be7852dfc0 Remove desktop resolution in favor of native (unscaled) resolution
Seeing 2 "native" resolutions for a single high DPI display is confusing.

If someone wants a lower resolution aspect-ratio match of a display, they
can use a custom resolution.
2022-08-16 01:22:26 -05:00
Cameron Gutman b0804ce048 Fix native resolution detection on high DPI wayland systems 2022-08-16 00:25:57 -05:00
Cameron Gutman aa7d5fa924 Don't use swap interval 1 by default on Wayland systems 2022-08-14 13:09:31 -05:00
Sargon-Isa b4cab12e9d Translated using Weblate (German)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-08-11 19:15:27 +02:00
Cameron Gutman 133dda2de0 Update SDL_GameControllerDB 2022-08-10 19:35:58 -05:00
Cameron Gutman ef5605ae39 Update FFmpeg to 5.1 2022-08-10 00:14:53 -05:00
Cameron Gutman 9b29b2702e Update VCRedist and add a script to update it in the future 2022-08-09 20:09:12 -05:00
Jorys Paulin abafa270e5 Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-08-06 14:19:54 +02:00
Cameron Gutman 15852ccf81 Update dependencies
SDL -> 602b7dd0f4
OpenSSL -> 1.1.1q
SDL_ttf -> 2.20.0
2022-08-02 00:38:33 -05:00
Kirill Korolev a427ecd029 Translated using Weblate (Russian)
Currently translated at 98.9% (190 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-07-22 18:18:21 +02:00
Wen-haur Chiu 77228dcb2c Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-07-21 14:19:41 +02:00
Cameron Gutman 3948cfe495 Update libva to 2.15 in AppImage 2022-07-02 13:05:47 -05:00
Cameron Gutman 36218b54f8 Don't hardcode /dev/dri/card0 and /dev/dri/renderD128 2022-06-30 19:25:33 -05:00
Cameron Gutman be2f4433db Avoid hardcoding VIDEO_FORMAT_H265_MAIN10 for HDR/10-bit color 2022-06-26 16:22:05 -05:00
Artur Szulc dd5d36cf07 Translated using Weblate (Polish)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2022-06-20 23:14:50 +02:00
Adam Lantos 685136d98f Make drmDropMaster() more reliable by checking for DRM master fds.
This should fix the majority of EACCES permission denied errors
when attempting to drop the DRM master.
2022-06-12 12:29:13 -07:00
Mattia Rombi 852937421e Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-06-07 11:15:33 +02:00
Jorys Paulin a5389b7be5 Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-05-31 10:15:58 +02:00
Cameron Gutman 1b96b18bc0 Fix handling of colorspace changes when using CUDA+SDL 2022-05-28 22:55:55 -05:00
Cameron Gutman e9edad6f8c Fix surface leak if SDLVideo_CreateOverlay() fails 2022-05-28 22:48:49 -05:00
Cameron Gutman f8a6012c3a Improve overlay format handling 2022-05-28 22:48:23 -05:00
Cameron Gutman e103f6c9b6 Avoid holding the overlay lock during vaPutSurface 2022-05-28 22:28:17 -05:00
Cameron Gutman 9daf7b5a36 Fix modesetting for non-EGL HEVC streams 2022-05-28 21:42:27 -05:00
Mattia Rombi d6142e1af0 Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-05-28 12:14:50 +02:00
Jorys Paulin b0491210ff Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-05-28 12:14:50 +02:00
Mattia Rombi 91d8550290 Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-05-26 19:36:07 +02:00
sanhoe dfaaa7d72a Translated using Weblate (Korean)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-05-26 19:15:29 +02:00
Dominik Chrástecký 5174a4f58a Translated using Weblate (Czech)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-05-25 14:20:23 +02:00
Cameron Gutman b9c73df488 Draw the black background even for the KMSDRM backend to fix modesetting 2022-05-24 19:41:37 -05:00
Cameron Gutman f99f1f6441 Disable EGL renderer on RPi due to very poor performance 2022-05-23 23:05:07 -05:00
Cameron Gutman 1ec1f5d3be Switch to D3D11VA by default on Windows ARM64
It performs much better at 4K on Surface Pro X
2022-05-22 22:29:18 -05:00
Cameron Gutman 713db06a05 Prepare for v4.1.0 release 2022-05-22 19:56:32 -05:00
Cameron Gutman a0adcbd90b Update SDL_GameControllerDB 2022-05-22 19:08:18 -05:00
Cameron Gutman b94776421c Rerun lupdate and lrelease 2022-05-22 19:03:55 -05:00
Thijs Lumeij 79c1043063 Translated using Weblate (Dutch)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2022-05-23 02:02:14 +02:00
Cameron Gutman cfabae17c0 Rerun lupdate and lrelease 2022-05-22 19:01:18 -05:00
Cameron Gutman 71a1d25e90 Merge remote-tracking branch 'origin/weblate' 2022-05-22 18:59:38 -05:00
Cameron Gutman c2d7b835fb Try moving session.h prior to vaapi.h 2022-05-21 16:58:28 -05:00
Cameron Gutman f72888ce6f Attempt to fix build error with older Qt headers 2022-05-21 16:52:04 -05:00
Wen-haur Chiu 30f474d253 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-05-21 14:16:30 +02:00
Cameron Gutman 216f274a92 Fix UAF in SLVideo overlay update 2022-05-21 00:30:07 -05:00
Cameron Gutman 5ea79efe4b Work around broken overlay state restoration in Qt GUI 2022-05-21 00:20:36 -05:00
Cameron Gutman 197c1ba21b Add support for the status overlay on Steam Link 2022-05-21 00:10:49 -05:00
Cameron Gutman 95c4a24d99 Destroy subpictures before the associated image 2022-05-20 21:46:40 -05:00
Cameron Gutman f5f23a7c22 Implement overlay support for the VAAPI direct renderer 2022-05-20 21:40:37 -05:00
Cameron Gutman c469576460 Update SDL and FFmpeg for AppImage 2022-05-20 17:45:35 -05:00
Cameron Gutman 0001bb0e4c Default to borderless windowed mode on Wayland systems 2022-05-19 19:22:01 -05:00
Cameron Gutman 56f184393f Allow the cursor lock toggle to work in full-screen mode
Fixes #793
2022-05-19 19:14:55 -05:00
Cameron Gutman 85777e85fa Use newer AppVeyor image for macOS builds 2022-05-18 00:54:21 -05:00
Cameron Gutman c750ec3cc7 Add workaround for macOS scrolling acceleration
See #778
2022-05-18 00:24:58 -05:00
Cameron Gutman c75b781d3f Use SDL_WINDOWEVENT_DISPLAY_CHANGED on SDL 2.0.18+ 2022-05-17 17:13:07 -05:00
Cameron Gutman 8aa42ff1d9 Reset the EGL renderer when specialization fails 2022-05-17 17:10:40 -05:00
Cameron Gutman 63a5bc5e12 Only force pacing in true full-screen mode to be consistent with DXVA2 2022-05-15 13:38:58 -05:00
Cameron Gutman e0b7b6dc3d Fix DXGI_FEATURE_PRESENT_ALLOW_TEARING feature check 2022-05-11 22:48:15 -05:00
Cameron Gutman 3d7ecf98c2 Fix HEVC Main10 support check on macOS GPUFamily1 GPUs 2022-05-11 22:00:34 -05:00
Cameron Gutman ad5581c620 Use DWM MMCSS for D3D11VA like DXVA2 does 2022-05-09 23:52:13 -05:00
Cameron Gutman 69af991772 Improve DXVA2 performance in borderless windowed on AMD hardware 2022-05-09 22:55:58 -05:00
Cameron Gutman 2bb2745f91 Enhance frame pacing logic for HDR renderers 2022-05-07 16:21:17 -05:00
Cameron Gutman 5f682bb45f Revert addition of D3DCREATE_NOWINDOWCHANGES
This flag breaks Alt+Tab in full-screen exclusive mode
2022-05-07 16:21:04 -05:00
Cameron Gutman 48bcb6b9a6 Rerun lupdate and lrelease 2022-05-07 14:32:34 -05:00
Cameron Gutman 092c0a7392 Integrate Czech and Polish translations 2022-05-07 14:32:07 -05:00
Cameron Gutman 4e8618c512 Merge remote-tracking branch 'origin/weblate' 2022-05-07 14:19:06 -05:00
Cameron Gutman c51a69c0dc Update SDL to 8cd908e 2022-05-07 14:18:39 -05:00
Cameron Gutman 2480849f39 Clean up DXGI adapter enumeration code 2022-05-02 19:05:00 -05:00
DankXylese 6bfe40607d Translated using Weblate (Ukrainian)
Currently translated at 27.4% (53 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-04-28 22:13:27 +02:00
Cameron Gutman a1c350a537 Fix WARP device leak 2022-04-26 23:29:04 -05:00
Cameron Gutman f732b1978e Require a test frame with D3D11VA 2022-04-26 23:04:31 -05:00
Cameron Gutman d3a542bac4 Try all available GPUs in D3D11VA decoder 2022-04-26 22:49:46 -05:00
Cameron Gutman b12724db02 Reduce log spam when choosing a resolution 2022-04-24 17:11:10 -05:00
Cameron Gutman f8f5e8e869 Don't discard all excess frames before rendering
This prevents the render queue's pacing logic from working and
interferes with renderers that take a full v-sync period between
their waitToRender() and renderFrame() callbacks.
2022-04-24 17:04:32 -05:00
Cameron Gutman 0733f06103 Fix saving keep awake value
Fixes #781
2022-04-24 16:49:36 -05:00
Cameron Gutman 6fdaa6ee8a Avoid modesetting if the display didn't change 2022-04-24 16:48:21 -05:00
Cameron Gutman f10b547a49 Partially revert "Rework window management to fix issues restoring window state between windowed and full-screen"
This exposes all sorts of issues with full-screen transitions on Windows and macOS:
- Loss of proper window decorations when transitioning from full-screen to windowed on Windows
- Improper sizing when transitioning from true full-screen to windowed on macOS

This reverts commit 38396b2691.
2022-04-24 16:40:19 -05:00
Cameron Gutman 38396b2691 Rework window management to fix issues restoring window state between windowed and full-screen 2022-04-24 16:22:17 -05:00
Cameron Gutman 220f50ebe4 Revert "Allow renderers to apply size and display changes seamlessly"
This reverts commit c989133d27.
2022-04-24 16:12:12 -05:00
Cameron Gutman c989133d27 Allow renderers to apply size and display changes seamlessly 2022-04-24 15:42:08 -05:00
Cameron Gutman 6c339551eb Allow resolution changes on all platforms
Take aspect ratio into account when making the choice too.
2022-04-21 23:57:17 -05:00
Cameron Gutman ef23a80b16 Fix EGL build when using EGL 1.4 or earlier headers 2022-04-21 21:13:39 -05:00
Cameron Gutman a521093731 Update Visual C++ Runtime installer 2022-04-17 00:04:03 -05:00
Cameron Gutman 747d3eedf1 Cleanup D3D11VA renderer by removing unnecessary codepaths
Waitable swapchains seem to be worse than our existing DXVsyncSource for synchronizing with VBlank.

Full-screen exclusive mode isn't beneficial vs Independent Flip on modern Win10/Win11 systems.
2022-04-15 23:26:32 -05:00
Cameron Gutman fd563726f0 Fix blocking presents in borderless windowed flip modes 2022-04-15 23:21:52 -05:00
Cameron Gutman 62136a1a96 Increase buffer count to prevent starvation on AMD GPUs 2022-04-14 23:21:32 -05:00
Cameron Gutman cf16c31d38 Improve performance and latency of D3D11VA renderer 2022-04-14 22:46:13 -05:00
Cameron Gutman 0f5d4aa72f Enhance EGLRenderer's waitForRender() implementation 2022-04-10 20:20:44 -05:00
Cameron Gutman d8dbe77427 Tiny EGL code cleanup 2022-04-10 19:35:29 -05:00
Cameron Gutman 0e5670d50d Don't compare StackView items by localized name
Fixes #767
2022-04-10 15:42:50 -05:00
Cameron Gutman 22924a1e92 Reload the FPS and window mode comboboxes after changing language
Fixes #765
2022-04-10 13:17:42 -05:00
Artur Szulc dbbb1bd8a1 Translated using Weblate (Polish)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2022-04-04 23:12:28 +02:00
Dominik Chrástecký 5c838b2fc5 Translated using Weblate (Czech)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-04-04 23:12:27 +02:00
Jorys Paulin 3a094d4ba8 Translated using Weblate (French)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-04-04 23:12:26 +02:00
Artur S 5d11c1ea6a Added translation using Weblate (Polish) 2022-04-03 20:52:00 +02:00
Dominik Chrástecký a7e2e15eac Added translation using Weblate (Czech) 2022-04-03 17:11:26 +02:00
Jorys Paulin 585a0ca1f4 Translated using Weblate (French)
Currently translated at 97.4% (188 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-04-03 09:12:06 +02:00
275 changed files with 48497 additions and 16603 deletions
+4 -3
View File
@@ -37,12 +37,13 @@ List the games you've tried that exhibit the issue. To see if the issue is game-
- OS: [e.g. Windows 10 1809]
- Moonlight Version: [e.g. v0.9.0]
- GPU: [e.g. Intel HD Graphics 520]
- Linux package type (if applicable): [e.g. Flatpak]
**Server PC details (please complete the following information)**
- OS: [e.g. Windows 10 1809]
- GeForce Experience version: [e.g. 3.16.0.140]
- Nvidia GPU driver: [e.g. 417.35]
- Antivirus and firewall software: [e.g. Windows Defender and Windows Firewall]
- Sunshine or GeForce Experience version: [e.g. Sunshine v0.21.0]
- GPU: [e.g. AMD Radeon RX 7900 XT]
- GPU driver: [e.g. 24.1.1]
**Moonlight Logs (please attach)**
- On Windows, `Moonlight-###.log` files can be found in `%TEMP%`. Simply type that into the File Explorer path field to navigate there.
+9
View File
@@ -0,0 +1,9 @@
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: "daily"
+165
View File
@@ -0,0 +1,165 @@
---
name: Build - Linux AppImage
permissions:
contents: read
on:
workflow_call:
inputs:
ci_version:
required: true
type: string
jobs:
build:
env:
CI_VERSION: ${{ inputs.ci_version }}
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
submodules: 'recursive'
fetch-depth: 1
- name: Setup environment
run: |
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.4.313-jammy.list https://packages.lunarg.com/vulkan/1.4.313/lunarg-vulkan-1.4.313-jammy.list
sudo apt update
sudo apt install -y qt6-base-dev qt6-declarative-dev libqt6svg6-dev qml6-module-qtquick-controls qml6-module-qtquick-templates qml6-module-qtquick-layouts \
qml6-module-qtqml-workerscript qml6-module-qtquick-window qml6-module-qtquick python3-pip nasm libgbm-dev libdrm-dev libfreetype-dev libasound2-dev \
libdbus-1-dev libegl1-mesa-dev libgl1-mesa-dev libgles2-mesa-dev libglu1-mesa-dev libibus-1.0-dev libpulse-dev libudev-dev libx11-dev libxcursor-dev \
libxext-dev libxi-dev libxinerama-dev libxkbcommon-dev libxrandr-dev libxss-dev libxt-dev libxv-dev libxxf86vm-dev libxcb-dri3-dev libx11-xcb-dev \
libxfixes-dev libxtst-dev wayland-protocols libopus-dev libvdpau-dev libgl-dev libpipewire-0.3-dev liburing-dev vulkan-sdk cmake
sudo pip3 install meson
mkdir -p dep_root/{bin,include,lib}
echo "DEP_ROOT=$PWD/dep_root" >> "${GITHUB_ENV}"
echo "$PWD/dep_root/bin" >> "${GITHUB_PATH}"
- name: Checkout SDL3
uses: actions/checkout@v5
with:
repository: libsdl-org/SDL
ref: a5e02a0927a2dd999718c1903f2d59440319ca99
path: deps/SDL
- name: Build SDL3
working-directory: deps/SDL
run: |
cmake -DSDL_KMSDRM=OFF -DSDL_TEST_LIBRARY=OFF -DSDL_INSTALL_DOCS=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -S . -B build
cmake --build build -j
sudo cmake --install build
- name: Checkout sdl2-compat
uses: actions/checkout@v5
with:
repository: libsdl-org/sdl2-compat
ref: release-2.32.70
path: deps/sdl2-compat
- name: Build sdl2-compat
working-directory: deps/sdl2-compat
run: |
cmake -DSDL2COMPAT_TESTS=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -S . -B build
cmake --build build -j
sudo cmake --install build
- name: Checkout SDL_ttf
uses: actions/checkout@v5
with:
repository: libsdl-org/SDL_ttf
ref: a883e490e30fb44a5336ea3dcb990c6982c5216f
path: deps/SDL_ttf
submodules: 'recursive'
- name: Build SDL_ttf
working-directory: deps/SDL_ttf
run: |
./autogen.sh
./configure
make -j$(nproc)
sudo make install
- name: Checkout libva
uses: actions/checkout@v5
with:
repository: intel/libva
ref: 2.23.0
path: deps/libva
- name: Build libva
working-directory: deps/libva
run: |
./autogen.sh
./configure --enable-x11
make -j$(nproc)
sudo make install
- name: Checkout libplacebo
uses: actions/checkout@v5
with:
repository: haasn/libplacebo
ref: 2d0979fb54e025e904c7372666fffbf5dae40f66
path: deps/libplacebo
submodules: 'recursive'
- name: Build libplacebo
working-directory: deps/libplacebo
run: |
meson setup build -Dvulkan=enabled -Dopengl=disabled -Ddemos=false
ninja -C build
sudo ninja install -C build
- name: Build dav1d
working-directory: deps
env:
DAV1D_VER: 1.5.3
run: |
git clone --branch $DAV1D_VER --depth 1 https://code.videolan.org/videolan/dav1d.git
pushd dav1d
meson setup build -Ddefault_library=static -Dbuildtype=release -Denable_tools=false -Denable_tests=false
ninja -C build
sudo ninja install -C build
popd
- name: Checkout FFmpeg
uses: actions/checkout@v5
with:
repository: FFmpeg/FFmpeg
ref: n8.1.1
path: deps/FFmpeg
- name: Build FFmpeg
working-directory: deps/FFmpeg
run: |
./configure --enable-pic --enable-lto --disable-static --enable-shared --disable-all --disable-autodetect \
--enable-avcodec --enable-avformat --enable-swscale \
--enable-decoder=h264 --enable-decoder=hevc --enable-decoder=av1 \
--enable-vaapi --enable-hwaccel=h264_vaapi --enable-hwaccel=hevc_vaapi --enable-hwaccel=av1_vaapi \
--enable-vdpau --enable-hwaccel=h264_vdpau --enable-hwaccel=hevc_vdpau --enable-hwaccel=av1_vdpau \
--enable-libdrm --enable-vulkan --enable-hwaccel=h264_vulkan --enable-hwaccel=hevc_vulkan --enable-hwaccel=av1_vulkan \
--enable-libdav1d --enable-decoder=libdav1d
make -j$(nproc)
sudo make install
- name: Install linuxdeploy
working-directory: dep_root/bin
run: |
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x linuxdeploy*.AppImage
- name: Build Binaries
run: |
sudo ldconfig
scripts/build-appimage.sh
- name: Upload Binaries
uses: actions/upload-artifact@v6
with:
name: Moonlight-LinuxAppImage-${{ env.CI_VERSION }}
path: build/installer-release/Moonlight-${{ env.CI_VERSION }}-x86_64.AppImage
compression-level: 0
if-no-files-found: error
+41
View File
@@ -0,0 +1,41 @@
---
name: Build - Steam Link
permissions:
contents: read
on:
workflow_call:
inputs:
ci_version:
required: true
type: string
jobs:
build:
env:
CI_VERSION: ${{ inputs.ci_version }}
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
submodules: 'recursive'
fetch-depth: 1
- name: Checkout Steam Link SDK
uses: actions/checkout@v5
with:
repository: ValveSoftware/steamlink-sdk
path: steamlink-sdk
fetch-depth: 1
- name: Build binaries
run: STEAMLINK_SDK_PATH=$PWD/steamlink-sdk scripts/build-steamlink-app.sh
- name: Upload Binaries
uses: actions/upload-artifact@v6
with:
name: Moonlight-SteamLink-${{ env.CI_VERSION }}
path: build/deploy-release/*
if-no-files-found: error
+125
View File
@@ -0,0 +1,125 @@
---
name: Build - Windows and macOS
permissions:
contents: read
on:
workflow_call:
inputs:
ci_version:
required: true
type: string
jobs:
build:
env:
CI_VERSION: ${{ inputs.ci_version }}
strategy:
fail-fast: false
matrix:
include:
# Windows
- os: windows-2025
qt_version: 6.11.1
# macOS
- os: macos-26
qt_version: 6.11.1
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
submodules: 'recursive'
fetch-depth: 1
- name: Download dependencies (Windows)
if: runner.os == 'Windows'
run: powershell ./setup-deps.ps1
- name: Install create-dmg (macOS)
if: runner.os == 'macOS'
run: |
brew install node
npm install --global create-dmg
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
cache: true
set-env: ${{ runner.os != 'Windows' }}
add-tools-to-path: ${{ runner.os != 'Windows' }}
version: ${{ matrix.qt_version }}
aqtsource: 'git+https://github.com/miurahr/aqtinstall.git@073e34d7c2ab4ae6961ed7cca690b3abd5ba5a7e'
- name: Install Qt ARM64 (Windows)
if: runner.os == 'Windows'
uses: jurplel/install-qt-action@v4
with:
cache: true
set-env: false
add-tools-to-path: false
arch: win64_msvc2022_arm64_cross_compiled
version: ${{ matrix.qt_version }}
- name: Build x64 binaries (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
set "PATH=%QT_PATH%;%PATH%"
scripts\build-arch.bat Release x64
env:
QT_PATH: ${{ runner.workspace }}\Qt\${{ matrix.qt_version }}\msvc2022_64\bin
- name: Build ARM64 binaries (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
set "PATH=%QT_PATH%;%PATH%"
scripts\build-arch.bat Release arm64
env:
QT_PATH: ${{ runner.workspace }}\Qt\${{ matrix.qt_version }}\msvc2022_arm64\bin
- name: Build Package
shell: pwsh
run: |
if ($Env:RUNNER_OS -eq "Windows") {
cmd /c scripts\generate-bundle.bat Release
} else {
bash scripts/generate-dmg.sh Release
}
- name: Upload Binaries (Windows x64)
uses: actions/upload-artifact@v6
if: runner.os == 'Windows'
with:
name: Moonlight-${{ runner.os }}-x64-${{ env.CI_VERSION }}
path: build/deploy-x64-release/*
if-no-files-found: error
- name: Upload Binaries (Windows arm64)
uses: actions/upload-artifact@v6
if: runner.os == 'Windows'
with:
name: Moonlight-${{ runner.os }}-arm64-${{ env.CI_VERSION }}
path: build/deploy-arm64-release/*
if-no-files-found: error
- name: Upload Binaries (macOS)
uses: actions/upload-artifact@v6
if: runner.os == 'macOS'
with:
name: Moonlight-${{ runner.os }}-${{ env.CI_VERSION }}
path: build/installer-Release/*.dmg
compression-level: 0
if-no-files-found: error
- name: Upload Symbols
uses: actions/upload-artifact@v6
with:
name: zDevDbgSyms-${{ runner.os }}-${{ env.CI_VERSION }}
path: |
build/installer-*/*.dsym/*
build/symbols-*/*.pdb
if-no-files-found: error
+45
View File
@@ -0,0 +1,45 @@
---
name: Build
permissions:
contents: read
on:
push:
pull_request:
branches:
- master
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
jobs:
setup:
runs-on: ubuntu-latest
outputs:
ci_version: ${{ steps.set-ci-version.outputs.ci_version }}
steps:
- name: Set CI version
id: set-ci-version
shell: bash
run: |
CI_VERSION=`echo ${GITHUB_SHA} | cut -c1-6`
echo "ci_version=${CI_VERSION}" >> "${GITHUB_OUTPUT}"
build-appimage:
needs: setup
uses: ./.github/workflows/build-appimage.yml
with:
ci_version: ${{ needs.setup.outputs.ci_version }}
build-steamlink:
needs: setup
uses: ./.github/workflows/build-steamlink.yml
with:
ci_version: ${{ needs.setup.outputs.ci_version }}
build-windows-macos:
needs: setup
uses: ./.github/workflows/build-win-mac.yml
with:
ci_version: ${{ needs.setup.outputs.ci_version }}
+2
View File
@@ -2,6 +2,8 @@
**/.vs/
.vscode/
build/
libs/
config.tests/*/.qmake.stash
config.tests/*/Makefile
-7
View File
@@ -7,13 +7,6 @@
[submodule "app/SDL_GameControllerDB"]
path = app/SDL_GameControllerDB
url = https://github.com/gabomdq/SDL_GameControllerDB.git
[submodule "soundio/libsoundio"]
path = soundio/libsoundio
url = https://github.com/cgutman/libsoundio.git
[submodule "h264bitstream/h264bitstream"]
path = h264bitstream/h264bitstream
url = https://github.com/aizvorski/h264bitstream.git
[submodule "libs"]
path = libs
url = https://github.com/cgutman/moonlight-qt-prebuilts.git
shallow = true
+22 -11
View File
@@ -158,17 +158,6 @@ private:
L"EZFRD32.dll",
L"EZFRD64.dll",
// These are the newer dList DLLs for Optimus hybrid graphics DDI.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/display/hybrid-system-ddi
//
// We forcefully block them from loading because Optimus has a bug that
// deadlocks DXVA2 when we present with D3DPRESENT_DONOTWAIT. This will prevent
// Optimus from ever using the dGPU even if the user has requested it.
// https://github.com/moonlight-stream/moonlight-qt/issues/240
// https://github.com/moonlight-stream/moonlight-qt/issues/235
L"nvdlist.dll",
L"nvdlistx.dll",
// These are the older dList/AppInit DLLs for Optimus hybrid graphics DDI.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/display/hybrid-system-ddi
//
@@ -218,6 +207,28 @@ private:
// Since the RTSS OSD doesn't even work with DXVA2, we'll just block the hooks entirely.
L"RTSSHooks.dll",
L"RTSSHooks64.dll",
// Bandicam's Vulkan layer DLL crashes during destruction of the Vulkan swapchain
// bdcamvk64+0x10b73:
// 00007ffa`be3b0b73 498b5630 mov rdx,qword ptr [r14+30h] ds:00000000`00000030=????????????????
//
// bdcamvk64+0x10b73
// libplacebo_357!vk_sw_destroy+0x14f [D:\a\moonlight-deps\moonlight-deps\libplacebo\src\vulkan\swapchain.c @ 460]
// libplacebo_357!pl_swapchain_destroy+0x1a [D:\a\moonlight-deps\moonlight-deps\libplacebo\src\swapchain.c @ 30]
// Moonlight!PlVkRenderer::~PlVkRenderer+0x159 [D:\a\moonlight-qt\app\streaming\video\ffmpeg-renderers\plvk.cpp @ 140]
// Moonlight!PlVkRenderer::`scalar deleting destructor'+0x17
// Moonlight!FFmpegVideoDecoder::reset+0x203 [D:\a\moonlight-qt\app\streaming\video\ffmpeg.cpp @ 301]
// Moonlight!FFmpegVideoDecoder::~FFmpegVideoDecoder+0x22 [D:\a\moonlight-qt\app\streaming\video\ffmpeg.cpp @ 257]
// Moonlight!FFmpegVideoDecoder::`scalar deleting destructor'+0x17
// Moonlight!Session::getDecoderInfo+0x19a [D:\a\moonlight-qt\app\streaming\session.cpp @ 415]
// Moonlight!SystemProperties::querySdlVideoInfoInternal+0x134 [D:\a\moonlight-qt\app\backend\systemproperties.cpp @ 161]
// Moonlight!SystemProperties::querySdlVideoInfo+0x97 [D:\a\moonlight-qt\app\backend\systemproperties.cpp @ 123]
// Moonlight!SystemProperties::SystemProperties+0x4bf [D:\a\moonlight-qt\app\backend\systemproperties.cpp @ 75]
//
// https://github.com/moonlight-stream/moonlight-qt/issues/1425
// https://github.com/moonlight-stream/moonlight-qt/issues/1579
L"bdcamvk32.dll",
L"bdcamvk64.dll",
};
};
+54 -27
View File
@@ -1,83 +1,110 @@
# Moonlight PC
[Moonlight PC](https://moonlight-stream.org) is an open source PC client for NVIDIA GameStream, as used by the NVIDIA Shield.
[Moonlight PC](https://moonlight-stream.org) is an open source PC client for NVIDIA GameStream and [Sunshine](https://github.com/LizardByte/Sunshine).
Moonlight also has mobile versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [iOS](https://github.com/moonlight-stream/moonlight-ios).
You can follow development on our [Discord server](https://moonlight-stream.org/discord) and help translate Moonlight into your language on [Weblate](https://hosted.weblate.org/projects/moonlight/moonlight-qt/).
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/glj5cxqwy2w3bglv/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-qt/branch/master)
[![Build](https://img.shields.io/github/actions/workflow/status/moonlight-stream/moonlight-qt/build.yml?branch=master)](https://github.com/moonlight-stream/moonlight-qt/actions/workflows/build.yml?query=branch%3Amaster)
[![Downloads](https://img.shields.io/github/downloads/moonlight-stream/moonlight-qt/total)](https://github.com/moonlight-stream/moonlight-qt/releases)
[![Translation Status](https://hosted.weblate.org/widgets/moonlight/-/moonlight-qt/svg-badge.svg)](https://hosted.weblate.org/projects/moonlight/moonlight-qt/)
## Features
- Hardware accelerated video decoding on Windows, Mac, and Linux
- Supports streaming at up to 120 FPS (high refresh rate monitor recommended)
- Supports streaming at 720p, 1080p, 1440p, 4K, and the client PC's native screen resolution
- H.264, HEVC, and AV1 codec support (AV1 requires Sunshine and a supported host GPU)
- YUV 4:4:4 support (Sunshine only)
- HDR streaming support
- 7.1 surround sound audio support
- 10-point multitouch support (Sunshine only)
- Gamepad support with force feedback and motion controls for up to 16 players
- Support for both pointer capture (for games) and direct mouse control (for remote desktop)
- Support for passing system-wide keyboard shortcuts like Alt+Tab to the host
- Direct touchscreen mouse control
- HEVC support for better image quality at reduced bandwidth
- Gamepad support with force feedback for up to 4 players
## Downloads
- [Windows, macOS, and Steam Link](https://github.com/moonlight-stream/moonlight-qt/releases)
- [Snap (for Ubuntu-based Linux distros)](https://snapcraft.io/moonlight)
- [Flatpak (for other Linux distros)](https://flathub.org/apps/details/com.moonlight_stream.Moonlight)
- [AppImage](https://github.com/moonlight-stream/moonlight-qt/releases)
- [Raspberry Pi 4](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-Raspberry-Pi-4)
- [Raspberry Pi 4 and 5](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-Raspberry-Pi-4)
- [Generic ARM 32-bit and 64-bit Debian packages](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-ARM%E2%80%90based-Single-Board-Computers) (not for Raspberry Pi)
- [Experimental RISC-V Debian packages](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-RISC%E2%80%90V-Single-Board-Computers)
- [NVIDIA Jetson and Nintendo Switch (Ubuntu L4T)](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-Linux4Tegra-(L4T)-Ubuntu)
### Nightly Builds
- [Downloads](https://nightly.link/moonlight-stream/moonlight-qt/workflows/build/master)
#### Special Thanks
[![Hosted By: Cloudsmith](https://img.shields.io/badge/OSS%20hosting%20by-cloudsmith-blue?logo=cloudsmith&style=flat-square)](https://cloudsmith.com)
Hosting for Moonlight's Raspberry Pi and L4T package repositories is graciously provided for free by [Cloudsmith](https://cloudsmith.com).
Hosting for Moonlight's Debian and L4T package repositories is graciously provided for free by [Cloudsmith](https://cloudsmith.com).
## Building
### Windows Build Requirements
* Qt 5.15 SDK or later
* Windows 7 or later
* [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/) (Community edition is fine)
* Select **MSVC 2019** option during Qt installation. MinGW is not supported.
* Qt 6.7 SDK or later (earlier versions may work but are not officially supported)
* [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) (Community edition is fine)
* Select **MSVC** option during Qt installation. MinGW is not supported.
* [7-Zip](https://www.7-zip.org/) (only if building installers for non-development PCs)
* [WiX Toolset](https://wixtoolset.org/releases/v3-14-0-5722/) v3.14.0.5722 or later (only if building installers for non-development PCs)
* Graphics Tools (only if running debug builds)
* Install "Graphics Tools" in the Optional Features page of the Windows Settings app.
* Alternatively, run `dism /online /add-capability /capabilityname:Tools.Graphics.DirectX~~~~0.0.1.0` and reboot.
### macOS Build Requirements
* Qt 6.2 SDK or later
* macOS Mojave (10.14) or later
* Xcode 13
* Qt 6.7 SDK or later (earlier versions may work but are not officially supported)
* Xcode 14 or later (earlier versions may work but are not officially supported)
* [create-dmg](https://github.com/sindresorhus/create-dmg) (only if building DMGs for use on non-development Macs)
### Linux/Unix Build Requirements
* Qt 5.9 SDK or later
* Qt 6 is recommended, but Qt 5.12 or later is also supported (replace `qmake6` with `qmake` when using Qt 5).
* GCC or Clang
* FFmpeg 4.0 or later
* Install the required packages:
* Debian/Ubuntu: `libegl1-mesa-dev libgl1-mesa-dev libopus-dev libqt5svg5-dev libsdl2-dev libsdl2-ttf-dev libssl-dev libavcodec-dev libva-dev libvdpau-dev libxkbcommon-dev qt5-default qt5-qmake qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev wayland-protocols qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtquick-window2 qml-module-qtquick2`
* RedHat/Fedora: `openssl-devel SDL2-devel SDL2_ttf-devel ffmpeg-devel qt5-qtsvg-devel qt5-qtquickcontrols2-devel libva-devel libvdpau-devel opus-devel pulseaudio-libs-devel alsa-lib-devel`
* FFmpeg 4.0+ is required to build. If your distro doesn't package FFmpeg 4.0 or later, you can build and install it from source on https://ffmpeg.org/
* Debian/Ubuntu:
* Base Requirements: `libegl1-mesa-dev libgl1-mesa-dev libopus-dev libsdl2-dev libsdl2-ttf-dev libssl-dev libavcodec-dev libavformat-dev libswscale-dev libva-dev libvdpau-dev libxkbcommon-dev wayland-protocols libdrm-dev`
* Qt 6 (Recommended): `qt6-base-dev qt6-declarative-dev libqt6svg6-dev qt6-wayland qml6-module-qtquick-controls qml6-module-qtquick-templates qml6-module-qtquick-layouts qml6-module-qtqml-workerscript qml6-module-qtquick-window qml6-module-qtquick`
* Qt 5: `qtbase5-dev qt5-qmake qtdeclarative5-dev qtquickcontrols2-5-dev qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtquick-window2 qml-module-qtquick2 qtwayland5`
* RedHat/Fedora (RPM Fusion repo required):
* Base Requirements: `openssl-devel SDL2-devel SDL2_ttf-devel ffmpeg-devel libva-devel libvdpau-devel opus-devel pulseaudio-libs-devel alsa-lib-devel libdrm-devel`
* Qt 6 (Recommended): `qt6-qtsvg-devel qt6-qtdeclarative-devel`
* Qt 5: `qt5-qtsvg-devel qt5-qtquickcontrols2-devel`
* Building the Vulkan renderer requires a `libplacebo-dev`/`libplacebo-devel` version of at least v7.349.0 and FFmpeg 6.1 or later.
### Steam Link Build Requirements
* [Steam Link SDK](https://github.com/ValveSoftware/steamlink-sdk) cloned on your build system
* STEAMLINK_SDK_PATH environment variable set to the Steam Link SDK path
**Steam Link Hardware Limitations**
Moonlight builds for Steam Link are subject to hardware limitations of the Steam Link device:
* Maximum resolution: **1080p (1920x1080)**
* Maximum framerate: **60 FPS**
* Maximum video bitrate: **40 Mbps**
* **HDR streaming is not supported** on the original hardware
### Docker containers
If you want to use Docker for building, look at [this repo](https://github.com/cgutman/moonlight-packaging) containing canonical containers
for different architectures, which handle building deps and extra linking for you.
### Build Setup Steps
1. Install the latest Qt SDK (and optionally, the Qt Creator IDE) from https://www.qt.io/download
* You can install Qt via Homebrew on macOS, but you will need to use `brew install qt --with-debug` to be able to create debug builds of Moonlight.
* You may also use your Linux distro's package manager for the Qt SDK as long as the packages are Qt 5.9 or later.
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.9.
2. Run `git submodule update --init --recursive` from within `moonlight-qt/`
* You may also use your Linux distro's package manager for the Qt SDK as long as the packages are Qt 5.12 or later.
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.14.
2. Download submodules and dependencies
* Run `git submodule update --init --recursive` from within `moonlight-qt/`.
* On Windows and macOS, you must also run `setup-deps.ps1` (Windows) or `setup-deps.py` (macOS).
* Perform these steps each time you pull new changes from the Git repository.
3. Open the project in Qt Creator or build from qmake on the command line.
* To build a binary for use on non-development machines, use the scripts in the `scripts` folder.
* For Windows builds, use `scripts\build-arch.bat` and `scripts\generate-bundle.bat`. Execute these scripts from the root of the repository within a Qt command prompt. Ensure WiX and 7-Zip binary directories are in your `%PATH%`.
* For Windows builds, use `scripts\build-arch.bat` and `scripts\generate-bundle.bat`. Execute these scripts from the root of the repository within a Qt command prompt. Ensure 7-Zip binary directory is on your `%PATH%`.
* For macOS builds, use `scripts/generate-dmg.sh`. Execute this script from the root of the repository and ensure Qt's `bin` folder is in your `$PATH`.
* For Steam Link builds, run `scripts/build-steamlink-app.sh` from the root of the repository.
* To build from the command line for development use, run `qmake moonlight-qt.pro` then `make debug` or `make release`
* To create an embedded build for a single-purpose device, use `qmake "CONFIG+=embedded" moonlight-qt.pro` and build normally.
* To build from the command line for development use on macOS or Linux, run `qmake6 moonlight-qt.pro` then `make debug` or `make release`.
* The final binary will be placed in `app/moonlight`.
* To create an embedded build for a single-purpose device, use `qmake6 "CONFIG+=embedded" moonlight-qt.pro` and build normally.
* This build will lack windowed mode, Discord/Help links, and other features that don't make sense on an embedded device.
* For platforms with poor GPU performance, add `"CONFIG+=gpuslow"` to prefer direct KMSDRM rendering over GL/Vulkan renderers. Direct KMSDRM rendering can use dedicated YUV/RGB conversion and scaling hardware rather than slower GPU shaders for these operations.
## Contribute
1. Fork us
+24 -2
View File
@@ -2,10 +2,14 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GCSupportsGameMode</key>
<true/>
<key>CFBundleExecutable</key>
<string>Moonlight</string>
<key>LSSupportsGameMode</key>
<true/>
<key>CFBundleGetInfoString</key>
<string>Stream games from your NVIDIA GameStream-enabled PC</string>
<string>Stream games and other applications from another PC</string>
<key>CFBundleIconFile</key>
<string>moonlight</string>
<key>CFBundleIdentifier</key>
@@ -17,16 +21,34 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>LSMinimumSystemVersion</key>
<string>10.14</string>
<string>11.0.0</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>GCSupportedGameControllers</key>
<array>
<dict>
<key>ProfileName</key>
<string>ExtendedGamepad</string>
</dict>
</array>
<key>GCSupportsControllerUserInteraction</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocalNetworkUsageDescription</key>
<string>Moonlight uses the local network to connect to your gaming PC for streaming.</string>
<key>CFBundleVersion</key>
<string>VERSION</string>
<key>CFBundleShortVersionString</key>
<string>VERSION</string>
<key>CFBundleDisplayName</key>
<string>Moonlight</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
</dict>
</plist>
+2 -1
View File
@@ -11,7 +11,8 @@
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitor</dpiAwareness>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2, permonitor</dpiAwareness>
<heapType xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings">SegmentHeap</heapType>
</asmv3:windowsSettings>
</asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+67
View File
@@ -0,0 +1,67 @@
//
// Compatibility header for older version of SDL.
// Include this instead of SDL.h directly.
//
#pragma once
#include <SDL.h>
// SDL_FRect wasn't added until 2.0.10
#if !SDL_VERSION_ATLEAST(2, 0, 10)
typedef struct SDL_FRect
{
float x;
float y;
float w;
float h;
} SDL_FRect;
#endif
#ifndef SDL_HINT_VIDEO_X11_FORCE_EGL
#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL"
#endif
#ifndef SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER
#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER"
#endif
#ifndef SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED
#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
#endif
#ifndef SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE
#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE"
#endif
#ifndef SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE
#define SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE "SDL_JOYSTICK_HIDAPI_PS5_RUMBLE"
#endif
#ifndef SDL_HINT_WINDOWS_USE_D3D9EX
#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX"
#endif
#ifndef SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS
#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS"
#endif
#ifndef SDL_HINT_MOUSE_RELATIVE_SCALING
#define SDL_HINT_MOUSE_RELATIVE_SCALING "SDL_MOUSE_RELATIVE_SCALING"
#endif
#ifndef SDL_HINT_AUDIO_DEVICE_APP_NAME
#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME"
#endif
#ifndef SDL_HINT_APP_NAME
#define SDL_HINT_APP_NAME "SDL_APP_NAME"
#endif
#ifndef SDL_HINT_MOUSE_AUTO_CAPTURE
#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE"
#endif
#ifndef SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP
#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP"
#endif
+216 -103
View File
@@ -1,5 +1,5 @@
QT += core quick network quickcontrols2 svg
CONFIG += c++11
CONFIG += c++17
unix:!macx {
TARGET = moonlight
@@ -12,10 +12,13 @@ include(../globaldefs.pri)
# Precompile QML files to avoid writing qmlcache on portable versions.
# Since this binds the app against the Qt runtime version, we will only
# do this for Windows and Mac, since they ship with the Qt runtime.
win32|macx {
CONFIG(release, debug|release) {
CONFIG += qtquickcompiler
# do this for Windows and Mac (when disable-prebuilts is not defined),
# since they always ship with the matching build of the Qt runtime.
!disable-prebuilts {
win32|macx {
CONFIG(release, debug|release) {
CONFIG += qtquickcompiler
}
}
}
@@ -33,100 +36,139 @@ DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
win32 {
contains(QT_ARCH, i386) {
LIBS += -L$$PWD/../libs/windows/lib/x86
INCLUDEPATH += $$PWD/../libs/windows/include/x86
!exists($$PWD/../libs/windows) {
error("Missing dependencies. Please run 'powershell .\setup-deps.ps1' to fetch prebuilt libraries.")
}
contains(QT_ARCH, x86_64) {
LIBS += -L$$PWD/../libs/windows/lib/x64
INCLUDEPATH += $$PWD/../libs/windows/include/x64
INCLUDEPATH += $$PWD/../libs/windows/include/x64 $$PWD/../libs/windows/include/x64/SDL2
}
contains(QT_ARCH, arm64) {
LIBS += -L$$PWD/../libs/windows/lib/arm64
INCLUDEPATH += $$PWD/../libs/windows/include/arm64
INCLUDEPATH += $$PWD/../libs/windows/include/arm64 $$PWD/../libs/windows/include/arm64/SDL2
}
INCLUDEPATH += $$PWD/../libs/windows/include
LIBS += ws2_32.lib winmm.lib dxva2.lib ole32.lib gdi32.lib user32.lib d3d9.lib dwmapi.lib dbghelp.lib
}
macx {
INCLUDEPATH += $$PWD/../libs/mac/include
INCLUDEPATH += $$PWD/../libs/mac/Frameworks/SDL2.framework/Versions/A/Headers
INCLUDEPATH += $$PWD/../libs/mac/Frameworks/SDL2_ttf.framework/Versions/A/Headers
LIBS += -L$$PWD/../libs/mac/lib -F$$PWD/../libs/mac/Frameworks
macx:!disable-prebuilts {
!exists($$PWD/../libs/mac) {
error("Missing dependencies. Please run 'python3 setup-deps.py' to fetch prebuilt libraries.")
}
INCLUDEPATH += $$PWD/../libs/mac/include $$PWD/../libs/mac/include/SDL2
LIBS += -L$$PWD/../libs/mac/lib
}
unix:!macx {
unix:if(!macx|disable-prebuilts) {
CONFIG += link_pkgconfig
PKGCONFIG += openssl sdl2 SDL2_ttf opus
PKGCONFIG += openssl sdl2 SDL2_ttf
packagesExist(libavcodec) {
PKGCONFIG += libavcodec libavutil
CONFIG += ffmpeg
packagesExist(libva) {
packagesExist(libva-x11) {
CONFIG += libva-x11
}
packagesExist(libva-wayland) {
CONFIG += libva-wayland
}
packagesExist(libva-drm) {
CONFIG += libva-drm
}
CONFIG += libva
}
packagesExist(vdpau) {
CONFIG += libvdpau
}
packagesExist(mmal) {
PKGCONFIG += mmal
CONFIG += mmal
}
packagesExist(libdrm) {
PKGCONFIG += libdrm
CONFIG += libdrm
}
packagesExist(ffnvcodec) {
PKGCONFIG += ffnvcodec
CONFIG += cuda
}
# We have our own optimized libopus.a for Steam Link
if(!config_SL|disable-prebuilts) {
PKGCONFIG += opus
}
packagesExist(wayland-client) {
DEFINES += HAS_WAYLAND
PKGCONFIG += wayland-client
}
!disable-ffmpeg {
packagesExist(libavcodec) {
PKGCONFIG += libavcodec libavutil libswscale
CONFIG += ffmpeg
packagesExist(x11) {
DEFINES += HAS_X11
PKGCONFIG += x11
!disable-libva {
packagesExist(libva) {
!disable-x11 {
packagesExist(libva-x11) {
CONFIG += libva-x11
}
}
!disable-wayland {
packagesExist(libva-wayland) {
CONFIG += libva-wayland
}
}
!disable-libdrm {
packagesExist(libva-drm) {
CONFIG += libva-drm
}
}
CONFIG += libva
}
}
!disable-libvdpau {
packagesExist(vdpau) {
CONFIG += libvdpau
}
}
!disable-mmal {
packagesExist(mmal) {
PKGCONFIG += mmal
CONFIG += mmal
}
}
!disable-libdrm {
packagesExist(libdrm) {
PKGCONFIG += libdrm
CONFIG += libdrm
}
}
# Disabled by default due to reliability issues. See #1314.
# CUDA interop is superseded by VDPAU and Vulkan Video.
enable-cuda {
packagesExist(ffnvcodec) {
PKGCONFIG += ffnvcodec
CONFIG += cuda
}
}
!disable-libplacebo {
packagesExist(libplacebo) {
PKGCONFIG += libplacebo
CONFIG += libplacebo
}
}
}
!disable-wayland {
packagesExist(wayland-client) {
CONFIG += wayland
PKGCONFIG += wayland-client
}
}
!disable-x11 {
packagesExist(x11) {
DEFINES += HAS_X11
PKGCONFIG += x11
}
}
}
}
win32 {
LIBS += -llibssl -llibcrypto -lSDL2 -lSDL2_ttf -lavcodec -lavutil -lopus -ldxgi -ld3d11
CONFIG += ffmpeg
LIBS += -llibssl -llibcrypto -lSDL2 -lSDL2_ttf -lavcodec -lavutil -lswscale -lopus -ldxgi -ld3d11 -llibplacebo
CONFIG += ffmpeg libplacebo
}
win32:!winrt {
CONFIG += soundio discord-rpc
CONFIG += discord-rpc
}
macx {
LIBS += -lssl -lcrypto -lavcodec.59 -lavutil.57 -lopus -framework SDL2 -framework SDL2_ttf
LIBS += -lobjc -framework VideoToolbox -framework AVFoundation -framework CoreVideo -framework CoreGraphics -framework CoreMedia -framework AppKit -framework Metal
!disable-prebuilts {
LIBS += -lssl.3 -lcrypto.3 -lavcodec.62 -lavutil.60 -lswscale.9 -lopus.0 -lSDL2 -lSDL2_ttf -lplacebo
CONFIG += discord-rpc libplacebo
}
# For libsoundio
LIBS += -framework CoreAudio -framework AudioUnit
CONFIG += ffmpeg soundio discord-rpc
LIBS += -lobjc -framework VideoToolbox -framework AVFoundation -framework CoreVideo -framework CoreGraphics -framework CoreMedia -framework AppKit -framework Metal -framework QuartzCore
CONFIG += ffmpeg
}
SOURCES += \
backend/nvaddress.cpp \
backend/nvapp.cpp \
cli/pair.cpp \
main.cpp \
backend/computerseeker.cpp \
backend/identitymanager.cpp \
@@ -137,6 +179,7 @@ SOURCES += \
backend/boxartmanager.cpp \
backend/richpresencemanager.cpp \
cli/commandlineparser.cpp \
cli/listapps.cpp \
cli/quitstream.cpp \
cli/startstream.cpp \
settings/compatfetcher.cpp \
@@ -153,6 +196,7 @@ SOURCES += \
streaming/audio/renderers/sdlaud.cpp \
gui/computermodel.cpp \
gui/appmodel.cpp \
streaming/bandwidth.cpp \
streaming/streamutils.cpp \
backend/autoupdatechecker.cpp \
path.cpp \
@@ -163,8 +207,10 @@ SOURCES += \
wm.cpp
HEADERS += \
SDL_compat.h \
backend/nvaddress.h \
backend/nvapp.h \
cli/pair.h \
settings/compatfetcher.h \
settings/mappingfetcher.h \
utils.h \
@@ -177,6 +223,7 @@ HEADERS += \
backend/boxartmanager.h \
backend/richpresencemanager.h \
cli/commandlineparser.h \
cli/listapps.h \
cli/quitstream.h \
cli/startstream.h \
settings/streamingpreferences.h \
@@ -187,6 +234,7 @@ HEADERS += \
gui/computermodel.h \
gui/appmodel.h \
streaming/video/decoder.h \
streaming/bandwidth.h \
streaming/streamutils.h \
backend/autoupdatechecker.h \
path.h \
@@ -202,16 +250,18 @@ ffmpeg {
DEFINES += HAVE_FFMPEG
SOURCES += \
streaming/video/ffmpeg.cpp \
streaming/video/ffmpeg-renderers/genhwaccel.cpp \
streaming/video/ffmpeg-renderers/sdlvid.cpp \
streaming/video/ffmpeg-renderers/pacer/pacer.cpp \
streaming/video/ffmpeg-renderers/pacer/nullthreadedvsyncsource.cpp
streaming/video/ffmpeg-renderers/swframemapper.cpp \
streaming/video/ffmpeg-renderers/pacer/pacer.cpp
HEADERS += \
streaming/video/ffmpeg.h \
streaming/video/ffmpeg-renderers/renderer.h \
streaming/video/ffmpeg-renderers/genhwaccel.h \
streaming/video/ffmpeg-renderers/sdlvid.h \
streaming/video/ffmpeg-renderers/pacer/pacer.h \
streaming/video/ffmpeg-renderers/pacer/nullthreadedvsyncsource.h
streaming/video/ffmpeg-renderers/swframemapper.h \
streaming/video/ffmpeg-renderers/pacer/pacer.h
}
libva {
message(VAAPI renderer selected)
@@ -233,7 +283,7 @@ libva-wayland {
PKGCONFIG += libva-wayland
DEFINES += HAVE_LIBVA_WAYLAND
}
libva-wayland {
libva-drm {
message(VAAPI DRM support enabled)
PKGCONFIG += libva-drm
@@ -252,6 +302,18 @@ mmal {
DEFINES += HAVE_MMAL
SOURCES += streaming/video/ffmpeg-renderers/mmal.cpp
HEADERS += streaming/video/ffmpeg-renderers/mmal.h
# We suppress EGL usage when MMAL is available because MMAL has
# significantly better performance than EGL on the Pi. Setting
# this option allows EGL usage even if built with MMAL support.
#
# It is highly recommended to also build with 'gpuslow' to avoid
# EGL being preferred if direct DRM rendering is available.
allow-egl-with-mmal {
message(Allowing EGL usage with MMAL enabled)
DEFINES += ALLOW_EGL_WITH_MMAL
}
}
libdrm {
message(DRM renderer selected)
@@ -261,9 +323,12 @@ libdrm {
HEADERS += streaming/video/ffmpeg-renderers/drm.h
linux {
message(Master hooks enabled)
SOURCES += masterhook.c
LIBS += -ldl
!disable-masterhooks {
message(Master hooks enabled)
DEFINES += HAVE_DRM_MASTER_HOOKS
SOURCES += masterhook.c masterhook_internal.c
LIBS += -ldl -pthread
}
}
}
cuda {
@@ -272,6 +337,23 @@ cuda {
DEFINES += HAVE_CUDA
SOURCES += streaming/video/ffmpeg-renderers/cuda.cpp
HEADERS += streaming/video/ffmpeg-renderers/cuda.h
# ffnvcodec uses libdl in cuda_load_functions()/cuda_free_functions()
LIBS += -ldl
}
libplacebo {
message(Vulkan support enabled via libplacebo)
DEFINES += HAVE_LIBPLACEBO_VULKAN
SOURCES += \
streaming/video/ffmpeg-renderers/plvk.cpp \
streaming/video/ffmpeg-renderers/plvk_c.c
HEADERS += \
streaming/video/ffmpeg-renderers/plvk.h
macx {
SOURCES += streaming/video/ffmpeg-renderers/plvk_objc.mm
}
}
config_EGL {
message(EGL renderer selected)
@@ -280,12 +362,22 @@ config_EGL {
DEFINES += HAVE_EGL
SOURCES += \
streaming/video/ffmpeg-renderers/eglvid.cpp \
streaming/video/ffmpeg-renderers/egl_extensions.cpp
HEADERS += streaming/video/ffmpeg-renderers/eglvid.h
streaming/video/ffmpeg-renderers/egl_extensions.cpp \
streaming/video/ffmpeg-renderers/eglimagefactory.cpp
HEADERS += \
streaming/video/ffmpeg-renderers/eglvid.h \
streaming/video/ffmpeg-renderers/eglimagefactory.h
}
config_SL {
message(Steam Link build configuration selected)
!disable-prebuilts {
# Link against our NEON-optimized libopus build
LIBS += -L$$PWD/../libs/steamlink/lib
INCLUDEPATH += $$PWD/../libs/steamlink/include
LIBS += -lopus -larmasm -lNE10
}
DEFINES += EMBEDDED_BUILD STEAM_LINK HAVE_SLVIDEO HAVE_SLAUDIO
LIBS += -lSLVideo -lSLAudio
@@ -316,18 +408,13 @@ macx {
message(VideoToolbox renderer selected)
SOURCES += \
streaming/video/ffmpeg-renderers/vt.mm
streaming/video/ffmpeg-renderers/vt_base.mm \
streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm \
streaming/video/ffmpeg-renderers/vt_metal.mm
HEADERS += \
streaming/video/ffmpeg-renderers/vt.h
}
soundio {
message(libsoundio audio renderer selected)
DEFINES += HAVE_SOUNDIO SOUNDIO_STATIC_LIBRARY
SOURCES += streaming/audio/renderers/soundioaudiorenderer.cpp
HEADERS += streaming/audio/renderers/soundioaudiorenderer.h
}
discord-rpc {
message(Discord integration enabled)
@@ -339,13 +426,35 @@ embedded {
DEFINES += EMBEDDED_BUILD
}
glslow {
message(GL slow build)
DEFINES += GL_IS_SLOW
}
vkslow {
message(Vulkan slow build)
DEFINES += VULKAN_IS_SLOW
}
gpuslow {
message(GPU slow build)
DEFINES += GL_IS_SLOW VULKAN_IS_SLOW
}
wayland {
message(Wayland extensions enabled)
DEFINES += HAS_WAYLAND
SOURCES += streaming/video/ffmpeg-renderers/pacer/waylandvsyncsource.cpp
HEADERS += streaming/video/ffmpeg-renderers/pacer/waylandvsyncsource.h
}
RESOURCES += \
resources.qrc \
qml.qrc
TRANSLATIONS += \
languages/qml_zh_cn.ts \
languages/qml_zh_CN.ts \
languages/qml_de.ts \
languages/qml_fr.ts \
languages/qml_nb_NO.ts \
@@ -360,12 +469,21 @@ TRANSLATIONS += \
languages/qml_sv.ts \
languages/qml_tr.ts \
languages/qml_uk.ts \
languages/qml_zh_Hant.ts \
languages/qml_zh_TW.ts \
languages/qml_el.ts \
languages/qml_hi.ts \
languages/qml_it.ts \
languages/qml_pt.ts \
languages/qml_pt_BR.ts
languages/qml_pt_BR.ts \
languages/qml_pl.ts \
languages/qml_cs.ts \
languages/qml_he.ts \
languages/qml_ckb.ts \
languages/qml_lt.ts \
languages/qml_et.ts \
languages/qml_bg.ts \
languages/qml_eo.ts \
languages/qml_ta.ts
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
@@ -387,15 +505,6 @@ else:unix: LIBS += -L$$OUT_PWD/../qmdnsengine/ -lqmdnsengine
INCLUDEPATH += $$PWD/../qmdnsengine/qmdnsengine/src/include $$PWD/../qmdnsengine
DEPENDPATH += $$PWD/../qmdnsengine/qmdnsengine/src/include $$PWD/../qmdnsengine
soundio {
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../soundio/release/ -lsoundio
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../soundio/debug/ -lsoundio
else:unix: LIBS += -L$$OUT_PWD/../soundio/ -lsoundio
INCLUDEPATH += $$PWD/../soundio/libsoundio
DEPENDPATH += $$PWD/../soundio/libsoundio
}
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../h264bitstream/release/ -lh264bitstream
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../h264bitstream/debug/ -lh264bitstream
else:unix: LIBS += -L$$OUT_PWD/../h264bitstream/ -lh264bitstream
@@ -454,15 +563,19 @@ macx {
APP_BUNDLE_RESOURCES.files = moonlight.icns
APP_BUNDLE_RESOURCES.path = Contents/Resources
APP_BUNDLE_FRAMEWORKS.files = $$files(../libs/mac/Frameworks/*.framework, true) $$files(../libs/mac/lib/*.dylib, true)
APP_BUNDLE_FRAMEWORKS.path = Contents/Frameworks
APP_BUNDLE_PLIST.files = $$OUT_PWD/Info.plist
APP_BUNDLE_PLIST.path = Contents
QMAKE_BUNDLE_DATA += APP_BUNDLE_RESOURCES APP_BUNDLE_FRAMEWORKS APP_BUNDLE_PLIST
QMAKE_BUNDLE_DATA += APP_BUNDLE_RESOURCES APP_BUNDLE_PLIST
QMAKE_RPATHDIR += @executable_path/../Frameworks
!disable-prebuilts {
APP_BUNDLE_FRAMEWORKS.files = $$files(../libs/mac/Frameworks/*.framework, true) $$files(../libs/mac/lib/*.dylib, true)
APP_BUNDLE_FRAMEWORKS.path = Contents/Frameworks
QMAKE_BUNDLE_DATA += APP_BUNDLE_FRAMEWORKS
QMAKE_RPATHDIR += @executable_path/../Frameworks
}
}
VERSION = "$$cat(version.txt)"
+21 -10
View File
@@ -6,16 +6,17 @@
#include <QJsonObject>
AutoUpdateChecker::AutoUpdateChecker(QObject *parent) :
QObject(parent),
m_Nam(this)
QObject(parent)
{
m_Nam = new QNetworkAccessManager(this);
// Never communicate over HTTP
m_Nam.setStrictTransportSecurityEnabled(true);
m_Nam->setStrictTransportSecurityEnabled(true);
// Allow HTTP redirects
m_Nam.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
m_Nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
connect(&m_Nam, &QNetworkAccessManager::finished,
connect(m_Nam, &QNetworkAccessManager::finished,
this, &AutoUpdateChecker::handleUpdateCheckRequestFinished);
QString currentVersion(VERSION_STR);
@@ -28,12 +29,17 @@ AutoUpdateChecker::AutoUpdateChecker(QObject *parent) :
void AutoUpdateChecker::start()
{
if (!m_Nam) {
Q_ASSERT(m_Nam);
return;
}
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) || defined(STEAM_LINK) || defined(APP_IMAGE) // Only run update checker on platforms without auto-update
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1) && !defined(QT_NO_BEARERMANAGEMENT)
// HACK: Set network accessibility to work around QTBUG-80947 (introduced in Qt 5.14.0 and fixed in Qt 5.15.1)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
m_Nam.setNetworkAccessible(QNetworkAccessManager::Accessible);
m_Nam->setNetworkAccessible(QNetworkAccessManager::Accessible);
QT_WARNING_POP
#endif
@@ -45,14 +51,14 @@ void AutoUpdateChecker::start()
#else
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
#endif
m_Nam.get(request);
m_Nam->get(request);
#endif
}
void AutoUpdateChecker::parseStringToVersionQuad(QString& string, QVector<int>& version)
{
QStringList list = string.split('.');
for (const QString& component : list) {
for (const QString& component : std::as_const(list)) {
version.append(component.toInt());
}
}
@@ -102,6 +108,11 @@ void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
{
Q_ASSERT(reply->isFinished());
// Delete the QNetworkAccessManager to free resources and
// prevent the bearer plugin from polling in the background.
m_Nam->deleteLater();
m_Nam = nullptr;
if (reply->error() == QNetworkReply::NoError) {
QTextStream stream(reply);
@@ -128,7 +139,7 @@ void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
return;
}
for (QJsonValueRef updateEntry : array) {
for (const auto& updateEntry : std::as_const(array)) {
if (updateEntry.isObject()) {
QJsonObject updateObj = updateEntry.toObject();
if (!updateObj.contains("platform") ||
@@ -201,7 +212,7 @@ void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
<< QSysInfo::buildCpuArchitecture() << getPlatform() << QSysInfo::kernelVersion();
}
else {
qWarning() << "Update checking failed with error: " << reply->error();
qWarning() << "Update checking failed with error:" << reply->error();
reply->deleteLater();
}
}
+1 -1
View File
@@ -25,5 +25,5 @@ private:
QString getPlatform();
QVector<int> m_CurrentVersionQuad;
QNetworkAccessManager m_Nam;
QNetworkAccessManager* m_Nam;
};
+257 -70
View File
@@ -1,7 +1,7 @@
#include "computermanager.h"
#include "boxartmanager.h"
#include "nvhttp.h"
#include "settings/streamingpreferences.h"
#include "nvpairingmanager.h"
#include <Limelight.h>
#include <QtEndian>
@@ -9,8 +9,10 @@
#include <QThread>
#include <QThreadPool>
#include <QCoreApplication>
#include <QRandomGenerator>
#define SER_HOSTS "hosts"
#define SER_HOSTS_BACKUP "hostsbackup"
class PcMonitorThread : public QThread
{
@@ -27,9 +29,9 @@ public:
}
private:
bool tryPollComputer(NvAddress address, bool& changed)
bool tryPollComputer(QNetworkAccessManager* nam, NvAddress address, bool& changed)
{
NvHTTP http(address, 0, m_Computer->serverCert);
NvHTTP http(address, 0, m_Computer->serverCert, !m_Computer->isNvidiaServerSoftware, nam);
QString serverInfo;
try {
@@ -42,7 +44,7 @@ private:
// Ensure the machine that responded is the one we intended to contact
if (m_Computer->uuid != newState.uuid) {
qInfo() << "Found unexpected PC " << newState.name << " looking for " << m_Computer->name;
qInfo() << "Found unexpected PC" << newState.name << "looking for" << m_Computer->name;
return false;
}
@@ -50,9 +52,9 @@ private:
return true;
}
bool updateAppList(bool& changed)
bool updateAppList(QNetworkAccessManager* nam, bool& changed)
{
NvHTTP http(m_Computer);
NvHTTP http(m_Computer, nam);
QVector<NvApp> appList;
@@ -72,6 +74,21 @@ private:
void run() override
{
// Reduce the power and performance impact of our
// computer status polling while it's running.
setPriority(QThread::LowPriority);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
setServiceLevel(QThread::QualityOfService::Eco);
#endif
// Share the QNetworkAccessManager to conserve resources when polling.
// Each instance creates a worker thread, so sharing them ensures that
// we are not spamming a new thread for every single polling attempt.
//
// Since QThread inherit the priority of the current thread, this also
// ensures that the NAM's worker thread will inherit our lower priority.
QNetworkAccessManager nam;
// Always fetch the applist the first time
int pollsSinceLastAppListFetch = POLLS_PER_APPLIST_FETCH;
while (!isInterruptionRequested()) {
@@ -84,7 +101,7 @@ private:
return;
}
if (tryPollComputer(address, stateChanged)) {
if (tryPollComputer(&nam, address, stateChanged)) {
if (!wasOnline) {
qInfo() << m_Computer->name << "is now online at" << m_Computer->activeAddress.toString();
}
@@ -115,7 +132,7 @@ private:
stateChanged = false;
}
if (updateAppList(stateChanged)) {
if (updateAppList(&nam, stateChanged)) {
pollsSinceLastAppListFetch = 0;
}
}
@@ -141,29 +158,43 @@ private:
NvComputer* m_Computer;
};
ComputerManager::ComputerManager(QObject *parent)
: QObject(parent),
ComputerManager::ComputerManager(StreamingPreferences* prefs)
: m_Prefs(prefs),
m_PollingRef(0),
m_MdnsBrowser(nullptr),
m_CompatFetcher(nullptr)
m_CompatFetcher(nullptr),
m_NeedsDelayedFlush(false)
{
QSettings settings;
// If there's a hosts backup copy, we must have failed to commit
// a previous update before exiting. Restore the backup now.
int hosts = settings.beginReadArray(SER_HOSTS_BACKUP);
if (hosts == 0) {
// If there's no host backup, read from the primary location.
settings.endArray();
hosts = settings.beginReadArray(SER_HOSTS);
}
// Inflate our hosts from QSettings
int hosts = settings.beginReadArray(SER_HOSTS);
for (int i = 0; i < hosts; i++) {
settings.setArrayIndex(i);
NvComputer* computer = new NvComputer(settings);
m_KnownHosts[computer->uuid] = computer;
m_LastSerializedHosts[computer->uuid] = *computer;
}
settings.endArray();
// Fetch latest compatibility data asynchronously
m_CompatFetcher.start();
// Start the delayed flush thread to handle saveHosts() calls
m_DelayedFlushThread = new DelayedFlushThread(this);
m_DelayedFlushThread->start();
// To quit in a timely manner, we must block additional requests
// after we receive the aboutToQuit() signal. This is neccessary
// because NvHTTP uses aboutToQuit() to abort requests in progres
// after we receive the aboutToQuit() signal. This is necessary
// because NvHTTP uses aboutToQuit() to abort requests in progress
// while quitting, however this is a one time signal - additional
// requests would not be aborted and block termination.
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &ComputerManager::handleAboutToQuit);
@@ -171,6 +202,21 @@ ComputerManager::ComputerManager(QObject *parent)
ComputerManager::~ComputerManager()
{
// Stop the delayed flush thread before acquiring the lock in write mode
// to avoid deadlocking with a flush that needs the lock in read mode.
{
// Wake the delayed flush thread
m_DelayedFlushThread->requestInterruption();
m_DelayedFlushCondition.wakeOne();
// Wait for it to terminate (and finish any pending flush)
m_DelayedFlushThread->wait();
delete m_DelayedFlushThread;
// Delayed flushes should have completed by now
Q_ASSERT(!m_NeedsDelayedFlush);
}
QWriteLocker lock(&m_Lock);
// Delete machines that haven't been resolved yet
@@ -185,34 +231,95 @@ ComputerManager::~ComputerManager()
m_MdnsBrowser = nullptr;
// Interrupt polling
for (ComputerPollingEntry* entry : m_PollEntries) {
for (ComputerPollingEntry* entry : std::as_const(m_PollEntries)) {
entry->interrupt();
}
// Delete all polling entries (and associated threads)
for (ComputerPollingEntry* entry : m_PollEntries) {
for (ComputerPollingEntry* entry : std::as_const(m_PollEntries)) {
delete entry;
}
// Destroy all NvComputer objects now that polling is halted
for (NvComputer* computer : m_KnownHosts) {
for (NvComputer* computer : std::as_const(m_KnownHosts)) {
delete computer;
}
}
void DelayedFlushThread::run() {
for (;;) {
// Wait for a delayed flush request or an interruption
{
QMutexLocker locker(&m_ComputerManager->m_DelayedFlushMutex);
while (!QThread::currentThread()->isInterruptionRequested() && !m_ComputerManager->m_NeedsDelayedFlush) {
m_ComputerManager->m_DelayedFlushCondition.wait(&m_ComputerManager->m_DelayedFlushMutex);
}
// Bail without flushing if we woke up for an interruption alone.
// If we have both an interruption and a flush request, do the flush.
if (!m_ComputerManager->m_NeedsDelayedFlush) {
Q_ASSERT(QThread::currentThread()->isInterruptionRequested());
break;
}
// Reset the delayed flush flag to ensure any racing saveHosts() call will set it again
m_ComputerManager->m_NeedsDelayedFlush = false;
// Update the last serialized hosts map under the delayed flush mutex
m_ComputerManager->m_LastSerializedHosts.clear();
for (const NvComputer* computer : std::as_const(m_ComputerManager->m_KnownHosts)) {
// Copy the current state of the NvComputer to allow us to check later if we need
// to serialize it again when attribute updates occur.
QReadLocker computerLock(&computer->lock);
m_ComputerManager->m_LastSerializedHosts[computer->uuid] = *computer;
}
}
// Perform the flush
{
QSettings settings;
// First, write to the backup location
settings.beginWriteArray(SER_HOSTS_BACKUP);
{
QReadLocker lock(&m_ComputerManager->m_Lock);
int i = 0;
for (const NvComputer* computer : std::as_const(m_ComputerManager->m_KnownHosts)) {
settings.setArrayIndex(i++);
computer->serialize(settings, false);
}
}
settings.endArray();
// Next, write to the primary location
settings.remove(SER_HOSTS);
settings.beginWriteArray(SER_HOSTS);
{
QReadLocker lock(&m_ComputerManager->m_Lock);
int i = 0;
for (const NvComputer* computer : std::as_const(m_ComputerManager->m_KnownHosts)) {
settings.setArrayIndex(i++);
computer->serialize(settings, true);
}
}
settings.endArray();
// Finally, delete the backup copy
settings.remove(SER_HOSTS_BACKUP);
}
}
}
void ComputerManager::saveHosts()
{
QSettings settings;
QReadLocker lock(&m_Lock);
Q_ASSERT(m_DelayedFlushThread != nullptr && m_DelayedFlushThread->isRunning());
settings.remove(SER_HOSTS);
settings.beginWriteArray(SER_HOSTS);
int i = 0;
for (const NvComputer* computer : m_KnownHosts) {
settings.setArrayIndex(i++);
computer->serialize(settings);
}
settings.endArray();
// Punt to a worker thread because QSettings on macOS can take ages (> 500 ms)
// to persist our host list to disk (especially when a host has a bunch of apps).
QMutexLocker locker(&m_DelayedFlushMutex);
m_NeedsDelayedFlush = true;
m_DelayedFlushCondition.wakeOne();
}
QHostAddress ComputerManager::getBestGlobalAddressV6(QVector<QHostAddress> &addresses)
@@ -259,16 +366,15 @@ void ComputerManager::startPolling()
return;
}
StreamingPreferences prefs;
if (prefs.enableMdns) {
if (m_Prefs->enableMdns) {
// Start an MDNS query for GameStream hosts
m_MdnsBrowser = new QMdnsEngine::Browser(&m_MdnsServer, "_nvstream._tcp.local.", &m_MdnsCache);
m_MdnsServer.reset(new QMdnsEngine::Server());
m_MdnsBrowser = new QMdnsEngine::Browser(m_MdnsServer.data(), "_nvstream._tcp.local.");
connect(m_MdnsBrowser, &QMdnsEngine::Browser::serviceAdded,
this, [this](const QMdnsEngine::Service& service) {
qInfo() << "Discovered mDNS host:" << service.hostname();
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(&m_MdnsServer, service);
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(m_MdnsServer, service);
connect(pendingComputer, &MdnsPendingComputer::resolvedHost,
this, &ComputerManager::handleMdnsServiceResolved);
m_PendingResolution.append(pendingComputer);
@@ -318,13 +424,15 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
bool added = false;
// Add the host using the IPv4 address
for (const QHostAddress& address : addresses) {
for (const QHostAddress& address : std::as_const(addresses)) {
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
// NB: We don't just call addNewHost() here with v6Global because the IPv6
// address may not be reachable (if the user hasn't installed the IPv6 helper yet
// or if this host lacks outbound IPv6 capability). We want to add IPv6 even if
// it's not currently reachable.
addNewHost(NvAddress(address, computer->port()), true, NvAddress(v6Global, computer->port()));
addNewHost(NvAddress(address, computer->port()),
true, computer->hostname(),
NvAddress(v6Global, computer->port()));
added = true;
break;
}
@@ -332,13 +440,15 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
if (!added) {
// If we get here, there wasn't an IPv4 address so we'll do it v6-only
for (const QHostAddress& address : addresses) {
for (const QHostAddress& address : std::as_const(addresses)) {
if (address.protocol() == QAbstractSocket::IPv6Protocol) {
// Use a link-local or site-local address for the "local address"
if (address.isInSubnet(QHostAddress("fe80::"), 10) ||
address.isInSubnet(QHostAddress("fec0::"), 10) ||
address.isInSubnet(QHostAddress("fc00::"), 7)) {
addNewHost(NvAddress(address, computer->port()), true, NvAddress(v6Global, computer->port()));
addNewHost(NvAddress(address, computer->port()),
true, computer->hostname(),
NvAddress(v6Global, computer->port()));
break;
}
}
@@ -349,6 +459,19 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
computer->deleteLater();
}
void ComputerManager::saveHost(NvComputer *computer)
{
// If no serializable properties changed, don't bother saving hosts
QMutexLocker lock(&m_DelayedFlushMutex);
QReadLocker computerLock(&computer->lock);
if (!m_LastSerializedHosts.value(computer->uuid).isEqualSerialized(*computer)) {
// Queue a request for a delayed flush to QSettings outside of the lock
computerLock.unlock();
lock.unlock();
saveHosts();
}
}
void ComputerManager::handleComputerStateChanged(NvComputer* computer)
{
emit computerStateChanged(computer);
@@ -358,15 +481,20 @@ void ComputerManager::handleComputerStateChanged(NvComputer* computer)
emit quitAppCompleted(QVariant());
}
// Save updated hosts to QSettings
saveHosts();
// Save updates to this host
saveHost(computer);
}
QVector<NvComputer*> ComputerManager::getComputers()
{
QReadLocker lock(&m_Lock);
return QVector<NvComputer*>::fromList(m_KnownHosts.values());
// Return a sorted host list
auto hosts = QVector<NvComputer*>::fromList(m_KnownHosts.values());
std::stable_sort(hosts.begin(), hosts.end(), [](const NvComputer* host1, const NvComputer* host2) {
return host1->name.toLower() < host2->name.toLower();
});
return hosts;
}
class DeferredHostDeletionTask : public QRunnable
@@ -390,7 +518,7 @@ public:
m_ComputerManager->m_KnownHosts.remove(m_Computer->uuid);
}
// Persist the new host list
// Persist the new host list with this computer deleted
m_ComputerManager->saveHosts();
// Delete the polling entry first. This will stop all polling threads too.
@@ -431,20 +559,17 @@ void ComputerManager::renameHost(NvComputer* computer, QString name)
void ComputerManager::clientSideAttributeUpdated(NvComputer* computer)
{
// Persist the change
saveHosts();
// Notify the UI of the state change
handleComputerStateChanged(computer);
}
void ComputerManager::handleAboutToQuit()
{
QWriteLocker lock(&m_Lock);
QReadLocker lock(&m_Lock);
// Interrupt polling threads immediately, so they
// avoid making additional requests while quitting
for (ComputerPollingEntry* entry : m_PollEntries) {
for (ComputerPollingEntry* entry : std::as_const(m_PollEntries)) {
entry->interrupt();
}
}
@@ -455,7 +580,8 @@ class PendingPairingTask : public QObject, public QRunnable
public:
PendingPairingTask(ComputerManager* computerManager, NvComputer* computer, QString pin)
: m_Computer(computer),
: m_ComputerManager(computerManager),
m_Computer(computer),
m_Pin(pin)
{
connect(this, &PendingPairingTask::pairingCompleted,
@@ -475,25 +601,34 @@ private:
switch (result)
{
case NvPairingManager::PairState::PIN_WRONG:
emit pairingCompleted(m_Computer, "The PIN from the PC didn't match. Please try again.");
emit pairingCompleted(m_Computer, tr("The PIN from the PC didn't match. Please try again."));
break;
case NvPairingManager::PairState::FAILED:
emit pairingCompleted(m_Computer, "Pairing failed. Please try again.");
if (m_Computer->currentGameId != 0) {
emit pairingCompleted(m_Computer, tr("You cannot pair while a previous session is still running on the host PC. Quit any running games or reboot the host PC, then try pairing again."));
}
else {
emit pairingCompleted(m_Computer, tr("Pairing failed. Please try again."));
}
break;
case NvPairingManager::PairState::ALREADY_IN_PROGRESS:
emit pairingCompleted(m_Computer, "Another pairing attempt is already in progress.");
emit pairingCompleted(m_Computer, tr("Another pairing attempt is already in progress."));
break;
case NvPairingManager::PairState::PAIRED:
// Persist the newly pinned server certificate for this host
m_ComputerManager->saveHost(m_Computer);
emit pairingCompleted(m_Computer, nullptr);
break;
}
} catch (const GfeHttpResponseException& e) {
emit pairingCompleted(m_Computer, "GeForce Experience returned error: " + e.toQString());
emit pairingCompleted(m_Computer, tr("GeForce Experience returned error: %1").arg(e.toQString()));
} catch (const QtNetworkReplyException& e) {
emit pairingCompleted(m_Computer, e.toQString());
}
}
ComputerManager* m_ComputerManager;
NvComputer* m_Computer;
QString m_Pin;
};
@@ -580,23 +715,28 @@ void ComputerManager::stopPollingAsync()
m_PendingResolution.removeFirst();
}
// Delete the browser to stop discovery
// Delete the browser and server to stop discovery and refresh polling
delete m_MdnsBrowser;
m_MdnsBrowser = nullptr;
m_MdnsServer.reset();
// Interrupt all threads, but don't wait for them to terminate
for (ComputerPollingEntry* entry : m_PollEntries) {
for (ComputerPollingEntry* entry : std::as_const(m_PollEntries)) {
entry->interrupt();
}
}
void ComputerManager::addNewHostManually(QString address)
{
QUrl url = QUrl::fromUserInput(address);
if (url.isValid() && !url.host().isEmpty()) {
QUrl url = QUrl::fromUserInput("moonlight://" + address);
if (url.isValid() && !url.host().isEmpty() && url.scheme() == "moonlight") {
// If there wasn't a port specified, use the default
addNewHost(NvAddress(url.host(), url.port(DEFAULT_HTTP_PORT)), false);
}
else if (QHostAddress(address).protocol() == QAbstractSocket::IPv6Protocol) {
// The user specified an IPv6 literal without URL escaping, so use the default port
addNewHost(NvAddress(address, DEFAULT_HTTP_PORT), false);
}
else {
emit computerAddCompleted(false, false);
}
@@ -607,16 +747,20 @@ class PendingAddTask : public QObject, public QRunnable
Q_OBJECT
public:
PendingAddTask(ComputerManager* computerManager, NvAddress address, NvAddress mdnsIpv6Address, bool mdns)
PendingAddTask(ComputerManager* computerManager, QString name, NvAddress address, NvAddress mdnsIpv6Address, bool mdns)
: m_ComputerManager(computerManager),
m_Name(name),
m_Address(address),
m_MdnsIpv6Address(mdnsIpv6Address),
m_Mdns(mdns)
m_Mdns(mdns),
m_AboutToQuit(false)
{
connect(this, &PendingAddTask::computerAddCompleted,
computerManager, &ComputerManager::computerAddCompleted);
connect(this, &PendingAddTask::computerStateChanged,
computerManager, &ComputerManager::handleComputerStateChanged);
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
this, &PendingAddTask::handleAboutToQuit);
}
signals:
@@ -625,9 +769,20 @@ signals:
void computerStateChanged(NvComputer* computer);
private:
void handleAboutToQuit()
{
m_AboutToQuit = true;
}
QString fetchServerInfo(NvHTTP& http)
{
QString serverInfo;
// Do nothing if we're quitting
if (m_AboutToQuit) {
return QString();
}
try {
// There's a race condition between GameStream servers reporting presence over
// mDNS and the HTTPS server being ready to respond to our queries. To work
@@ -650,10 +805,9 @@ private:
return serverInfo;
} catch (...) {
if (!m_Mdns) {
StreamingPreferences prefs;
int portTestResult;
unsigned int portTestResult;
if (prefs.detectNetworkBlocking) {
if (m_ComputerManager->m_Prefs->detectNetworkBlocking) {
// We failed to connect to the specified PC. Let's test to make sure this network
// isn't blocking Moonlight, so we can tell the user about it.
portTestResult = LiTestClientConnectivity("qt.conntest.moonlight-stream.org", 443,
@@ -671,9 +825,21 @@ private:
void run()
{
NvHTTP http(m_Address, 0, QSslCertificate());
// Use the placeholder UID for the initial poll, then we'll switch to the real one if it's not GFE
NvHTTP http(m_Address, 0, QSslCertificate(), false);
qInfo() << "Processing new PC at" << m_Address.toString() << "from" << (m_Mdns ? "mDNS" : "user") << "with IPv6 address" << m_MdnsIpv6Address.toString();
if (m_Mdns) {
if (m_MdnsIpv6Address.isNull()) {
qInfo() << "Processing new PC" << m_Name << "from mDNS with local address" << m_Address.toString();
}
else {
qInfo() << "Processing new PC" << m_Name << "from mDNS with local address" << m_Address.toString()
<< "and IPv6 address" << m_MdnsIpv6Address.toString();
}
}
else {
qInfo() << "Processing new PC at" << m_Address.toString() << "from user";
}
// Perform initial serverinfo fetch over HTTP since we don't know which cert to use
QString serverInfo = fetchServerInfo(http);
@@ -688,6 +854,7 @@ private:
// Create initial newComputer using HTTP serverinfo with no pinned cert
NvComputer* newComputer = new NvComputer(http, serverInfo);
http.setTrueUid(!newComputer->isNvidiaServerSoftware);
// Check if we have a record of this host UUID to pull the pinned cert
NvComputer* existingComputer;
@@ -749,16 +916,31 @@ private:
hostAddress.isInSubnet(QHostAddress("192.168.0.0"), 16);
{
// Check if this PC already exists
QWriteLocker lock(&m_ComputerManager->m_Lock);
// Check if this PC already exists using opportunistic read lock
m_ComputerManager->m_Lock.lockForRead();
NvComputer* existingComputer = m_ComputerManager->m_KnownHosts.value(newComputer->uuid);
// If it doesn't already exist, convert to a write lock in preparation for updating.
//
// NB: ComputerManager's lock protects the host map itself, not the elements inside.
// Those are protected by their individual locks. Since we only mutate the map itself
// when the PC doesn't exist, we need the lock in write-mode for that case only.
if (existingComputer == nullptr) {
m_ComputerManager->m_Lock.unlock();
m_ComputerManager->m_Lock.lockForWrite();
// Since we had to unlock to lock for write, someone could have raced and added
// this PC before us. We have to check again whether it already exists.
existingComputer = m_ComputerManager->m_KnownHosts.value(newComputer->uuid);
}
if (existingComputer != nullptr) {
// Fold it into the existing PC
bool changed = existingComputer->update(*newComputer);
delete newComputer;
// Drop the lock before notifying
lock.unlock();
m_ComputerManager->m_Lock.unlock();
// For non-mDNS clients, let them know it succeeded
if (!m_Mdns) {
@@ -779,17 +961,15 @@ private:
m_ComputerManager->startPollingComputer(newComputer);
// Drop the lock before notifying
lock.unlock();
m_ComputerManager->m_Lock.unlock();
// If this wasn't added via mDNS but it is a RFC 1918 IPv4 address and not a VPN,
// go ahead and do the STUN request now to populate an external address.
if (!m_Mdns && addressIsSiteLocalV4 && !newComputer->isReachableOverVpn()) {
if (!m_Mdns && addressIsSiteLocalV4 && newComputer->getActiveAddressReachability() != NvComputer::RI_VPN) {
quint32 addr;
int err = LiFindExternalAddressIP4("stun.moonlight-stream.org", 3478, &addr);
if (err == 0) {
lock.relock();
newComputer->setRemoteAddress(QHostAddress(qFromBigEndian(addr)));
lock.unlock();
}
else {
qWarning() << "STUN failed to get WAN address:" << err;
@@ -808,17 +988,24 @@ private:
}
ComputerManager* m_ComputerManager;
QString m_Name;
NvAddress m_Address;
NvAddress m_MdnsIpv6Address;
bool m_Mdns;
bool m_AboutToQuit;
};
void ComputerManager::addNewHost(NvAddress address, bool mdns, NvAddress mdnsIpv6Address)
void ComputerManager::addNewHost(NvAddress address, bool mdns, QString name, NvAddress mdnsIpv6Address)
{
// Punt to a worker thread to avoid stalling the
// UI while waiting for serverinfo query to complete
PendingAddTask* addTask = new PendingAddTask(this, address, mdnsIpv6Address, mdns);
PendingAddTask* addTask = new PendingAddTask(this, name, address, mdnsIpv6Address, mdns);
QThreadPool::globalInstance()->start(addTask);
}
QString ComputerManager::generatePinString()
{
return QString::asprintf("%04u", QRandomGenerator::system()->bounded(10000));
}
#include "computermanager.moc"
+73 -15
View File
@@ -1,7 +1,7 @@
#pragma once
#include "nvcomputer.h"
#include "nvpairingmanager.h"
#include "settings/streamingpreferences.h"
#include "settings/compatfetcher.h"
#include <qmdnsengine/server.h>
@@ -15,17 +15,38 @@
#include <QSettings>
#include <QRunnable>
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>
class ComputerManager;
class DelayedFlushThread : public QThread
{
Q_OBJECT
public:
DelayedFlushThread(ComputerManager* cm)
: m_ComputerManager(cm)
{
setObjectName("CM Delayed Flush Thread");
}
void run();
private:
ComputerManager* m_ComputerManager;
};
class MdnsPendingComputer : public QObject
{
Q_OBJECT
public:
explicit MdnsPendingComputer(QMdnsEngine::Server* server,
explicit MdnsPendingComputer(const QSharedPointer<QMdnsEngine::Server> server,
const QMdnsEngine::Service& service)
: m_Hostname(service.hostname()),
m_Port(service.port()),
m_Server(server),
m_ServerWeak(server),
m_Resolver(nullptr)
{
// Start resolving
@@ -51,9 +72,15 @@ private slots:
void handleResolvedTimeout()
{
if (m_Addresses.isEmpty()) {
// Try again
qInfo() << "Resolving" << hostname() << "timed out. Retrying...";
resolve();
if (m_Retries-- > 0) {
// Try again
qInfo() << "Resolving" << hostname() << "timed out. Retrying...";
resolve();
}
else {
qWarning() << "Giving up on resolving" << hostname() << "after repeated failures";
cleanup();
}
}
else {
Q_ASSERT(!m_Addresses.isEmpty());
@@ -63,7 +90,6 @@ private slots:
void handleResolvedAddress(const QHostAddress& address)
{
qInfo() << "Resolved" << hostname() << "to" << address;
m_Addresses.push_back(address);
}
@@ -71,10 +97,29 @@ signals:
void resolvedHost(MdnsPendingComputer*,QVector<QHostAddress>&);
private:
void cleanup()
{
// Delete our resolver, so we're guaranteed that nothing is referencing m_Server.
delete m_Resolver;
m_Resolver = nullptr;
// Now delete our strong reference that we held on behalf of m_Resolver.
// The server may be destroyed after we make this call.
m_Server.reset();
}
void resolve()
{
delete m_Resolver;
m_Resolver = new QMdnsEngine::Resolver(m_Server, m_Hostname);
// Clean up any existing resolver object and server references
cleanup();
// Re-acquire a strong reference if the server still exists.
m_Server = m_ServerWeak.toStrongRef();
if (!m_Server) {
return;
}
m_Resolver = new QMdnsEngine::Resolver(m_Server.data(), m_Hostname);
connect(m_Resolver, &QMdnsEngine::Resolver::resolved,
this, &MdnsPendingComputer::handleResolvedAddress);
QTimer::singleShot(2000, this, &MdnsPendingComputer::handleResolvedTimeout);
@@ -82,9 +127,11 @@ private:
QByteArray m_Hostname;
uint16_t m_Port;
QMdnsEngine::Server* m_Server;
QWeakPointer<QMdnsEngine::Server> m_ServerWeak;
QSharedPointer<QMdnsEngine::Server> m_Server;
QMdnsEngine::Resolver* m_Resolver;
QVector<QHostAddress> m_Addresses;
int m_Retries = 10;
};
class ComputerPollingEntry
@@ -103,7 +150,7 @@ public:
// interrupt() should have taken care of this
Q_ASSERT(m_ActiveThread == nullptr);
for (QThread* thread : m_InactiveList) {
for (QThread* thread : std::as_const(m_InactiveList)) {
thread->wait();
delete thread;
}
@@ -166,9 +213,11 @@ class ComputerManager : public QObject
friend class DeferredHostDeletionTask;
friend class PendingAddTask;
friend class PendingPairingTask;
friend class DelayedFlushThread;
public:
explicit ComputerManager(QObject *parent = nullptr);
explicit ComputerManager(StreamingPreferences* prefs);
virtual ~ComputerManager();
@@ -178,7 +227,9 @@ public:
Q_INVOKABLE void addNewHostManually(QString address);
void addNewHost(NvAddress address, bool mdns, NvAddress mdnsIpv6Address = NvAddress());
void addNewHost(NvAddress address, bool mdns, QString name = QString(), NvAddress mdnsIpv6Address = NvAddress());
QString generatePinString();
void pairHost(NvComputer* computer, QString pin);
@@ -212,17 +263,24 @@ private slots:
private:
void saveHosts();
void saveHost(NvComputer* computer);
QHostAddress getBestGlobalAddressV6(QVector<QHostAddress>& addresses);
void startPollingComputer(NvComputer* computer);
StreamingPreferences* m_Prefs;
int m_PollingRef;
QReadWriteLock m_Lock;
QMap<QString, NvComputer*> m_KnownHosts;
QMap<QString, ComputerPollingEntry*> m_PollEntries;
QMdnsEngine::Server m_MdnsServer;
QHash<QString, NvComputer> m_LastSerializedHosts; // Protected by m_DelayedFlushMutex
QSharedPointer<QMdnsEngine::Server> m_MdnsServer;
QMdnsEngine::Browser* m_MdnsBrowser;
QMdnsEngine::Cache m_MdnsCache;
QVector<MdnsPendingComputer*> m_PendingResolution;
CompatFetcher m_CompatFetcher;
DelayedFlushThread* m_DelayedFlushThread;
QMutex m_DelayedFlushMutex; // Lock ordering: Must never be acquired while holding NvComputer lock
QWaitCondition m_DelayedFlushCondition;
bool m_NeedsDelayedFlush;
};
+30 -6
View File
@@ -6,6 +6,12 @@ ComputerSeeker::ComputerSeeker(ComputerManager *manager, QString computerName, Q
: QObject(parent), m_ComputerManager(manager), m_ComputerName(computerName),
m_TimeoutTimer(new QTimer(this))
{
// If we know this computer, send a WOL packet to wake it up in case it is asleep.
NvComputer* matchingComputer = findMatchingComputer();
if (matchingComputer) {
matchingComputer->wake();
}
m_TimeoutTimer->setSingleShot(true);
connect(m_TimeoutTimer, &QTimer::timeout,
this, &ComputerSeeker::onTimeout);
@@ -16,11 +22,16 @@ ComputerSeeker::ComputerSeeker(ComputerManager *manager, QString computerName, Q
void ComputerSeeker::start(int timeout)
{
m_TimeoutTimer->start(timeout);
// Seek desired computer by both connecting to it directly (this may fail
// if m_ComputerName is UUID, or the name that doesn't resolve to an IP
// address) and by polling it using mDNS, hopefully one of these methods
// would find the host
m_ComputerManager->addNewHostManually(m_ComputerName);
// If we don't know this computer by name, address, or UUID, try adding it
// manually and see if we can find it by address, hostname, or mDNS.
//
// NB: We don't do this unconditionally because it will wipe out the user's
// manual address if they pass another reachable hostname/address.
if (!findMatchingComputer()) {
m_ComputerManager->addNewHostManually(m_ComputerName);
}
m_ComputerManager->startPolling();
}
@@ -44,7 +55,8 @@ bool ComputerSeeker::matchComputer(NvComputer *computer) const
return true;
}
for (const NvAddress& addr : computer->uniqueAddresses()) {
const auto uniqueAddresses = computer->uniqueAddresses();
for (const NvAddress& addr : uniqueAddresses) {
if (addr.address().toLower() == value || addr.toString().toLower() == value) {
return true;
}
@@ -53,6 +65,18 @@ bool ComputerSeeker::matchComputer(NvComputer *computer) const
return false;
}
NvComputer* ComputerSeeker::findMatchingComputer() const
{
const auto computers = m_ComputerManager->getComputers();
for (NvComputer* computer : computers) {
if (this->matchComputer(computer)) {
return computer;
}
}
return nullptr;
}
bool ComputerSeeker::isOnline(NvComputer *computer) const
{
return computer->state == NvComputer::CS_ONLINE;
+1
View File
@@ -24,6 +24,7 @@ private slots:
private:
bool matchComputer(NvComputer *computer) const;
NvComputer* findMatchingComputer() const;
bool isOnline(NvComputer *computer) const;
private:
+38 -36
View File
@@ -31,6 +31,10 @@ void IdentityManager::createCredentials(QSettings& settings)
X509* cert = X509_new();
THROW_BAD_ALLOC_IF_NULL(cert);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_PKEY* pk = EVP_RSA_gen(2048);
THROW_BAD_ALLOC_IF_NULL(pk);
#else
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
THROW_BAD_ALLOC_IF_NULL(ctx);
@@ -43,6 +47,7 @@ void IdentityManager::createCredentials(QSettings& settings)
EVP_PKEY_CTX_free(ctx);
THROW_BAD_ALLOC_IF_NULL(pk);
#endif
X509_set_version(cert, 2);
ASN1_INTEGER_set(X509_get_serialNumber(cert), 0);
@@ -50,28 +55,20 @@ void IdentityManager::createCredentials(QSettings& settings)
X509_gmtime_adj(X509_get_notBefore(cert), 0);
X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * 20); // 20 yrs
#else
ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert));
THROW_BAD_ALLOC_IF_NULL(before);
ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert));
THROW_BAD_ALLOC_IF_NULL(after);
X509_gmtime_adj(before, 0);
X509_gmtime_adj(after, 60 * 60 * 24 * 365 * 20); // 20 yrs
X509_set1_notBefore(cert, before);
X509_set1_notAfter(cert, after);
ASN1_STRING_free(before);
ASN1_STRING_free(after);
X509_gmtime_adj(X509_getm_notBefore(cert), 0);
X509_gmtime_adj(X509_getm_notAfter(cert), 60 * 60 * 24 * 365 * 20); // 20 yrs
#endif
X509_set_pubkey(cert, pk);
X509_NAME* name = X509_get_subject_name(cert);
X509_NAME* name = X509_NAME_new();
THROW_BAD_ALLOC_IF_NULL(name);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
reinterpret_cast<unsigned char *>(const_cast<char*>("NVIDIA GameStream Client")),
-1, -1, 0);
X509_set_subject_name(cert, name);
X509_set_issuer_name(cert, name);
X509_NAME_free(name);
X509_sign(cert, pk, EVP_sha256());
@@ -95,6 +92,14 @@ void IdentityManager::createCredentials(QSettings& settings)
BIO_free(biokey);
BIO_free(biocert);
// Check that the new keypair is valid before persisting it
if (getSslCertificate().isNull()) {
qFatal("Newly generated certificate is unreadable");
}
if (getSslKey().isNull()) {
qFatal("Newly generated private key is unreadable");
}
settings.setValue(SER_CERT, m_CachedPemCert);
settings.setValue(SER_KEY, m_CachedPrivateKey);
@@ -123,10 +128,26 @@ IdentityManager::IdentityManager()
// We should have valid credentials now. If not, we're screwed
if (getSslCertificate().isNull()) {
qFatal("Newly generated certificate is unreadable");
qFatal("Certificate is unreadable");
}
if (getSslKey().isNull()) {
qFatal("Newly generated private key is unreadable");
qFatal("Private key is unreadable");
}
// Load the unique ID from settings
m_CachedUniqueId = settings.value(SER_UNIQUEID).toString();
if (!m_CachedUniqueId.isEmpty()) {
qInfo() << "Loaded unique ID from settings:" << m_CachedUniqueId;
}
else {
// Generate a new unique ID in base 16
uint64_t uid;
RAND_bytes(reinterpret_cast<unsigned char*>(&uid), sizeof(uid));
m_CachedUniqueId = QString::number(uid, 16);
qInfo() << "Generated new unique ID:" << m_CachedUniqueId;
settings.setValue(SER_UNIQUEID, m_CachedUniqueId);
}
}
@@ -165,7 +186,7 @@ IdentityManager::getSslKey()
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
m_CachedSslKey = QSslKey(QByteArray::fromRawData(mem->data, (int)mem->length), QSsl::Rsa);
m_CachedSslKey = QSslKey(QByteArray(mem->data, (int)mem->length), QSsl::Rsa);
BIO_free(bio);
EVP_PKEY_free(pk);
@@ -185,25 +206,6 @@ IdentityManager::getSslConfig()
QString
IdentityManager::getUniqueId()
{
if (m_CachedUniqueId.isEmpty()) {
QSettings settings;
// Load the unique ID from settings
m_CachedUniqueId = settings.value(SER_UNIQUEID).toString();
if (!m_CachedUniqueId.isEmpty()) {
qInfo() << "Loaded unique ID from settings:" << m_CachedUniqueId;
}
else {
// Generate a new unique ID in base 16
uint64_t uid;
RAND_bytes(reinterpret_cast<unsigned char*>(&uid), sizeof(uid));
m_CachedUniqueId = QString::number(uid, 16);
qInfo() << "Generated new unique ID:" << m_CachedUniqueId;
settings.setValue(SER_UNIQUEID, m_CachedUniqueId);
}
}
return m_CachedUniqueId;
}
+3 -1
View File
@@ -25,7 +25,9 @@ public:
bool isInitialized()
{
return id != 0 && !name.isEmpty();
// We use isNull() instead of isEmpty() here because we want
// to detect cases where the name is unassigned, not empty.
return id != 0 && !name.isNull();
}
void
+173 -62
View File
@@ -21,6 +21,7 @@
#define SER_APPLIST "apps"
#define SER_SRVCERT "srvcert"
#define SER_CUSTOMNAME "customname"
#define SER_NVIDIASOFTWARE "nvidiasw"
NvComputer::NvComputer(QSettings& settings)
{
@@ -37,6 +38,7 @@ NvComputer::NvComputer(QSettings& settings)
this->manualAddress = NvAddress(settings.value(SER_MANUALADDR).toString(),
settings.value(SER_MANUALPORT, QVariant(DEFAULT_HTTP_PORT)).toUInt());
this->serverCert = QSslCertificate(settings.value(SER_SRVCERT).toByteArray());
this->isNvidiaServerSoftware = settings.value(SER_NVIDIASOFTWARE).toBool();
int appCount = settings.beginReadArray(SER_APPLIST);
this->appList.reserve(appCount);
@@ -65,12 +67,14 @@ NvComputer::NvComputer(QSettings& settings)
void NvComputer::setRemoteAddress(QHostAddress address)
{
QWriteLocker lock(&this->lock);
Q_ASSERT(this->externalPort != 0);
this->remoteAddress = NvAddress(address, this->externalPort);
}
void NvComputer::serialize(QSettings& settings) const
void NvComputer::serialize(QSettings& settings, bool serializeApps) const
{
QReadLocker lock(&this->lock);
@@ -87,19 +91,35 @@ void NvComputer::serialize(QSettings& settings) const
settings.setValue(SER_MANUALADDR, manualAddress.address());
settings.setValue(SER_MANUALPORT, manualAddress.port());
settings.setValue(SER_SRVCERT, serverCert.toPem());
settings.setValue(SER_NVIDIASOFTWARE, isNvidiaServerSoftware);
// Avoid deleting an existing applist if we couldn't get one
if (!appList.isEmpty()) {
if (!appList.isEmpty() && serializeApps) {
settings.remove(SER_APPLIST);
settings.beginWriteArray(SER_APPLIST);
for (int i = 0; i < appList.count(); i++) {
settings.setArrayIndex(i);
appList[i].serialize(settings);
appList.at(i).serialize(settings);
}
settings.endArray();
}
}
bool NvComputer::isEqualSerialized(const NvComputer &that) const
{
return this->name == that.name &&
this->hasCustomName == that.hasCustomName &&
this->uuid == that.uuid &&
this->macAddress == that.macAddress &&
this->localAddress == that.localAddress &&
this->remoteAddress == that.remoteAddress &&
this->ipv6Address == that.ipv6Address &&
this->manualAddress == that.manualAddress &&
this->serverCert == that.serverCert &&
this->isNvidiaServerSoftware == that.isNvidiaServerSoftware &&
this->appList == that.appList;
}
void NvComputer::sortAppList()
{
std::stable_sort(appList.begin(), appList.end(), [](const NvApp& app1, const NvApp& app2) {
@@ -121,7 +141,7 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
QString newMacString = NvHTTP::getXmlString(serverInfo, "mac");
if (newMacString != "00:00:00:00:00:00") {
QStringList macOctets = newMacString.split(':');
for (const QString& macOctet : macOctets) {
for (const QString& macOctet : std::as_const(macOctets)) {
this->macAddress.append((char) macOctet.toInt(nullptr, 16));
}
}
@@ -131,7 +151,8 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
this->serverCodecModeSupport = codecSupport.toInt();
}
else {
this->serverCodecModeSupport = 0;
// Assume H.264 is always supported
this->serverCodecModeSupport = SCM_H264;
}
QString maxLumaPixelsHEVC = NvHTTP::getXmlString(serverInfo, "MaxLumaPixelsHEVC");
@@ -145,8 +166,8 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
this->displayModes = NvHTTP::getDisplayModeList(serverInfo);
std::stable_sort(this->displayModes.begin(), this->displayModes.end(),
[](const NvDisplayMode& mode1, const NvDisplayMode& mode2) {
return mode1.width * mode1.height * mode1.refreshRate <
mode2.width * mode2.height * mode2.refreshRate;
return (uint64_t)mode1.width * mode1.height * mode1.refreshRate <
(uint64_t)mode2.width * mode2.height * mode2.refreshRate;
});
// We can get an IPv4 loopback address if we're using the GS IPv6 Forwarder
@@ -164,7 +185,7 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
// to support dynamic HTTP WAN ports without requiring the user to manually enter the port.
QString remotePortStr = NvHTTP::getXmlString(serverInfo, "ExternalPort");
if (remotePortStr.isEmpty() || (this->externalPort = remotePortStr.toUShort()) == 0) {
this->externalPort = DEFAULT_HTTP_PORT;
this->externalPort = http.httpPort();
}
QString remoteAddress = NvHTTP::getXmlString(serverInfo, "ExternalIP");
@@ -175,6 +196,11 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
this->remoteAddress = NvAddress();
}
// Real Nvidia host software (GeForce Experience and RTX Experience) both use the 'Mjolnir'
// codename in the state field and no version of Sunshine does. We can use this to bypass
// some assumptions about Nvidia hardware that don't apply to Sunshine hosts.
this->isNvidiaServerSoftware = NvHTTP::getXmlString(serverInfo, "state").contains("MJOLNIR");
this->pairState = NvHTTP::getXmlString(serverInfo, "PairStatus") == "1" ?
PS_PAIRED : PS_NOT_PAIRED;
this->currentGameId = NvHTTP::getCurrentGame(serverInfo);
@@ -187,43 +213,57 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
this->isSupportedServerVersion = CompatFetcher::isGfeVersionSupported(this->gfeVersion);
}
bool NvComputer::wake()
bool NvComputer::wake() const
{
if (state == NvComputer::CS_ONLINE) {
qWarning() << name << "is already online";
return true;
QByteArray wolPayload;
{
QReadLocker readLocker(&lock);
if (state == NvComputer::CS_ONLINE) {
qWarning() << name << "is already online";
return true;
}
if (macAddress.isEmpty()) {
qWarning() << name << "has no MAC address stored";
return false;
}
// Create the WoL payload
wolPayload.append(QByteArray::fromHex("FFFFFFFFFFFF"));
for (int i = 0; i < 16; i++) {
wolPayload.append(macAddress);
}
Q_ASSERT(wolPayload.size() == 102);
}
if (macAddress.isEmpty()) {
qWarning() << name << "has no MAC address stored";
return false;
}
const quint16 WOL_PORTS[] = {
// Ports used as-is
const quint16 STATIC_WOL_PORTS[] = {
9, // Standard WOL port (privileged port)
47998, 47999, 48000, 48002, 48010, // Ports opened by GFE
47009, // Port opened by Moonlight Internet Hosting Tool for WoL (non-privileged port)
};
// Create the WoL payload
QByteArray wolPayload;
wolPayload.append(QByteArray::fromHex("FFFFFFFFFFFF"));
for (int i = 0; i < 16; i++) {
wolPayload.append(macAddress);
}
Q_ASSERT(wolPayload.count() == 102);
// Ports offset by the HTTP base port for hosts using alternate ports
const quint16 DYNAMIC_WOL_PORTS[] = {
47998, 47999, 48000, 48002, 48010, // Ports opened by GFE
};
// Add the addresses that we know this host to be
// and broadcast addresses for this link just in
// case the host has timed out in ARP entries.
QVector<QString> addressList;
for (const NvAddress& addr : uniqueAddresses()) {
addressList.append(addr.address());
QMap<QString, quint16> addressMap;
QSet<quint16> basePortSet;
const auto uniqueHostAddresses = uniqueAddresses();
for (const NvAddress& addr : uniqueHostAddresses) {
addressMap.insert(addr.address(), addr.port());
basePortSet.insert(addr.port());
}
addressList.append("255.255.255.255");
addressMap.insert("255.255.255.255", 0);
// Try to broadcast on all available NICs
for (const QNetworkInterface& nic : QNetworkInterface::allInterfaces()) {
const auto allInterfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface& nic : allInterfaces) {
// Ensure the interface is up and skip the loopback adapter
if ((nic.flags() & QNetworkInterface::IsUp) == 0 ||
(nic.flags() & QNetworkInterface::IsLoopBack) != 0) {
@@ -231,7 +271,8 @@ bool NvComputer::wake()
}
QHostAddress allNodesMulticast("FF02::1");
for (const QNetworkAddressEntry& addr : nic.addressEntries()) {
const auto allInterfaceAddresses = nic.addressEntries();
for (const QNetworkAddressEntry& addr : allInterfaceAddresses) {
// Store the scope ID for this NIC if IPv6 is enabled
if (!addr.ip().scopeId().isEmpty()) {
allNodesMulticast.setScopeId(addr.ip().scopeId());
@@ -239,31 +280,42 @@ bool NvComputer::wake()
// Skip IPv6 which doesn't support broadcast
if (!addr.broadcast().isNull()) {
addressList.append(addr.broadcast().toString());
addressMap.insert(addr.broadcast().toString(), 0);
}
}
if (!allNodesMulticast.scopeId().isEmpty()) {
addressList.append(allNodesMulticast.toString());
addressMap.insert(allNodesMulticast.toString(), 0);
}
}
// Try all unique address strings or host names
bool success = false;
for (QString& addressString : addressList) {
QHostInfo hostInfo = QHostInfo::fromName(addressString);
for (auto i = addressMap.constBegin(); i != addressMap.constEnd(); i++) {
QHostAddress literalAddress;
QList<QHostAddress> addressList;
if (hostInfo.error() != QHostInfo::NoError) {
qWarning() << "Error resolving" << addressString << ":" << hostInfo.errorString();
continue;
// If this is an IPv4/IPv6 literal, don't use QHostInfo::fromName() because that will
// try to perform a reverse DNS lookup that leads to delays sending WoL packets.
if (literalAddress.setAddress(i.key())) {
addressList.append(literalAddress);
}
else {
QHostInfo hostInfo = QHostInfo::fromName(i.key());
if (hostInfo.error() != QHostInfo::NoError) {
qWarning() << "Error resolving" << i.key() << ":" << hostInfo.errorString();
continue;
}
addressList.append(hostInfo.addresses());
}
// Try all IP addresses that this string resolves to
for (QHostAddress& address : hostInfo.addresses()) {
for (QHostAddress& address : addressList) {
QUdpSocket sock;
// Send to all ports
for (quint16 port : WOL_PORTS) {
// Send to all static ports
for (quint16 port : STATIC_WOL_PORTS) {
if (sock.writeDatagram(wolPayload, address, port)) {
qInfo().nospace().noquote() << "Sent WoL packet to " << name << " via " << address.toString() << ":" << port;
success = true;
@@ -272,32 +324,69 @@ bool NvComputer::wake()
qWarning() << "Send failed:" << sock.error();
}
}
QList<quint16> basePorts;
if (i.value() != 0) {
// If we have a known base port for this address, use only that port
basePorts.append(i.value());
}
else {
// If this is a broadcast address without a known HTTP port, try all of them
basePorts.append(basePortSet.values());
}
// Send to all dynamic ports using the HTTP port offset(s) for this address
for (quint16 basePort : basePorts) {
for (quint16 port : DYNAMIC_WOL_PORTS) {
port = (port - 47989) + basePort;
if (sock.writeDatagram(wolPayload, address, port)) {
qInfo().nospace().noquote() << "Sent WoL packet to " << name << " via " << address.toString() << ":" << port;
success = true;
}
else {
qWarning() << "Send failed:" << sock.error();
}
}
}
}
}
return success;
}
bool NvComputer::isReachableOverVpn()
NvComputer::ReachabilityType NvComputer::getActiveAddressReachability() const
{
if (activeAddress.isNull()) {
return false;
NvAddress copyOfActiveAddress;
{
QReadLocker readLocker(&lock);
if (activeAddress.isNull()) {
return ReachabilityType::RI_UNKNOWN;
}
// Grab a copy of the active address to avoid having to hold
// the computer lock while doing socket operations
copyOfActiveAddress = activeAddress;
}
QTcpSocket s;
s.setProxy(QNetworkProxy::NoProxy);
s.connectToHost(activeAddress.address(), activeAddress.port());
s.connectToHost(copyOfActiveAddress.address(), copyOfActiveAddress.port());
if (s.waitForConnected(3000)) {
Q_ASSERT(!s.localAddress().isNull());
Q_ASSERT(!s.peerAddress().isNull());
for (const QNetworkInterface& nic : QNetworkInterface::allInterfaces()) {
const auto allInterfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface& nic : allInterfaces) {
// Ensure the interface is up
if ((nic.flags() & QNetworkInterface::IsUp) == 0) {
continue;
}
for (const QNetworkAddressEntry& addr : nic.addressEntries()) {
const auto allInterfaceAddresses = nic.addressEntries();
for (const QNetworkAddressEntry& addr : allInterfaceAddresses) {
if (addr.ip() == s.localAddress()) {
qInfo() << "Found matching interface:" << nic.humanReadableName() << nic.hardwareAddress() << nic.flags();
@@ -308,48 +397,68 @@ bool NvComputer::isReachableOverVpn()
if (nic.type() == QNetworkInterface::Virtual ||
nic.type() == QNetworkInterface::Ppp) {
// Treat PPP and virtual interfaces as likely VPNs
return true;
return ReachabilityType::RI_VPN;
}
if (nic.maximumTransmissionUnit() != 0 && nic.maximumTransmissionUnit() < 1500) {
// Treat MTUs under 1500 as likely VPNs
return true;
return ReachabilityType::RI_VPN;
}
#endif
if (nic.flags() & QNetworkInterface::IsPointToPoint) {
// Treat point-to-point links as likely VPNs.
// This check detects OpenVPN on Unix-like OSes.
return true;
return ReachabilityType::RI_VPN;
}
#ifdef Q_OS_WINDOWS
if (nic.name().startsWith("iftype53_") || nic.name().startsWith("iftype131_")) {
// Match by NDIS interface type. These values are Microsoft's recommended values for VPN connections:
// https://learn.microsoft.com/en-US/troubleshoot/windows-client/networking/windows-connection-manager-disconnects-wlan#more-information
//
// The following VPNs use IF_TYPE_PROP_VIRTUAL under Windows:
// - WireguardNT VPNs
// - All WinTun-based VPNs (such as Slack Nebula)
// - OpenVPN with tap-windows6
return ReachabilityType::RI_VPN;
}
#endif
if (nic.hardwareAddress().startsWith("00:FF", Qt::CaseInsensitive)) {
// OpenVPN TAP interfaces have a MAC address starting with 00:FF on Windows
return true;
return ReachabilityType::RI_VPN;
}
if (nic.humanReadableName().startsWith("ZeroTier")) {
// ZeroTier interfaces always start with "ZeroTier"
return true;
return ReachabilityType::RI_VPN;
}
if (nic.humanReadableName().contains("VPN")) {
// This one is just a final heuristic if all else fails
return true;
// This one is just a final VPN heuristic if all else fails
return ReachabilityType::RI_VPN;
}
// Didn't meet any of our VPN heuristics
return false;
// Didn't meet any of our VPN heuristics. Let's see if the peer address is on-link.
Q_ASSERT(addr.prefixLength() >= 0);
if (addr.prefixLength() >= 0 && s.localAddress().isInSubnet(s.peerAddress(), addr.prefixLength())) {
return ReachabilityType::RI_LAN;
}
// Default to unknown if nothing else matched
return ReachabilityType::RI_UNKNOWN;
}
}
}
qWarning() << "No match found for address:" << s.localAddress();
return false;
return ReachabilityType::RI_UNKNOWN;
}
else {
// If we fail to connect, just pretend that it's not a VPN
return false;
qWarning() << "Unable to check for reachability within 3 seconds";
return ReachabilityType::RI_UNKNOWN;
}
}
@@ -359,7 +468,7 @@ bool NvComputer::updateAppList(QVector<NvApp> newAppList) {
}
// Propagate client-side attributes to the new app list
for (const NvApp& existingApp : appList) {
for (const NvApp& existingApp : std::as_const(appList)) {
for (NvApp& newApp : newAppList) {
if (existingApp.id == newApp.id) {
newApp.hidden = existingApp.hidden;
@@ -375,6 +484,7 @@ bool NvComputer::updateAppList(QVector<NvApp> newAppList) {
QVector<NvAddress> NvComputer::uniqueAddresses() const
{
QReadLocker readLocker(&lock);
QVector<NvAddress> uniqueAddressList;
// Start with addresses correctly ordered
@@ -406,7 +516,7 @@ QVector<NvAddress> NvComputer::uniqueAddresses() const
return uniqueAddressList;
}
bool NvComputer::update(NvComputer& that)
bool NvComputer::update(const NvComputer& that)
{
bool changed = false;
@@ -456,6 +566,7 @@ bool NvComputer::update(NvComputer& that)
ASSIGN_IF_CHANGED(gfeVersion);
ASSIGN_IF_CHANGED(appVersion);
ASSIGN_IF_CHANGED(isSupportedServerVersion);
ASSIGN_IF_CHANGED(isNvidiaServerSoftware);
ASSIGN_IF_CHANGED(maxLumaPixelsHEVC);
ASSIGN_IF_CHANGED(gpuModel);
ASSIGN_IF_CHANGED_AND_NONNULL(serverCert);
+37 -6
View File
@@ -8,6 +8,16 @@
#include <QSettings>
#include <QRunnable>
class CopySafeReadWriteLock : public QReadWriteLock
{
public:
CopySafeReadWriteLock() = default;
// Don't actually copy the QReadWriteLock
CopySafeReadWriteLock(const CopySafeReadWriteLock&) : QReadWriteLock() {}
CopySafeReadWriteLock& operator=(const CopySafeReadWriteLock &) { return *this; }
};
class NvComputer
{
friend class PcMonitorThread;
@@ -22,6 +32,14 @@ private:
bool pendingQuit;
public:
NvComputer() = default;
// Caller is responsible for synchronizing read access to the other host
NvComputer(const NvComputer&) = default;
// Caller is responsible for synchronizing read access to the other host
NvComputer& operator=(const NvComputer &) = default;
explicit NvComputer(NvHTTP& http, QString serverInfo);
explicit NvComputer(QSettings& settings);
@@ -30,19 +48,30 @@ public:
setRemoteAddress(QHostAddress);
bool
update(NvComputer& that);
update(const NvComputer& that);
bool
wake();
wake() const;
bool
isReachableOverVpn();
enum ReachabilityType
{
RI_UNKNOWN,
RI_LAN,
RI_VPN,
};
ReachabilityType
getActiveAddressReachability() const;
QVector<NvAddress>
uniqueAddresses() const;
void
serialize(QSettings& settings) const;
serialize(QSettings& settings, bool serializeApps) const;
// Caller is responsible for synchronizing read access to both hosts
bool
isEqualSerialized(const NvComputer& that) const;
enum PairState
{
@@ -83,9 +112,11 @@ public:
QString uuid;
QSslCertificate serverCert;
QVector<NvApp> appList;
bool isNvidiaServerSoftware;
// Remember to update isEqualSerialized() when adding fields here!
// Synchronization
mutable QReadWriteLock lock;
mutable CopySafeReadWriteLock lock;
private:
uint16_t externalPort;
+91 -94
View File
@@ -18,8 +18,16 @@
#define RESUME_TIMEOUT_MS 30000
#define QUIT_TIMEOUT_MS 30000
NvHTTP::NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert) :
m_ServerCert(serverCert)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#define XML_NAME_EQUALS(x, y) ((x) == (y))
#else
#define XML_NAME_EQUALS(x, y) ((x) == (u##y))
#endif
NvHTTP::NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert, bool useTrueUid, QNetworkAccessManager* nam) :
m_Nam(nam ? nam : new QNetworkAccessManager(this)),
m_ServerCert(serverCert),
m_UseTrueUid(useTrueUid)
{
m_BaseUrlHttp.setScheme("http");
m_BaseUrlHttps.setScheme("https");
@@ -29,15 +37,12 @@ NvHTTP::NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert
// Never use a proxy server
QNetworkProxy noProxy(QNetworkProxy::NoProxy);
m_Nam.setProxy(noProxy);
connect(&m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
m_Nam->setProxy(noProxy);
}
NvHTTP::NvHTTP(NvComputer* computer) :
NvHTTP(computer->activeAddress, computer->activeHttpsPort, computer->serverCert)
NvHTTP::NvHTTP(NvComputer* computer, QNetworkAccessManager* nam) :
NvHTTP(computer->activeAddress, computer->activeHttpsPort, computer->serverCert, !computer->isNvidiaServerSoftware, nam)
{
}
void NvHTTP::setServerCert(QSslCertificate serverCert)
@@ -62,6 +67,11 @@ void NvHTTP::setHttpsPort(uint16_t port)
m_BaseUrlHttps.setPort(port);
}
void NvHTTP::setTrueUid(bool useTrueUid)
{
m_UseTrueUid = useTrueUid;
}
NvAddress NvHTTP::address()
{
return m_Address;
@@ -110,7 +120,7 @@ NvHTTP::getCurrentGame(QString serverInfo)
// has the semantics that its name would indicate. To contain the effects of this change as much
// as possible, we'll force the current game to zero if the server isn't in a streaming session.
QString serverState = getXmlString(serverInfo, "state");
if (serverState != nullptr && serverState.endsWith("_SERVER_BUSY"))
if (serverState.endsWith("_SERVER_BUSY"))
{
return getXmlString(serverInfo, "currentgame").toInt();
}
@@ -187,12 +197,15 @@ NvHTTP::getServerInfo(NvLogLevel logLevel, bool fastFail)
}
void
NvHTTP::launchApp(int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
QString& rtspSessionUrl)
NvHTTP::startApp(QString verb,
bool isGfe,
int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
bool persistGameControllersOnDisconnect,
QString& rtspSessionUrl)
{
int riKeyId;
@@ -201,25 +214,27 @@ NvHTTP::launchApp(int appId,
QString response =
openConnectionToString(m_BaseUrlHttps,
"launch",
verb,
"appid="+QString::number(appId)+
"&mode="+QString::number(streamConfig->width)+"x"+
QString::number(streamConfig->height)+"x"+
// Using an FPS value over 60 causes SOPS to default to 720p60,
// so force it to 0 to ensure the correct resolution is set. We
// used to use 60 here but that locked the frame rate to 60 FPS
// on GFE 3.20.3.
QString::number(streamConfig->fps > 60 ? 0 : streamConfig->fps)+
// on GFE 3.20.3. We don't need this hack for Sunshine.
QString::number((streamConfig->fps > 60 && isGfe) ? 0 : streamConfig->fps)+
"&additionalStates=1&sops="+QString::number(sops ? 1 : 0)+
"&rikey="+QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex()+
"&rikeyid="+QString::number(riKeyId)+
(streamConfig->enableHdr ?
((streamConfig->supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) ?
"&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0" :
"")+
"&localAudioPlayMode="+QString::number(localAudio ? 1 : 0)+
"&surroundAudioInfo="+QString::number(SURROUNDAUDIOINFO_FROM_AUDIO_CONFIGURATION(streamConfig->audioConfiguration))+
"&remoteControllersBitmap="+QString::number(gamepadMask)+
"&gcmap="+QString::number(gamepadMask),
"&gcmap="+QString::number(gamepadMask)+
"&gcpersist="+QString::number(persistGameControllersOnDisconnect ? 1 : 0)+
LiGetLaunchUrlQueryParameters(),
LAUNCH_TIMEOUT_MS);
qInfo() << "Launch response:" << response;
@@ -230,30 +245,6 @@ NvHTTP::launchApp(int appId,
rtspSessionUrl = getXmlString(response, "sessionUrl0");
}
void
NvHTTP::resumeApp(PSTREAM_CONFIGURATION streamConfig, QString& rtspSessionUrl)
{
int riKeyId;
memcpy(&riKeyId, streamConfig->remoteInputAesIv, sizeof(riKeyId));
riKeyId = qFromBigEndian(riKeyId);
QString response =
openConnectionToString(m_BaseUrlHttps,
"resume",
"rikey="+QString(QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex())+
"&rikeyid="+QString::number(riKeyId)+
"&surroundAudioInfo="+QString::number(SURROUNDAUDIOINFO_FROM_AUDIO_CONFIGURATION(streamConfig->audioConfiguration)),
RESUME_TIMEOUT_MS);
qInfo() << "Resume response:" << response;
// Throws if the request failed
verifyResponseStatus(response);
rtspSessionUrl = getXmlString(response, "sessionUrl0");
}
void
NvHTTP::quitApp()
{
@@ -269,7 +260,7 @@ NvHTTP::quitApp()
verifyResponseStatus(response);
// Newer GFE versions will just return success even if quitting fails
// if we're not the original requestor.
// if we're not the original requester.
if (getCurrentGame(getServerInfo(NvHTTP::NVLL_ERROR)) != 0) {
// Generate a synthetic GfeResponseException letting the caller know
// that they can't kill someone else's stream.
@@ -286,17 +277,19 @@ NvHTTP::getDisplayModeList(QString serverInfo)
while (!xmlReader.atEnd()) {
while (xmlReader.readNextStartElement()) {
auto name = xmlReader.name();
if (name == QString("DisplayMode")) {
if (XML_NAME_EQUALS(name, "DisplayMode")) {
modes.append(NvDisplayMode());
}
else if (name == QString("Width")) {
modes.last().width = xmlReader.readElementText().toInt();
}
else if (name == QString("Height")) {
modes.last().height = xmlReader.readElementText().toInt();
}
else if (name == QString("RefreshRate")) {
modes.last().refreshRate = xmlReader.readElementText().toInt();
else if (!modes.isEmpty()) {
if (XML_NAME_EQUALS(name, "Width")) {
modes.last().width = xmlReader.readElementText().toInt();
}
else if (XML_NAME_EQUALS(name, "Height")) {
modes.last().height = xmlReader.readElementText().toInt();
}
else if (XML_NAME_EQUALS(name, "RefreshRate")) {
modes.last().refreshRate = xmlReader.readElementText().toInt();
}
}
}
}
@@ -319,26 +312,36 @@ NvHTTP::getAppList()
while (!xmlReader.atEnd()) {
while (xmlReader.readNextStartElement()) {
auto name = xmlReader.name();
if (name == QString("App")) {
if (XML_NAME_EQUALS(name, "App")) {
// We must have a valid app before advancing to the next one
if (!apps.isEmpty() && !apps.last().isInitialized()) {
qWarning() << "Invalid applist XML";
Q_ASSERT(false);
return QVector<NvApp>();
throw std::runtime_error("Invalid applist XML");
}
apps.append(NvApp());
}
else if (name == QString("AppTitle")) {
apps.last().name = xmlReader.readElementText();
}
else if (name == QString("ID")) {
apps.last().id = xmlReader.readElementText().toInt();
}
else if (name == QString("IsHdrSupported")) {
apps.last().hdrSupported = xmlReader.readElementText() == "1";
}
else if (name == QString("IsAppCollectorGame")) {
apps.last().isAppCollectorGame = xmlReader.readElementText() == "1";
else if (!apps.isEmpty()) {
if (XML_NAME_EQUALS(name, "AppTitle")) {
// If an app has no name, Sunshine may send us <AppTitle/>,
// which readElementText() returns as a null QString.
// We want to treat this as an empty QString instead, so we
// will explicitly convert it. An empty string will satisfy
// NvApp's isInitialized() check.
QString name = xmlReader.readElementText();
if (name.isNull()) {
name = "";
}
apps.last().name = name;
}
else if (XML_NAME_EQUALS(name, "ID")) {
apps.last().id = xmlReader.readElementText().toInt();
}
else if (XML_NAME_EQUALS(name, "IsHdrSupported")) {
apps.last().hdrSupported = xmlReader.readElementText() == "1";
}
else if (XML_NAME_EQUALS(name, "IsAppCollectorGame")) {
apps.last().isAppCollectorGame = xmlReader.readElementText() == "1";
}
}
}
}
@@ -353,7 +356,7 @@ NvHTTP::verifyResponseStatus(QString xml)
while (xmlReader.readNextStartElement())
{
if (xmlReader.name() == QString("root"))
if (XML_NAME_EQUALS(xmlReader.name(), "root"))
{
// Status code can be 0xFFFFFFFF in some rare cases on GFE 3.20.3, and
// QString::toInt() will fail in that case, so use QString::toUInt()
@@ -382,7 +385,7 @@ NvHTTP::verifyResponseStatus(QString xml)
}
}
throw GfeHttpResponseException(-1, "Malformed GFE XML (missing root element)");
throw GfeHttpResponseException(-1, "Malformed XML (missing root element)");
}
QImage
@@ -404,13 +407,7 @@ QByteArray
NvHTTP::getXmlStringFromHex(QString xml,
QString tagName)
{
QString str = getXmlString(xml, tagName);
if (str == nullptr)
{
return nullptr;
}
return QByteArray::fromHex(str.toLatin1());
return QByteArray::fromHex(getXmlString(xml, tagName).toUtf8());
}
QString
@@ -432,7 +429,7 @@ NvHTTP::getXmlString(QString xml,
}
}
return nullptr;
return QString();
}
void NvHTTP::handleSslErrors(QNetworkReply* reply, const QList<QSslError>& errors)
@@ -495,11 +492,9 @@ NvHTTP::openConnection(QUrl baseUrl,
QUrl url(baseUrl);
url.setPath("/" + command);
// Use a common UID for Moonlight clients to allow them to quit
// games for each other (otherwise GFE gets screwed up and it requires
// manual intervention to solve).
url.setQuery("uniqueid=0123456789ABCDEF&uuid=" +
QUuid::createUuid().toRfc4122().toHex() +
// Use a placeholder UID for GFE allow them to quit games for each other.
url.setQuery("uniqueid=" + (m_UseTrueUid ? IdentityManager::get()->getUniqueId() : "0123456789ABCDEF") +
"&uuid=" + QUuid::createUuid().toRfc4122().toHex() +
((arguments != nullptr) ? ("&" + arguments) : ""));
QNetworkRequest request(url);
@@ -512,15 +507,15 @@ NvHTTP::openConnection(QUrl baseUrl,
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1) && !defined(QT_NO_BEARERMANAGEMENT)
// HACK: Set network accessibility to work around QTBUG-80947 (introduced in Qt 5.14.0 and fixed in Qt 5.15.1)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
m_Nam.setNetworkAccessible(QNetworkAccessManager::Accessible);
QT_WARNING_POP
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// Use fine-grained idle timeouts to avoid calling QNetworkAccessManager::clearAccessCache(),
// which tears down the NAM's global thread each time. We must not keep persistent connections
// or GFE will puke.
request.setAttribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute, 0);
#endif
QNetworkReply* reply = m_Nam.get(request);
auto sslErrorsConnection = connect(m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
QNetworkReply* reply = m_Nam->get(request);
// Run the request with a timeout if requested
QEventLoop loop;
@@ -543,15 +538,17 @@ NvHTTP::openConnection(QUrl baseUrl,
reply->abort();
}
// We must clear out cached authentication and connections or
// GFE will puke next time
m_Nam.clearAccessCache();
#if QT_VERSION < QT_VERSION_CHECK(6, 3, 0)
// If we couldn't use fine-grained connection idle timeouts, kill them all now
m_Nam->clearAccessCache();
#endif
disconnect(sslErrorsConnection);
// Handle error
if (reply->error() != QNetworkReply::NoError)
{
if (logLevel >= NvLogLevel::NVLL_ERROR) {
qWarning() << command << " request failed with error " << reply->error();
qWarning() << command << "request failed with error:" << reply->error();
}
if (reply->error() == QNetworkReply::SslHandshakeFailedError) {
+24 -24
View File
@@ -33,19 +33,19 @@ class GfeHttpResponseException : public std::exception
public:
GfeHttpResponseException(int statusCode, QString message) :
m_StatusCode(statusCode),
m_StatusMessage(message)
m_StatusMessage(message.toUtf8())
{
}
const char* what() const throw()
{
return m_StatusMessage.toLatin1();
return m_StatusMessage.constData();
}
const char* getStatusMessage() const
{
return m_StatusMessage.toLatin1();
return m_StatusMessage.constData();
}
int getStatusCode() const
@@ -55,12 +55,12 @@ public:
QString toQString() const
{
return m_StatusMessage + " (Error " + QString::number(m_StatusCode) + ")";
return QString::fromUtf8(m_StatusMessage) + " (Error " + QString::number(m_StatusCode) + ")";
}
private:
int m_StatusCode;
QString m_StatusMessage;
QByteArray m_StatusMessage;
};
class QtNetworkReplyException : public std::exception
@@ -68,19 +68,19 @@ class QtNetworkReplyException : public std::exception
public:
QtNetworkReplyException(QNetworkReply::NetworkError error, QString errorText) :
m_Error(error),
m_ErrorText(errorText)
m_ErrorText(errorText.toUtf8())
{
}
const char* what() const throw()
{
return m_ErrorText.toLatin1();
return m_ErrorText.constData();
}
const char* getErrorText() const
{
return m_ErrorText.toLatin1();
return m_ErrorText.constData();
}
QNetworkReply::NetworkError getError() const
@@ -90,12 +90,12 @@ public:
QString toQString() const
{
return m_ErrorText + " (Error " + QString::number(m_Error) + ")";
return QString::fromUtf8(m_ErrorText) + " (Error " + QString::number(m_Error) + ")";
}
private:
QNetworkReply::NetworkError m_Error;
QString m_ErrorText;
QByteArray m_ErrorText;
};
class NvHTTP : public QObject
@@ -109,9 +109,9 @@ public:
NVLL_VERBOSE
};
explicit NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert);
explicit NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert, bool useTrueUid, QNetworkAccessManager* nam = nullptr);
explicit NvHTTP(NvComputer* computer);
explicit NvHTTP(NvComputer* computer, QNetworkAccessManager* nam = nullptr);
static
int
@@ -142,9 +142,9 @@ public:
NvLogLevel logLevel = NvLogLevel::NVLL_VERBOSE);
void setServerCert(QSslCertificate serverCert);
void setAddress(NvAddress address);
void setHttpsPort(uint16_t port);
void setTrueUid(bool useTrueUid);
NvAddress address();
@@ -162,16 +162,15 @@ public:
quitApp();
void
resumeApp(PSTREAM_CONFIGURATION streamConfig,
QString& rtspSessionUrl);
void
launchApp(int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
QString& rtspSessionUrl);
startApp(QString verb,
bool isGfe,
int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
bool persistGameControllersOnDisconnect,
QString& rtspSessionUrl);
QVector<NvApp>
getAppList();
@@ -197,6 +196,7 @@ private:
NvLogLevel logLevel);
NvAddress m_Address;
QNetworkAccessManager m_Nam;
QNetworkAccessManager* m_Nam;
QSslCertificate m_ServerCert;
bool m_UseTrueUid;
};
+53 -36
View File
@@ -54,16 +54,18 @@ NvPairingManager::generateRandomBytes(int length)
QByteArray
NvPairingManager::encrypt(const QByteArray& plaintext, const QByteArray& key)
{
QByteArray ciphertext(plaintext.size(), 0);
EVP_CIPHER_CTX* cipher;
int ciphertextLen;
if (plaintext.isEmpty()) {
return QByteArray();
}
cipher = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX* cipher = EVP_CIPHER_CTX_new();
THROW_BAD_ALLOC_IF_NULL(cipher);
EVP_EncryptInit(cipher, EVP_aes_128_ecb(), reinterpret_cast<const unsigned char*>(key.data()), NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
QByteArray ciphertext(plaintext.size(), 0);
int ciphertextLen;
EVP_EncryptUpdate(cipher,
reinterpret_cast<unsigned char*>(ciphertext.data()),
&ciphertextLen,
@@ -79,16 +81,18 @@ NvPairingManager::encrypt(const QByteArray& plaintext, const QByteArray& key)
QByteArray
NvPairingManager::decrypt(const QByteArray& ciphertext, const QByteArray& key)
{
QByteArray plaintext(ciphertext.size(), 0);
EVP_CIPHER_CTX* cipher;
int plaintextLen;
if (ciphertext.isEmpty()) {
return QByteArray();
}
cipher = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX* cipher = EVP_CIPHER_CTX_new();
THROW_BAD_ALLOC_IF_NULL(cipher);
EVP_DecryptInit(cipher, EVP_aes_128_ecb(), reinterpret_cast<const unsigned char*>(key.data()), NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
QByteArray plaintext(ciphertext.size(), 0);
int plaintextLen;
EVP_DecryptUpdate(cipher,
reinterpret_cast<unsigned char*>(plaintext.data()),
&plaintextLen,
@@ -101,6 +105,29 @@ NvPairingManager::decrypt(const QByteArray& ciphertext, const QByteArray& key)
return plaintext;
}
QByteArray
NvPairingManager::getSignatureFromCert(X509* cert)
{
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
ASN1_BIT_STRING *asnSignature = cert->signature;
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, cert);
#else
const ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, cert);
#endif
return QByteArray(
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
reinterpret_cast<const char*>(ASN1_STRING_data(asnSignature)),
#else
reinterpret_cast<const char*>(ASN1_STRING_get0_data(asnSignature)),
#endif
ASN1_STRING_length(asnSignature)
);
}
QByteArray
NvPairingManager::getSignatureFromPemCert(const QByteArray& certificate)
{
@@ -114,18 +141,7 @@ NvPairingManager::getSignatureFromPemCert(const QByteArray& certificate)
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
BIO_free_all(bio);
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
ASN1_BIT_STRING *asnSignature = cert->signature;
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, cert);
#else
const ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, cert);
#endif
QByteArray signature(reinterpret_cast<char*>(asnSignature->data), asnSignature->length);
QByteArray signature = getSignatureFromCert(cert);
X509_free(cert);
return signature;
@@ -184,7 +200,7 @@ NvPairingManager::signMessage(const QByteArray& message)
QByteArray
NvPairingManager::saltPin(const QByteArray& salt, QString pin)
{
return QByteArray().append(salt).append(pin.toLatin1());
return QByteArray().append(salt).append(pin.toUtf8());
}
NvPairingManager::PairState
@@ -227,8 +243,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
}
QByteArray serverCertStr = NvHTTP::getXmlStringFromHex(getCert, "plaincert");
if (serverCertStr == nullptr)
{
if (serverCertStr.isEmpty()) {
qCritical() << "Server likely already pairing";
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
return PairState::ALREADY_IN_PROGRESS;
@@ -263,22 +278,18 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
}
QByteArray challengeResponseData = decrypt(m_Http.getXmlStringFromHex(challengeXml, "challengeresponse"), aesKey);
if (challengeResponseData.size() < hashLength) {
qCritical() << "Invalid challengeresponse at stage #2";
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
return PairState::FAILED;
}
QByteArray clientSecretData = generateRandomBytes(16);
QByteArray challengeResponse;
QByteArray serverResponse(challengeResponseData.data(), hashLength);
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
ASN1_BIT_STRING *asnSignature = m_Cert->signature;
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, m_Cert);
#else
const ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, m_Cert);
#endif
challengeResponse.append(challengeResponseData.data() + hashLength, 16);
challengeResponse.append(reinterpret_cast<char*>(asnSignature->data), asnSignature->length);
challengeResponse.append(getSignatureFromCert(m_Cert));
challengeResponse.append(clientSecretData);
QByteArray paddedHash = QCryptographicHash::hash(challengeResponse, hashAlgo);
@@ -298,8 +309,14 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
}
QByteArray pairingSecret = NvHTTP::getXmlStringFromHex(respXml, "pairingsecret");
QByteArray serverSecret = QByteArray(pairingSecret.data(), 16);
QByteArray serverSignature = QByteArray(&pairingSecret.data()[16], 256);
if (pairingSecret.size() <= 16) {
qCritical() << "Invalid pairingsecret at stage #3";
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
return PairState::FAILED;
}
QByteArray serverSecret = pairingSecret.left(16);
QByteArray serverSignature = pairingSecret.mid(16);
if (!verifySignature(serverSecret,
serverSignature,
+3
View File
@@ -37,6 +37,9 @@ private:
QByteArray
decrypt(const QByteArray& ciphertext, const QByteArray& key);
QByteArray
getSignatureFromCert(X509* cert);
QByteArray
getSignatureFromPemCert(const QByteArray& certificate);
+136 -118
View File
@@ -2,6 +2,7 @@
#include "utils.h"
#include <QGuiApplication>
#include <QLibraryInfo>
#include "streaming/session.h"
#include "streaming/streamutils.h"
@@ -11,21 +12,53 @@
#include <Windows.h>
#endif
class SystemPropertyQueryThread : public QThread
{
public:
SystemPropertyQueryThread(SystemProperties* properties)
: QThread(properties), m_Properties(properties)
{
setObjectName("System Properties Async Query Thread");
}
private:
void run() override
{
bool hasHardwareAcceleration;
bool rendererAlwaysFullScreen;
bool supportsHdr;
QSize maximumResolution;
Session::getDecoderInfo(m_Properties->testWindow, hasHardwareAcceleration, rendererAlwaysFullScreen, supportsHdr, maximumResolution);
// Propagate the decoder properties to the SystemProperties singleton and emit any change signals on the main thread
QMetaObject::invokeMethod(m_Properties, "updateDecoderProperties",
Qt::QueuedConnection,
Q_ARG(bool, hasHardwareAcceleration),
Q_ARG(bool, rendererAlwaysFullScreen),
Q_ARG(QSize, maximumResolution),
Q_ARG(bool, supportsHdr));
}
private:
SystemProperties* m_Properties;
};
SystemProperties::SystemProperties()
{
versionString = QString(VERSION_STR);
hasDesktopEnvironment = WMUtils::isRunningDesktopEnvironment();
isRunningWayland = WMUtils::isRunningWayland();
isRunningXWayland = isRunningWayland && QGuiApplication::platformName() == "xcb";
usesMaterial3Theme = QLibraryInfo::version() >= QVersionNumber(6, 5, 0);
QString nativeArch = QSysInfo::currentCpuArchitecture();
#ifdef Q_OS_WIN32
{
USHORT processArch, machineArch;
// Use IsWow64Process2 on TH2 and later, because it supports ARM64
auto fnIsWow64Process2 = (decltype(IsWow64Process2)*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process2");
if (fnIsWow64Process2 != nullptr && fnIsWow64Process2(GetCurrentProcess(), &processArch, &machineArch)) {
// Use IsWow64Process2() because it doesn't lie on ARM64
if (IsWow64Process2(GetCurrentProcess(), &processArch, &machineArch)) {
switch (machineArch) {
case IMAGE_FILE_MACHINE_I386:
nativeArch = "i386";
@@ -64,62 +97,86 @@ SystemProperties::SystemProperties()
hasDiscordIntegration = false;
#endif
unmappedGamepads = SdlInputHandler::getUnmappedGamepads();
// Populate data that requires talking to SDL. We do it all in one shot
// and cache the results to speed up future queries on this data.
querySdlVideoInfo();
Q_ASSERT(maximumStreamingFrameRate >= 60);
Q_ASSERT(!monitorDesktopResolutions.isEmpty());
Q_ASSERT(!monitorNativeResolutions.isEmpty());
// These will be queried asynchronously to avoid blocking the UI
hasHardwareAcceleration = true;
rendererAlwaysFullScreen = false;
supportsHdr = true;
maximumResolution = QSize(0, 0);
}
QRect SystemProperties::getDesktopResolution(int displayIndex)
SystemProperties::~SystemProperties()
{
// Returns default constructed QRect if out of bounds
return monitorDesktopResolutions.value(displayIndex);
waitForAsyncLoad();
}
void SystemProperties::updateDecoderProperties(bool hasHardwareAcceleration, bool rendererAlwaysFullScreen, QSize maximumResolution, bool supportsHdr)
{
SDL_assert(testWindow);
if (hasHardwareAcceleration != this->hasHardwareAcceleration) {
this->hasHardwareAcceleration = hasHardwareAcceleration;
emit hasHardwareAccelerationChanged();
}
if (rendererAlwaysFullScreen != this->rendererAlwaysFullScreen) {
this->rendererAlwaysFullScreen = rendererAlwaysFullScreen;
emit rendererAlwaysFullScreenChanged();
}
if (maximumResolution != this->maximumResolution) {
this->maximumResolution = maximumResolution;
emit maximumResolutionChanged();
}
if (supportsHdr != this->supportsHdr) {
this->supportsHdr = supportsHdr;
emit supportsHdrChanged();
}
SDL_DestroyWindow(testWindow);
testWindow = nullptr;
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
QRect SystemProperties::getNativeResolution(int displayIndex)
{
// Returns default constructed QRect if out of bounds
Q_ASSERT(!monitorNativeResolutions.isEmpty());
return monitorNativeResolutions.value(displayIndex);
}
class QuerySdlVideoThread : public QThread
QRect SystemProperties::getSafeAreaResolution(int displayIndex)
{
public:
QuerySdlVideoThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->querySdlVideoInfoInternal();
}
SystemProperties* m_Me;
};
void SystemProperties::querySdlVideoInfo()
{
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
QuerySdlVideoThread thread(this);
thread.start();
thread.wait();
}
else {
querySdlVideoInfoInternal();
}
// Returns default constructed QRect if out of bounds
Q_ASSERT(!monitorSafeAreaResolutions.isEmpty());
return monitorSafeAreaResolutions.value(displayIndex);
}
void SystemProperties::querySdlVideoInfoInternal()
int SystemProperties::getRefreshRate(int displayIndex)
{
hasHardwareAcceleration = false;
// Returns 0 if out of bounds
Q_ASSERT(!monitorRefreshRates.isEmpty());
return monitorRefreshRates.value(displayIndex);
}
void SystemProperties::startAsyncLoad()
{
if (systemPropertyQueryThread) {
// Already started/completed
return;
}
// This isn't actually asynchronous (due to the need to synchronize with
// SdlGamepadKeyNavigation), but we don't query it in the constructor
// because it's expensive.
unmappedGamepads = SdlInputHandler::getUnmappedGamepads();
if (!unmappedGamepads.isEmpty()) {
emit unmappedGamepadsChanged();
}
// We initialize the video subsystem and test window on the main thread
// because some platforms (macOS) do not support window creation on
// non-main threads.
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s",
@@ -127,64 +184,34 @@ void SystemProperties::querySdlVideoInfoInternal()
return;
}
testWindow = StreamUtils::createTestWindow();
if (!testWindow) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
// Update display related attributes (max FPS, native resolution, etc).
// We call the internal variant because we're already in a safe thread context.
refreshDisplaysInternal();
//
// NB: SDL3 will forcefully refresh displays when a window is created,
// so we place this after the window creation to ensure we don't pay
// the penalty for mode enumeration twice.
refreshDisplays();
SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720,
SDL_WINDOW_HIDDEN | StreamUtils::getPlatformWindowFlags());
if (!testWindow) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create test window with platform flags: %s",
SDL_GetError());
testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_WINDOW_HIDDEN);
if (!testWindow) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
}
Session::getDecoderInfo(testWindow, hasHardwareAcceleration, rendererAlwaysFullScreen, supportsHdr, maximumResolution);
SDL_DestroyWindow(testWindow);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
systemPropertyQueryThread = new SystemPropertyQueryThread(this);
systemPropertyQueryThread->start();
}
class RefreshDisplaysThread : public QThread
void SystemProperties::waitForAsyncLoad()
{
public:
RefreshDisplaysThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->refreshDisplaysInternal();
if (systemPropertyQueryThread) {
systemPropertyQueryThread->wait();
}
SystemProperties* m_Me;
};
}
void SystemProperties::refreshDisplays()
{
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
RefreshDisplaysThread thread(this);
thread.start();
thread.wait();
}
else {
refreshDisplaysInternal();
}
}
void SystemProperties::refreshDisplaysInternal()
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
@@ -193,37 +220,17 @@ void SystemProperties::refreshDisplaysInternal()
return;
}
monitorDesktopResolutions.clear();
monitorNativeResolutions.clear();
// Never let the maximum drop below 60 FPS
maximumStreamingFrameRate = 60;
SDL_DisplayMode bestMode;
for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) {
SDL_DisplayMode desktopMode;
int err;
SDL_Rect safeArea;
err = SDL_GetDesktopDisplayMode(displayIndex, &desktopMode);
if (err == 0) {
if (desktopMode.w <= 8192 && desktopMode.h <= 8192) {
monitorDesktopResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h));
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Skipping resolution over 8K: %dx%d",
desktopMode.w, desktopMode.h);
}
}
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetDesktopDisplayMode() failed: %s",
SDL_GetError());
}
if (StreamUtils::getRealDesktopMode(displayIndex, &desktopMode)) {
if (StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) {
if (desktopMode.w <= 8192 && desktopMode.h <= 8192) {
monitorNativeResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h));
monitorSafeAreaResolutions.insert(displayIndex, QRect(0, 0, safeArea.w, safeArea.h));
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
@@ -233,7 +240,8 @@ void SystemProperties::refreshDisplaysInternal()
// Start at desktop mode and work our way up
bestMode = desktopMode;
for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) {
int numDisplayModes = SDL_GetNumDisplayModes(displayIndex);
for (int i = 0; i < numDisplayModes; i++) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) {
if (mode.w == desktopMode.w && mode.h == desktopMode.h) {
@@ -244,7 +252,17 @@ void SystemProperties::refreshDisplaysInternal()
}
}
maximumStreamingFrameRate = qMax(maximumStreamingFrameRate, bestMode.refresh_rate);
// Try to normalize values around our our standard refresh rates.
// Some displays/OSes report values that are slightly off.
if (bestMode.refresh_rate >= 58 && bestMode.refresh_rate <= 62) {
monitorRefreshRates.append(60);
}
else if (bestMode.refresh_rate >= 28 && bestMode.refresh_rate <= 32) {
monitorRefreshRates.append(30);
}
else {
monitorRefreshRates.append(bestMode.refresh_rate);
}
}
}
+42 -20
View File
@@ -3,18 +3,19 @@
#include <QObject>
#include <QRect>
#include "SDL_compat.h"
class SystemProperties : public QObject
{
Q_OBJECT
friend class QuerySdlVideoThread;
friend class RefreshDisplaysThread;
friend class SystemPropertyQueryThread;
public:
SystemProperties();
~SystemProperties();
Q_PROPERTY(bool hasHardwareAcceleration MEMBER hasHardwareAcceleration CONSTANT)
Q_PROPERTY(bool rendererAlwaysFullScreen MEMBER rendererAlwaysFullScreen CONSTANT)
// Static properties queried synchronously during the constructor
Q_PROPERTY(bool isRunningWayland MEMBER isRunningWayland CONSTANT)
Q_PROPERTY(bool isRunningXWayland MEMBER isRunningXWayland CONSTANT)
Q_PROPERTY(bool isWow64 MEMBER isWow64 CONSTANT)
@@ -22,26 +23,40 @@ public:
Q_PROPERTY(bool hasDesktopEnvironment MEMBER hasDesktopEnvironment CONSTANT)
Q_PROPERTY(bool hasBrowser MEMBER hasBrowser CONSTANT)
Q_PROPERTY(bool hasDiscordIntegration MEMBER hasDiscordIntegration CONSTANT)
Q_PROPERTY(QString unmappedGamepads MEMBER unmappedGamepads NOTIFY unmappedGamepadsChanged)
Q_PROPERTY(int maximumStreamingFrameRate MEMBER maximumStreamingFrameRate CONSTANT)
Q_PROPERTY(QSize maximumResolution MEMBER maximumResolution CONSTANT)
Q_PROPERTY(bool usesMaterial3Theme MEMBER usesMaterial3Theme CONSTANT)
Q_PROPERTY(QString versionString MEMBER versionString CONSTANT)
Q_PROPERTY(bool supportsHdr MEMBER supportsHdr CONSTANT)
Q_INVOKABLE void refreshDisplays();
Q_INVOKABLE QRect getDesktopResolution(int displayIndex);
// Properties queried asynchronously (startAsyncLoad() must be called!)
Q_PROPERTY(bool hasHardwareAcceleration MEMBER hasHardwareAcceleration NOTIFY hasHardwareAccelerationChanged)
Q_PROPERTY(bool rendererAlwaysFullScreen MEMBER rendererAlwaysFullScreen NOTIFY rendererAlwaysFullScreenChanged)
Q_PROPERTY(QString unmappedGamepads MEMBER unmappedGamepads NOTIFY unmappedGamepadsChanged)
Q_PROPERTY(QSize maximumResolution MEMBER maximumResolution NOTIFY maximumResolutionChanged)
Q_PROPERTY(bool supportsHdr MEMBER supportsHdr NOTIFY supportsHdrChanged)
// Either startAsyncLoad()+waitForAsyncLoad() or refreshDisplays() must be invoked first
Q_INVOKABLE QRect getNativeResolution(int displayIndex);
Q_INVOKABLE QRect getSafeAreaResolution(int displayIndex);
Q_INVOKABLE int getRefreshRate(int displayIndex);
Q_INVOKABLE void startAsyncLoad();
Q_INVOKABLE void waitForAsyncLoad();
Q_INVOKABLE void refreshDisplays();
signals:
void unmappedGamepadsChanged();
void hasHardwareAccelerationChanged();
void rendererAlwaysFullScreenChanged();
void maximumResolutionChanged();
void supportsHdrChanged();
private slots:
void updateDecoderProperties(bool hasHardwareAcceleration, bool rendererAlwaysFullScreen, QSize maximumResolution, bool supportsHdr);
private:
void querySdlVideoInfo();
void querySdlVideoInfoInternal();
void refreshDisplaysInternal();
QThread* systemPropertyQueryThread = nullptr;
SDL_Window* testWindow = nullptr;
bool hasHardwareAcceleration;
bool rendererAlwaysFullScreen;
// Properties set by the constructor
bool isRunningWayland;
bool isRunningXWayland;
bool isWow64;
@@ -49,12 +64,19 @@ private:
bool hasDesktopEnvironment;
bool hasBrowser;
bool hasDiscordIntegration;
QString unmappedGamepads;
int maximumStreamingFrameRate;
QSize maximumResolution;
QList<QRect> monitorDesktopResolutions;
QList<QRect> monitorNativeResolutions;
QString versionString;
bool usesMaterial3Theme;
// Properties only set if startAsyncLoad() is called
bool hasHardwareAcceleration;
bool rendererAlwaysFullScreen;
QSize maximumResolution;
bool supportsHdr;
QString unmappedGamepads;
// Properties set by refreshDisplays()
QList<QRect> monitorNativeResolutions;
QList<QRect> monitorSafeAreaResolutions;
QList<int> monitorRefreshRates;
};
+138 -15
View File
@@ -59,13 +59,6 @@ public:
void showMessage(QString message, MessageType type) const
{
#if defined(Q_OS_WIN32)
UINT flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND;
flags |= (type == Info ? MB_ICONINFORMATION : MB_ICONERROR);
QString title = "Moonlight";
MessageBoxW(nullptr, reinterpret_cast<const wchar_t *>(message.utf16()),
reinterpret_cast<const wchar_t *>(title.utf16()), flags);
#endif
message = message.endsWith('\n') ? message : message + '\n';
fputs(qPrintable(message), type == Info ? stdout : stderr);
}
@@ -113,7 +106,7 @@ public:
QPair<int,int> getResolutionOptionValue(QString name) const
{
QRegularExpression re("^(\\d+)x(\\d+)$", QRegularExpression::CaseInsensitiveOption);
static QRegularExpression re("^(\\d+)x(\\d+)$", QRegularExpression::CaseInsensitiveOption);
auto match = re.match(value(name));
if (!match.hasMatch()) {
showError(QString("Invalid %1 format: %2").arg(name, value(name)));
@@ -164,8 +157,10 @@ GlobalCommandLineParser::ParseResult GlobalCommandLineParser::parse(const QStrin
"Starts Moonlight normally if no arguments are given.\n"
"\n"
"Available actions:\n"
" list List the available apps on a host\n"
" quit Quit the currently running app\n"
" stream Start streaming an app\n"
" pair Pair a new host\n"
"\n"
"See 'moonlight <action> --help' for help of specific action."
);
@@ -193,10 +188,14 @@ GlobalCommandLineParser::ParseResult GlobalCommandLineParser::parse(const QStrin
return QuitRequested;
} else if (action == "stream") {
return StreamRequested;
} else if (action == "pair") {
return PairRequested;
} else if (action == "list") {
return ListRequested;
}
}
parser.showError(QString("Invalid action"));
parser.showError("Invalid action");
}
}
@@ -242,6 +241,58 @@ QString QuitCommandLineParser::getHost() const
return m_Host;
}
PairCommandLineParser::PairCommandLineParser()
{
}
PairCommandLineParser::~PairCommandLineParser()
{
}
void PairCommandLineParser::parse(const QStringList &args)
{
CommandLineParser parser;
parser.setupCommonOptions();
parser.setApplicationDescription(
"\n"
"Pair with the specified host."
);
parser.addPositionalArgument("pair", "pair host");
parser.addPositionalArgument("host", "Host computer name, UUID, or IP address", "<host>");
parser.addValueOption("pin", "4 digit pairing PIN");
if (!parser.parse(args)) {
parser.showError(parser.errorText());
}
parser.handleUnknownOptions();
// This method will not return and terminates the process if --version or
// --help is specified
parser.handleHelpAndVersionOptions();
// Verify that host has been provided
auto posArgs = parser.positionalArguments();
if (posArgs.length() < 2) {
parser.showError("Host not provided");
}
m_Host = parser.positionalArguments().at(1);
m_PredefinedPin = parser.value("pin");
if (!m_PredefinedPin.isEmpty() && m_PredefinedPin.length() != 4) {
parser.showError("PIN must be 4 digits");
}
}
QString PairCommandLineParser::getHost() const
{
return m_Host;
}
QString PairCommandLineParser::getPredefinedPin() const
{
return m_PredefinedPin;
}
StreamCommandLineParser::StreamCommandLineParser()
{
m_WindowModeMap = {
@@ -258,6 +309,7 @@ StreamCommandLineParser::StreamCommandLineParser()
{"auto", StreamingPreferences::VCC_AUTO},
{"H.264", StreamingPreferences::VCC_FORCE_H264},
{"HEVC", StreamingPreferences::VCC_FORCE_HEVC},
{"AV1", StreamingPreferences::VCC_FORCE_AV1},
};
m_VideoDecoderMap = {
{"auto", StreamingPreferences::VDS_AUTO},
@@ -313,6 +365,9 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
parser.addToggleOption("reverse-scroll-direction", "inverted scroll direction");
parser.addToggleOption("swap-gamepad-buttons", "swap A/B and X/Y gamepad buttons (Nintendo-style)");
parser.addToggleOption("keep-awake", "prevent display sleep while streaming");
parser.addToggleOption("performance-overlay", "show performance overlay");
parser.addToggleOption("hdr", "HDR streaming");
parser.addToggleOption("yuv444", "YUV 4:4:4 sampling, if supported");
parser.addChoiceOption("capture-system-keys", "capture system key combos", m_CaptureSysKeysModeMap.keys());
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
@@ -324,7 +379,7 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
parser.handleUnknownOptions();
// Resolve display's width and height
QRegularExpression resolutionRexExp("^(720|1080|1440|4K|resolution)$");
static QRegularExpression resolutionRexExp("^(720|1080|1440|4K|resolution)$");
QStringList resoOptions = parser.optionNames().filter(resolutionRexExp);
bool displaySet = !resoOptions.isEmpty();
if (displaySet) {
@@ -351,20 +406,20 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --fps option
if (parser.isSet("fps")) {
preferences->fps = parser.getIntOption("fps");
if (!inRange(preferences->fps, 30, 240)) {
parser.showError("FPS must be in range: 30 - 240");
if (!inRange(preferences->fps, 10, 480)) {
fprintf(stderr, "Warning: FPS is out of the supported range (10 - 480 FPS). Performance may suffer!\n");
}
}
// Resolve --bitrate option
if (parser.isSet("bitrate")) {
preferences->bitrateKbps = parser.getIntOption("bitrate");
if (!inRange(preferences->bitrateKbps, 500, 150000)) {
parser.showError("Bitrate must be in range: 500 - 150000");
if (!inRange(preferences->bitrateKbps, 500, 500000)) {
fprintf(stderr, "Warning: Bitrate is out of the supported range (500 - 500000 Kbps). Performance may suffer!\n");
}
} else if (displaySet || parser.isSet("fps")) {
preferences->bitrateKbps = preferences->getDefaultBitrate(
preferences->width, preferences->height, preferences->fps);
preferences->width, preferences->height, preferences->fps, preferences->enableYUV444);
}
// Resolve --packet-size option
@@ -427,6 +482,15 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --keep-awake and --no-keep-awake options
preferences->keepAwake = parser.getToggleOptionValue("keep-awake", preferences->keepAwake);
// Resolve --performance-overlay and --no-performance-overlay options
preferences->showPerformanceOverlay = parser.getToggleOptionValue("performance-overlay", preferences->showPerformanceOverlay);
// Resolve --hdr and --no-hdr options
preferences->enableHdr = parser.getToggleOptionValue("hdr", preferences->enableHdr);
// Resolve --yuv444 and --no-yuv444 options
preferences->enableYUV444 = parser.getToggleOptionValue("yuv444", preferences->enableYUV444);
// Resolve --capture-system-keys option
if (parser.isSet("capture-system-keys")) {
preferences->captureSysKeysMode = mapValue(m_CaptureSysKeysModeMap, parser.getChoiceOptionValue("capture-system-keys"));
@@ -468,3 +532,62 @@ QString StreamCommandLineParser::getAppName() const
{
return m_AppName;
}
ListCommandLineParser::ListCommandLineParser()
{
}
ListCommandLineParser::~ListCommandLineParser()
{
}
void ListCommandLineParser::parse(const QStringList &args)
{
CommandLineParser parser;
parser.setupCommonOptions();
parser.setApplicationDescription(
"\n"
"List the available apps on the given host."
);
parser.addPositionalArgument("list", "list available apps");
parser.addPositionalArgument("host", "Host computer name, UUID, or IP address", "<host>");
parser.addFlagOption("csv", "Print as CSV with additional information");
parser.addFlagOption("verbose", "Displays additional information");
if (!parser.parse(args)) {
parser.showError(parser.errorText());
}
parser.handleUnknownOptions();
m_PrintCSV = parser.isSet("csv");
m_Verbose = parser.isSet("verbose");
// This method will not return and terminates the process if --version or
// --help is specified
parser.handleHelpAndVersionOptions();
// Verify that host has been provided
auto posArgs = parser.positionalArguments();
if (posArgs.length() < 2) {
parser.showError("Host not provided");
}
m_Host = parser.positionalArguments().at(1);
}
QString ListCommandLineParser::getHost() const
{
return m_Host;
}
bool ListCommandLineParser::isPrintCSV() const
{
return m_PrintCSV;
}
bool ListCommandLineParser::isVerbose() const
{
return m_Verbose;
}
+36
View File
@@ -12,6 +12,8 @@ public:
NormalStartRequested,
StreamRequested,
QuitRequested,
PairRequested,
ListRequested,
};
GlobalCommandLineParser();
@@ -35,6 +37,22 @@ private:
QString m_Host;
};
class PairCommandLineParser
{
public:
PairCommandLineParser();
virtual ~PairCommandLineParser();
void parse(const QStringList &args);
QString getHost() const;
QString getPredefinedPin() const;
private:
QString m_Host;
QString m_PredefinedPin;
};
class StreamCommandLineParser
{
public:
@@ -55,3 +73,21 @@ private:
QMap<QString, StreamingPreferences::VideoDecoderSelection> m_VideoDecoderMap;
QMap<QString, StreamingPreferences::CaptureSysKeysMode> m_CaptureSysKeysModeMap;
};
class ListCommandLineParser
{
public:
ListCommandLineParser();
virtual ~ListCommandLineParser();
void parse(const QStringList &args);
QString getHost() const;
bool isPrintCSV() const;
bool isVerbose() const;
private:
QString m_Host;
bool m_PrintCSV;
bool m_Verbose;
};
+196
View File
@@ -0,0 +1,196 @@
#include "listapps.h"
#include "backend/boxartmanager.h"
#include "backend/computermanager.h"
#include "backend/computerseeker.h"
#include <QCoreApplication>
#define COMPUTER_SEEK_TIMEOUT 30000
namespace CliListApps
{
enum State {
StateInit,
StateSeekComputer,
StateListApps,
StateFailure,
};
class Event
{
public:
enum Type {
ComputerFound,
ComputerSeekTimedout,
Executed,
};
Event(Type type)
: type(type), computerManager(nullptr), computer(nullptr) {}
Type type;
ComputerManager *computerManager;
NvComputer *computer;
QString errorMessage;
};
class LauncherPrivate
{
Q_DECLARE_PUBLIC(Launcher)
public:
LauncherPrivate(Launcher *q) : q_ptr(q) {}
void handleEvent(Event event)
{
Q_Q(Launcher);
NvApp app;
switch (event.type) {
// Occurs when CLI main calls execute
case Event::Executed:
if (m_State == StateInit) {
m_State = StateSeekComputer;
m_ComputerManager = event.computerManager;
m_ComputerSeeker = new ComputerSeeker(m_ComputerManager, m_ComputerName, q);
q->connect(m_ComputerSeeker, &ComputerSeeker::computerFound,
q, &Launcher::onComputerFound);
q->connect(m_ComputerSeeker, &ComputerSeeker::errorTimeout,
q, &Launcher::onComputerSeekTimeout);
m_ComputerSeeker->start(COMPUTER_SEEK_TIMEOUT);
m_BoxArtManager = new BoxArtManager(q);
if (m_Arguments.isVerbose()) {
fprintf(stdout, "Establishing connection to PC...\n");
}
}
break;
// Occurs when computer search timed out
case Event::ComputerSeekTimedout:
if (m_State == StateSeekComputer) {
fprintf(stderr, "%s\n", qPrintable(QString("Failed to connect to %1").arg(m_ComputerName)));
QCoreApplication::exit(-1);
}
break;
// Occurs when searched computer is found
case Event::ComputerFound:
if (m_State == StateSeekComputer) {
if (event.computer->pairState == NvComputer::PS_PAIRED) {
m_State = StateListApps;
m_Computer = event.computer;
if (m_Arguments.isVerbose()) {
fprintf(stdout, "Loading app list...\n");
}
// To avoid race conditions where ComputerSeeker stops async polling, but
// ComputerManager is yet to update the app list, we will explicitly fetch the latest app list.
// Otherwise, it becomes complicated as we would have to guess whether ComputerManager
// would emit 1 signal (the list did not change) or 2 signals (indicating that the list has changed)
try {
NvHTTP http{m_Computer};
const auto appList = http.getAppList();
m_Arguments.isPrintCSV() ? printAppsCSV(appList) : printApps(appList);
QCoreApplication::exit(0);
} catch (std::exception& exception) {
fprintf(stderr, "%s\n", exception.what());
QCoreApplication::exit(1);
}
} else {
m_State = StateFailure;
fprintf(stderr, "%s\n", qPrintable(QObject::tr("Computer %1 has not been paired. "
"Please open Moonlight to pair before retrieving games list.")
.arg(event.computer->name)));
QCoreApplication::exit(-1);
}
}
break;
}
}
void printApps(QVector<NvApp> apps) {
for (int i = 0; i < apps.length(); i++) {
fprintf(stdout, "%s\n", qPrintable(apps[i].name));
}
}
void printAppsCSV(QVector<NvApp> apps) {
fprintf(stdout, "Name, ID, HDR Support, App Collection Game, Hidden, Direct Launch, Boxart URL\n");
for (int i = 0; i < apps.length(); i++) {
printAppCSV(apps[i]);
}
}
void printAppCSV(NvApp app) const
{
fprintf(stdout, "\"%s\",%d,%s,%s,%s,%s,\"%s\"\n", qPrintable(app.name),
app.id,
app.hdrSupported ? "true" : "false",
app.isAppCollectorGame ? "true" : "false",
app.hidden ? "true" : "false",
app.directLaunch ? "true" : "false",
qPrintable(m_BoxArtManager->loadBoxArt(m_Computer, app).toDisplayString()));
}
Launcher *q_ptr;
ComputerManager *m_ComputerManager;
QString m_ComputerName;
ComputerSeeker *m_ComputerSeeker;
BoxArtManager *m_BoxArtManager;
NvComputer *m_Computer;
State m_State;
ListCommandLineParser m_Arguments;
};
Launcher::Launcher(QString computer, ListCommandLineParser arguments, QObject *parent)
: QObject(parent),
m_DPtr(new LauncherPrivate(this))
{
Q_D(Launcher);
d->m_ComputerName = computer;
d->m_State = StateInit;
d->m_Arguments = arguments;
}
Launcher::~Launcher()
{
}
void Launcher::execute(ComputerManager *manager)
{
Q_D(Launcher);
Event event(Event::Executed);
event.computerManager = manager;
d->handleEvent(event);
}
bool Launcher::isExecuted() const
{
Q_D(const Launcher);
return d->m_State != StateInit;
}
void Launcher::onComputerFound(NvComputer *computer)
{
Q_D(Launcher);
Event event(Event::ComputerFound);
event.computer = computer;
d->handleEvent(event);
}
void Launcher::onComputerSeekTimeout()
{
Q_D(Launcher);
Event event(Event::ComputerSeekTimedout);
d->handleEvent(event);
}
}
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include "commandlineparser.h"
#include <QObject>
#include <QVariant>
class ComputerManager;
class NvComputer;
namespace CliListApps
{
class LauncherPrivate;
class Launcher : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE_D(m_DPtr, Launcher)
public:
explicit Launcher(QString computer, ListCommandLineParser arguments, QObject *parent = nullptr);
~Launcher();
Q_INVOKABLE void execute(ComputerManager *manager);
Q_INVOKABLE bool isExecuted() const;
private slots:
void onComputerFound(NvComputer *computer);
void onComputerSeekTimeout();
private:
QScopedPointer<LauncherPrivate> m_DPtr;
ListCommandLineParser m_Arguments;
};
}
+181
View File
@@ -0,0 +1,181 @@
#include "pair.h"
#include "backend/computermanager.h"
#include "backend/computerseeker.h"
#include <QCoreApplication>
#include <QTimer>
#define COMPUTER_SEEK_TIMEOUT 10000
namespace CliPair
{
enum State {
StateInit,
StateSeekComputer,
StatePairing,
StateFailure,
StateComplete,
};
class Event
{
public:
enum Type {
ComputerFound,
Executed,
PairingCompleted,
Timedout,
};
Event(Type type)
: type(type), computerManager(nullptr), computer(nullptr) {}
Type type;
ComputerManager *computerManager;
NvComputer *computer;
QString errorMessage;
};
class LauncherPrivate
{
Q_DECLARE_PUBLIC(Launcher)
public:
LauncherPrivate(Launcher *q) : q_ptr(q) {}
void handleEvent(Event event)
{
Q_Q(Launcher);
switch (event.type) {
// Occurs when CliPair becomes visible and the UI calls launcher's execute()
case Event::Executed:
if (m_State == StateInit) {
m_State = StateSeekComputer;
m_ComputerManager = event.computerManager;
q->connect(m_ComputerManager, &ComputerManager::pairingCompleted,
q, &Launcher::onPairingCompleted);
// If we weren't provided a predefined PIN, generate one now
if (m_PredefinedPin.isEmpty()) {
m_PredefinedPin = m_ComputerManager->generatePinString();
}
m_ComputerSeeker = new ComputerSeeker(m_ComputerManager, m_ComputerName, q);
q->connect(m_ComputerSeeker, &ComputerSeeker::computerFound,
q, &Launcher::onComputerFound);
q->connect(m_ComputerSeeker, &ComputerSeeker::errorTimeout,
q, &Launcher::onTimeout);
m_ComputerSeeker->start(COMPUTER_SEEK_TIMEOUT);
emit q->searchingComputer();
}
break;
// Occurs when searched computer is found
case Event::ComputerFound:
if (m_State == StateSeekComputer) {
if (event.computer->pairState == NvComputer::PS_PAIRED) {
m_State = StateFailure;
QString msg = QObject::tr("%1 is already paired").arg(event.computer->name);
emit q->failed(msg);
}
else {
Q_ASSERT(!m_PredefinedPin.isEmpty());
m_State = StatePairing;
m_ComputerManager->pairHost(event.computer, m_PredefinedPin);
emit q->pairing(event.computer->name, m_PredefinedPin);
}
}
break;
// Occurs when pairing operation completes
case Event::PairingCompleted:
if (m_State == StatePairing) {
if (event.errorMessage.isEmpty()) {
m_State = StateComplete;
emit q->success();
}
else {
m_State = StateFailure;
emit q->failed(event.errorMessage);
}
}
break;
// Occurs when computer search timed out
case Event::Timedout:
if (m_State == StateSeekComputer) {
m_State = StateFailure;
emit q->failed(QObject::tr("Failed to connect to %1").arg(m_ComputerName));
}
break;
}
}
Launcher *q_ptr;
QString m_ComputerName;
QString m_PredefinedPin;
ComputerManager *m_ComputerManager;
ComputerSeeker *m_ComputerSeeker;
NvComputer *m_Computer;
State m_State;
QTimer *m_TimeoutTimer;
};
Launcher::Launcher(QString computer, QString predefinedPin, QObject *parent)
: QObject(parent),
m_DPtr(new LauncherPrivate(this))
{
Q_D(Launcher);
d->m_ComputerName = computer;
d->m_PredefinedPin = predefinedPin;
d->m_State = StateInit;
d->m_TimeoutTimer = new QTimer(this);
d->m_TimeoutTimer->setSingleShot(true);
connect(d->m_TimeoutTimer, &QTimer::timeout,
this, &Launcher::onTimeout);
}
Launcher::~Launcher()
{
}
void Launcher::execute(ComputerManager *manager)
{
Q_D(Launcher);
Event event(Event::Executed);
event.computerManager = manager;
d->handleEvent(event);
}
bool Launcher::isExecuted() const
{
Q_D(const Launcher);
return d->m_State != StateInit;
}
void Launcher::onComputerFound(NvComputer *computer)
{
Q_D(Launcher);
Event event(Event::ComputerFound);
event.computer = computer;
d->handleEvent(event);
}
void Launcher::onTimeout()
{
Q_D(Launcher);
Event event(Event::Timedout);
d->handleEvent(event);
}
void Launcher::onPairingCompleted(NvComputer* computer, QString error)
{
Q_D(Launcher);
Event event(Event::PairingCompleted);
event.computer = computer;
event.errorMessage = error;
d->handleEvent(event);
}
}
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include <QObject>
#include <QVariant>
class ComputerManager;
class NvComputer;
class Session;
class StreamingPreferences;
namespace CliPair
{
class Event;
class LauncherPrivate;
class Launcher : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE_D(m_DPtr, Launcher)
public:
explicit Launcher(QString computer, QString predefinedPin,
QObject *parent = nullptr);
~Launcher();
Q_INVOKABLE void execute(ComputerManager *manager);
Q_INVOKABLE bool isExecuted() const;
signals:
void searchingComputer();
void pairing(QString pcName, QString pin);
void failed(QString text);
void success();
private slots:
void onComputerFound(NvComputer *computer);
void onPairingCompleted(NvComputer *computer, QString error);
void onTimeout();
private:
QScopedPointer<LauncherPrivate> m_DPtr;
};
}
+3 -3
View File
@@ -6,7 +6,7 @@
#include <QCoreApplication>
#include <QTimer>
#define COMPUTER_SEEK_TIMEOUT 10000
#define COMPUTER_SEEK_TIMEOUT 30000
#define APP_SEEK_TIMEOUT 10000
namespace CliStartStream
@@ -118,7 +118,7 @@ public:
}
break;
// Occurs when the previous app quit has been completed, handles quitting errors if any
// happended. ComputerUpdated event's handler handles session start when previous app has
// happened. ComputerUpdated event's handler handles session start when previous app has
// quit.
case Event::AppQuitCompleted:
if (m_State == StateSeekApp && !event.errorMessage.isEmpty()) {
@@ -162,7 +162,7 @@ public:
QString getCurrentAppName() const
{
for (NvApp app : m_Computer->appList) {
for (const NvApp& app : std::as_const(m_Computer->appList)) {
if (m_Computer->currentGameId == app.id) {
return app.name;
}
@@ -1,41 +1,272 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<component type="desktop-application">
<id>com.moonlight_stream.Moonlight</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>Moonlight</name>
<summary>Play games remotely from your NVIDIA GameStream-enabled PC</summary>
<summary>Stream games and other applications from another PC running Sunshine or GeForce Experience</summary>
<description>
<p>Moonlight can stream games and other applications from a PC with an NVIDIA GeForce GTX/RTX or NVIDIA Quadro GPU and GeForce/Quadro Experience installed.</p>
<p>Moonlight can stream games and other applications from another PC with Sunshine or GeForce Experience software installed.</p>
<p>Features include:</p>
<ul>
<li>Streaming at up to 4K resolution</li>
<li>Support for up to 120 FPS streaming (high refresh rate monitor recommended)</li>
<li>Hardware accelerated video decoding with VAAPI, VDPAU, and NVDEC support</li>
<li>Hardware accelerated video decoding with VAAPI, VDPAU, and Vulkan Video support</li>
<li>H.264, HEVC, and AV1 codec support</li>
<li>7.1 surround sound audio support</li>
<li>10-point multitouch support</li>
<li>Gamepad support with force feedback for up to 16 players</li>
<li>Support for both pointer capture (for games) and direct mouse control (for remote desktop)</li>
<li>Support for passing system-wide keyboard shortcuts like Alt+Tab to the host</li>
<li>Direct touchscreen mouse control</li>
<li>HEVC support for better video compression efficiency</li>
<li>Gamepad support with force feedback for up to 4 players</li>
</ul>
</description>
<url type="homepage">https://moonlight-stream.org</url>
<url type="bugtracker">https://github.com/moonlight-stream/moonlight-qt/issues</url>
<url type="help">https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide</url>
<url type="vcs-browser">https://github.com/moonlight-stream/moonlight-qt</url>
<developer id="org.moonlight-stream">
<name>Moonlight Game Streaming Team</name>
</developer>
<update_contact>cameron@moonlight-stream.org</update_contact>
<launchable type="desktop-id">com.moonlight_stream.Moonlight.desktop</launchable>
<provides>
<binary>moonlight</binary>
</provides>
<content_rating type="oars-1.1" />
<branding>
<color type="primary" scheme_preference="light">#710085</color>
<color type="primary" scheme_preference="dark">#55285d</color>
</branding>
<screenshots>
<screenshot type="default">
<image>https://moonlight-stream.org/appstream_resources/moonlight_screenshot_1.png</image>
<caption>Host selection page showing local PCs</caption>
</screenshot>
<screenshot>
<image>https://moonlight-stream.org/appstream_resources/moonlight_screenshot_2.png</image>
<caption>Settings page displaying streaming options</caption>
</screenshot>
</screenshots>
<releases>
<release version="6.1.0" date="2024-09-16">
<description>
<p>New features:</p>
<ul>
<li>Experimental YUV 4:4:4 support for improved text clarity during remote desktop usage</li>
<li>HDR is now supported with software decoding (requires GPU with Vulkan support)</li>
<li>Bitrate limit can now be increased to 500 Mbps</li>
<li>Audio decoding now uses 32-bit floating point format</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed incorrect color range when streaming with AV1 from a host with an AMD GPU</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="6.0.1" date="2024-06-30">
<description>
<p>New features:</p>
<ul>
<li>HDR to SDR tonemapping is now supported by the Vulkan renderer on Linux</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>More time is now provided for PCs to wake up before displaying an error when starting a stream from the CLI</li>
<li>Moonlight will no longer try to guess VA driver names when running libva 2.20 or later</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed crash when the Vulkan renderer executed on a system with no Vulkan devices</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="6.0.0" date="2024-06-06">
<description>
<p>New features:</p>
<ul>
<li>HDR is now supported on Steam Deck and other HDR-capable Linux systems using a new Vulkan-based renderer</li>
<li>Vulkan Video decoding of H.264, HEVC, and AV1 is now supported using the new Vulkan renderer</li>
<li>Full E2E stream encryption is now supported when streaming from Sunshine v0.22 or later</li>
<li>Initiating a stream via the command-line will now automatically wake the target machine if it is sleeping</li>
<li>Error codes are now displayed in the connection termination dialog</li>
<li>Detailed PC state information is now available via the new "View Details" context menu option (similar to the Android client)</li>
<li>The performance overlay can now be configured to be shown by default when starting a stream</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>The selected bitrate is no longer silently adjusted by Moonlight based upon the video codec or HDR mode</li>
<li>The selected mouse mode when starting a stream no longer influences the acceleration curve when the mouse mode is toggled using the Ctrl+Alt+Shift+M key combo while streaming</li>
<li>Hardcoded fallback paths for VAAPI and VDPAU drivers are no longer used</li>
<li>Per-session keys (rikey and rikeyid values) are now automatically stripped from logs</li>
<li>Log messages will now be logged to stderr rather than stdout</li>
<li>EGL is now always used instead of GLX for loading OpenGL in X11 environments on non-x86 platforms</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Improved reliability of streaming during momentary drops of WiFi connections</li>
<li>Improved performance with high polling rate mice</li>
<li>Improved input latency when a gamepad is connected</li>
<li>Added missing command-line options to control HDR and AV1 codec usage</li>
<li>Fixed instant connection termination error when streaming over the Internet behind certain Carrier-Grade NAT devices</li>
<li>Fixed incorrect MTU detection when streaming over the Internet without a VPN</li>
<li>Fixed recovery of audio when no audio output device is present when the stream starts</li>
<li>Fixed merging of gamepad state when multi-controller mode is disabled</li>
<li>Fixed indefinitely resending mDNS queries when a host could not be resolved</li>
<li>Fixed inability to pair when the host is not using a RSA-2048 key</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="5.0.1" date="2023-11-02">
<description>
<p>Bugfixes:</p>
<ul>
<li>Fixed connection issue streaming from some hosts running GeForce Experience or Sunshine v0.20 and earlier</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="5.0.0" date="2023-10-18">
<description>
<p>New features:</p>
<ul>
<li>Custom FPS values</li>
<li>Streaming using the AV1 codec from Sunshine hosts</li>
<li>Horizontal scrolling with Sunshine hosts</li>
<li>Native multi-touch input with Sunshine hosts</li>
<li>Controller type information is passed to Sunshine for controller type autoselection</li>
<li>Extended features of PS4/PS5 controllers (touchpad, battery state, gyro/accelerometer motion, and RGB LED) are natively passed to Sunshine hosts</li>
<li>Support for up to 16 gamepads with Sunshine hosts</li>
<li>Frame pacing support on Wayland</li>
<li>Host-side processing latency is now displayed in the performance overlay with Sunshine hosts</li>
<li>Window title now includes the PC name when streaming</li>
<li>Alphabetical sorting of the PC list</li>
<li>Updated Play and Stop button design to improve contrast with app box art</li>
<li>The settings page automatically scrolls to the selected element when using keyboard or gamepad navigation</li>
<li>Pressing Share+PS buttons on PS4/PS5 controllers can be used to emulate a clickpad press</li>
<li>Improved audio quality when streaming with a high bitrate from remote hosts</li>
<li>Increased mouse polling rate</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>IPv6 addresses must be provided in URL-escaped form. Example: [2001:db8::1234:5678] or [2001:db8::1234:5678]:47989</li>
<li>Default bitrate logic has been adjusted to behave better with custom resolutions and frame rates</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Reduced the frequency of audio underruns (clicks and pops) by increasing audio buffer size</li>
<li>Fixed "Quitting App" message never dismissing in some cases</li>
<li>Fixed parsing IPv6 literals with port numbers</li>
<li>Fixed unnecessary WiFi activity causing stream disruptions</li>
<li>Fixed paired hosts being forgotten if Moonlight terminates while writing hosts to disk</li>
<li>Fixed freeze when closing the stream on Windows with some software that uses DX11 hooks</li>
<li>Fixed delayed PC wake when activating Wake-On-LAN feature</li>
<li>Fixed Wake-on-LAN when Sunshine is running on alternate ports</li>
<li>Fixed leak of /dev/dri fds when trying to initialize VAAPI decoder</li>
<li>Fixed support for the Applications/Menu key</li>
<li>Fixed automatic language detection for Simplified Chinese and Traditional Chinese</li>
<li>Fixed streaming from Sunshine when the client PC has multiple network interfaces or IPv6 privacy extensions enabled</li>
<li>Fixed small receive buffer causing video packet loss on some systems</li>
<li>Fixed theme overrides causing the UI to be unusable on some systems</li>
<li>Fixed tearing with V-Sync enabled on macOS and Linux when using the SDL renderer (software decoding and some hardware decoders)</li>
<li>Fixed stateful V4L2 hardware decoding using h264_v4l2m2m and hevc_v4l2m2m decoders</li>
<li>Fixed CVE-2023-42801</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.3.1" date="2022-11-03">
<description>
<p>Changes:</p>
<ul>
<li>Fixed crash during specific patterns of audio packet loss</li>
<li>Fixed detection of local streaming when using IPv6 addresses</li>
<li>Windowed mode streaming now starts maximized if the GUI window was maximized</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.3.0" date="2022-10-28">
<description>
<p>New features:</p>
<ul>
<li>Improved support for GeForce Experience 3.26</li>
<li>Improved image quality and performance when recovering from video packet loss using HEVC</li>
<li>Improved error concealment after audio packet loss</li>
<li>Improved UI performance when paired with many hosts or hosts with large numbers of apps</li>
<li>Pairing with Sunshine hosts is now supported even if the host is in a streaming session</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed streaming at resolutions below 720x480 with GeForce Experience 3.26</li>
<li>Fixed window position and size being lost when toggling between full-screen and windowed mode</li>
<li>Fixed initial window size not always respecting the stream aspect ratio</li>
<li>Fixed unexpected error when streaming at resolutions above 4096x4096 using Sunshine</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.2.1" date="2022-09-12">
<description>
<p>Bugfixes:</p>
<ul>
<li>Fixed streaming from hosts running Sunshine</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.2.0" date="2022-09-10">
<description>
<p>New features:</p>
<ul>
<li>Added support for pairing via the terminal</li>
<li>Added support for listing installed apps on a host via the terminal</li>
<li>Improved handling of V-Sync on Wayland systems to reduce latency</li>
<li>Improved performance using the legacy non-EGL VAAPI rendering code</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed native resolution detection on high DPI Wayland systems</li>
<li>Fixed audio crackling with SDL 2.24.0 on systems using PulseAudio</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.1.0" date="2022-05-23">
<description>
<p>New features:</p>
<ul>
<li>Overlays are now supported on the non-EGL X11 VAAPI renderer (requires RGBA subpicture support in the VAAPI driver)</li>
<li>Cursor lock can now be disabled when in full-screen mode</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>Moonlight can now reduce the client display resolution in full-screen mode if the current display mode doesn't have a high enough refresh rate for the selected stream frame rate</li>
<li>When choosing a new client display resolution in full-screen mode, Moonlight will pick a display mode with the closest aspect ratio to the selected stream resolution</li>
<li>Moonlight now defaults to borderless windowed mode on Wayland systems</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed missing toolbar buttons in certain languages</li>
<li>Fixed some text on the settings page not updating when the language is changed</li>
<li>Fixed a frame pacing bug that could cause excessive frame drops</li>
<li>Fixed the "keep display awake" setting not being saved when Moonlight restarts</li>
<li>Fixed black screen after unmaximizing the Moonlight window on some Linux systems</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.0.0" date="2022-04-02">
<description>
<p>New features:</p>
@@ -602,19 +833,4 @@
</release>
</releases>
<categories>
<category>Game</category>
<category>Qt</category>
</categories>
<developer_name>Moonlight Game Streaming Team</developer_name>
<update_contact>cameron@moonlight-stream.org</update_contact>
<launchable type="desktop-id">com.moonlight_stream.Moonlight.desktop</launchable>
<provides>
<binary>moonlight</binary>
</provides>
<content_rating type="oars-1.0" />
</component>
@@ -1,9 +1,9 @@
[Desktop Entry]
Name=Moonlight
Comment=Stream games from your NVIDIA GameStream-enabled PC
Comment=Stream games and other applications from another PC running Sunshine or GeForce Experience
Exec=moonlight
Icon=moonlight
Terminal=false
Type=Application
Categories=Qt;Game;
Keywords=nvidia;gamestream;stream;
Categories=Qt;Game;Network;RemoteAccess;
Keywords=nvidia;gamestream;stream;sunshine;remote play;
+5 -1
View File
@@ -5,9 +5,13 @@
# pairing data will be lost each reboot.
HOME=/usr/local/moonlight
# Enable Steam Controller detection in SDL
# https://github.com/moonlight-stream/moonlight-qt/issues/697
export SDL_ENABLE_STEAM_CONTROLLERS=1
# Renice PE_Single_CPU which seems to host A/V stuff
renice -10 -p $(pidof PE_Single_CPU)
# Renice Moonlight itself to avoid preemption by background tasks
# Write output to a logfile in /tmp
exec nice -n -10 ./bin/moonlight > /tmp/moonlight.log
exec nice -n -10 ./bin/moonlight > /tmp/moonlight.log 2>&1
+44 -36
View File
@@ -1,5 +1,6 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import AppModel 1.0
import ComputerManager 1.0
@@ -37,7 +38,7 @@ CenteredGridView {
activated = true
// Highlight the first item if a gamepad is connected
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
if (currentIndex === -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
currentIndex = 0
}
@@ -89,13 +90,13 @@ CenteredGridView {
onSourceSizeChanged: {
// Nearly all of Nvidia's official box art does not match the dimensions of placeholder
// images, however the one known exeception is Overcooked. Therefore, we only execute
// images, however the one known exception is Overcooked. Therefore, we only execute
// the image size checks if this is not an app collector game. We know the officially
// supported games all have box art, so this check is not required.
if (!model.isAppCollectorGame &&
((sourceSize.width == 130 && sourceSize.height == 180) || // GFE 2.0 placeholder image
(sourceSize.width == 628 && sourceSize.height == 888) || // GFE 3.0 placeholder image
(sourceSize.width == 200 && sourceSize.height == 266))) // Our no_app_image.png
((sourceSize.width === 130 && sourceSize.height === 180) || // GFE 2.0 placeholder image
(sourceSize.width === 628 && sourceSize.height === 888) || // GFE 3.0 placeholder image
(sourceSize.width === 200 && sourceSize.height === 266))) // Our no_app_image.png
{
isPlaceholder = true
}
@@ -121,21 +122,19 @@ CenteredGridView {
anchors.fill: appIcon
sourceComponent: Item {
ToolButton {
RoundButton {
// Don't steal focus from the toolbar buttons
focusPolicy: Qt.NoFocus
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? -47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : -60
anchors.centerIn: parent
implicitWidth: 125
implicitHeight: 125
implicitWidth: 85
implicitHeight: 85
Image {
source: "qrc:/res/baseline-play_circle_filled_white-48px.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
}
}
icon.source: "qrc:/res/play_arrow_FILL1_wght700_GRAD200_opsz48.svg"
icon.width: 75
icon.height: 75
onClicked: {
launchOrResumeSelectedApp(true)
@@ -145,23 +144,23 @@ CenteredGridView {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
Material.background: "#D0808080"
}
ToolButton {
RoundButton {
// Don't steal focus from the toolbar buttons
focusPolicy: Qt.NoFocus
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? 47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : 60
anchors.centerIn: parent
implicitWidth: 125
implicitHeight: 125
implicitWidth: 85
implicitHeight: 85
Image {
source: "qrc:/res/baseline-cancel-24px.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
}
}
icon.source: "qrc:/res/stop_FILL1_wght700_GRAD200_opsz48.svg"
icon.width: 75
icon.height: 75
onClicked: {
doQuitGame()
@@ -171,6 +170,8 @@ CenteredGridView {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
Material.background: "#D0808080"
}
}
}
@@ -251,7 +252,7 @@ CenteredGridView {
anchors.fill: parent
acceptedButtons: Qt.RightButton;
onClicked: {
parent.onPressAndHold()
parent.pressAndHold()
}
}
@@ -293,19 +294,17 @@ CenteredGridView {
asynchronous: true
sourceComponent: NavigableMenu {
id: appContextMenu
initiator: appContextMenuLoader.parent
NavigableMenuItem {
parentMenu: appContextMenu
text: model.running ? qsTr("Resume Game") : qsTr("Launch Game")
onTriggered: launchOrResumeSelectedApp(true)
}
NavigableMenuItem {
parentMenu: appContextMenu
text: qsTr("Quit Game")
onTriggered: doQuitGame()
visible: model.running
}
NavigableMenuItem {
parentMenu: appContextMenu
checkable: true
checked: model.directLaunch
text: qsTr("Direct Launch")
@@ -318,7 +317,6 @@ CenteredGridView {
ToolTip.visible: hovered
}
NavigableMenuItem {
parentMenu: appContextMenu
checkable: true
checked: model.hidden
text: qsTr("Hide Game")
@@ -334,6 +332,19 @@ CenteredGridView {
}
}
Row {
anchors.centerIn: parent
spacing: 5
visible: appGrid.count === 0
Label {
text: qsTr("This computer doesn't seem to have any applications or some applications are hidden")
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
NavigableMessageDialog {
id: quitAppDialog
property string appName : ""
@@ -345,7 +356,7 @@ CenteredGridView {
function quitApp() {
var component = Qt.createComponent("QuitSegue.qml")
var params = {"appName": appName}
var params = {"appName": appName, "quitRunningAppFn": function() { appModel.quitRunningApp() }}
if (segueToStream) {
// Store the session and app name if we're going to stream after
// successfully quitting the old app.
@@ -358,9 +369,6 @@ CenteredGridView {
}
stackView.push(component.createObject(stackView, params))
// Trigger the quit after pushing the quit segue on screen
appModel.quitRunningApp()
}
onAccepted: quitApp()
+15
View File
@@ -2,6 +2,7 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import SdlGamepadKeyNavigation 1.0
import SystemProperties 1.0
// https://stackoverflow.com/questions/45029968/how-do-i-set-the-combobox-width-to-fit-the-largest-item
ComboBox {
@@ -38,9 +39,23 @@ ComboBox {
popup.onAboutToShow: {
// Switch to normal navigation for combo boxes
SdlGamepadKeyNavigation.setUiNavMode(false)
// Override the popup color to improve contrast with the overridden
// Material 2 background color set in main.qml.
if (SystemProperties.usesMaterial3Theme) {
popup.background.color = "#424242"
}
}
popup.onAboutToHide: {
SdlGamepadKeyNavigation.setUiNavMode(true)
}
Keys.onLeftPressed: {
decrementCurrentIndex()
}
Keys.onRightPressed: {
incrementCurrentIndex()
}
}
-18
View File
@@ -2,10 +2,6 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
GridView {
// Detect Qt 5.11 or earlier using presence of synchronousDrag.
// Prior to 5.12, the leftMargin and rightMargin values did not work.
property bool hasBrokenMargins: this.synchronousDrag === undefined
property int minMargin: 10
property real availableWidth: (parent.width - 2 * minMargin)
property int itemsPerRow: availableWidth / cellWidth
@@ -15,11 +11,6 @@ GridView {
function updateMargins() {
leftMargin = horizontalMargin
rightMargin = horizontalMargin
if (hasBrokenMargins) {
anchors.leftMargin = leftMargin
anchors.rightMargin = rightMargin
}
}
onHorizontalMarginChanged: {
@@ -27,15 +18,6 @@ GridView {
}
Component.onCompleted: {
if (hasBrokenMargins) {
// This will cause an anchor conflict with the parent StackView
// which breaks animation, but otherwise the grid will not be
// centered in the window.
anchors.fill = parent
anchors.topMargin = topMargin
anchors.bottomMargin = bottomMargin
}
updateMargins()
}
+87
View File
@@ -0,0 +1,87 @@
import QtQuick 2.0
import QtQuick.Controls 2.2
import ComputerManager 1.0
Item {
function onSearchingComputer() {
stageLabel.text = qsTr("Establishing connection to PC...")
}
function onPairing(pcName, pin) {
stageLabel.text = qsTr("Pairing... Please enter '%1' on %2.").arg(pin).arg(pcName)
}
function onFailed(message) {
stageIndicator.visible = false
errorDialog.text = message
errorDialog.open()
}
function onSuccess(appName) {
stageIndicator.visible = false
pairCompleteDialog.open()
}
// Allow user to back out of pairing
Keys.onEscapePressed: {
Qt.quit()
}
Keys.onBackPressed: {
Qt.quit()
}
Keys.onCancelPressed: {
Qt.quit()
}
StackView.onActivated: {
if (!launcher.isExecuted()) {
toolBar.visible = false
launcher.searchingComputer.connect(onSearchingComputer)
launcher.pairing.connect(onPairing)
launcher.failed.connect(onFailed)
launcher.success.connect(onSuccess)
launcher.execute(ComputerManager)
}
}
Row {
anchors.centerIn: parent
spacing: 5
id: stageIndicator
BusyIndicator {
id: stageSpinner
running: visible
}
Label {
id: stageLabel
height: stageSpinner.height
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
ErrorMessageDialog {
id: errorDialog
onClosed: {
Qt.quit();
}
}
NavigableMessageDialog {
id: pairCompleteDialog
closePolicy: Popup.CloseOnEscape
text:qsTr("Pairing completed successfully")
standardButtons: Dialog.Ok
onClosed: {
Qt.quit()
}
}
}
+1
View File
@@ -34,6 +34,7 @@ Item {
BusyIndicator {
id: stageSpinner
running: visible
}
Label {
+3 -8
View File
@@ -2,7 +2,6 @@ import QtQuick 2.0
import QtQuick.Controls 2.2
import ComputerManager 1.0
import SdlGamepadKeyNavigation 1.0
Item {
function onSearchingComputer() {
@@ -26,6 +25,7 @@ Item {
function onLaunchFailed(message) {
errorDialog.text = message
errorDialog.open()
console.error(message)
}
function onAppQuitRequired(appName) {
@@ -37,10 +37,6 @@ Item {
if (!launcher.isExecuted()) {
toolBar.visible = false
// Normally this is enabled by PcView, but we will won't
// load PcView when streaming from the command-line.
SdlGamepadKeyNavigation.enable()
launcher.searchingComputer.connect(onSearchingComputer)
launcher.searchingApp.connect(onSearchingApp)
launcher.sessionCreated.connect(onSessionCreated)
@@ -56,6 +52,7 @@ Item {
BusyIndicator {
id: stageSpinner
running: visible
}
Label {
@@ -84,10 +81,8 @@ Item {
function quitApp() {
var component = Qt.createComponent("QuitSegue.qml")
var params = {"appName": appName}
var params = {"appName": appName, "quitRunningAppFn": function() { launcher.quitRunningApp() }}
stackView.push(component.createObject(stackView, params))
// Trigger the quit after pushing the quit segue on screen
launcher.quitRunningApp()
}
onAccepted: quitApp()
+6 -10
View File
@@ -1,17 +1,13 @@
import QtQuick 2.0
import QtQuick.Controls 2.2
import QtQuick.Controls 2.5
Dialog {
// We should use Overlay.overlay here but that's not available in Qt 5.9 :(
parent: ApplicationWindow.contentItem
modal: true
anchors.centerIn: Overlay.overlay
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2)
onAboutToHide: {
// We must force focus back to the last item for platforms without
// support for more than one active window like Steam Link. If
// we don't, gamepad and keyboard navigation will break after a
onClosed: {
// We must force focus back to the last item. If we don't,
// gamepad and keyboard navigation will break after a
// dialog appears.
stackView.forceActiveFocus()
}
+5
View File
@@ -17,6 +17,11 @@ ItemDelegate {
}
Keys.onUpPressed: {
grid.moveCurrentIndexUp()
// If we've reached the top of the grid, move focus to the toolbar
if (grid.currentItem === this) {
nextItemInFocusChain(false).forceActiveFocus(Qt.TabFocus)
}
}
Keys.onReturnPressed: {
clicked()
+11 -6
View File
@@ -2,13 +2,18 @@ import QtQuick 2.0
import QtQuick.Controls 2.2
Menu {
property var initiator
onOpened: {
// Give focus to the first visible and enabled menu item
for (var i = 0; i < count; i++) {
var item = itemAt(i)
if (item.visible && item.enabled) {
item.forceActiveFocus(Qt.TabFocusReason)
break
// If the initiating object currently has keyboard focus,
// give focus to the first visible and enabled menu item
if (initiator.focus) {
for (var i = 0; i < count; i++) {
var item = itemAt(i)
if (item.visible && item.enabled) {
item.forceActiveFocus(Qt.TabFocusReason)
break
}
}
}
}
+2 -6
View File
@@ -2,10 +2,6 @@ import QtQuick 2.0
import QtQuick.Controls 2.2
MenuItem {
// Qt 5.10 has a menu property, but we need to support 5.9
// so we must make our own.
property Menu parentMenu
// Ensure focus can't be given to an invisible item
enabled: visible
height: visible ? implicitHeight : 0
@@ -15,7 +11,7 @@ MenuItem {
// We must close the context menu first or
// it can steal focus from any dialogs that
// onTriggered may spawn.
parentMenu.close()
menu.close()
}
Keys.onReturnPressed: {
@@ -27,6 +23,6 @@ MenuItem {
}
Keys.onEscapePressed: {
parentMenu.close()
menu.close()
}
}
+13 -13
View File
@@ -15,7 +15,9 @@ NavigableDialog {
onOpened: {
// Force keyboard focus on the label so keyboard navigation works
dialogLabel.forceActiveFocus()
if (dialogButtonBox.count > 0) {
dialogButtonBox.itemAt(dialogButtonBox.count - 1).forceActiveFocus(Qt.TabFocus)
}
}
RowLayout {
@@ -24,6 +26,7 @@ NavigableDialog {
BusyIndicator {
id: dialogSpinner
visible: false
running: visible
}
Image {
@@ -51,18 +54,6 @@ NavigableDialog {
// will cause word wrap to kick in.
Layout.maximumWidth: 400
Layout.maximumHeight: 400
Keys.onReturnPressed: {
accept()
}
Keys.onEnterPressed: {
accept()
}
Keys.onEscapePressed: {
reject()
}
}
}
@@ -70,6 +61,15 @@ NavigableDialog {
id: dialogButtonBox
standardButtons: dialog.standardButtons
delegate: Button {
flat: true
Keys.onReturnPressed: clicked()
Keys.onEnterPressed: clicked()
Keys.onRightPressed: nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocus)
Keys.onLeftPressed: nextItemInFocusChain(false).forceActiveFocus(Qt.TabFocus)
}
onHelpRequested: {
Qt.openUrlExternally(helpUrl)
close()
+3 -11
View File
@@ -7,17 +7,9 @@ ToolButton {
activeFocusOnTab: true
// FIXME: We're using an Image here rather than icon.source because
// icons don't work on Qt 5.9 LTS.
Image {
id: image
source: iconSource
anchors.centerIn: parent.background
sourceSize {
width: parent.background.width * 1.10
height: parent.background.height * 1.10
}
}
icon.source: iconSource
icon.width: background.width
icon.height: background.height
// This determines the size of the Material highlight. We increase it
// from the default because we use larger than normal icons for TV readability.
+47 -45
View File
@@ -6,6 +6,7 @@ import ComputerModel 1.0
import ComputerManager 1.0
import StreamingPreferences 1.0
import SystemProperties 1.0
import SdlGamepadKeyNavigation 1.0
CenteredGridView {
@@ -33,13 +34,8 @@ CenteredGridView {
// Setup signals on CM
ComputerManager.computerAddCompleted.connect(addComplete)
// This is a bit of a hack to do this here as opposed to main.qml, but
// we need it enabled before calling getConnectedGamepads() and PcView
// is never destroyed, so it should be okay.
SdlGamepadKeyNavigation.enable()
// Highlight the first item if a gamepad is connected
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
if (currentIndex === -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
currentIndex = 0
}
}
@@ -94,12 +90,13 @@ CenteredGridView {
BusyIndicator {
id: searchSpinner
visible: StreamingPreferences.enableMdns
running: visible
}
Label {
height: searchSpinner.height
elide: Label.ElideRight
text: StreamingPreferences.enableMdns ? qsTr("Searching for PCs on your local network with NVIDIA GameStream enabled...")
text: StreamingPreferences.enableMdns ? qsTr("Searching for compatible hosts on your local network...")
: qsTr("Automatic PC discovery is disabled. Add your PC manually.")
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
@@ -130,12 +127,12 @@ CenteredGridView {
id: stateIcon
anchors.horizontalCenter: pcIcon.horizontalCenter
anchors.verticalCenter: pcIcon.verticalCenter
anchors.verticalCenterOffset: -15
anchors.verticalCenterOffset: !model.online ? -18 : -16
visible: !model.statusUnknown && (!model.online || !model.paired)
source: !model.online ? "qrc:/res/baseline-warning-24px.svg" : "qrc:/res/baseline-lock-24px.svg"
source: !model.online ? "qrc:/res/warning_FILL1_wght300_GRAD200_opsz24.svg" : "qrc:/res/baseline-lock-24px.svg"
sourceSize {
width: 75
height: 75
width: !model.online ? 75 : 70
height: !model.online ? 75 : 70
}
}
@@ -147,6 +144,7 @@ CenteredGridView {
width: 75
height: 75
visible: model.statusUnknown
running: visible
}
Label {
@@ -167,13 +165,13 @@ CenteredGridView {
asynchronous: true
sourceComponent: NavigableMenu {
id: pcContextMenu
initiator: pcContextMenuLoader.parent
MenuItem {
text: qsTr("PC Status: %1").arg(model.online ? qsTr("Online") : qsTr("Offline"))
font.bold: true
enabled: false
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("View All Apps")
onTriggered: {
var component = Qt.createComponent("AppView.qml")
@@ -183,13 +181,11 @@ CenteredGridView {
visible: model.online && model.paired
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Wake PC")
onTriggered: computerModel.wakeComputer(index)
visible: !model.online && model.wakeable
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Test Network")
onTriggered: {
computerModel.testConnectionForComputer(index)
@@ -198,7 +194,6 @@ CenteredGridView {
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Rename PC")
onTriggered: {
renamePcDialog.pcIndex = index
@@ -207,14 +202,20 @@ CenteredGridView {
}
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Delete PC")
onTriggered: {
deletePcDialog.pcIndex = index
// get confirmation first, actual closing is called from the dialog
deletePcDialog.pcName = model.name
deletePcDialog.open()
}
}
NavigableMenuItem {
text: qsTr("View Details")
onTriggered: {
showPcDetailsDialog.pcDetails = model.details
showPcDetailsDialog.open()
}
}
}
}
@@ -232,22 +233,14 @@ CenteredGridView {
stackView.push(appView)
}
else {
if (!model.busy) {
var pin = computerModel.generatePinString()
var pin = computerModel.generatePinString()
// Kick off pairing in the background
computerModel.pairComputer(index, pin)
// Kick off pairing in the background
computerModel.pairComputer(index, pin)
// Display the pairing dialog
pairDialog.pin = pin
pairDialog.open()
}
else {
// cannot pair while something is streaming or attempting to pair
errorDialog.text = qsTr("You cannot pair while a previous session is still running on the host PC. Quit any running games or reboot the host PC, then try pairing again.")
errorDialog.helpText = ""
errorDialog.open()
}
// Display the pairing dialog
pairDialog.pin = pin
pairDialog.open()
}
} else if (!model.online) {
// Using open() here because it may be activated by keyboard
@@ -270,7 +263,7 @@ CenteredGridView {
anchors.fill: parent
acceptedButtons: Qt.RightButton;
onClicked: {
parent.onPressAndHold()
parent.pressAndHold()
}
}
@@ -279,6 +272,12 @@ CenteredGridView {
// the ItemDelegate and not where the mouse cursor is
pcContextMenu.open()
}
Keys.onDeletePressed: {
deletePcDialog.pcIndex = index
deletePcDialog.pcName = model.name
deletePcDialog.open()
}
}
ErrorMessageDialog {
@@ -291,15 +290,12 @@ CenteredGridView {
NavigableMessageDialog {
id: pairDialog
// Pairing dialog must be modal to prevent double-clicks from triggering
// pairing twice
modal: true
closePolicy: Popup.CloseOnEscape
// don't allow edits to the rest of the window while open
property string pin : "0000"
text:qsTr("Please enter %1 on your GameStream PC. This dialog will close when pairing is completed.").arg(pin)
text:qsTr("Please enter %1 on your host PC. This dialog will close when pairing is completed.").arg(pin)+"\n\n"+
qsTr("If your host PC is running Sunshine, navigate to the Sunshine web UI to enter the PIN.")
standardButtons: Dialog.Cancel
onRejected: {
// FIXME: We should interrupt pairing here
@@ -309,16 +305,14 @@ CenteredGridView {
NavigableMessageDialog {
id: deletePcDialog
// don't allow edits to the rest of the window while open
property int pcIndex : -1;
text:qsTr("Are you sure you want to remove this PC?")
property int pcIndex : -1
property string pcName : ""
text: qsTr("Are you sure you want to remove '%1'?").arg(pcName)
standardButtons: Dialog.Yes | Dialog.No
function deletePc() {
console.log("deleting PC pairing for PC at index: " + pcIndex)
computerModel.deleteComputer(pcIndex);
onAccepted: {
computerModel.deleteComputer(pcIndex)
}
onAccepted: deletePc()
}
NavigableMessageDialog {
@@ -327,7 +321,7 @@ CenteredGridView {
standardButtons: Dialog.Ok
onAboutToShow: {
testConnectionDialog.text = qsTr("Moonlight is testing your network connection to determine if NVIDIA GameStream is blocked.") + "\n\n" + qsTr("This may take a few seconds…")
testConnectionDialog.text = qsTr("Moonlight is testing your network connection to determine if any required ports are blocked.") + "\n\n" + qsTr("This may take a few seconds…")
showSpinner = true
}
@@ -398,5 +392,13 @@ CenteredGridView {
}
}
NavigableMessageDialog {
id: showPcDetailsDialog
property string pcDetails : "";
text: showPcDetailsDialog.pcDetails
imageSrc: "qrc:/res/baseline-help_outline-24px.svg"
standardButtons: Dialog.Ok
}
ScrollBar.vertical: ScrollBar {}
}
+8
View File
@@ -6,6 +6,7 @@ import Session 1.0
Item {
property string appName
property var quitRunningAppFn
property Session nextSession : null
property string nextAppName : ""
@@ -17,6 +18,7 @@ Item {
if (error !== undefined) {
errorDialog.text = error
errorDialog.open()
console.error(error)
}
// If we're supposed to launch another game after this, do so now
@@ -37,6 +39,11 @@ Item {
// Connect the quit completion signal
ComputerManager.quitAppCompleted.connect(quitAppCompleted)
// Start the quit operation if requested
if (quitRunningAppFn) {
quitRunningAppFn()
}
}
StackView.onDeactivating: {
@@ -53,6 +60,7 @@ Item {
BusyIndicator {
id: stageSpinner
running: visible
}
Label {
+527 -253
View File
File diff suppressed because it is too large Load Diff
+63 -34
View File
@@ -4,6 +4,7 @@ import QtQuick.Window 2.2
import SdlGamepadKeyNavigation 1.0
import Session 1.0
import SystemProperties 1.0
Item {
property Session session
@@ -45,17 +46,7 @@ Item {
{
// Display the error dialog after Session::exec() returns
streamSegueErrorDialog.text = text
}
function displayLaunchWarning(text)
{
// This toast appears for 3 seconds, just shorter than how long
// Session will wait for it to be displayed. This gives it time
// to transition to invisible before continuing.
var toast = Qt.createQmlObject('import QtQuick.Controls 2.2; ToolTip {}', parent, '')
toast.text = text
toast.timeout = 3000
toast.visible = true
console.error(text)
}
function quitStarting()
@@ -74,23 +65,19 @@ Item {
streamSegueErrorDialog.text += "\n\n" + qsTr("This PC's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network.")
}
// Enable GUI gamepad usage now
// Re-enable GUI gamepad usage now
SdlGamepadKeyNavigation.enable()
if (quitAfter) {
if (streamSegueErrorDialog.text) {
// Quit when the error dialog is acknowledged
streamSegueErrorDialog.quitAfter = quitAfter
streamSegueErrorDialog.open()
}
else {
// Quit immediately
Qt.quit()
}
} else {
// Exit this view
// Pop the StreamSegue off the stack if this is a GUI-based app launch
if (!quitAfter) {
stackView.pop()
}
if (quitAfter && !streamSegueErrorDialog.text) {
// If this was a CLI launch without errors, exit now
Qt.quit()
}
else {
// Show the Qt window again after streaming
window.visible = true
@@ -117,7 +104,7 @@ Item {
// Show the toolbar again when popped off the stack
toolBar.visible = true
// Enable GUI gamepad usage now
// Re-enable GUI gamepad usage now
SdlGamepadKeyNavigation.enable()
}
@@ -130,11 +117,14 @@ Item {
session.stageFailed.connect(stageFailed)
session.connectionStarted.connect(connectionStarted)
session.displayLaunchError.connect(displayLaunchError)
session.displayLaunchWarning.connect(displayLaunchWarning)
session.quitStarting.connect(quitStarting)
session.sessionFinished.connect(sessionFinished)
session.readyForDeletion.connect(sessionReadyForDeletion)
// Ensure the SystemProperties async thread is finished,
// since it may currently be using the SDL video subsystem
SystemProperties.waitForAsyncLoad()
// Kick off the stream
spinnerTimer.start()
streamLoader.active = true
@@ -149,7 +139,20 @@ Item {
// middle of the animation on Windows, which looks very
// obviously broken.
interval: 100
onTriggered: stageSpinner.running = true
onTriggered: stageSpinner.visible = true
}
Timer {
id: startSessionTimer
onTriggered: {
// Garbage collect QML stuff before we start streaming,
// since we'll probably be streaming for a while and we
// won't be able to GC during the stream.
gc()
// Run the streaming session to completion
session.start()
}
}
Loader {
@@ -168,13 +171,38 @@ Item {
// Stop GUI gamepad usage now
SdlGamepadKeyNavigation.disable()
// Garbage collect QML stuff before we start streaming,
// since we'll probably be streaming for a while and we
// won't be able to GC during the stream.
gc()
// Initialize the session and probe for host/client capabilities
if (!session.initialize(window)) {
sessionFinished(0);
sessionReadyForDeletion();
return;
}
// Run the streaming session to completion
session.exec(Screen.virtualX, Screen.virtualY)
// Don't wait unless we have toasts to display
startSessionTimer.interval = 0
// Display the toasts together in a vertical centered arrangement
var yOffset = 0
for (var i = 0; i < session.launchWarnings.length; i++) {
var text = session.launchWarnings[i]
console.warn(text)
// Show the tooltip for 3 seconds
var toast = Qt.createQmlObject('import QtQuick.Controls 2.2; ToolTip {}', parent, '')
toast.timeout = 3000
toast.text = text
toast.y += yOffset
toast.visible = true
// Offset the next toast below the previous one
yOffset = toast.y + toast.padding + toast.height
// Allow an extra 500 ms for the tooltip's fade-out animation to finish
startSessionTimer.interval = toast.timeout + 500;
}
// Start the timer to wait for toasts (or start the session immediately)
startSessionTimer.start()
}
sourceComponent: Item {}
@@ -186,7 +214,8 @@ Item {
BusyIndicator {
id: stageSpinner
running: false
running: visible
visible: false
}
Label {
+3 -3
View File
@@ -120,7 +120,7 @@ void AppModel::quitRunningApp()
bool AppModel::isAppCurrentlyVisible(const NvApp& app)
{
for (const NvApp& visibleApp : m_VisibleApps) {
for (const NvApp& visibleApp : std::as_const(m_VisibleApps)) {
if (app.id == visibleApp.id) {
return true;
}
@@ -156,7 +156,7 @@ void AppModel::updateAppList(QVector<NvApp> newList)
const NvApp& existingApp = m_VisibleApps.at(i);
bool found = false;
for (const NvApp& newApp : newVisibleList) {
for (const NvApp& newApp : std::as_const(newVisibleList)) {
if (existingApp.id == newApp.id) {
// If the data changed, update it in our list
if (existingApp != newApp) {
@@ -178,7 +178,7 @@ void AppModel::updateAppList(QVector<NvApp> newList)
}
// Process additions now
for (const NvApp& newApp : newVisibleList) {
for (const NvApp& newApp : std::as_const(newVisibleList)) {
int insertionIndex = m_VisibleApps.size();
bool found = false;
+52 -19
View File
@@ -2,8 +2,6 @@
#include <QThreadPool>
#include <random>
ComputerModel::ComputerModel(QObject* object)
: QAbstractListModel(object) {}
@@ -44,6 +42,46 @@ QVariant ComputerModel::data(const QModelIndex& index, int role) const
return computer->state == NvComputer::CS_UNKNOWN;
case ServerSupportedRole:
return computer->isSupportedServerVersion;
case DetailsRole: {
QString state, pairState;
switch (computer->state) {
case NvComputer::CS_ONLINE:
state = tr("Online");
break;
case NvComputer::CS_OFFLINE:
state = tr("Offline");
break;
default:
state = tr("Unknown");
break;
}
switch (computer->pairState) {
case NvComputer::PS_PAIRED:
pairState = tr("Paired");
break;
case NvComputer::PS_NOT_PAIRED:
pairState = tr("Unpaired");
break;
default:
pairState = tr("Unknown");
break;
}
return tr("Name: %1").arg(computer->name) + '\n' +
tr("Status: %1").arg(state) + '\n' +
tr("Active Address: %1").arg(computer->activeAddress.toString()) + '\n' +
tr("UUID: %1").arg(computer->uuid) + '\n' +
tr("Local Address: %1").arg(computer->localAddress.toString()) + '\n' +
tr("Remote Address: %1").arg(computer->remoteAddress.toString()) + '\n' +
tr("IPv6 Address: %1").arg(computer->ipv6Address.toString()) + '\n' +
tr("Manual Address: %1").arg(computer->manualAddress.toString()) + '\n' +
tr("MAC Address: %1").arg(computer->macAddress.isEmpty() ? tr("Unknown") : QString(computer->macAddress.toHex(':'))) + '\n' +
tr("Pair State: %1").arg(pairState) + '\n' +
tr("Running Game ID: %1").arg(computer->state == NvComputer::CS_ONLINE ? QString::number(computer->currentGameId) : tr("Unknown")) + '\n' +
tr("HTTPS Port: %1").arg(computer->state == NvComputer::CS_ONLINE ? QString::number(computer->activeHttpsPort) : tr("Unknown"));
}
default:
return QVariant();
}
@@ -71,6 +109,7 @@ QHash<int, QByteArray> ComputerModel::roleNames() const
names[WakeableRole] = "wakeable";
names[StatusUnknownRole] = "statusUnknown";
names[ServerSupportedRole] = "serverSupported";
names[DetailsRole] = "details";
return names;
}
@@ -140,14 +179,9 @@ void ComputerModel::renameComputer(int computerIndex, QString name)
m_ComputerManager->renameHost(m_Computers[computerIndex], name);
}
// TODO: Use QRandomGenerator when we drop Qt 5.9 support
QString ComputerModel::generatePinString()
{
std::uniform_int_distribution<int> dist(0, 9999);
std::random_device rd;
std::mt19937 engine(rd());
return QString::asprintf("%04u", dist(engine));
return m_ComputerManager->generatePinString();
}
class DeferredTestConnectionTask : public QObject, public QRunnable
@@ -193,19 +227,18 @@ void ComputerModel::handlePairingCompleted(NvComputer*, QString error)
void ComputerModel::handleComputerStateChanged(NvComputer* computer)
{
// If this is an existing computer, we can report the data changed
int index = m_Computers.indexOf(computer);
if (index >= 0) {
// Let the view know that this specific computer changed
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
QVector<NvComputer*> newComputerList = m_ComputerManager->getComputers();
// Reset the model if the structural layout of the list has changed
if (m_Computers != newComputerList) {
beginResetModel();
m_Computers = newComputerList;
endResetModel();
}
else {
// This is a new PC which may be inserted at an arbitrary point
// in our computer list (since it comes from CM's QMap). Reload
// the whole model state to ensure it stays consistent.
beginResetModel();
m_Computers = m_ComputerManager->getComputers();
endResetModel();
// Let the view know that this specific computer changed
int index = m_Computers.indexOf(computer);
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
}
}
+2 -1
View File
@@ -15,7 +15,8 @@ class ComputerModel : public QAbstractListModel
BusyRole,
WakeableRole,
StatusUnknownRole,
ServerSupportedRole
ServerSupportedRole,
DetailsRole
};
public:
+89 -53
View File
@@ -2,6 +2,7 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.2
import ComputerManager 1.0
import AutoUpdateChecker 1.0
@@ -18,23 +19,81 @@ ApplicationWindow {
property bool clearOnBack: false
id: window
visible: true
width: 1280
height: 600
visibility: {
// This function runs prior to creation of the initial StackView item
function doEarlyInit() {
// Override the background color to Material 2 colors for Qt 6.5+
// in order to improve contrast between GFE's placeholder box art
// and the background of the app grid.
if (SystemProperties.usesMaterial3Theme) {
Material.background = "#303030"
}
SdlGamepadKeyNavigation.enable()
}
Component.onCompleted: {
// Show the window according to the user's preferences
if (SystemProperties.hasDesktopEnvironment) {
if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_WINDOWED) return "Windowed"
else if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_MAXIMIZED) return "Maximized"
else if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_FULLSCREEN) return "FullScreen"
if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_MAXIMIZED) {
window.showMaximized()
}
else if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_FULLSCREEN) {
window.showFullScreen()
}
else {
window.show()
}
} else {
return "FullScreen"
window.showFullScreen()
}
// Display any modal dialogs for configuration warnings
if (runConfigChecks) {
if (SystemProperties.isWow64) {
wow64Dialog.open()
}
// Hardware acceleration and unmapped gamepads are checked asynchronously
SystemProperties.hasHardwareAccelerationChanged.connect(hasHardwareAccelerationChanged)
SystemProperties.unmappedGamepadsChanged.connect(hasUnmappedGamepadsChanged)
SystemProperties.startAsyncLoad()
}
}
function hasHardwareAccelerationChanged() {
if (!SystemProperties.hasHardwareAcceleration && StreamingPreferences.videoDecoderSelection !== StreamingPreferences.VDS_FORCE_SOFTWARE) {
if (SystemProperties.isRunningXWayland) {
xWaylandDialog.open()
}
else {
noHwDecoderDialog.open()
}
}
}
function hasUnmappedGamepadsChanged() {
if (SystemProperties.unmappedGamepads) {
unmappedGamepadDialog.unmappedGamepads = SystemProperties.unmappedGamepads
unmappedGamepadDialog.open()
}
}
// It would be better to use TextMetrics here, but it always lays out
// the text slightly more compactly than real Text does in ToolTip,
// causing unexpected line breaks to be inserted
Text {
id: tooltipTextLayoutHelper
visible: false
font: ToolTip.toolTip.font
text: ToolTip.toolTip.text
}
// This configures the maximum width of the singleton attached QML ToolTip. If left unconstrained,
// it will never insert a line break and just extend on forever.
ToolTip.toolTip.contentWidth: ToolTip.toolTip.implicitContentWidth < 400 ? ToolTip.toolTip.implicitContentWidth : 400
ToolTip.toolTip.contentWidth: Math.min(tooltipTextLayoutHelper.width, 400)
function goBack() {
if (clearOnBack) {
@@ -49,10 +108,16 @@ ApplicationWindow {
StackView {
id: stackView
initialItem: initialView
anchors.fill: parent
focus: true
Component.onCompleted: {
// Perform our early initialization before constructing
// the initial view and pushing it to the StackView
doEarlyInit()
push(initialView)
}
onCurrentItemChanged: {
// Ensure focus travels to the next view when going back
if (currentItem) {
@@ -126,6 +191,9 @@ ApplicationWindow {
pollingActive = true
}
}
// Poll for gamepad input only when the window is in focus
SdlGamepadKeyNavigation.notifyWindowFocus(visible && active)
}
onActiveChanged: {
@@ -144,47 +212,15 @@ ApplicationWindow {
// if focus does not return within a few minutes.
inactivityTimer.restart()
}
// Poll for gamepad input only when the window is in focus
SdlGamepadKeyNavigation.notifyWindowFocus(visible && active)
}
property bool initialized: false
// BUG: Using onAfterSynchronizing: here causes very strange
// failures on Linux. Many shaders fail to compile and we
// eventually segfault deep inside the Qt OpenGL code.
onAfterRendering: {
// We use this callback to trigger dialog display because
// it only happens once the window is fully constructed.
// Doing it earlier can lead to the dialog appearing behind
// the window or otherwise without input focus.
if (!initialized) {
// Set initialized before calling anything else, because
// pumping the event loop can cause us to get another
// onAfterRendering call and potentially reenter this code.
initialized = true;
if (SystemProperties.isWow64) {
wow64Dialog.open()
}
else if (!SystemProperties.hasHardwareAcceleration) {
if (SystemProperties.isRunningXWayland) {
xWaylandDialog.open()
}
else {
noHwDecoderDialog.open()
}
}
if (SystemProperties.unmappedGamepads) {
unmappedGamepadDialog.unmappedGamepads = SystemProperties.unmappedGamepads
unmappedGamepadDialog.open()
}
}
}
function navigateTo(url, objectName)
function navigateTo(url, objectType)
{
var existingItem = stackView.find(function(item, index) {
return item.objectName === objectName
return item instanceof objectType
})
if (existingItem !== null) {
@@ -251,7 +287,7 @@ ApplicationWindow {
Label {
id: versionLabel
visible: stackView.currentItem.objectName === qsTr("Settings")
visible: stackView.currentItem instanceof SettingsView
text: qsTr("Version %1").arg(SystemProperties.versionString)
font.pointSize: 12
horizontalAlignment: Qt.AlignRight
@@ -261,9 +297,9 @@ ApplicationWindow {
NavigableToolButton {
id: discordButton
visible: SystemProperties.hasBrowser &&
stackView.currentItem.objectName === qsTr("Settings")
stackView.currentItem instanceof SettingsView
iconSource: "qrc:/res/Discord-Logo-White.svg"
iconSource: "qrc:/res/discord.svg"
ToolTip.delay: 1000
ToolTip.timeout: 3000
@@ -280,7 +316,7 @@ ApplicationWindow {
NavigableToolButton {
id: addPcButton
visible: stackView.currentItem.objectName === qsTr("Computers")
visible: stackView.currentItem instanceof PcView
iconSource: "qrc:/res/ic_add_to_queue_white_48px.svg"
@@ -378,7 +414,7 @@ ApplicationWindow {
iconSource: "qrc:/res/ic_videogame_asset_white_48px.svg"
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", qsTr("Gamepad Mapping"))
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", GamepadMapper)
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
@@ -390,7 +426,7 @@ ApplicationWindow {
iconSource: "qrc:/res/settings.svg"
onClicked: navigateTo("qrc:/gui/SettingsView.qml", qsTr("Settings"))
onClicked: navigateTo("qrc:/gui/SettingsView.qml", SettingsView)
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
@@ -478,7 +514,7 @@ ApplicationWindow {
NavigableDialog {
id: addPcDialog
property string label: qsTr("Enter the IP address of your GameStream PC:")
property string label: qsTr("Enter the IP address of your host PC:")
standardButtons: Dialog.Ok | Dialog.Cancel
+52 -58
View File
@@ -4,15 +4,16 @@
#include <QGuiApplication>
#include <QWindow>
#include "settings/streamingpreferences.h"
#include "settings/mappingmanager.h"
#define AXIS_NAVIGATION_REPEAT_DELAY 150
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation()
: m_Enabled(false),
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation(StreamingPreferences* prefs)
: m_Prefs(prefs),
m_Enabled(false),
m_UiNavMode(false),
m_FirstPoll(false),
m_HasFocus(false),
m_LastAxisNavigationEventTime(0)
{
m_PollingTimer = new QTimer(this);
@@ -50,11 +51,16 @@ void SdlGamepadKeyNavigation::enable()
// on first init of the GC subsystem. We can't depend on them due to
// overlapping lifetimes of SdlGamepadKeyNavigation instances, so we
// will attach ourselves.
SDL_PumpEvents();
//
// NB: We use SDL_JoystickUpdate() instead of SDL_PumpEvents() because
// the latter can do a bit more work that we want (like handling video
// events that we intentionally do not want to process yet).
SDL_JoystickUpdate();
SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED);
// Open all currently attached game controllers
for (int i = 0; i < SDL_NumJoysticks(); i++) {
int numJoysticks = SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; i++) {
if (SDL_IsGameController(i)) {
SDL_GameController* gc = SDL_GameControllerOpen(i);
if (gc != nullptr) {
@@ -63,13 +69,10 @@ void SdlGamepadKeyNavigation::enable()
}
}
// Flush events on the first poll
m_FirstPoll = true;
// Poll every 50 ms for a new joystick event
m_PollingTimer->start(50);
m_Enabled = true;
// Start the polling timer if the window is focused
updateTimerState();
}
void SdlGamepadKeyNavigation::disable()
@@ -78,7 +81,9 @@ void SdlGamepadKeyNavigation::disable()
return;
}
m_PollingTimer->stop();
m_Enabled = false;
updateTimerState();
Q_ASSERT(!m_PollingTimer->isActive());
while (!m_Gamepads.isEmpty()) {
SDL_GameControllerClose(m_Gamepads[0]);
@@ -86,26 +91,31 @@ void SdlGamepadKeyNavigation::disable()
}
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
}
m_Enabled = false;
void SdlGamepadKeyNavigation::notifyWindowFocus(bool hasFocus)
{
m_HasFocus = hasFocus;
updateTimerState();
}
void SdlGamepadKeyNavigation::onPollingTimerFired()
{
SDL_Event event;
StreamingPreferences prefs;
// Update joystick state without pumping other events (see enable() comment)
SDL_JoystickUpdate();
// Discard any pending button events on the first poll to avoid picking up
// stale input data from the stream session (like the quit combo).
if (m_FirstPoll) {
SDL_PumpEvents();
SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN);
SDL_FlushEvent(SDL_CONTROLLERBUTTONUP);
m_FirstPoll = false;
}
while (SDL_PollEvent(&event)) {
// Peep events rather than polling to avoid calling SDL_PumpEvents()
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1) {
switch (event.type) {
case SDL_QUIT:
// SDL may send us a quit event since we initialize
@@ -121,7 +131,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
// Swap face buttons if needed
if (prefs.swapFaceButtons) {
if (m_Prefs->swapFaceButtons) {
switch (event.cbutton.button) {
case SDL_CONTROLLER_BUTTON_A:
event.cbutton.button = SDL_CONTROLLER_BUTTON_B;
@@ -191,14 +201,24 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
case SDL_CONTROLLERDEVICEADDED:
SDL_GameController* gc = SDL_GameControllerOpen(event.cdevice.which);
if (gc != nullptr) {
m_Gamepads.append(gc);
// SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same
// gamepad in rare cases, because SDL doesn't fixup the device index in
// the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
// before we've processed the add event.
if (!m_Gamepads.contains(gc)) {
m_Gamepads.append(gc);
}
else {
// We already have this game controller open
SDL_GameControllerClose(gc);
}
}
break;
}
}
// Handle analog sticks by polling
for (auto gc : m_Gamepads) {
for (auto gc : std::as_const(m_Gamepads)) {
short leftX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX);
short leftY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY);
if (SDL_GetTicks() - m_LastAxisNavigationEventTime < AXIS_NAVIGATION_REPEAT_DELAY) {
@@ -239,31 +259,6 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
sendKey(QEvent::Type::KeyRelease, Qt::Key_Right);
m_LastAxisNavigationEventTime = SDL_GetTicks();
}
// In UI navigation mode (settings page), use the right stick to scroll
if (m_UiNavMode) {
short rightX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTX);
short rightY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTY);
QPoint wheelDelta;
if (rightX > 30000) {
wheelDelta.setX(30);
}
else if (rightX < -30000) {
wheelDelta.setX(-30);
}
if (rightY > 30000) {
wheelDelta.setY(-30);
}
else if (rightY < -30000) {
wheelDelta.setY(30);
}
if (!wheelDelta.isNull()) {
sendWheel(wheelDelta);
}
}
}
}
@@ -277,19 +272,17 @@ void SdlGamepadKeyNavigation::sendKey(QEvent::Type type, Qt::Key key, Qt::Keyboa
}
}
void SdlGamepadKeyNavigation::sendWheel(QPoint& angleDelta)
void SdlGamepadKeyNavigation::updateTimerState()
{
QGuiApplication* app = static_cast<QGuiApplication*>(QGuiApplication::instance());
QWindow* focusWindow = app->focusWindow();
if (focusWindow != nullptr) {
QPoint mousePos(focusWindow->width() / 2, focusWindow->height() / 2);
QPoint globalPos(focusWindow->mapToGlobal(mousePos));
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
QWheelEvent wheelEvent(mousePos, globalPos, QPoint(), angleDelta, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false, Qt::MouseEventSynthesizedByApplication);
#else
QWheelEvent wheelEvent(mousePos, globalPos, QPoint(), angleDelta, angleDelta.y(), Qt::Vertical, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, Qt::MouseEventSynthesizedByApplication, false);
#endif
app->sendEvent(focusWindow, &wheelEvent);
if (m_PollingTimer->isActive() && (!m_HasFocus || !m_Enabled)) {
m_PollingTimer->stop();
}
else if (!m_PollingTimer->isActive() && m_HasFocus && m_Enabled) {
// Flush events on the first poll
m_FirstPoll = true;
// Poll every 50 ms for a new joystick event
m_PollingTimer->start(50);
}
}
@@ -303,7 +296,8 @@ int SdlGamepadKeyNavigation::getConnectedGamepads()
Q_ASSERT(m_Enabled);
int count = 0;
for (int i = 0; i < SDL_NumJoysticks(); i++) {
int numJoysticks = SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; i++) {
if (SDL_IsGameController(i)) {
count++;
}
+10 -3
View File
@@ -3,14 +3,16 @@
#include <QTimer>
#include <QEvent>
#include <SDL.h>
#include "SDL_compat.h"
#include "settings/streamingpreferences.h"
class SdlGamepadKeyNavigation : public QObject
{
Q_OBJECT
public:
SdlGamepadKeyNavigation();
SdlGamepadKeyNavigation(StreamingPreferences* prefs);
~SdlGamepadKeyNavigation();
@@ -18,22 +20,27 @@ public:
Q_INVOKABLE void disable();
Q_INVOKABLE void notifyWindowFocus(bool hasFocus);
Q_INVOKABLE void setUiNavMode(bool settingsMode);
Q_INVOKABLE int getConnectedGamepads();
private:
void sendKey(QEvent::Type type, Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
void sendWheel(QPoint& angleDelta);
void updateTimerState();
private slots:
void onPollingTimerFired();
private:
StreamingPreferences* m_Prefs;
QTimer* m_PollingTimer;
QList<SDL_GameController*> m_Gamepads;
bool m_Enabled;
bool m_UiNavMode;
bool m_FirstPoll;
bool m_HasFocus;
Uint32 m_LastAxisNavigationEventTime;
};
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+669 -409
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+554 -298
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+560 -304
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+617 -396
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+718 -454
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
+906 -634
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+561 -305
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+566 -306
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+563 -303
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+675 -419
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+632 -376
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More