Compare commits

..
194 Commits
Author SHA1 Message Date
Boria138 4d6f6c1b82 bump to 1.2.0
Code check / Check code (push) Successful in 58s
Build AppImage, Arch, Fedora and Debian Packages / Build AppImage (push) Successful in 7m3s
Build AppImage, Arch, Fedora and Debian Packages / Build Arch Package (push) Successful in 2m7s
Build AppImage, Arch, Fedora and Debian Packages / Build Fedora RPM (43) (push) Successful in 1m6s
Build AppImage, Arch, Fedora and Debian Packages / Build Fedora RPM (42) (push) Successful in 1m7s
Build AppImage, Arch, Fedora and Debian Packages / Build Fedora RPM (44) (push) Successful in 1m22s
Build AppImage, Arch, Fedora and Debian Packages / Build Fedora RPM (rawhide) (push) Successful in 1m30s
Build AppImage, Arch, Fedora and Debian Packages / Build Debian Package (push) Successful in 2m2s
Build AppImage, Arch, Fedora and Debian Packages / Create and Publish Release (push) Successful in 30s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-10 11:01:19 +05:00
Codeberg TranslateandBoria138 4451d7e26a Translated using Weblate (Russian)
Check Translations / check-translations (push) Successful in 15s
Code check / Check code (push) Successful in 57s
Currently translated at 100.0% (679 of 679 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-10 05:58:37 +00:00
Boria138 a4199e2a16 chore(locale): update
Check Translations / check-translations (push) Failing after 25s
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-10 10:56:09 +05:00
Boria138 401d1ddac2 feat: add file delete and rename to file explorer
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-10 10:55:42 +05:00
Boria138 86f66a1174 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-10 10:44:49 +05:00
Boria138 8d5a99f0de fix: delay library controls auto-close after combo selection
Code check / Check code (push) Successful in 59s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 20:34:51 +05:00
Dervart 92f795f0e5 fix: combobox styles for filters
Code check / Check code (pull_request) Successful in 59s
Code check / Check code (push) Successful in 1m0s
2026-06-09 20:36:45 +07:00
Codeberg TranslateandBoria138 821c9172b2 Translated using Weblate (Russian)
Check Translations / check-translations (push) Failing after 18s
Code check / Check code (push) Successful in 58s
Currently translated at 100.0% (672 of 672 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-09 11:26:33 +00:00
Codeberg Translateandrogerio-mattos 9c2febb40a Translated using Weblate (Portuguese (Brazil))
Currently translated at 43.2% (290 of 670 strings)

Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: rogerio-mattos <rogerio-mattos@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/
Translation: PortProtonQt/PortProtonQt
2026-06-09 11:26:33 +00:00
Boria138 da21309b0c chore(locale): update
Check Translations / check-translations (push) Failing after 1m6s
Code check / Check code (push) Successful in 1m7s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 16:24:47 +05:00
Boria138 9be9187ea5 feat: add sound driver setting to gui
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 16:24:13 +05:00
Boria138 18d1ad2d92 fix: skip exiftool when it is not installed
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 15:56:22 +05:00
Boria138 f9cefe501b fix: move badge view control to library submenu
Code check / Check code (push) Successful in 59s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 15:46:28 +05:00
Boria138 d385e4e120 fix: make refresh button compact in library toolbar
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-09 15:42:42 +05:00
Mikhail Tergoev 4d9f7be000 update WINE_LG to 11-10
Code check / Check code (push) Successful in 58s
2026-06-08 22:08:06 +03:00
Boria138 ee6255a507 fix: collapse filters on card hover
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 16:43:21 +00:00
Boria138 2a8630db1b feat: make search compat
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 16:43:21 +00:00
Boria138 078bb9e8c7 feat: improve library filter controls
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 16:43:21 +00:00
Mikhail Tergoev be7f7056d3 Merge branch 'scripts-show-ppdb'
Code check / Check code (push) Successful in 2m0s
2026-06-08 18:16:08 +03:00
Mikhail Tergoev b31dcb9c63 fix merge conflict
Code check / Check code (push) Failing after 13m6s
2026-06-08 18:13:56 +03:00
Boria138 0958914cf1 fix: handle uppercase exe in show-ppdb
Code check / Check code (pull_request) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 13:42:22 +05:00
Boria138 ff23e4c0df feat: add nrg disc image launch support
Code check / Check code (pull_request) Successful in 52s
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 09:54:47 +05:00
Boria138 4ae1b71823 fix: fall back to Xbox gamepad type without SDL3
Code check / Check code (push) Successful in 1m15s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-08 09:20:06 +05:00
Boria138 25bf639f00 fix: avoid runtime cwd in system scripts dir
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-07 16:30:43 +05:00
Boria138 5dfdc91b75 chore: create shortcuts only in app by default
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-07 16:18:44 +05:00
Mikhail Tergoev e5076a683c update CHANGELOG.md 2026-06-07 12:09:16 +03:00
Mikhail Tergoev c3d3668eee mouse emulator sensitivity = 20 2026-06-07 12:09:16 +03:00
Renovate Bot f6d2a37d6f chore(deps): update archlinux:base-devel docker digest to c84ad63
Code check / Check code (push) Successful in 53s
2026-06-07 04:16:26 +00:00
Renovate Bot 6969c534a8 chore(deps): update https://git.linux-gaming.ru/actions/checkout digest to df4cb1c
Code check / Check code (pull_request) Successful in 1m4s
Package Build - AppImage, Arch, Fedora, Debian / changes (pull_request) Successful in 14s
Package Build - AppImage, Arch, Fedora, Debian / Build AppImage (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (42) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (43) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (44) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (rawhide) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Arch Package (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Debian Package (pull_request) Has been skipped
Code check / Check code (push) Successful in 55s
2026-06-07 00:00:52 +00:00
Boria138 4fcf48a7cf chore(locale): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 22:59:40 +05:00
Boria138 090818a356 Merge remote-tracking branch 'origin/weblate'
Check Translations / check-translations (push) Successful in 15s
Code check / Check code (push) Successful in 53s
2026-06-06 22:53:16 +05:00
Codeberg TranslateandBoria138 7451d1f876 Translated using Weblate (Russian)
Currently translated at 100.0% (670 of 670 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-06 17:53:02 +00:00
Boria138 f30e3fd405 chore(locale): update
Check Translations / check-translations (push) Failing after 19s
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 22:51:41 +05:00
Boria138 01e2c3bfd5 chore: add Weblate accept script 2026-06-06 22:51:06 +05:00
Boria138 52e1b303ba Merge remote-tracking branch 'weblate/main'
Check Translations / check-translations (push) Failing after 12s
Code check / Check code (push) Successful in 53s
2026-06-06 22:46:13 +05:00
Boria138 ab954936fc Merge branch 'weblate'
Check Translations / check-translations (push) Failing after 13s
Code check / Check code (push) Successful in 55s
2026-06-06 22:41:58 +05:00
Codeberg Translateandrogerio-mattos d25342331d Translated using Weblate (Portuguese (Brazil))
Currently translated at 32.8% (220 of 670 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 32.3% (217 of 670 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 30.2% (203 of 670 strings)

Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: rogerio-mattos <rogerio-mattos@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/
Translation: PortProtonQt/PortProtonQt
2026-06-06 17:41:26 +00:00
Codeberg Translateandgallegonovato 26d1661f63 Translated using Weblate (Spanish)
Currently translated at 8.6% (58 of 670 strings)

Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: gallegonovato <gallegonovato@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/es/
Translation: PortProtonQt/PortProtonQt
2026-06-06 17:41:26 +00:00
Boria138 6ddb630fea fix: adjust vkBasalt CAS and action controls
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 22:40:21 +05:00
Codeberg Translateandrogerio-mattos 2b934bef6e Translated using Weblate (Portuguese (Brazil))
Currently translated at 30.2% (203 of 670 strings)

Co-authored-by: rogerio-mattos <rogerio-mattos@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/
Translation: PortProtonQt/PortProtonQt
2026-06-06 16:07:54 +00:00
Codeberg Translateandgallegonovato 5d2101475e Translated using Weblate (Spanish)
Currently translated at 8.6% (58 of 670 strings)

Co-authored-by: gallegonovato <gallegonovato@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/es/
Translation: PortProtonQt/PortProtonQt
2026-06-06 16:07:54 +00:00
Boria138 c16b481679 fix: add LG latest aliases to default Wine selection
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 19:38:21 +05:00
Boria138 b91ed1b135 fix: read XDG paths always and fix Flatpak container download disable
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 18:30:56 +05:00
Boria138 a25c30f463 fix: restore right gamepad stick working
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 16:48:11 +05:00
Boria138 ebded297d3 fix: select vkBasalt user config in Flatpak
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 16:17:05 +05:00
Boria138 73d8c8e030 fix: improve GPU info command diagnostics
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 13:09:03 +05:00
Boria138 079d79f2c8 fix: keep selected table row color on hover
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 12:49:14 +05:00
Boria138 4f8e0c2d41 fix: speed up winetricks list loading
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-06 12:45:27 +05:00
Mikhail Tergoev 37d9104274 add support third-party installation scripts
Code check / Check code (push) Successful in 54s
2026-06-05 18:42:58 +03:00
Boria138 764bb3ced5 fix: handle spaced exe names in last launch cache
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 20:20:04 +05:00
37dd71284f Translated using Weblate (Chinese (Simplified Han script))
Code check / Check code (push) Successful in 55s
Check Translations / check-translations (push) Successful in 9s
Currently translated at 95.5% (640 of 670 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 95.5% (640 of 670 strings)

Co-authored-by: Anonymous <anonymous@noreply.codeberg.org>
Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/zh_Hans/
Translation: PortProtonQt/PortProtonQt
2026-06-05 14:33:00 +00:00
03da1b2c61 Translated using Weblate (Russian)
Currently translated at 100.0% (670 of 670 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (670 of 670 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (670 of 670 strings)

Co-authored-by: Anonymous <anonymous@noreply.codeberg.org>
Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Co-authored-by: Simple16 <simple16@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-05 14:33:00 +00:00
e77a7edf4c Translated using Weblate (Portuguese (Brazil))
Currently translated at 3.4% (23 of 670 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 3.4% (23 of 670 strings)

Co-authored-by: Anonymous <anonymous@noreply.codeberg.org>
Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/
Translation: PortProtonQt/PortProtonQt
2026-06-05 14:33:00 +00:00
Codeberg TranslateandAnonymous 065cf835c5 Translated using Weblate (Belarusian)
Currently translated at 0.0% (0 of 670 strings)

Co-authored-by: Anonymous <anonymous@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/be/
Translation: PortProtonQt/PortProtonQt
2026-06-05 14:33:00 +00:00
Boria138 3001fdac30 chore(locales): return es
Check Translations / check-translations (push) Failing after 9s
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 19:32:48 +05:00
Boria138 4456d06b50 chore(locales): drop unused locales
Check Translations / check-translations (push) Failing after 10s
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 19:17:36 +05:00
Codeberg TranslateandBoria138 1d423d7ebe Translated using Weblate (Portuguese (Brazil))
Currently translated at 3.4% (23 of 670 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/
Translation: PortProtonQt/PortProtonQt
2026-06-05 14:12:52 +00:00
Boria138 1c91219cef fix: improve vkBasalt gamepad navigation
Check Translations / check-translations (push) Failing after 22s
Code check / Check code (push) Successful in 1m11s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 16:41:49 +05:00
Boria138 718b7f0eaa chore: avoid translating tool names in settings buttons
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 16:33:43 +05:00
Boria138 0b4fcd37d4 feat: add vkBasalt toggle key setting
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 16:25:58 +05:00
Boria138 f08ae3091e chore: move vkbasalt to separate tab
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 16:12:29 +05:00
Boria138 947a5d522a chore: add SpecialK to spell ignore
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 13:48:52 +05:00
Codeberg TranslateandBoria138 2ad468491e Translated using Weblate (Russian)
Check Translations / check-translations (push) Failing after 15s
Code check / Check code (push) Successful in 56s
Currently translated at 100.0% (674 of 674 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-05 08:34:50 +00:00
Boria138 5bb0848f56 Merge branch 'weblate'
Check Translations / check-translations (push) Successful in 10s
Code check / Check code (push) Successful in 54s
2026-06-05 12:35:07 +05:00
Boria138 6d6ed36bc0 chore(locale): update
Check Translations / check-translations (push) Failing after 1m0s
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 12:34:19 +05:00
Boria138 93d6c4610c feat: add vkBasalt exe settings
Code check / Check code (push) Successful in 59s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 12:31:31 +05:00
Boria138 72ec18e099 ci: use own action mirrors
Code check / Check code (push) Successful in 1m58s
Build vk_gpu_info on Debian 11 / Build vk_gpu_info on Debian 11 (push) Successful in 3m14s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 10:57:03 +05:00
Boria138 a04b0e41e9 chore(scripts): use unpack for p7zip archives
Code check / Check code (pull_request) Failing after 1s
Code check / Check code (push) Failing after 1s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-05 09:00:46 +05:00
Codeberg Translateandrogerio-mattos 6e4664589b Added translation using Weblate (Portuguese (Brazil))
Co-authored-by: rogerio-mattos <rogerio-mattos@noreply.codeberg.org>
2026-06-05 00:00:41 +00:00
Mikhail Tergoev 6ccf99c73f add download error checking
Code check / Check code (push) Failing after 30s
2026-06-04 17:03:29 +03:00
Mikhail Tergoev 20372331d6 revert logging scripts to terminal 2026-06-04 16:34:29 +03:00
Boria138 b17bbb2f46 fix: avoid file explorer focus jumps from gamepad axis
Code check / Check code (push) Successful in 58s
Prevent left stick axis events from forcing focus to the first path
button in FileExplorer. Keep list reset to the first row only for a
discrete D-pad down transition from path buttons.

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 12:03:24 +05:00
Codeberg TranslateandBoria138 4debfae5aa Translated using Weblate (Russian)
Check Translations / check-translations (push) Failing after 17s
Code check / Check code (push) Successful in 56s
Currently translated at 100.0% (669 of 669 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-04 05:34:30 +00:00
Boria138 36a086129e chore(locale): update
Check Translations / check-translations (push) Failing after 23s
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 10:32:26 +05:00
Boria138 912dc2c77e feat: add exe settings favorites tab
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 10:31:14 +05:00
Boria138 26f3a35560 fix: move default Wine settings to Wine tab
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 10:05:18 +05:00
Boria138 ad8cbb35dc fix: refresh autoinstall status after install
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 09:50:21 +05:00
Boria138 612c10595d feat(scripts): automate metainfo updates in bump_ver.py
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 09:29:13 +05:00
Boria138 ac3d1045e4 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-04 09:08:51 +05:00
Mikhail Tergoev 363ff0d86e Merge branch 'scripts-specialk'
Code check / Check code (push) Successful in 54s
2026-06-03 20:32:27 +03:00
Mikhail Tergoev fe6b84db56 Merge branch 'scripts-default' 2026-06-03 20:10:19 +03:00
Mikhail Tergoev 02ebc440ec Merge branch 'scripts-wrapper'
Code check / Check code (push) Successful in 55s
2026-06-03 20:07:47 +03:00
Mikhail Tergoev bf6421547d Merge branch 'scripts-winetrics' 2026-06-03 20:02:07 +03:00
Mikhail Tergoev 4679fb7eb0 Merge branch 'scripts-ppdb'
Code check / Check code (push) Successful in 56s
2026-06-03 19:59:20 +03:00
Mikhail Tergoev 5c5d544bc7 Merge branch 'scripts-wayland' 2026-06-03 19:55:25 +03:00
Boria138 a4abeca70d Merge branch 'weblate'
Check Translations / check-translations (push) Successful in 16s
Code check / Check code (push) Successful in 54s
2026-06-03 19:57:59 +05:00
Boria138 bb39b07445 chore: improve exe settings row highlight
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-03 10:30:18 +05:00
Boria138 4c27ca8365 chore(locale): update
Check Translations / check-translations (push) Successful in 11s
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 22:40:02 +05:00
Boria138 8b0eb13d72 chore: remove ppdb cleanup success message from exe settings
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 22:39:24 +05:00
Boria138 08ec0773fa feat: support Special K with OptiScaler
Code check / Check code (pull_request) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 21:56:56 +05:00
Boria138 52f7c04cff feat: add SpecialK injection support
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 21:26:03 +05:00
Boria138 00e20f2165 feat: add default exe Wine and prefix settings
Code check / Check code (pull_request) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 20:41:29 +05:00
Codeberg TranslateandBoria138 758c731106 Translated using Weblate (Russian)
Currently translated at 100.0% (668 of 668 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-06-02 07:07:50 +00:00
Boria138 01a82510f2 feat: support launch wrapper in run-after setting
Code check / Check code (pull_request) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-02 09:48:38 +05:00
Boria138 72daab8cd6 chore: add SLR log only on SLR_DEBUG=1
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 21:45:57 +05:00
Boria138 a0445d8c45 feat(scripts): added cli to winetricks
Code check / Check code (pull_request) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 14:00:50 +05:00
Boria138 343bc12c1e chore(locale): update
Check Translations / check-translations (push) Failing after 22s
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 11:23:31 +05:00
Boria138 8aff408bda fix: keep autoinstall running after leaving card
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 11:23:05 +05:00
Boria138 66586b2a36 fix: prevent MangoHud auto-enable from config
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 11:14:09 +05:00
Boria138 3fb6727818 chore(locale): update
Check Translations / check-translations (push) Successful in 11s
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 10:40:55 +05:00
Boria138 520fa55988 feat(system): add logout and make power actions init agnostic
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-06-01 10:40:14 +05:00
Gitea Actions b34004cff3 chore: update steam apps list 2026-06-01T00:00:46Z 2026-06-01 00:00:46 +00:00
Renovate Bot 2eb8c1f7b6 chore(deps): update archlinux:base-devel docker digest to 2507482
Code check / Check code (push) Successful in 52s
2026-05-31 03:14:21 +00:00
Renovate Bot f36073ee32 chore(deps): pin debian docker tag to 4ae6766
Package Build - AppImage, Arch, Fedora, Debian / Build AppImage (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (42) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (43) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (44) (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Fedora RPM (rawhide) (pull_request) Has been skipped
Code check / Check code (pull_request) Successful in 55s
Package Build - AppImage, Arch, Fedora, Debian / Build Debian Package (pull_request) Has been skipped
Package Build - AppImage, Arch, Fedora, Debian / Build Arch Package (pull_request) Has been skipped
Code check / Check code (push) Successful in 53s
Package Build - AppImage, Arch, Fedora, Debian / changes (pull_request) Successful in 13s
2026-05-31 00:01:28 +00:00
Boria138 a258a63c8e fix: migrate shortcuts using current launcher mode
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 20:16:17 +05:00
Boria138 def3fe27f8 feat: appimage shortcut migration and steam scripts update
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 18:47:37 +05:00
Boria138 45fd7da18a fix: backspace in folder rename dialog
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 18:33:34 +05:00
Boria138 6afce40576 fix: create folders in parent directory
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 18:30:15 +05:00
Boria138 c2f45736db fix: use AppImage scripts for silent launch
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 10:29:13 +05:00
Boria138 4f3fdb621e fix: select MangoHud conf from flatpak home config first
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 10:08:51 +05:00
Boria138 e40e9811cf fix: stabilize Steam shortcut launch wrappers
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-30 10:08:51 +05:00
Codeberg TranslateandBoria138 d1bfab6c7c Translated using Weblate (Russian)
Check Translations / check-translations (pull_request) Successful in 16s
Code check / Check code (pull_request) Successful in 54s
Check Translations / check-translations (push) Successful in 14s
Code check / Check code (push) Successful in 53s
Currently translated at 100.0% (667 of 667 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-05-29 13:53:57 +00:00
Boria138 4f8929da40 fix: filter network shares from mounted drives
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-29 09:37:36 +05:00
Boria138 4b0b613659 chore: fix autoFullscreenGamepad settings style
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 13:08:49 +05:00
Boria138 0802e7852f chore(build): fix typo on arch
Code check / Check code (push) Successful in 1m31s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 10:17:30 +05:00
Boria138 4a03d803f4 chore(locale): added Belarusian po template
Code check / Check code (push) Successful in 55s
Check Translations / check-translations (push) Successful in 10s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 10:14:07 +05:00
Boria138 4271461282 chore(locale): update
Check Translations / check-translations (push) Successful in 11s
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 10:08:45 +05:00
Boria138 f4477101cc chore(mangohud): fix typo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 10:07:57 +05:00
Boria138 0dc11ecd3c feat(input): use SDL3 for gamepad type detection
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-28 09:58:00 +05:00
Boria138 3248392e78 chore(locale): update
Check Translations / check-translations (push) Failing after 20s
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 21:30:57 +05:00
Boria138 9468c3f286 feat(settings): return gamepad type setting
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 21:27:22 +05:00
Boria138 c826153ddf fix: repair native Wayland launch setup
Code check / Check code (pull_request) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 20:47:24 +05:00
Boria138 f2b80604cb feat(mangohud): added display_server to PortProton preset
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 20:35:32 +05:00
Boria138 dd61c72a3a fix: copy ppdb templates and fix runtime game path
Code check / Check code (pull_request) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 19:15:44 +05:00
Boria138 36a36ad7d2 fix: load bundled terminal color schemes
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 19:00:47 +05:00
Boria138 03ada79e88 fix: improve installed autoinstall handling
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 15:30:07 +05:00
Boria138 20444bc3d1 feat: add drag and drop restore for ppack backups
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 15:02:34 +05:00
Boria138 ae89b5a0fb ci: merge package build workflows
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 12:11:16 +05:00
Boria138 3372bb58ba fix: pass Steam launch options to games
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 12:03:09 +05:00
Boria138 200b257622 fix: launch Steam games via detected client type
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-27 12:03:09 +05:00
VanoMJ 0b8ef53cdd ci: build Debian package
Build Check - AppImage, Arch, Fedora, Debian / changes (pull_request) Successful in 14s
Code check / Check code (pull_request) Successful in 54s
Build Check - AppImage, Arch, Fedora, Debian / Build AppImage (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Fedora RPM (42) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Fedora RPM (43) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Fedora RPM (44) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Fedora RPM (rawhide) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Arch Package (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora, Debian / Build Debian Package (pull_request) Successful in 2m39s
Code check / Check code (push) Successful in 55s
2026-05-26 21:42:23 +03:00
Boria138 41aea94fff fix: detect Steam directory via .steam symlink
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 21:48:35 +05:00
Boria138 0a4cb81906 fix: add missing .cmd launch support
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 21:05:54 +05:00
Boria138 1743c69261 feat: add hidden time display mode
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 20:57:35 +05:00
Boria138 d0d1dff778 bump to 1.1.0 (hotfix)
Code check / Check code (push) Successful in 54s
Build AppImage, Arch and Fedora Packages / Build AppImage (push) Successful in 6m53s
Build AppImage, Arch and Fedora Packages / Build Arch Package (push) Successful in 2m8s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (43) (push) Successful in 1m3s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (44) (push) Successful in 1m9s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (rawhide) (push) Successful in 1m20s
Build AppImage, Arch and Fedora Packages / Create and Publish Release (push) Successful in 17s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (42) (push) Successful in 1m9s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:48:45 +05:00
Boria138 07e07dbe09 chore(locale): update
Code check / Check code (push) Successful in 54s
Check Translations / check-translations (push) Successful in 10s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:44:38 +05:00
Boria138 004916a82b fix: filter invalid GPU entries in settings
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:44:15 +05:00
Codeberg TranslateandBoria138 ae2115ad0a Translated using Weblate (Russian)
Check Translations / check-translations (push) Successful in 15s
Code check / Check code (push) Successful in 55s
Currently translated at 100.0% (665 of 665 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-05-26 06:33:50 +00:00
Boria138 357a0dcf42 chore(locale): update
Check Translations / check-translations (push) Failing after 20s
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:31:45 +05:00
Boria138 e5df48b9b0 chore: move gamepad fullscreen option in settings
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:31:10 +05:00
Boria138 48217b93f5 feat: validate PORT_DATA_PATH read-write access
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:27:29 +05:00
Boria138 cc2372107a feat: add version-based download counter
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 11:12:26 +05:00
Boria138 a32d63f5e5 refactor: centralize script D-Bus calls
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 10:58:35 +05:00
Boria138 cbf29005ff fix: remove obsolete PROGRAMS prefix
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-26 10:35:39 +05:00
Boria138 8d10bae8f2 fix: avoid duplicate library refresh
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:42:38 +05:00
Boria138 28d0417ede chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:32:47 +05:00
Boria138 7efb0aadec fix: reset PortProton user config from CLI
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:18:17 +05:00
Boria138 d4d7e9c044 fix: always show pinned prefixes
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:15:06 +05:00
Boria138 eb18178958 fix: reset PortProton user config with app settings
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:10:51 +05:00
Boria138 979e208969 fix: update PortProton dependency progress from live output
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 21:03:32 +05:00
Boria138 8704ba00e9 fix: keep Wine settings tab populated without dist directory
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 20:31:58 +05:00
Mikhail Tergoev d9d8242475 add check write access to the game directory
Code check / Check code (push) Successful in 55s
2026-05-25 18:12:59 +03:00
Codeberg TranslateandBoria138 64e626b2b2 Translated using Weblate (Russian)
Check Translations / check-translations (push) Successful in 17s
Code check / Check code (push) Successful in 53s
Currently translated at 100.0% (664 of 664 strings)

Co-authored-by: Boria138 <boria138@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/portprotonqt/portprotonqt/ru/
Translation: PortProtonQt/PortProtonQt
2026-05-25 05:14:31 +00:00
Boria138 8af84460eb fix: improve library toolbar focus navigation
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 10:03:38 +05:00
Boria138 b7e83ad1d2 fix: handle gamepad fullscreen startup
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 09:56:21 +05:00
Boria138 ffff6efa68 fix: keep Wine and LG builds in dist
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 09:46:53 +05:00
Boria138 fabf14fc46 chore(localization): update
Check Translations / check-translations (push) Failing after 22s
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 09:35:55 +05:00
Boria138 88db436b94 fix: keep mouse emulation available after launcher start
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 09:35:18 +05:00
Boria138 592d24c9c6 ui: depersonalize interface by using generic terminology
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 09:02:54 +05:00
Boria138 c472c785cc feat(ui): add quick launch button
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 08:45:03 +05:00
Boria138 759e931dfc ui: remove redundant tab titles
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 08:30:01 +05:00
Boria138 93f5ea49d4 chore(build): replace steam compat
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-25 08:15:04 +05:00
Mikhail Tergoev d9c55bed61 Merge branch 'main' of git.linux-gaming.ru:Linux-Gaming/PortProtonQt
Code check / Check code (push) Successful in 55s
2026-05-24 21:35:19 +03:00
Mikhail Tergoev 64bbabd0f1 fix auto update compat tools 2026-05-24 21:33:59 +03:00
Boria138 c3e9433f9d fix: defer empty library refresh until window shows
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 17:26:48 +05:00
Boria138 c4274bbef6 fix: restore legacy squashfs via easyterm
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 17:20:59 +05:00
Boria138 cdfd983580 fix: avoid prefix restore on theme restart
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 17:13:44 +05:00
Boria138 749113b48c fix: use classic autoinstall covers for list themes
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 15:03:05 +05:00
Boria138 5fdba88c5c fix: refresh empty library after silent launch
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 14:54:30 +05:00
Boria138 a20887da5b fix: refresh library after all PortProton shortcut creation
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 14:44:40 +05:00
Boria138 c9b8871fb1 fix: fallback to exe icon when cover download fails
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 14:38:48 +05:00
Boria138 6db27ef7af feat: add GUI support for bat msi reg launch files
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 14:25:55 +05:00
Boria138 97de53303c fix: force 96 DPI on prefix initialization
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 11:02:59 +05:00
Simple16 07ac67e934 Updating the Russian localization
Check Translations / check-translations (push) Successful in 15s
Code check / Check code (push) Successful in 51s
2026-05-24 05:27:33 +00:00
Simple16 66e1e437f8 Updating the Russian localization 2026-05-24 05:27:33 +00:00
Boria138 12c98adbd7 fix: resolve pyright type errors in wine_extractor, downloader, and prefix_backup
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 10:27:14 +05:00
Boria138 d7de29008e fix(deps): update python dependencies
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 10:21:03 +05:00
Boria138 4d99a66e84 chore: finally migrate custom data to https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt-Custom-Metadata
Code check / Check code (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 09:55:35 +05:00
Simple16 288242195b Updating the English localization
Code check / Check code (pull_request) Successful in 56s
Code check / Check code (push) Successful in 56s
2026-05-24 09:26:37 +05:00
Boria138 892124efba fix: normalize Proton dist hyphen spacing
Code check / Check code (push) Successful in 54s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-24 03:24:49 +00:00
Renovate Bot ae7bd3e5ff fix(deps): update dependency dbus-fast to v5
Code check / Check code (push) Successful in 56s
2026-05-24 03:19:56 +00:00
Renovate Bot 042b90d663 chore(deps): update ghcr.io/renovatebot/renovate:latest docker digest to 47421f2
Code check / Check code (pull_request) Successful in 55s
Code check / Check code (push) Successful in 57s
2026-05-24 00:00:43 +00:00
Boria138 4fdaf0115e feat: rework prefix backups with libarchive progress UI
Code check / Check code (push) Successful in 56s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 16:31:16 +00:00
Boria138 b00f62776c feat: add svg cover image support
Code check / Check code (push) Successful in 57s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 21:29:43 +05:00
Boria138 69674b5c75 fix: check moved Python files in meson hook
Code check / Check code (push) Successful in 58s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 21:14:37 +05:00
Boria138 eaa3467410 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 21:07:19 +05:00
Boria138 47a949fe6e chore(scripts): fix easyterm location
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 20:41:22 +05:00
Mikhail Tergoev 8902369fe7 fix create desktop and choose ppdb for setup-msi
Code check / Check code (push) Successful in 57s
2026-05-23 16:41:08 +03:00
Mikhail Tergoev c0529ac9fd move easyterm to scripts_utils 2026-05-23 13:49:36 +03:00
Mikhail Tergoev a9ed377b00 add runner terminal function: python_term 2026-05-23 13:40:08 +03:00
Mikhail Tergoev bc523762b6 add runner python3 function: python_module 2026-05-23 13:20:50 +03:00
Boria138 2f5159129c fix: include check_variables defaults in --show-ppdb output
Code check / Check code (push) Successful in 59s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 14:10:47 +05:00
Boria138 eef8c7d496 chore(locale): rm zh_Hans
Check Translations / check-translations (push) Successful in 13s
Code check / Check code (push) Successful in 55s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 11:08:38 +05:00
Boria138 64cad59d53 chore(locale): rename zh_Hans to zh_CN for glibc compatibility
Code check / Check code (push) Successful in 57s
Check Translations / check-translations (push) Failing after 17s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2026-05-23 11:03:51 +05:00
273 changed files with 23420 additions and 4623 deletions

No files matched your search

-142
View File
@@ -1,142 +0,0 @@
name: Nightly Build - AppImage, Arch, Fedora
on:
workflow_dispatch:
env:
BUILD_BRANCH: ${{ github.ref_name }}
PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt"
jobs:
build-appimage:
name: Build AppImage
runs-on: ubuntu-22.04
container:
image: archlinux:base-devel@sha256:6db772fd1dd128b9cf7b7231ca5284af70879596fe4ec754c911cfc4ac30d5eb
options: --privileged --device /dev/fuse
steps:
- name: Prepare container
run: |
pacman-key --init
pacman -Sy --noconfirm archlinux-keyring
pacman -Syu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm xorg-server-xvfb zsync
- uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Install appimage dependencies
run: |
cd build-aux/AppImage
chmod +x get-dependencies.sh portprotonqt-appimage.sh
./get-dependencies.sh --local --branch "${{ env.BUILD_BRANCH }}"
- name: Build AppImage
run: |
cd build-aux/AppImage
./portprotonqt-appimage.sh
- name: Upload AppImage
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-AppImage
path: build-aux/AppImage/dist/*.AppImage
build-fedora:
name: Build Fedora RPM
runs-on: ubuntu-latest
strategy:
matrix:
fedora_version: [42, 43, 44, rawhide]
container:
image: fedora:${{ matrix.fedora_version }}
options: --privileged
steps:
- name: Install build dependencies
run: |
dnf install -y git rpmdevtools meson ninja-build python3-devel \
systemd-rpm-macros vulkan-loader-devel redhat-rpm-config nodejs npm \
gcc gettext
- name: Setup rpmbuild environment
run: |
useradd rpmbuild -u 5002 -g users || true
mkdir -p /home/rpmbuild/{BUILD,RPMS,SPECS,SRPMS,SOURCES}
chown -R rpmbuild:users /home/rpmbuild
echo '%_topdir /home/rpmbuild' > /home/rpmbuild/.rpmmacros
- name: Checkout repo
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Copy fedora.spec
run: |
sed "s|git clone https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|git clone -b ${{ env.BUILD_BRANCH }} https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|" \
build-aux/fedora-git.spec > /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec
chown -R rpmbuild:users /home/rpmbuild
- name: Build RPM
run: |
su rpmbuild -c "rpmbuild -ba /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec"
- name: Upload RPM package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-RPM-Fedora-${{ matrix.fedora_version }}
path: /home/rpmbuild/RPMS/**/*.rpm
build-arch:
name: Build Arch Package
runs-on: ubuntu-22.04
container:
image: archlinux:base-devel@sha256:6db772fd1dd128b9cf7b7231ca5284af70879596fe4ec754c911cfc4ac30d5eb
steps:
- name: Prepare container
run: |
pacman -Syuu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm
sed -i 's/#MAKEFLAGS="-j2"/MAKEFLAGS="-j$(nproc) -l$(nproc)"/g' /etc/makepkg.conf
sed -i 's/OPTIONS=(.*)/OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge lto)/g' /etc/makepkg.conf
yes | pacman -Scc
pacman-key --init
pacman -S --noconfirm archlinux-keyring
mkdir -p /__w/portproton-repo
pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com
pacman-key --lsign-key 3056513887B78AEB
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst'
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst'
cat << EOM >> /etc/pacman.conf
[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist
EOM
pacman -Syy
useradd -m user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "PACKAGER=\"Boris Yumankulov <boria138@altlinux.org>\"" >> /etc/makepkg.conf
chown user -R /tmp
chown user -R ..
- name: Checkout
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Build
run: |
cd /__w/portproton-repo
cp -r "$GITHUB_WORKSPACE" PortProtonQt
cd /__w/portproton-repo/PortProtonQt/build-aux
sed -i "s|source=(\"git+https://git.linux-gaming.ru/Boria138/PortProtonQt.git\")|source=(\"git+https://git.linux-gaming.ru/Boria138/PortProtonQt.git#branch=${{ env.BUILD_BRANCH }}\")|" PKGBUILD-git
chown user -R ..
su user -c "yes '' | makepkg --noconfirm -s -p PKGBUILD-git"
- name: Upload Arch package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-Arch
path: ${{ env.PKGDEST }}/*
@@ -25,12 +25,12 @@ jobs:
apt-get install -y build-essential pkg-config libvulkan-dev git curl wget nodejs npm
- name: Set up Node.js
uses: https://gitea.com/actions/setup-node@v2
uses: https://git.linux-gaming.ru/actions/setup-node@v2
with:
node-version: 20
- name: Checkout code
uses: https://gitea.com/actions/checkout@v3
uses: https://git.linux-gaming.ru/actions/checkout@v3
- name: Compile vk_gpu_info
run: |
@@ -51,7 +51,7 @@ jobs:
fi
- name: Upload vk_gpu_info binary
uses: https://gitea.com/actions/gitea-upload-artifact@v4
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: vk_gpu_info-debian11-binary
path: build-aux/vk_gpu_info
+41 -11
View File
@@ -1,4 +1,4 @@
name: Build AppImage, Arch and Fedora Packages
name: Build AppImage, Arch, Fedora and Debian Packages
on:
workflow_dispatch:
@@ -8,7 +8,7 @@ on:
env:
# Common version, will be used for tagging the release
VERSION: 1.0
VERSION: 1.2.0
PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt"
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
@@ -27,7 +27,7 @@ jobs:
pacman -Sy --noconfirm archlinux-keyring
pacman -Syu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm xorg-server-xvfb zsync
- uses: https://gitea.com/actions/checkout@v4
- uses: https://git.linux-gaming.ru/actions/checkout@v4
- name: Install appimage dependencies
run: |
@@ -41,7 +41,7 @@ jobs:
./portprotonqt-appimage.sh
- name: Upload AppImage
uses: https://gitea.com/actions/gitea-upload-artifact@v4
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-AppImage
path: build-aux/AppImage/dist/*.AppImage
@@ -78,7 +78,7 @@ jobs:
chown user -R ..
- name: Checkout
uses: https://gitea.com/actions/checkout@v4
uses: https://git.linux-gaming.ru/actions/checkout@v4
- name: Build
run: |
@@ -89,7 +89,7 @@ jobs:
su user -c "yes '' | makepkg --noconfirm -s"
- name: Upload Arch package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-Arch
path: ${{ env.PKGDEST }}/*
@@ -121,7 +121,7 @@ jobs:
echo '%_topdir /home/rpmbuild' > /home/rpmbuild/.rpmmacros
- name: Checkout repo
uses: https://gitea.com/actions/checkout@v4
uses: https://git.linux-gaming.ru/actions/checkout@v4
- name: Copy fedora.spec
run: |
@@ -133,16 +133,46 @@ jobs:
su rpmbuild -c "rpmbuild -ba /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec"
- name: Upload RPM package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-RPM-Fedora-${{ matrix.fedora_version }}
path: /home/rpmbuild/RPMS/**/*.rpm
build-debian:
name: Build Debian Package
runs-on: ubuntu-latest
container:
image: debian:13
options: --privileged
steps:
- name: Install build dependencies
run: |
apt-get update
apt-get install -y build-essential debhelper dpkg-dev gettext git \
libvulkan-dev meson ninja-build nodejs npm \
pkgconf python3
- name: Checkout
uses: https://git.linux-gaming.ru/actions/checkout@v4
- name: Build Debian package
run: |
dpkg-buildpackage -us -uc -b
mkdir -p dist/deb
mv ../*.deb ../*.buildinfo ../*.changes dist/deb/
- name: Upload Debian package
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-DEB-Debian-13
path: dist/deb/*
release:
name: Create and Publish Release
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/actions/checkout@v4
- uses: https://git.linux-gaming.ru/actions/checkout@v4
- name: Install required dependencies
run: |
@@ -150,7 +180,7 @@ jobs:
sudo apt install -y original-awk unzip
- name: Download all artifacts
uses: https://gitea.com/actions/download-artifact@v3
uses: https://git.linux-gaming.ru/actions/download-artifact@v3
continue-on-error: true
with:
path: release/
@@ -170,7 +200,7 @@ jobs:
awk "/^## \\[$VERSION\\]/ {flag=1; next} /^## \\[/ || /^---/ {flag=0} flag" CHANGELOG.md > changelog.txt
- name: Release
uses: https://gitea.com/actions/gitea-release-action@v1
uses: https://git.linux-gaming.ru/actions/gitea-release-action@v1
env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
with:
+2 -2
View File
@@ -15,12 +15,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
fetch-depth: 0
- name: Set up Python
uses: https://gitea.com/actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
uses: https://git.linux-gaming.ru/actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version-file: "pyproject.toml"
-195
View File
@@ -1,195 +0,0 @@
name: Build Check - AppImage, Arch, Fedora
on:
workflow_dispatch:
pull_request:
paths:
- 'build-aux/AppImage/**'
- 'build-aux/fedora-git.spec'
- 'build-aux/PKGBUILD-git'
- '.gitea/workflows/code-build.yml'
env:
PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt"
PR_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }}
PR_BRANCH: ${{ github.head_ref }}
jobs:
changes:
runs-on: ubuntu-latest
outputs:
appimage: ${{ steps.check.outputs.appimage }}
fedora: ${{ steps.check.outputs.fedora }}
arch: ${{ steps.check.outputs.arch }}
steps:
- uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Ensure git is installed
run: |
sudo apt update
sudo apt install -y git
- name: Check changed files
id: check
run: |
# Get changed files
git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} > changed_files.txt
echo "Changed files:"
cat changed_files.txt
# Check AppImage files
if grep -q "build-aux/AppImage/" changed_files.txt; then
echo "appimage=true" >> $GITHUB_OUTPUT
else
echo "appimage=false" >> $GITHUB_OUTPUT
fi
# Check Fedora spec files (only fedora-git.spec)
if grep -q "build-aux/fedora-git.spec" changed_files.txt; then
echo "fedora=true" >> $GITHUB_OUTPUT
else
echo "fedora=false" >> $GITHUB_OUTPUT
fi
# Check Arch PKGBUILD-git
if grep -q "build-aux/PKGBUILD-git" changed_files.txt; then
echo "arch=true" >> $GITHUB_OUTPUT
else
echo "arch=false" >> $GITHUB_OUTPUT
fi
build-appimage:
name: Build AppImage
runs-on: ubuntu-22.04
needs: changes
if: needs.changes.outputs.appimage == 'true' || github.event_name == 'workflow_dispatch'
container:
image: archlinux:base-devel@sha256:6db772fd1dd128b9cf7b7231ca5284af70879596fe4ec754c911cfc4ac30d5eb
options: --privileged --device /dev/fuse
steps:
- name: Prepare container
run: |
pacman-key --init
pacman -Sy --noconfirm --disable-download-timeout --needed archlinux-keyring
pacman -Syu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm xorg-server-xvfb zsync
- uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Install appimage dependencies
run: |
cd build-aux/AppImage
chmod +x get-dependencies.sh portprotonqt-appimage.sh
./get-dependencies.sh --local --branch "${{ env.PR_BRANCH }}" --repo "${{ env.PR_REPO_URL }}"
- name: Build AppImage
run: |
cd build-aux/AppImage
./portprotonqt-appimage.sh
- name: Upload AppImage
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-AppImage
path: build-aux/AppImage/dist/*.AppImage
build-fedora:
name: Build Fedora RPM
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.fedora == 'true' || github.event_name == 'workflow_dispatch'
strategy:
matrix:
fedora_version: [42, 43, 44, rawhide]
container:
image: fedora:${{ matrix.fedora_version }}
options: --privileged
steps:
- name: Install build dependencies
run: |
dnf install -y git rpmdevtools meson ninja-build python3-devel \
systemd-rpm-macros redhat-rpm-config nodejs npm \
gcc vulkan-loader-devel gettext
- name: Setup rpmbuild environment
run: |
useradd rpmbuild -u 5002 -g users || true
mkdir -p /home/rpmbuild/{BUILD,RPMS,SPECS,SRPMS,SOURCES}
chown -R rpmbuild:users /home/rpmbuild
echo '%_topdir /home/rpmbuild' > /home/rpmbuild/.rpmmacros
- name: Checkout repo
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Copy fedora-git.spec
run: |
sed "s|git clone https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|git clone -b ${{ env.PR_BRANCH }} ${{ env.PR_REPO_URL }}|" \
build-aux/fedora-git.spec > /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec
chown -R rpmbuild:users /home/rpmbuild
- name: Build RPM
run: |
su rpmbuild -c "rpmbuild -ba /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec"
- name: Upload RPM package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-RPM-Fedora-${{ matrix.fedora_version }}
path: /home/rpmbuild/RPMS/**/*.rpm
build-arch:
name: Build Arch Package
runs-on: ubuntu-22.04
needs: changes
if: needs.changes.outputs.arch == 'true' || github.event_name == 'workflow_dispatch'
container:
image: archlinux:base-devel@sha256:6db772fd1dd128b9cf7b7231ca5284af70879596fe4ec754c911cfc4ac30d5eb
steps:
- name: Prepare container
run: |
pacman -Sy --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm
sed -i 's/#MAKEFLAGS="-j2"/MAKEFLAGS="-j$(nproc) -l$(nproc)"/g' /etc/makepkg.conf
sed -i 's/OPTIONS=(.*)/OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge lto)/g' /etc/makepkg.conf
yes | pacman -Scc
pacman-key --init
pacman -S --noconfirm archlinux-keyring
mkdir -p /__w/portproton-repo
pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com
pacman-key --lsign-key 3056513887B78AEB
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst'
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst'
cat << EOM >> /etc/pacman.conf
[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist
EOM
pacman -Syy
useradd -m user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "PACKAGER=\"Boris Yumankulov <boria138@altlinux.org>\"" >> /etc/makepkg.conf
chown user -R /tmp
chown user -R ..
- name: Checkout
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Build
run: |
cd /__w/portproton-repo
git clone -b ${{ env.PR_BRANCH }} ${{ env.PR_REPO_URL }} PortProtonQt
cd /__w/portproton-repo/PortProtonQt/build-aux
sed -i "s|source=(\"git+https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git\")|source=(\"git+${{ env.PR_REPO_URL }}#branch=${{ env.PR_BRANCH }}\")|" PKGBUILD-git
chown user -R ..
su user -c "yes '' | makepkg --noconfirm -s -p PKGBUILD-git"
- name: Upload Arch package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-Arch
path: ${{ env.PKGDEST }}/*
+2 -2
View File
@@ -20,10 +20,10 @@ jobs:
name: Check code
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Set up Node.js
uses: https://gitea.com/actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
uses: https://git.linux-gaming.ru/actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 20
+2 -2
View File
@@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Set up Python
uses: https://gitea.com/actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
uses: https://git.linux-gaming.ru/actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version-file: "pyproject.toml"
+283
View File
@@ -0,0 +1,283 @@
name: Package Build - AppImage, Arch, Fedora, Debian
on:
workflow_dispatch:
pull_request:
paths:
- 'build-aux/AppImage/**'
- 'build-aux/fedora-git.spec'
- 'build-aux/PKGBUILD-git'
- 'debian/**'
- '.gitea/workflows/package-build.yml'
env:
BUILD_BRANCH: ${{ github.ref_name }}
PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt"
PR_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }}
PR_BRANCH: ${{ github.head_ref }}
jobs:
changes:
runs-on: ubuntu-latest
outputs:
appimage: ${{ steps.check.outputs.appimage }}
fedora: ${{ steps.check.outputs.fedora }}
arch: ${{ steps.check.outputs.arch }}
debian: ${{ steps.check.outputs.debian }}
steps:
- uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'pull_request'
with:
fetch-depth: 0
- name: Ensure git is installed
if: github.event_name == 'pull_request'
run: |
sudo apt update
sudo apt install -y git
- name: Check changed files
if: github.event_name == 'pull_request'
id: check
run: |
git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} > changed_files.txt
echo "Changed files:"
cat changed_files.txt
if grep -q "build-aux/AppImage/" changed_files.txt; then
echo "appimage=true" >> $GITHUB_OUTPUT
else
echo "appimage=false" >> $GITHUB_OUTPUT
fi
if grep -q "build-aux/fedora-git.spec" changed_files.txt; then
echo "fedora=true" >> $GITHUB_OUTPUT
else
echo "fedora=false" >> $GITHUB_OUTPUT
fi
if grep -q "build-aux/PKGBUILD-git" changed_files.txt; then
echo "arch=true" >> $GITHUB_OUTPUT
else
echo "arch=false" >> $GITHUB_OUTPUT
fi
if grep -q "debian/" changed_files.txt; then
echo "debian=true" >> $GITHUB_OUTPUT
else
echo "debian=false" >> $GITHUB_OUTPUT
fi
- name: Skip change detection
if: github.event_name == 'workflow_dispatch'
run: true
build-appimage:
name: Build AppImage
runs-on: ubuntu-22.04
needs: changes
if: needs.changes.outputs.appimage == 'true' || github.event_name == 'workflow_dispatch'
container:
image: archlinux:base-devel@sha256:c84ad63503efc5d386e30a5f44945fa8eee10fcb21b3d5fceda260783de394ff
options: --privileged --device /dev/fuse
steps:
- name: Prepare container
run: |
pacman-key --init
pacman -Sy --noconfirm archlinux-keyring
pacman -Syu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm xorg-server-xvfb zsync
- uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'pull_request'
- uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'workflow_dispatch'
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Install appimage dependencies
run: |
cd build-aux/AppImage
chmod +x get-dependencies.sh portprotonqt-appimage.sh
if [ "${{ github.event_name }}" = "pull_request" ]; then
./get-dependencies.sh --local --branch "${{ env.PR_BRANCH }}" --repo "${{ env.PR_REPO_URL }}"
else
./get-dependencies.sh --local --branch "${{ env.BUILD_BRANCH }}"
fi
- name: Build AppImage
run: |
cd build-aux/AppImage
./portprotonqt-appimage.sh
- name: Upload AppImage
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-AppImage
path: build-aux/AppImage/dist/*.AppImage
build-fedora:
name: Build Fedora RPM
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.fedora == 'true' || github.event_name == 'workflow_dispatch'
strategy:
matrix:
fedora_version: [42, 43, 44, rawhide]
container:
image: fedora:${{ matrix.fedora_version }}
options: --privileged
steps:
- name: Install build dependencies
run: |
dnf install -y git rpmdevtools meson ninja-build python3-devel \
systemd-rpm-macros vulkan-loader-devel redhat-rpm-config nodejs npm \
gcc gettext
- name: Setup rpmbuild environment
run: |
useradd rpmbuild -u 5002 -g users || true
mkdir -p /home/rpmbuild/{BUILD,RPMS,SPECS,SRPMS,SOURCES}
chown -R rpmbuild:users /home/rpmbuild
echo '%_topdir /home/rpmbuild' > /home/rpmbuild/.rpmmacros
- name: Checkout PR
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'pull_request'
- name: Checkout branch
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'workflow_dispatch'
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Copy fedora.spec
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
sed "s|git clone https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|git clone -b ${{ env.PR_BRANCH }} ${{ env.PR_REPO_URL }}|" \
build-aux/fedora-git.spec > /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec
else
sed "s|git clone https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|git clone -b ${{ env.BUILD_BRANCH }} https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git|" \
build-aux/fedora-git.spec > /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec
fi
chown -R rpmbuild:users /home/rpmbuild
- name: Build RPM
run: |
su rpmbuild -c "rpmbuild -ba /home/rpmbuild/SPECS/${{ env.PACKAGE }}.spec"
- name: Upload RPM package
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-RPM-Fedora-${{ matrix.fedora_version }}
path: /home/rpmbuild/RPMS/**/*.rpm
build-arch:
name: Build Arch Package
runs-on: ubuntu-22.04
needs: changes
if: needs.changes.outputs.arch == 'true' || github.event_name == 'workflow_dispatch'
container:
image: archlinux:base-devel@sha256:c84ad63503efc5d386e30a5f44945fa8eee10fcb21b3d5fceda260783de394ff
steps:
- name: Prepare container
run: |
pacman -Syuu --noconfirm --disable-download-timeout --needed git wget gnupg nodejs npm
sed -i 's/#MAKEFLAGS="-j2"/MAKEFLAGS="-j$(nproc) -l$(nproc)"/g' /etc/makepkg.conf
sed -i 's/OPTIONS=(.*)/OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge lto)/g' /etc/makepkg.conf
yes | pacman -Scc
pacman-key --init
pacman -S --noconfirm archlinux-keyring
mkdir -p /__w/portproton-repo
pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com
pacman-key --lsign-key 3056513887B78AEB
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst'
pacman -U --noconfirm 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst'
cat << EOM >> /etc/pacman.conf
[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist
EOM
pacman -Syy
useradd -m user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "PACKAGER=\"Boris Yumankulov <boria138@altlinux.org>\"" >> /etc/makepkg.conf
chown user -R /tmp
chown user -R ..
- name: Checkout PR
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'pull_request'
- name: Checkout branch
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'workflow_dispatch'
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Build
run: |
cd /__w/portproton-repo
if [ "${{ github.event_name }}" = "pull_request" ]; then
git clone -b ${{ env.PR_BRANCH }} ${{ env.PR_REPO_URL }} PortProtonQt
else
cp -r "$GITHUB_WORKSPACE" PortProtonQt
fi
cd /__w/portproton-repo/PortProtonQt/build-aux
if [ "${{ github.event_name }}" = "pull_request" ]; then
sed -i "s|source=(\"git+https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git\")|source=(\"git+${{ env.PR_REPO_URL }}#branch=${{ env.PR_BRANCH }}\")|" PKGBUILD-git
else
sed -i "s|source=(\"git+https://git.linux-gaming.ru/Boria138/PortProtonQt.git\")|source=(\"git+https://git.linux-gaming.ru/Boria138/PortProtonQt.git#branch=${{ env.BUILD_BRANCH }}\")|" PKGBUILD-git
fi
chown user -R ..
su user -c "yes '' | makepkg --noconfirm -s -p PKGBUILD-git"
- name: Upload Arch package
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-Arch
path: ${{ env.PKGDEST }}/*
build-debian:
name: Build Debian Package
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.debian == 'true' || github.event_name == 'workflow_dispatch'
container:
image: debian:13@sha256:4ae67669760b807c19f23902a3fd7c121a6a70cf2ae709035674b23e712e4d62
options: --privileged
steps:
- name: Install build dependencies
run: |
apt-get update
apt-get install -y build-essential debhelper dpkg-dev gettext git \
libvulkan-dev meson ninja-build nodejs npm \
pkgconf python3
- name: Checkout PR
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'pull_request'
- name: Checkout branch
uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
if: github.event_name == 'workflow_dispatch'
with:
ref: ${{ env.BUILD_BRANCH }}
- name: Build Debian package
run: |
dpkg-buildpackage -us -uc -b
mkdir -p dist/deb
mv ../*.deb ../*.buildinfo ../*.changes dist/deb/
- name: Upload Debian package
uses: https://git.linux-gaming.ru/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-DEB-Debian-13
path: dist/deb/*
+3 -3
View File
@@ -8,12 +8,12 @@ on:
jobs:
renovate:
runs-on: ubuntu-latest
container: ghcr.io/renovatebot/renovate:latest@sha256:2ccc5b1f0340593c40e1598547aa98feee4e521a0906a423fe0be0431a733dfa
container: ghcr.io/renovatebot/renovate:latest@sha256:47421f2f3f82048e969b5195dd808d5ac2c5f69d43d192191c4a3dca390afe06
steps:
- uses: https://gitea.com/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: https://git.linux-gaming.ru/actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Set up Node.js
uses: https://gitea.com/actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
uses: https://git.linux-gaming.ru/actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 20
+1
View File
@@ -8,6 +8,7 @@ wheels/
# Meson
builddir/
build-deb/
# Virtual environments
.venv
+10
View File
@@ -628,6 +628,11 @@ shadow.setBlurRadius(self.theme.shadow_blur_radius)
label.setStyleSheet(self.theme.CONTENT_STYLE)
```
**Tooltip rule:**
- Prefer the themed `gamepad_tooltip`/`TOOLTIP_STYLE` mechanism for in-app `QWidget` tooltips
- Avoid `setToolTip()` for regular widgets when the themed tooltip can be used
- `setToolTip()` is acceptable only for APIs that are not regular widgets, such as `QSystemTrayIcon`
### Comments
```python
# NEVER: Russian or verbose
@@ -785,6 +790,11 @@ PortProtonQt/
- These scripts are for developer convenience only
- Do not refactor or improve dev-scripts unless explicitly requested
## PortProton Scripts
- In `build-aux/share/portproton/scripts/`, run `portprotonqt.scripts_utils` modules through the existing `python_module` function
- Do not add direct `python3 -m portprotonqt.scripts_utils.*` calls where `python_module` is available
---
## Dependencies
+120 -1
View File
@@ -3,6 +3,125 @@
Все заметные изменения в этом проекте фиксируются в этом файле.
Формат основан на [Keep a Changelog](https://keepachangelog.com/) и придерживается принципов [Semantic Versioning](https://semver.org/).
## [1.2.0] - 2026-06-10
### Added
- Добавлено удаление и переименование файла в файловом менеджере
- Добавлена поддержка Special K
- Добавлены настройки Wine, префикса и 3D Api по умолчанию
- Добавлена настройка выбора звукового драйвера
- Добавлена поддержка команд в настройке `запуск после`
- Добавлена кнопка выхода во вкладку `Система`
- Добавлена поддержка перетаскивания `.ppack` для восстановления префиксов
- Добавлен скрытый тип отображения времени, скрывающий последний запуск и проведённое время
- Добавлена сборка Deb-пакета (Debian 13+ и Ubuntu 25.04+)
- Добавлена кнопка открытия установленного приложения из карточки автоустановки
- Добавлено создание `.desktop` ярлыков под AppImage и их миграция при смене AppImage
- Добавлено обновление `steam_scripts` в миграции ярлыков
- Добавлена вкладка избранных параметров в диалог настроек exe
- Добавлена вкладка настроек vkBasalt в диалог настроек exe
- Добавлена проверка хэш-суммы после скачивания компонентов
- Добавлена поддержка запуска `.nrg`
- Начат португальский перевод `https://translate.codeberg.org/projects/portprotonqt/portprotonqt/pt_BR/`
### Changed
- Действия управления питанием во вкладке `Система` переведены на использование `loginctl`
- В пресет MangoHud `PortProton` добавлен параметр `display_server`
- Возвращена настройка типа геймпада для подсказок: Авто, Xbox или PlayStation (для авто нужен libSDL3)
- Убрано лишнее сообщение об успешной очистке PPDB в диалоге настроек exe
- Улучшено выделение строк и читаемость комбобоксов в настройках exe
- Увеличена скорость передвижения курсора при эмуляции мыши
- Ярлыки по умолчанию создаются только внутри PortProtonQt, без копирования в меню приложений и на рабочий стол
- Обновлён WINE_LG: 11-1 -> 11-10
- Обновлён испанский перевод `https://translate.codeberg.org/projects/portprotonqt/portprotonqt/es/`
### Fixed
- Исправлена работа Winetricks с версиями Proton/Wine имеющими путь `files/bin/wine`
- `exiftool` больше не запускается, если он не установлен
- Исправлено копирование PPDB к exe
- Исправлено отображение настроек `.bat`, `.cmd`, `.msi` и `.reg`
- Исправлена настройка запуска нативного Wayland
- Исправлен запуск PortProtonQt AppImage в режиме `--silent`
- Исправлен запуск добавленных в Steam приложений из AppImage
- Исправлено отключение скачивания контейнера во Flatpak
- Исправлено чтение XDG Base Directory в скриптах: теперь пути читаются всегда, если заданы, без привязки к Flatpak
- Исправлена миграция ярлыков на рабочем столе
- Исправлен выбор системного `MangoHud.conf` в Flatpak: сначала проверяется `~/.config`, затем `XDG_CONFIG_HOME`
- Исправлен выбор системного `vkBasalt.conf` в Flatpak: сначала проверяется `~/.config`, затем `XDG_CONFIG_HOME`
- Исправлено авто-включение MangoHud при наличии `MANGOHUD_CONFIG`
- Добавлена пропущенная поддержка `.cmd` рядом с `.bat`
- Исправлено определение каталога Steam на OpenSUSE и Deb-based системах
- Исправлен запуск игр Steam с учётом native, Snap и Flatpak установок
- Исправлена передача параметров запуска игр в Steam compatibility mode
- Исправлено определение установленных автоустановок по `.desktop`
- Исправлена загрузка встроенных цветовых схем терминала
- Исправлено попадание NFS и SMB шар в список смонтированных дисков
- Исправлено создание папки в файловом менеджере
- Исправлено редактирование имени папки в файловом менеджере
- Исправлен сброс фокуса в файловом менеджере при навигации геймпадом
- Исправлено прерывание автоустановки при выходе из карточки
- Исправлено чтение последнего запуска для приложений с пробелами в имени exe
- Исправлено отображение настроек exe с расширением в верхнем регистре
- Исправлена неработоспособность правого стика геймпада из-за обработки прокрутки
- Получение списка компонентов winetricks теперь занимает 0.11 с, а не 6.8
- Исправлено бесконечное скачивание компонентов из автоустановок, если скорость скачивания падает до нуля
### Contributors
- @VanoMJ
- @CastroFidel
- @Dervart
- @rogerio-mattos
- @gallegonovato
---
## [1.1.0] - 2026-05-26
### Added
- Добавлен диалог прогресса для создания и восстановления резервных копий префиксов
- Добавлено автосоздание ярлыков GOG игр
- Для обложек добавлена поддержка SVG
- Добавлена поддержка `.bat`, `.msi` и `.reg`
- Добавлена кнопка `Быстрый запуск` в библиотеку для открытия детальной страницы любого исполняемого файла без создания ярлыка
- Добавлена проверка доступа на чтение и запись для `PORT_DATA_PATH` при выборе и запуске
### Changed
- Обезличен интерфейс: игровые термины (Игра, Игровое время, Играть и т.д.) заменены на более общие (Приложение, Время в приложении, Запуск)
- Резервные копии `.ppack` теперь создаются через `libarchive-c` в формате `pax` с `zstd` вместо SquashFS (лучше скорость и качество сжатия)
- При ошибке загрузки обложки Steam/SGDB теперь используется иконка из `.exe`
- Удалены заголовки вкладок `Библиотека` и `Автоустановка`
- Улучшена навигация по библиотеке с клавиатуры и геймпада: фокус ставится на первую карточку, а верхние кнопки доступны из первого ряда
- Пустая библиотека теперь корректно обновляется после запуска приложения через правую кнопку мыши
- Для тем с режимом библиотеки `list` теперь используются обложки автоустановок
- Установка Wine/LG-сборок в `data/dist` теперь не зависит от настройки загрузки Proton в Steam
- При сбросе настроек PortProtonQt теперь также сбрасывается `user.conf` PortProton
- Удалён отдельный пакет `portprotonqt-steam-compat` теперь установленный через галочку режим совместимости self-update
- D-Bus операции скриптов перенесены в `scripts_utils.dbus_tools` на базе `dbus-fast`
- Настройка авто-перехода в полноэкранный режим при подключении геймпада перенесена в подпункт настройки полноэкранного запуска
### Fixed
- Исправлена некорректная установка DPI в Wine, когда опция `Использовать системный DPI` отключена
- Исправлено определение версии DXVK в логе, если у приложения отсутствует PPDB
- Исправлена пустая вкладка настроек Wine при отсутствии каталога `data/dist`
- Исправлено обновление прогресса кнопок при загрузке библиотек и зависимостей PortProton
- Исправлен повторный запуск восстановления префикса после смены темы сразу после восстановления
- Исправлена эмуляция мыши с геймпада после запуска приложений через лаунчеры
- Исправлен запуск PortProtonQt в полноэкранном режиме, если геймпад подключён до старта приложения
- Исправлено отображение префиксов `DEFAULT` и `DOTNET` при отсутствии соответствующих каталогов
- Исправлена локализация AppImage на РОСА «ФРЕШ»
- Исправлено обновление библиотеки после создания ярлыков PortProton
- Исправлен запуск `exiftool` для ярлыков с отсутствующими `.exe`
- Исправлено восстановление профиля питания после остановки приложения из трея
- Исправлено применения языка `Китайский (упрощённый)`
- Исправлено попадание служебных строк PortProton в список видеокарт и скрытие выбора видеокарты при одной доступной GPU
### Contributors
- @Castro-Fidel
- @Simple16
- @Dervart
---
## [1.0] - 2026-05-23
### Added
@@ -59,7 +178,7 @@
- Улучшенно качестве иконок из `exe` файлов
- В трей добавлены компактный и детальный режимы меню
- Автоустановки теперь можно остановить
- Префиксы `DEFAULT`, `DOTNET` и `PROGRAMS` теперь всегда отображаются вверху списков префиксов
- Префиксы `DEFAULT` и `DOTNET` теперь всегда отображаются вверху списков префиксов
- Из лога удалена версия скриптов, так как скрипты теперь внутри PortProtonQt
- Из downloader удалена отдельная проверка сети через Yandex и Google
- Выбор видеокарты теперь не отображается в настройках PortProtonQt если видеокарта всего одна
+1 -1
View File
@@ -60,7 +60,7 @@ PortProtonQt использует код и зависимости от след
- [Icoextract](https://github.com/jlu5/icoextract) — библиотека для извлечения иконок, лицензия [MIT](https://github.com/jlu5/icoextract/blob/master/LICENSE).
- [HowLongToBeat Python API](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI) — библиотека для взаимодействия с HowLongToBeat, лицензия [MIT](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/LICENSE.md).
- [iat](https://sourceforge.net/projects/iat.berlios) — библиотека для конвертации mdf в iso, лицензия GPLv3
- [iat](https://sourceforge.net/projects/iat.berlios) — библиотека для конвертации mdf и nrg в iso, лицензия GPLv3
- [pyte](https://github.com/selectel/pyte) — разбор ANSI escape-кодов, лицензия [LGPLv3](https://github.com/selectel/pyte?tab=LGPL-3.0-1-ov-file)
Полный текст лицензий см. в файле [LICENSE](LICENSE).
+7 -17
View File
@@ -1,13 +1,16 @@
pkgname=('portprotonqt' 'portprotonqt-steam-compat')
pkgver=1.0
pkgname=('portprotonqt')
pkgver=1.2.0
pkgrel=1
pkgdesc="Modern GUI for managing and launching games from PortProton and Steam"
arch=('any')
url="https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt"
license=('GPL-3.0')
depends=('python-requests' 'python-babel' 'python-evdev' 'python-pygame' 'python-orjson'
'python-psutil' 'python-tqdm' 'python-vdf' 'python-libarchive-c' 'pyside6' 'python-rapidfuzz' 'python-pefile' 'python-pillow' 'perl-image-exiftool' 'python-websocket-client' 'cabextract' 'unzip' 'curl' 'jq' 'file' 'findutils' 'gawk' 'grep' 'tar' 'xz' 'zstd' 'gzip' 'unrar' 'qt6-svg' 'qt6-imageformats' 'pciutils' 'mesa-utils' 'vulkan-icd-loader' 'procps-ng' 'psmisc' 'squashfs-tools' '7zip' 'python-dbus-fast')
'python-psutil' 'python-tqdm' 'python-vdf' 'python-libarchive-c' 'pyside6' 'python-rapidfuzz' 'python-pefile' 'python-pillow' 'perl-image-exiftool' 'python-websocket-client' 'cabextract' 'unzip' 'curl' 'jq' 'file' 'findutils' 'gawk' 'grep' 'tar' 'xz' 'zstd' 'gzip' 'unrar' 'qt6-svg' 'qt6-imageformats' 'pciutils' 'mesa-utils' 'vulkan-icd-loader' 'procps-ng' 'psmisc' '7zip' 'python-dbus-fast' 'sdl3')
makedepends=('meson' 'ninja' 'vulkan-headers' 'gettext')
conflicts=("portprotonqt-steam-compat")
provides=('portprotonqt-steam-compat')
replaces=('portprotonqt-steam-compat')
source=("git+https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt#tag=v$pkgver")
sha256sums=('SKIP')
@@ -24,6 +27,7 @@ package_portprotonqt() {
'upower: System tab bluetooth battery level'
'libpulse: System tab audio volume/output management'
'python-qrcode: Wi-Fi QR code generation'
'squashfs-tools: for legacy PortProton prefix backup support'
)
DESTDIR="$pkgdir" meson install -C build --skip-subprojects
@@ -32,18 +36,4 @@ package_portprotonqt() {
install -Dpm 0644 "$srcdir/PortProtonQt/completions/portprotonqt" -t "$pkgdir/usr/share/bash-completion/completions"
install -Dpm 0644 "$srcdir/PortProtonQt/completions/portprotonqt.fish" -t "$pkgdir/usr/share/fish/vendor_completions.d"
install -Dpm 0644 "$srcdir/PortProtonQt/completions/_portprotonqt" -t "$pkgdir/usr/share/zsh/site-functions"
# Remove steam-compat files from main package
rm -rf "$pkgdir/usr/share/steam"
}
package_portprotonqt-steam-compat() {
pkgdesc="Steam compatibility tool for PortProtonQt"
depends=('portprotonqt')
DESTDIR="$pkgdir" meson install -C build --skip-subprojects
# Keep only steam-compat files
find "$pkgdir/usr" -mindepth 1 -type f -not -path "${pkgdir}/usr/share/steam*" -print0 | xargs -0 rm -f
find "$pkgdir/usr" -mindepth 1 -type d -not -path "${pkgdir}/usr/share/steam*" -empty -delete
}
+6 -16
View File
@@ -1,4 +1,4 @@
pkgname=('portprotonqt-git' 'portprotonqt-git-steam-compat')
pkgname=('portprotonqt-git')
pkgver=.
pkgrel=1
pkgdesc="Modern GUI for managing and launching games from PortProton and Steam (development build)"
@@ -6,8 +6,11 @@ arch=('any')
url="https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt"
license=('GPL-3.0')
depends=('python-requests' 'python-babel' 'python-evdev' 'python-pygame' 'python-orjson'
'python-psutil' 'python-tqdm' 'python-vdf' 'python-libarchive-c' 'pyside6' 'python-rapidfuzz' 'python-pefile' 'python-pillow' 'perl-image-exiftool' 'python-websocket-client' 'cabextract' 'unzip' 'curl' 'jq' 'file' 'findutils' 'gawk' 'grep' 'tar' 'xz' 'zstd' 'gzip' 'unrar' 'qt6-svg' 'qt6-imageformats' 'pciutils' 'mesa-utils' 'vulkan-icd-loader' 'procps-ng' 'psmisc' 'squashfs-tools' '7zip' 'python-dbus-fast')
'python-psutil' 'python-tqdm' 'python-vdf' 'python-libarchive-c' 'pyside6' 'python-rapidfuzz' 'python-pefile' 'python-pillow' 'perl-image-exiftool' 'python-websocket-client' 'cabextract' 'unzip' 'curl' 'jq' 'file' 'findutils' 'gawk' 'grep' 'tar' 'xz' 'zstd' 'gzip' 'unrar' 'qt6-svg' 'qt6-imageformats' 'pciutils' 'mesa-utils' 'vulkan-icd-loader' 'procps-ng' 'psmisc' '7zip' 'python-dbus-fast' 'sdl3')
makedepends=('meson' 'ninja' 'vulkan-headers' 'gettext')
conflicts=("portprotonqt-steam-compat")
provides=('portprotonqt-steam-compat')
replaces=('portprotonqt-steam-compat')
source=("git+https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt.git")
sha256sums=('SKIP')
@@ -29,6 +32,7 @@ package_portprotonqt-git() {
'upower: System tab bluetooth battery level'
'libpulse: System tab audio volume/output management'
'python-qrcode: Wi-Fi QR code generation'
'squashfs-tools: for legacy PortProton prefix backup support'
)
DESTDIR="$pkgdir" meson install -C build --skip-subprojects
@@ -37,18 +41,4 @@ package_portprotonqt-git() {
install -Dpm 0644 "$srcdir/PortProtonQt/completions/portprotonqt" -t "$pkgdir/usr/share/bash-completion/completions"
install -Dpm 0644 "$srcdir/PortProtonQt/completions/portprotonqt.fish" -t "$pkgdir/usr/share/fish/vendor_completions.d"
install -Dpm 0644 "$srcdir/PortProtonQt/completions/_portprotonqt" -t "$pkgdir/usr/share/zsh/site-functions"
# Remove steam-compat files from main package
rm -rf "$pkgdir/usr/share/steam"
}
package_portprotonqt-git-steam-compat() {
pkgdesc="Steam compatibility tool for PortProtonQt (development build)"
depends=('portprotonqt-git')
DESTDIR="$pkgdir" meson install -C build --skip-subprojects
# Keep only steam-compat files
find "$pkgdir/usr" -mindepth 1 -type f -not -path "${pkgdir}/usr/share/steam*" -print0 | xargs -0 rm -f
find "$pkgdir/usr" -mindepth 1 -type d -not -path "${pkgdir}/usr/share/steam*" -empty -delete
}
+9 -15
View File
@@ -1,5 +1,5 @@
%global pypi_name portprotonqt
%global pypi_version 1.0
%global pypi_version 1.2.0
%global oname PortProtonQt
%global build_timestamp %(date +"%Y%m%d")
%global _python_no_extras_requires 1
@@ -13,7 +13,7 @@ Summary: Modern GUI for managing and launching games from PortProton and
License: GPL-3.0
URL: https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt
ExclusiveArch: x86_64 aarch64
ExclusiveArch: x86_64
BuildRequires: meson >= 0.61.2
BuildRequires: ninja-build
@@ -43,6 +43,7 @@ Requires: python3-pillow-qt
Requires: python3-rapidfuzz
Requires: python3-libarchive-c
Requires: perl-Image-ExifTool
Requires: SDL3
Requires: qt6-qtsvg
Requires: qt6-qtimageformats
Requires: cabextract
@@ -63,7 +64,6 @@ Requires: pciutils
Requires: vulkan-loader
Requires: procps-ng
Requires: psmisc
Requires: squashfs-tools
Requires: 7zip
Requires: python3-dbus-fast
@@ -74,18 +74,15 @@ Recommends: upower
Recommends: pulseaudio-utils
Recommends: python3-qrcode
# For legacy PortProton prefix backup support
Recommends: squashfs-tools
Obsoletes: %{pypi_name}-steam-compat < %{?epoch:%{epoch}:}%{version}-%{release}
Provides: %{pypi_name}-steam-compat = %{?epoch:%{epoch}:}%{version}-%{release}
%description
A modern and intuitive interface for managing and launching games from PortProton and Steam. Combines libraries in one place and simplifies running Windows games on Linux.
%package -n %{pypi_name}-git-steam-compat
Summary: Steam compatibility tool for PortProtonQt (development build)
License: GPL-3.0
Requires: %{pypi_name}-git = %{version}-%{release}
%description -n %{pypi_name}-git-steam-compat
Steam compatibility tool integration for PortProtonQt. This package installs
the necessary files to use PortProtonQt as a Proton compatibility tool in Steam.
%{?python_disable_dependency_generator}
%prep
@@ -125,7 +122,4 @@ install -Dpm 0644 ./completions/_portprotonqt -t %{buildroot}%{zsh_completions_d
%{fish_completions_dir}/portprotonqt.fish
%{zsh_completions_dir}/_portprotonqt
%files -n %{pypi_name}-git-steam-compat
%{_datadir}/steam/compatibilitytools.d/PortProtonQt/
%changelog
+9 -15
View File
@@ -1,5 +1,5 @@
%global pypi_name portprotonqt
%global pypi_version 1.0
%global pypi_version 1.2.0
%global oname PortProtonQt
%global _python_no_extras_requires 1
@@ -10,7 +10,7 @@ Summary: Modern GUI for managing and launching games from PortProton and
License: GPL-3.0
URL: https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt
ExclusiveArch: x86_64 aarch64
ExclusiveArch: x86_64
BuildRequires: meson >= 0.61.2
BuildRequires: ninja-build
@@ -40,6 +40,7 @@ Requires: python3-pillow-qt
Requires: python3-rapidfuzz
Requires: python3-libarchive-c
Requires: perl-Image-ExifTool
Requires: SDL3
Requires: qt6-qtsvg
Requires: qt6-qtimageformats
Requires: cabextract
@@ -60,7 +61,6 @@ Requires: pciutils
Requires: vulkan-loader
Requires: procps-ng
Requires: psmisc
Requires: squashfs-tools
Requires: 7zip
Requires: python3-dbus-fast
@@ -71,18 +71,15 @@ Recommends: upower
Recommends: pulseaudio-utils
Recommends: python3-qrcode
# For legacy PortProton prefix backup support
Recommends: squashfs-tools
Obsoletes: %{pypi_name}-steam-compat < %{?epoch:%{epoch}:}%{version}-%{release}
Provides: %{pypi_name}-steam-compat = %{?epoch:%{epoch}:}%{version}-%{release}
%description
A modern and intuitive interface for managing and launching games from PortProton and Steam. Combines libraries in one place and simplifies running Windows games on Linux.
%package -n %{pypi_name}-steam-compat
Summary: Steam compatibility tool for PortProtonQt
License: GPL-3.0
Requires: %{pypi_name} = %{version}-%{release}
%description -n %{pypi_name}-steam-compat
Steam compatibility tool integration for PortProtonQt. This package installs
the necessary files to use PortProtonQt as a Proton compatibility tool in Steam.
%{?python_disable_dependency_generator}
%prep
@@ -123,7 +120,4 @@ install -Dpm 0644 ./completions/_portprotonqt -t %{buildroot}%{zsh_completions_d
%{fish_completions_dir}/portprotonqt.fish
%{zsh_completions_dir}/_portprotonqt
%files -n %{pypi_name}-steam-compat
%{_datadir}/steam/compatibilitytools.d/PortProtonQt/
%changelog
@@ -11,4 +11,4 @@ Terminal=false
Icon=ru.linux_gaming.PortProtonQt
StartupWMClass=ru.linux_gaming.PortProtonQt
Categories=Game;Utility;
MimeType=x-scheme-handler/portproton;application/x-portproton-prefix-backup;application/x-ms-dos-exec;application/x-executable;application/x-dosexec;application/x-iso9660-image;application/x-cd-image;application/x-raw-disk-image;application/x-mdf;application/x-mds-disk;
MimeType=x-scheme-handler/portproton;application/x-portproton-prefix-backup;application/x-ms-dos-exec;application/x-ms-dos-batch;application/x-bat;application/x-msi;text/x-ms-regedit;application/x-executable;application/x-dosexec;application/x-iso9660-image;application/x-cd-image;application/x-raw-disk-image;application/x-mdf;application/x-mds-disk;application/x-nrg;
@@ -24,34 +24,51 @@
</developer>
<releases>
<release version="1.0.0" date="2026-04-28">
<description>
<ul>
<li>Built-in PortProton scripts with full PortProton feature parity</li>
<li>New classic theme for an easier transition from PortProton</li>
<li>Network-saving mode, improved caching, and fully local Steam game covers</li>
<li>File manager actions for creating, deleting, and renaming folders</li>
<li>Support for animated covers, JXL images, MDF launch, and external Steam Proton builds</li>
<li>New tray controls for stopping a running game and silent exe launch support</li>
<li>Improved gamepad controls with automatic Xbox and PlayStation type selection</li>
<li>Improved tray, auto-install page, lost exe handling, and Wine/Proton list ordering</li>
<li>Fixes for Bluetooth, SteamGridDB, QComboBox scrolling, Steam Compatdata, and desktop shortcuts</li>
</ul>
</description>
<release version="1.2.0" date="2026-06-10">
<description></description>
</release>
<release version="1.1.0" date="2026-05-26">
<description/>
</release>
<release version="1.0" date="2026-05-23">
<description/>
</release>
<release version="0.1.12" date="2026-04-17" type="development">
<description/>
</release>
<release version="0.1.11" date="2026-02-18" type="development">
<description/>
</release>
<release version="0.1.10" date="2026-01-14" type="development">
<description/>
</release>
<release version="0.1.9" date="2025-12-08" type="development">
<description/>
</release>
<release version="0.1.8" date="2025-10-18" type="development">
<description/>
</release>
<release version="0.1.7" date="2025-10-12" type="development">
<description/>
</release>
<release version="0.1.6" date="2025-09-23" type="development">
<description/>
</release>
<release version="0.1.5" date="2025-08-31" type="development">
<description/>
</release>
<release version="0.1.4" date="2025-07-21" type="development">
<description/>
</release>
<release version="0.1.3" date="2025-07-05" type="development">
<description/>
</release>
<release version="0.1.2" date="2025-06-15" type="development">
<description/>
</release>
<release version="0.1.1" date="2025-05-17" type="development">
<description/>
</release>
<release version="0.1.12" date="2026-04-17" type="development"/>
<release version="0.1.11" date="2026-02-18" type="development"/>
<release version="0.1.10" date="2026-01-14" type="development"/>
<release version="0.1.9" date="2025-12-08" type="development"/>
<release version="0.1.8" date="2025-10-18" type="development"/>
<release version="0.1.7" date="2025-10-12" type="development"/>
<release version="0.1.6" date="2025-09-23" type="development"/>
<release version="0.1.5" date="2025-08-31" type="development"/>
<release version="0.1.4" date="2025-07-21" type="development"/>
<release version="0.1.3" date="2025-07-05" type="development"/>
<release version="0.1.2" date="2025-06-15" type="development"/>
<release version="0.1.1" date="2025-05-17" type="development"/>
</releases>
<recommends>
@@ -4,6 +4,5 @@
<comment>PortProton prefix backup</comment>
<comment xml:lang="ru">Резервная копия префикса PortProton</comment>
<glob pattern="*.ppack"/>
<sub-class-of type="application/vnd.squashfs"/>
</mime-type>
</mime-info>
File diff suppressed because it is too large. Load diff
@@ -13,7 +13,7 @@ export PORTWINE_CREATE_SHORTCUT_NAME="DC Universe Online"
start_portproton
if try_download "https://launch.daybreakgames.com/installer/DCUO_setup.exe" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/Program Files (x86)/Daybreak Game Company"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/Program Files (x86)/Daybreak Game Company"
PW_EXE_FILE="$WINEPREFIX/drive_c/Program Files (x86)/Daybreak Game Company/LaunchPad.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${PW_EXE_FILE}.ppdb"
@@ -26,10 +26,10 @@ if try_download "https://launcher.ccpgames.com/eve-online/release/win32/x64/eve-
then
EVE_LAUNCHER_DIR="${WINEPREFIX}/drive_c/users/steamuser/AppData/Local/eve-online"
$pw_7z x "${PORT_WINE_TMP_PATH}/eve-online-latest+Setup.exe" -o"${EVE_LAUNCHER_DIR}" -y
unpack "${PORT_WINE_TMP_PATH}/eve-online-latest+Setup.exe" "${EVE_LAUNCHER_DIR}"
EVE_VERSION="$(cat "${EVE_LAUNCHER_DIR}/RELEASES" | awk '{print $2}' | awk -F"-" '{print $3}')"
$pw_7z x "${EVE_LAUNCHER_DIR}/eve-online-${EVE_VERSION}-full.nupkg" -o"${EVE_LAUNCHER_DIR}/tmp" -y
unpack "${EVE_LAUNCHER_DIR}/eve-online-${EVE_VERSION}-full.nupkg" "${EVE_LAUNCHER_DIR}/tmp"
create_new_dir "${EVE_LAUNCHER_DIR}/app-$EVE_VERSION"
@@ -15,8 +15,8 @@ start_portproton
if try_download "https://static-gl.lilithgame.com/p/pcsdk/launcher/10060/prodef4621e968ad6b383b8754148b63/0/launcher/res/release/Farlight84_setup_1.3.0.1_238.exe" "${PW_AUTOINSTALL_EXE}" no_mirror
then
create_new_dir "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84"
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/Program Files (x86)/Farlight84"
"$pw_7z" x -y "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84/launcher.7z" -o"$WINEPREFIX/drive_c/Program Files (x86)/Farlight84"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84"
unpack "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84/launcher.7z" "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84"
PW_EXE_FILE="$WINEPREFIX/drive_c/Program Files (x86)/Farlight84/Farlight84Launcher.exe"
try_remove_file "$WINEPREFIX/drive_c/Program Files (x86)/Farlight84/launcher.7z"
try_remove_file "${PW_AUTOINSTALL_EXE}"
@@ -13,7 +13,7 @@ export PORTWINE_CREATE_SHORTCUT_NAME="Last Chaos"
start_portproton
if try_download "https://last-chaos.ru/download/Last%20Chaos.zip" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"${WINEPREFIX}/drive_c/Program Files/"
unpack "${PW_AUTOINSTALL_EXE}" "${WINEPREFIX}/drive_c/Program Files/"
PW_EXE_FILE="${WINEPREFIX}/drive_c/Program Files/Last Chaos/LC.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${PW_EXE_FILE}.ppdb"
@@ -15,7 +15,7 @@ URL_LOST_LIGHT="$(curl -s --list-only "https://adl.easebar.com/d/g/yhtj/c/lostli
start_portproton
if try_download "${URL_LOST_LIGHT}" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/Program Files (x86)/LostLight"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/Program Files (x86)/LostLight"
export PW_EXE_FILE="$WINEPREFIX/drive_c/Program Files (x86)/LostLight/launcher.exe"
pw_create_unique_exe "lostlight_launcher_pp"
try_remove_file "${PW_AUTOINSTALL_EXE}"
@@ -15,7 +15,7 @@ export PORTWINE_CREATE_SHORTCUT_NAME="Mini World"
start_portproton
if try_download "https://mwu-api.miniworldgame.com/app_install/${URL_VER//[[:space:]]/}universal" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/users/steamuser/AppData/Roaming/miniworldOverseasgame"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/users/steamuser/AppData/Roaming/miniworldOverseasgame"
PW_EXE_FILE="$WINEPREFIX/drive_c/users/steamuser/AppData/Roaming/miniworldOverseasgame/MicroMiniNew.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${PW_EXE_FILE}.ppdb"
@@ -14,7 +14,7 @@ export PORTWINE_CREATE_SHORTCUT_NAME="Rise of Flight"
start_portproton
if try_download "https://il2bosrd1.cdnvideo.ru/ROF/ROF_UE.zip" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/Program Files (x86)/1C-777/Rise of Flight"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/Program Files (x86)/1C-777/Rise of Flight"
pw_kill_autostart "3rd_party" &
pw_run "$WINEPREFIX/drive_c/Program Files (x86)/1C-777/Rise of Flight/ROF_UE/setup.exe"
PW_EXE_FILE="$WINEPREFIX/drive_c/Program Files (x86)/1C-777/Rise of Flight/bin_game/release/rof_updater.exe"
@@ -12,7 +12,7 @@ export PW_AUTOINSTALL_EXE="${PORT_WINE_TMP_PATH}/saturn.zip"
start_portproton
if try_download "https://cdn-s3.quadrosim.ru/saturn/saturn.zip" "${PW_AUTOINSTALL_EXE}" no_mirror
then
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"$WINEPREFIX/drive_c/Program Files (x86)/saturn"
unpack "${PW_AUTOINSTALL_EXE}" "$WINEPREFIX/drive_c/Program Files (x86)/saturn"
PW_EXE_FILE="$WINEPREFIX/drive_c/Program Files (x86)/saturn/Saturn.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${PW_EXE_FILE}.ppdb"
+97 -14
View File
@@ -23,8 +23,7 @@ PORT_IMG_PATH="$(dirname "$PORT_SCRIPTS_PATH")/img"
PORT_CONF_PATH="$(dirname "$PORT_SCRIPTS_PATH")/conf"
if [[ -z "$PORT_DATA_PATH" ]] ; then
if [[ -n "${FLATPAK_ID:-}" ]] \
&& [[ -n "${XDG_DATA_HOME:-}" ]] ; then
if [[ -n "${XDG_DATA_HOME:-}" ]] ; then
PORT_DATA_PATH="$(dirname "${XDG_DATA_HOME}")"
elif [[ -f "$HOME/.config/PortProtonQt.conf" ]] \
&& grep "portdata_path" "$HOME/.config/PortProtonQt.conf" ; then
@@ -37,8 +36,11 @@ if [[ -z "$PORT_DATA_PATH" ]] ; then
fi
fi
if [[ -f "$HOME/.config/PortProtonQt.conf" ]] \
&& grep "disable_runtime_download = True" "$HOME/.config/PortProtonQt.conf" ; then
if [[ -n "${XDG_CONFIG_HOME:-}" ]] \
&& grep -q "disable_runtime_download = True" "$XDG_CONFIG_HOME/PortProtonQt.conf" ; then
export PW_DISABLE_RUNTIME_DOWNLOAD=1
elif [[ -f "$HOME/.config/PortProtonQt.conf" ]] \
&& grep -q "disable_runtime_download = True" "$HOME/.config/PortProtonQt.conf" ; then
export PW_DISABLE_RUNTIME_DOWNLOAD=1
fi
@@ -92,7 +94,7 @@ if [[ "${1,,}" =~ \.ppack$ ]] ; then
export PW_NO_RESTART_PPDB="1"
export PW_DISABLED_CREATE_DB="1"
PW_EXE_FILE="$1"
elif [[ "${1,,}" =~ \.(exe|bat|msi|reg|lnk)$ ]] ; then
elif [[ "${1,,}" =~ \.(exe|bat|cmd|msi|reg|lnk)$ ]] ; then
if [[ -f "$1" ]] ; then
PW_EXE_FILE="$(realpath -s "$1")"
elif [[ -f "$OLDPWD/$1" ]] ; then
@@ -105,7 +107,7 @@ elif [[ "${1,,}" =~ \.(exe|bat|msi|reg|lnk)$ ]] ; then
get_lnk "${PW_EXE_FILE}"
PW_EXE_FILE="$(realpath "${link_path}" 2>/dev/null)"
fi
elif [[ "$1" =~ ^--(debug|launch|edit-db)$ && "${2,,}" =~ \.(exe|bat|msi|reg)$ ]] ; then
elif [[ "$1" =~ ^--(debug|launch|edit-db)$ && "${2,,}" =~ \.(exe|bat|cmd|msi|reg)$ ]] ; then
if [[ -f "$2" ]] ; then
PW_EXE_FILE="$(realpath -s "$2")"
elif [[ -f "$OLDPWD/$2" ]] ; then
@@ -128,7 +130,7 @@ create_new_dir "${HOME}/.local/share/applications"
create_new_dir "${PORT_DATA_PATH}/data/dist"
IFS=$'\n'
for dist_dir in $(lsbash "${PORT_DATA_PATH}/data/dist/") ; do
dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e s/[[:blank:]]/_/g)
dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e 's/[[:blank:]]*-[[:blank:]]*/-/g' -e 's/[[:blank:]]/_/g')
if [[ ! -d "${PORT_DATA_PATH}/data/dist/${dist_dir_new^^}" ]] ; then
mv -- "${PORT_DATA_PATH}/data/dist/$dist_dir" "${PORT_DATA_PATH}/data/dist/${dist_dir_new^^}"
fi
@@ -159,6 +161,8 @@ cd "${PORT_SCRIPTS_PATH}" || fatal
# shellcheck source=/dev/null
source "${PORT_SCRIPTS_PATH}/var"
# HACK: Avoid inheriting a system scripts cwd in pressure-vessel.
cd "${XDG_DATA_HOME:-$HOME}" || fatal
[[ ! -f "$VKBASALT_CONFIG_FILE" ]] && cp -f "${PORT_CONF_PATH}/vkBasalt.conf" "$VKBASALT_CONFIG_FILE"
[[ ! -f "$DXVK_CONFIG_FILE" ]] && cp -f "${PORT_CONF_PATH}/dxvk.conf" "$DXVK_CONFIG_FILE"
@@ -205,8 +209,8 @@ fi
print_info "The first mirror in used: $MIRROR"
if check_gamescope_session
then PW_TERM="env LANG=C python3 -m portprotonqt.easyterm --fullscreen -e"
else PW_TERM="env LANG=C python3 -m portprotonqt.easyterm -e"
then PW_TERM="env LANG=C python3 -m portprotonqt.scripts_utils.easyterm --fullscreen -e"
else PW_TERM="env LANG=C python3 -m portprotonqt.scripts_utils.easyterm -e"
fi
pw_cleanup () {
@@ -269,6 +273,8 @@ case "$1" in
--winecmd Open wine command prompt, requires WINE version and prefix name
--winereg Open wine registry editor, requires WINE version and prefix name
--wine_uninstaller Open wine uninstaller, requires WINE version and prefix name
--winetricks-list-all List winetricks DLLs, fonts, and settings
--winetricks-install Install winetricks items, requires WINE version and prefix name
--clear_pfx Clear specified prefix, requires WINE version and prefix name
--mangohud-preview Starts MangoHud preview in vkcube (optional argument: inline MangoHud config)
--initial Initial setup command
@@ -285,6 +291,8 @@ Usage examples:
portproton cli --backup-prefix DEFAULT /path/to/backup/directory
portproton cli --restore-prefix /path/to/backup/file.ppack
portproton cli --winecfg WINE_LG DEFAULT
portproton cli --winetricks-list-all WINE_LG DEFAULT
portproton cli --winetricks-install WINE_LG DEFAULT --no-force corefonts
portproton cli --mangohud-preview \"fps,frametime,cpu_temp,gpu_temp\"
portproton cli --autoinstall [script_name_from_pw_autoinstall]
"
@@ -325,8 +333,15 @@ Usage examples:
export PW_USE_D3D_EXTRAS=1
export WINE_LARGE_ADDRESS_AWARE=0
trap "stop_portproton" SIGTERM SIGINT
# shellcheck source=/dev/null
. "${PORT_SCRIPTS_PATH}/pw_autoinstall/${2}"
if [[ "$2" =~ "/" ]] && [[ -f "$2" ]] ; then
# shellcheck source=/dev/null
. "${2}"
elif [[ -f "${PORT_SCRIPTS_PATH}/pw_autoinstall/${2}" ]] ; then
# shellcheck source=/dev/null
. "${PORT_SCRIPTS_PATH}/pw_autoinstall/${2}"
else
fatal "Not found autoinstal script: $2"
fi
stop_portproton
;;
--debug)
@@ -357,12 +372,12 @@ Usage examples:
exit 0
;;
--show-ppdb)
# --show-ppdb /полный/путь/до/файла.exe ИЛИ /полный/путь/до/файла.exe.ppdb
# --show-ppdb /полный/путь/до/файла.(exe|bat|cmd|msi|reg) ИЛИ /полный/путь/до/файла.ext.ppdb
input_path="$2"
case "$input_path" in
*.ppdb) exe_path="${input_path%.ppdb}" ;;
*.exe) exe_path="$input_path" ;;
*.[bB][aA][tT]|*.[cC][mM][dD]|*.[eE][xX][eE]|*.[mM][sS][iI]|*.[rR][eE][gG]) exe_path="$input_path" ;;
esac
ppdb_path="${exe_path}.ppdb"
@@ -396,6 +411,11 @@ Usage examples:
done < <(grep -E '^export ' "$USER_CONF" 2>/dev/null | sed -E 's/[[:space:]]*#.*$//' | sed '/^[[:space:]]*$/d')
fi
[[ -n "${PW_DEFAULT_WINE_USE:-}" && -z "${all_vars[PW_WINE_USE]+x}" ]] && all_vars["PW_WINE_USE"]="$PW_DEFAULT_WINE_USE"
[[ -n "${PW_DEFAULT_PREFIX_NAME:-}" && -z "${all_vars[PW_PREFIX_NAME]+x}" ]] && all_vars["PW_PREFIX_NAME"]="$PW_DEFAULT_PREFIX_NAME"
[[ -n "${PW_DEFAULT_VULKAN_USE:-}" && -z "${all_vars[PW_VULKAN_USE]+x}" ]] && all_vars["PW_VULKAN_USE"]="$PW_DEFAULT_VULKAN_USE"
all_vars["PW_PLUGINS_VER"]="$PW_PLUGINS_VER"
while IFS='=' read -r key val; do
key="${key#export }"
val="${val#\"}"
@@ -403,7 +423,12 @@ Usage examples:
if [[ -z "${all_vars[$key]+x}" ]]; then
all_vars["$key"]="$val"
fi
done < <(grep -E '^export ' "$PORT_SCRIPTS_PATH/var" | sed -E 's/[[:space:]]*#.*$//' | sed '/^[[:space:]]*$/d')
done < <(
{
grep -E '^export ' "$PORT_SCRIPTS_PATH/var"
grep -E '^check_variables ' "$PORT_SCRIPTS_PATH/var" | sed -E 's/^check_variables ([^[:space:]]+) (.*)$/export \1=\2/'
} | sed -E 's/[[:space:]]*#.*$//' | sed '/^[[:space:]]*$/d'
)
for key in "${!all_vars[@]}"; do
echo "${key}=\"${all_vars[$key]}\""
@@ -454,6 +479,64 @@ Usage examples:
pw_run uninstaller
stop_portproton
;;
--winetricks-list-all)
get_wine_and_pfx "$2" "$3"
update_winetricks >&2
sh -n "${PORT_WINE_TMP_PATH}/winetricks" >&2 || exit 1
awk '
function save_entry() {
if (category == "") {
return
}
count[category]++
entries[category, count[category]] = name " " title
category = ""
name = ""
title = ""
}
/^w_metadata[[:space:]]+/ {
save_entry()
if ($3 == "dlls" || $3 == "fonts" || $3 == "settings") {
name = $2
category = $3
}
next
}
category != "" && /^[[:space:]]*title="/ {
title = $0
sub(/^[[:space:]]*title="/, "", title)
sub(/[[:space:]]*\\$/, "", title)
sub(/"$/, "", title)
}
END {
save_entry()
split("dlls fonts settings", categories, " ")
for (i = 1; i <= 3; i++) {
category = categories[i]
print "__PORTPROTONQT_WINETRICKS_SECTION__:" category
for (j = 1; j <= count[category]; j++) {
print entries[category, j]
}
}
}
' "${PORT_WINE_TMP_PATH}/winetricks"
winetricks_status="$?"
exit "$winetricks_status"
;;
--winetricks-install)
get_wine_and_pfx "$2" "$3"
winetricks_force="$4"
shift 4
start_portproton
update_winetricks
winetricks_args=("--unattended")
[[ "$winetricks_force" == "--force" ]] && winetricks_args+=("--force")
"${PORT_WINE_TMP_PATH}/winetricks" "${winetricks_args[@]}" "$@"
winetricks_status=$?
wait_wineserver
stop_portproton
exit "$winetricks_status"
;;
--clear_pfx)
get_wine_and_pfx "$2" "$3"
pw_clear_pfx
+5 -2
View File
@@ -3,7 +3,7 @@
###BASE VARIABLES###
export PW_PROTON_LG_VER="PROTON_LG_10-30"
export PW_WINE_LG_VER="WINE_LG_11-1"
export PW_WINE_LG_VER="WINE_LG_11-10"
export PW_LIBS_VER="_v3.0.20260218"
export PW_PLUGINS_VER="_v20"
export DXVK_NEW_VER="2.7.1-509"
@@ -14,6 +14,7 @@ export VKD3D_OLD_VER="2.14.1"
export VKD3D_SAREK_VER="sarek-2.6.0"
export PW_LSFG_VK_VER="2.0.0-dev25-p11"
export PW_OPTISCALER_VER="v03-0.9.0-pre8"
export PW_SPECIALK_VER="SK_26_5_15"
export PW_GALLIUM_NINE_VER="0.10"
export DOTPFX_VER="48v9"
export DEFPFX_VER="v1"
@@ -29,6 +30,7 @@ export PW_RT_MOUNT_RW=("/media" "/mnt" "/run/media/${USER}" "${PORT_DATA_PATH}")
check_variables PW_WINE_USE "PROTON_LG"
check_variables PROTON_USE_XALIA "0"
check_variables PW_USE_RUNTIME "1"
check_variables PW_USE_SPECIALK "0"
check_variables PW_USE_ESYNC "0"
check_variables PW_USE_FSYNC "0"
check_variables PW_USE_NTSYNC "0"
@@ -70,6 +72,7 @@ check_variables VKD3D_LIMIT_TESS_FACTORS "64"
check_variables PW_VKBASALT "0"
check_variables PW_VKBASALT_EFFECTS "Curves:cas"
check_variables PW_VKBASALT_FFX_CAS "0.50"
check_variables PW_VKBASALT_TOOGLE_KEY "Home"
export VKBASALT_CONFIG_FILE="${PORT_DATA_PATH}/data/vkBasalt.conf"
###GAMESCOPE###
@@ -80,7 +83,7 @@ export PW_GAMESCOPE_ARGS_NEW=" -f --sharpness 10 --hdr-sdr-content-nits 0"
###MANGOHUD###
check_variables PW_MANGOHUD "0"
export DEFAULT_MANGOHUD_CONFIG="arch,cpu_mhz,cpu_temp,engine_version,gamemode,gpu_core_clock,gpu_mem_clock,gpu_name,gpu_temp,ram,resolution,vkbasalt,vram,vulkan_driver,wine,winesync"
export DEFAULT_MANGOHUD_CONFIG="arch,cpu_mhz,cpu_temp,engine_version,gamemode,gpu_core_clock,gpu_mem_clock,gpu_name,gpu_temp,ram,resolution,vkbasalt,vram,vulkan_driver,wine,winesync,display_server"
###DGVOODOO2###
check_variables PW_DGVOODOO2 "0"
@@ -1,14 +0,0 @@
"compatibilitytools"
{
"compat_tools"
{
"PortProtonQt"
{
"install_path" "."
"display_name" "PortProtonQt"
"from_oslist" "windows"
"to_oslist" "linux"
"Priority" "75"
}
}
}
@@ -1,12 +0,0 @@
# Install PortProtonQt Steam compatibility tool
install_data(
'compatibilitytool.vdf',
'toolmanifest.vdf',
install_dir: prefix / get_option('datadir') / 'steam' / 'compatibilitytools.d' / 'PortProtonQt',
)
install_data(
'portproton',
install_dir: prefix / get_option('datadir') / 'steam' / 'compatibilitytools.d' / 'PortProtonQt',
install_mode: 'rwxr-xr-x',
)
@@ -1,76 +0,0 @@
#!/usr/bin/env bash
# Remove Steam Runtime libraries
unset LD_LIBRARY_PATH
export STEAM_COMPAT=1
exe_name="$(basename "$1")"
exe_dir="$(dirname "$1")"
# Ignore specific executables
if [[ "$exe_name" == "iscriptevaluator.exe" ]] || \
[[ "$exe_name" == "d3ddriverquery64.exe" ]]; then
exit 0
fi
# Copy PPDB file from steam_scripts to exe directory if it exists
# Steam passes the appid via SteamAppId environment variable
if [[ -n "$SteamAppId" ]]; then
# Get PortProton directory from config file or Flatpak defaults
portproton_dir=""
new_config_file="$HOME/.config/PortProtonQt.conf"
legacy_config_file="$HOME/.config/PortProton.conf"
new_flatpak_id="ru.linux_gaming.PortProtonQt"
legacy_flatpak_id="ru.linux_gaming.PortProton"
new_flatpak_config_file="$HOME/.var/app/$new_flatpak_id/config/PortProtonQt.conf"
new_flatpak_dir="$HOME/.var/app/$new_flatpak_id/data"
legacy_flatpak_dir="$HOME/.var/app/$legacy_flatpak_id/data"
if [[ -f "$new_config_file" ]]; then
portproton_dir="$(awk -F'= ' '/^portdata_path/ {print $2; exit}' "$new_config_file" | tr -d '\n')"
fi
if [[ -z "$portproton_dir" ]] || [[ ! -d "$portproton_dir" ]]; then
if [[ -f "$legacy_config_file" ]]; then
portproton_dir="$(cat "$legacy_config_file" | tr -d '\n')"
fi
fi
if [[ -z "$portproton_dir" ]] || [[ ! -d "$portproton_dir" ]]; then
if [[ -f "$new_flatpak_config_file" ]]; then
portproton_dir="$(awk -F'= ' '/^portdata_path/ {print $2; exit}' "$new_flatpak_config_file" | tr -d '\n')"
fi
fi
if [[ -z "$portproton_dir" ]] || [[ ! -d "$portproton_dir" ]]; then
if [[ -d "$new_flatpak_dir" ]]; then
portproton_dir="$new_flatpak_dir"
elif [[ -d "$legacy_flatpak_dir" ]]; then
portproton_dir="$legacy_flatpak_dir"
fi
fi
ppdb_source="$portproton_dir/steam_scripts/${SteamAppId}.exe.ppdb"
ppdb_dest="$exe_dir/${exe_name}.ppdb"
if [[ -f "$ppdb_source" ]]; then
cp "$ppdb_source" "$ppdb_dest"
echo "Copied PPDB from $ppdb_source to $ppdb_dest"
fi
fi
# Activate virtual environment if available
if [[ -n "$PPQT_VENV_PATH" ]]; then
cd "$PPQT_VENV_PATH" || exit 1
source .venv/bin/activate || exit 1
fi
# Use AppImage if specified, then Flatpak if installed, otherwise use portprotonqt from PATH
if [[ -n "$PPQT_BIN_PATH" ]]; then
"$PPQT_BIN_PATH" --silent --debug-level INFO "$@"
elif command -v flatpak >/dev/null 2>&1 && flatpak info ru.linux_gaming.PortProtonQt >/dev/null 2>&1; then
flatpak run ru.linux_gaming.PortProtonQt --silent --debug-level INFO "$@"
else
portprotonqt --silent --debug-level INFO "$@"
fi
@@ -1,4 +0,0 @@
"manifest"
{
"commandline" "/portproton"
}
Binary file not shown.
+14886 -1046
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
portprotonqt (1.0) unstable; urgency=medium
* Add Debian packaging.
-- Ivan Mazhukin <vanyamajukin@outlook.com> Sat, 23 May 2026 13:32:57 +0300
+1
View File
@@ -0,0 +1 @@
completions/
+70
View File
@@ -0,0 +1,70 @@
Source: portprotonqt
Section: utils
Priority: optional
Maintainer: Ivan Mazhukin <vanyamajukin@outlook.com>
Build-Depends:
debhelper-compat (= 13),
gettext,
libvulkan-dev,
meson,
ninja-build,
pkgconf,
python3,
Standards-Version: 4.7.0
Homepage: https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt
Rules-Requires-Root: no
Package: portprotonqt
Architecture: linux-any
Depends:
7zip,
cabextract,
curl,
file,
gawk,
jq,
libimage-exiftool-perl,
libsdl3-0,
mesa-utils,
pciutils,
procps,
psmisc,
python3,
python3-babel,
python3-dbus-fast,
python3-evdev,
python3-libarchive-c,
python3-orjson,
python3-pefile,
python3-pil,
python3-psutil,
python3-pygame,
python3-pyside6.qtcore,
python3-pyside6.qtgui,
python3-pyside6.qtnetwork,
python3-pyside6.qtsvg,
python3-pyside6.qtwidgets,
python3-qrcode,
python3-rapidfuzz,
python3-requests,
python3-tqdm,
python3-vdf,
python3-websocket,
qt6-image-formats-plugins,
qt6-svg-plugins,
unrar-free,
unzip,
xz-utils,
zstd,
${misc:Depends},
${shlibs:Depends},
Recommends:
bluez,
network-manager,
pulseaudio-utils,
squashfs-tools,
udisks2,
upower,
Description: GUI for managing PortProton and Steam games
PortProtonQt provides a graphical interface for managing and launching
games from PortProton and Steam.
+20
View File
@@ -0,0 +1,20 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: PortProtonQt
Source: https://git.linux-gaming.ru/Linux-Gaming/PortProtonQt
Files: *
Copyright:
2026 PortProtonQt contributors
License: GPL-3.0
Files: debian/*
Copyright:
2026 PortProtonQt contributors
License: GPL-3.0
License: GPL-3.0
This package is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 3.
.
On Debian systems, the complete text of the GNU General Public License
version 3 can be found in /usr/share/common-licenses/GPL-3.
+14
View File
@@ -0,0 +1,14 @@
usr/bin/portprotonqt
usr/bin/vk_gpu_info
usr/lib/python3/dist-packages/portprotonqt/
usr/lib/udev/rules.d/60-portprotonqt.rules
usr/share/applications/ru.linux_gaming.PortProtonQt.desktop
usr/share/bash-completion/completions/portprotonqt
usr/share/fish/vendor_completions.d/portprotonqt.fish
usr/share/icons/hicolor/scalable/apps/ru.linux_gaming.PortProtonQt.svg
usr/share/locale/
usr/share/metainfo/ru.linux_gaming.PortProtonQt.metainfo.xml
usr/share/mime/packages/ru.linux_gaming.PortProtonQt.xml
usr/share/polkit-1/rules.d/ru.linux_gaming.PortProtonQt.rules
usr/share/portproton/
usr/share/zsh/site-functions/_portprotonqt
Vendored Executable
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/make -f
%:
dh $@ --buildsystem=meson
override_dh_auto_configure:
dh_auto_configure -- \
-Dpython_purelibdir=/usr/lib/python3/dist-packages \
-Dudev_rulesdir=/usr/lib/udev/rules.d
override_dh_auto_install:
dh_auto_install --destdir=debian/tmp
execute_after_dh_auto_install:
bash ./dev-scripts/generate-completions.sh
install -Dpm 0644 completions/portprotonqt \
debian/tmp/usr/share/bash-completion/completions/portprotonqt
install -Dpm 0644 completions/_portprotonqt \
debian/tmp/usr/share/zsh/site-functions/_portprotonqt
install -Dpm 0644 completions/portprotonqt.fish \
debian/tmp/usr/share/fish/vendor_completions.d/portprotonqt.fish
+1
View File
@@ -0,0 +1 @@
3.0 (native)
+2
View File
@@ -77,3 +77,5 @@ State
HLTB
Delete Folder
PPQT
SpecialK
Reshade
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
remote="${1:-origin}"
main_branch="${2:-main}"
weblate_branch="${3:-weblate}"
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Working tree is not clean."
exit 1
fi
git fetch "$remote" "$main_branch" "$weblate_branch"
git switch "$main_branch"
git merge --ff-only "$remote/$main_branch"
if git merge-base --is-ancestor "$remote/$weblate_branch" HEAD; then
echo "No new Weblate changes to merge."
elif git merge-base --is-ancestor HEAD "$remote/$weblate_branch"; then
git merge --ff-only "$remote/$weblate_branch"
else
git switch -C "$weblate_branch" "$remote/$weblate_branch"
git rebase "$main_branch"
git switch "$main_branch"
git merge --ff-only "$weblate_branch"
fi
python dev-scripts/l10n.py
git push "$remote" "$main_branch"
git push "$remote" "$main_branch:$weblate_branch"
echo "Weblate translations accepted and $weblate_branch synced to $main_branch."
+45 -1
View File
@@ -18,6 +18,7 @@ MESON_BUILD = BASE_DIR / "meson.build"
APP_PY = BASE_DIR / "portprotonqt" / "app.py"
GITEA_WORKFLOW = BASE_DIR / ".gitea" / "workflows" / "build.yml"
CHANGELOG = BASE_DIR / "CHANGELOG.md"
METAINFO = BASE_DIR / "build-aux" / "share" / "metainfo" / "ru.linux_gaming.PortProtonQt.metainfo.xml"
def bump_appimage(path: Path, old: str, new: str) -> bool:
"""
@@ -125,6 +126,48 @@ def bump_changelog(path: Path, old: str, new: str) -> bool:
path.write_text(new_text, encoding='utf-8')
return bool(count)
def bump_metainfo(path: Path, old: str, new: str) -> bool:
"""
Update releases in metainfo:
1. Change old version's <description></description> to <description/>
2. Prepend new version with <description></description>
"""
if not path.exists():
return False
text = path.read_text(encoding='utf-8')
# 1. Update the old version entry to use self-closing description
# Match tag starting with <release version="OLD" and ending with >
old_pattern = re.compile(
r'(<release version="' + re.escape(old) + r'"[^>]*>)\s*<description></description>\s*(</release>)',
re.DOTALL
)
current_date = date.today().strftime('%Y-%m-%d')
type_attr = ' type="development"' if new.startswith('0.') else ''
new_entry = (
f' <release version="{new}" date="{current_date}"{type_attr}>\n'
f' <description></description>\n'
f' </release>'
)
# Replace old entry's description with self-closing
new_text, count = old_pattern.subn(r'\1\n <description/>\n \2', text, count=1)
if count:
# 2. Insert the new entry at the beginning of the <releases> tag
new_text = new_text.replace('<releases>', f'<releases>\n{new_entry}')
path.write_text(new_text, encoding='utf-8')
return True
# Fallback if old version wasn't found with expected pattern
if f'version="{new}"' not in text:
new_text = text.replace('<releases>', f'<releases>\n{new_entry}')
path.write_text(new_text, encoding='utf-8')
return True
return False
def main():
parser = argparse.ArgumentParser(description='Bump project version in specific files')
parser.add_argument('old', help='Old version string')
@@ -141,7 +184,8 @@ def main():
(MESON_BUILD, bump_meson),
(APP_PY, bump_app_py),
(GITEA_WORKFLOW, bump_workflow),
(CHANGELOG, bump_changelog)
(CHANGELOG, bump_changelog),
(METAINFO, bump_metainfo)
]
updated = []
+33 -4
View File
@@ -654,13 +654,14 @@ class MesonLinter:
def get_python_files_from_directory(directory):
"""Get all Python files from a directory (excluding __pycache__ and other non-source files)"""
python_files = []
for file_path in Path(directory).iterdir():
base_dir = Path(directory)
for file_path in base_dir.rglob('*.py'):
if (file_path.is_file() and
file_path.suffix == '.py' and
file_path.name != '__pycache__' and
'__pycache__' not in file_path.parts and
not file_path.name.startswith('.') and # Skip hidden files
file_path.name != 'meson.build'): # Exclude meson.build itself
python_files.append(file_path.name)
python_files.append(file_path.relative_to(base_dir).as_posix())
return sorted(python_files)
@@ -747,8 +748,28 @@ def check_files(repo_root: Path) -> list[str]:
dir_files = get_python_files_from_directory(portprotonqt_dir)
meson_files = get_files_from_meson_build(portprotonqt_meson)
meson_subdirs = get_subdirs_from_meson_build(portprotonqt_meson)
return [f for f in dir_files if f not in meson_files]
return [
f for f in dir_files
if f not in meson_files and
not any(f == subdir or f.startswith(f"{subdir}/") for subdir in meson_subdirs)
]
def check_stale_files(repo_root: Path) -> list[str]:
"""Check if meson.build lists Python files that no longer exist."""
portprotonqt_dir = repo_root / 'portprotonqt'
portprotonqt_meson = portprotonqt_dir / 'meson.build'
if not portprotonqt_meson.exists():
return []
meson_files = get_files_from_meson_build(portprotonqt_meson)
return [
f for f in meson_files
if f.endswith('.py') and not (portprotonqt_dir / f).exists()
]
def check_portproton_subdirs(repo_root: Path) -> list[str]:
@@ -796,6 +817,7 @@ def main():
# Check files inclusion (only if syntax is OK)
if exit_code == 0:
missing_files = check_files(repo_root)
stale_files = check_stale_files(repo_root)
missing_subdirs = check_portproton_subdirs(repo_root)
if missing_files:
@@ -805,6 +827,13 @@ def main():
print("\nPlease add these files to the install_data section in portprotonqt/meson.build")
exit_code = 1
if stale_files:
print("ERROR: The following files are listed in meson.build but do not exist:")
for file in stale_files:
print(f" - {file}")
print("\nPlease remove or update these files in portprotonqt/meson.build")
exit_code = 1
if missing_subdirs:
print("ERROR: The following PortProton directories are missing from meson.build:")
for directory in missing_subdirs:
+3 -6
View File
@@ -1,5 +1,5 @@
project('portprotonqt', 'c',
version: '1.0',
version: '1.2.0',
meson_version: '>= 0.61.2',
license: 'GPL-3.0',
)
@@ -33,7 +33,7 @@ bindir = prefix / get_option('bindir')
# Use custom purelibdir if specified, otherwise use default
purelibdir_opt = get_option('python_purelibdir')
pythondir = purelibdir_opt != '' ? purelibdir_opt : python3.get_install_dir(pure: true)
pythondir = purelibdir_opt != '' ? purelibdir_opt: python3.get_install_dir(pure: true)
pkgdatadir = pythondir / meson.project_name()
# C compiler for vk_gpu_info
@@ -131,12 +131,9 @@ install_subdir(
install_mode: 'rwxr-xr-x',
)
# Install Steam compatibility tool
subdir('build-aux/share/steam/compatibilitytools.d/PortProtonQt')
# Install udev rules
udev_rulesdir_opt = get_option('udev_rulesdir')
udevdir = udev_rulesdir_opt != '' ? udev_rulesdir_opt : prefix / 'lib' / 'udev' / 'rules.d'
udevdir = udev_rulesdir_opt != '' ? udev_rulesdir_opt: prefix / 'lib' / 'udev' / 'rules.d'
install_data(
'build-aux/lib/udev/rules.d/60-portprotonqt.rules',
+3
View File
@@ -1,9 +1,12 @@
from portprotonqt.animations.detail_page import DetailPageAnimations
from portprotonqt.animations.game_card import GameCardAnimations
from portprotonqt.animations.library_controls import ExpandingSearchAnimation, LibraryControlsAnimation
from portprotonqt.animations.virtual_keyboard import VirtualKeyboardAnimations
__all__ = [
"DetailPageAnimations",
"ExpandingSearchAnimation",
"GameCardAnimations",
"LibraryControlsAnimation",
"VirtualKeyboardAnimations",
]
+117
View File
@@ -0,0 +1,117 @@
from PySide6.QtCore import (
QAbstractAnimation,
QByteArray,
QEasingCurve,
QParallelAnimationGroup,
QPropertyAnimation,
)
from PySide6.QtWidgets import QGraphicsOpacityEffect, QWidget
class ExpandingSearchAnimation:
def __init__(self, widget: QWidget, theme: object, fallback_duration: int):
self.widget = widget
self.theme = theme
self.fallback_duration = fallback_duration
self.animation = QPropertyAnimation(widget, QByteArray(b"maximumWidth"))
def setup(self, collapsed_width: int, expanded_width: int) -> None:
self.collapsed_width = collapsed_width
self.expanded_width = expanded_width
self.widget.setMaximumWidth(collapsed_width)
def expand(self) -> None:
self._start(self.expanded_width)
def collapse(self) -> None:
if getattr(self.widget, "text", lambda: "")():
return
self._start(self.collapsed_width)
def _start(self, target_width: int) -> None:
if self.animation.state() == QAbstractAnimation.State.Running:
self.animation.stop()
self.animation = QPropertyAnimation(self.widget, QByteArray(b"maximumWidth"))
self.animation.setDuration(self._duration())
self.animation.setStartValue(self.widget.maximumWidth())
self.animation.setEndValue(target_width)
self.animation.setEasingCurve(self._easing(target_width == self.expanded_width))
self.animation.start()
def _duration(self) -> int:
animation_config = getattr(self.theme, "GAME_CARD_ANIMATION", {})
return animation_config.get("scale_anim_duration", self.fallback_duration)
def _easing(self, opening: bool) -> QEasingCurve:
animation_config = getattr(self.theme, "GAME_CARD_ANIMATION", {})
key = "scale_easing_curve" if opening else "scale_easing_curve_out"
easing_name = animation_config.get(key, QEasingCurve.Type.InOutQuad.name)
easing_type = getattr(QEasingCurve.Type, easing_name, QEasingCurve.Type.InOutQuad)
return QEasingCurve(easing_type)
class LibraryControlsAnimation:
def __init__(self, widget: QWidget, theme: object, fallback_duration: int):
self.widget = widget
self.theme = theme
self.fallback_duration = fallback_duration
self.opacity_effect = QGraphicsOpacityEffect(widget)
self.opacity_effect.setOpacity(0)
self.widget.setGraphicsEffect(self.opacity_effect)
self.group = QParallelAnimationGroup(widget)
def setup_hidden(self) -> None:
self.widget.setVisible(False)
self.widget.setMaximumHeight(0)
def toggle(self, opening: bool) -> None:
if self.group.state() == QAbstractAnimation.State.Running:
self.group.stop()
if opening:
self.widget.setVisible(True)
target_height = self.widget.sizeHint().height() if opening else 0
self.group = QParallelAnimationGroup(self.widget)
height_animation = self._create_widget_animation(
b"maximumHeight",
self.widget.maximumHeight(),
target_height,
)
opacity_animation = self._create_opacity_animation(opening, height_animation.duration())
self.group.addAnimation(height_animation)
self.group.addAnimation(opacity_animation)
if not opening:
self.group.finished.connect(self.widget.hide)
self.group.start()
def _create_widget_animation(
self,
property_name: bytes,
start_value: object,
end_value: object,
) -> QPropertyAnimation:
animation = QPropertyAnimation(self.widget, QByteArray(property_name))
animation.setDuration(self._duration())
animation.setStartValue(start_value)
animation.setEndValue(end_value)
animation.setEasingCurve(self._easing(end_value != 0))
return animation
def _create_opacity_animation(self, opening: bool, duration: int) -> QPropertyAnimation:
animation = QPropertyAnimation(self.opacity_effect, QByteArray(b"opacity"))
animation.setDuration(duration)
animation.setStartValue(self.opacity_effect.opacity())
animation.setEndValue(1 if opening else 0)
animation.setEasingCurve(self._easing(opening))
return animation
def _duration(self) -> int:
animation_config = getattr(self.theme, "GAME_CARD_ANIMATION", {})
return animation_config.get("scale_anim_duration", self.fallback_duration)
def _easing(self, opening: bool) -> QEasingCurve:
animation_config = getattr(self.theme, "GAME_CARD_ANIMATION", {})
key = "scale_easing_curve" if opening else "scale_easing_curve_out"
easing_name = animation_config.get(key, QEasingCurve.Type.InOutQuad.name)
easing_type = getattr(QEasingCurve.Type, easing_name, QEasingCurve.Type.InOutQuad)
return QEasingCurve(easing_type)
+93 -19
View File
@@ -3,6 +3,10 @@ import sys
import os
import importlib
import subprocess
import threading
import urllib.error
import urllib.request
from urllib.parse import quote, unquote
from logging import Logger
__app_id__ = "ru.linux_gaming.PortProtonQt"
@@ -14,7 +18,7 @@ try:
APP_VERSION = version_module.APP_VERSION
except ImportError:
APP_COMMIT = ""
APP_VERSION = "1.0"
APP_VERSION = "1.2.0"
__app_version__ = APP_VERSION
@@ -23,11 +27,13 @@ from PySide6.QtWidgets import QApplication, QMenu, QSystemTrayIcon
from PySide6.QtGui import QAction, QIcon
from portprotonqt.config import (
consume_download_counter_skip,
display_config,
get_portproton_start_command,
get_portproton_location,
save_portdata_path_to_config,
ui_config,
update_app_version,
window_config,
)
from portprotonqt.logger import get_logger, setup_logger
@@ -37,7 +43,6 @@ from portprotonqt.cli import (
parse_portproton_url,
is_launch_file,
is_prefix_backup_file,
is_exe_file,
normalize_launch_path,
add_steam_compat_tool,
reinstall_steam_compat_tool,
@@ -48,6 +53,8 @@ from portprotonqt.cli import (
)
from portprotonqt.localization import _, get_steam_language
COUNTER_DOWNLOAD_URL = "http://cloud.linux-gaming.ru:8081/api/download/{version}"
def get_version():
if APP_COMMIT:
return f"{__app_version__} ({APP_COMMIT})"
@@ -142,6 +149,22 @@ def restore_prefix_backup(start_sh: list[str], backup_path: str) -> int:
return 1
def notify_download_counter(app_version: str, logger: Logger) -> None:
url = COUNTER_DOWNLOAD_URL.format(version=quote(app_version, safe=""))
def send_request() -> None:
try:
request = urllib.request.Request(url, method="GET")
with urllib.request.urlopen(request, timeout=10):
pass
except urllib.error.URLError as e:
logger.debug("Failed to notify download counter: %s", e)
except OSError as e:
logger.debug("Failed to notify download counter: %s", e)
threading.Thread(target=send_request, daemon=True).start()
def create_prefix_backup(start_sh: list[str], prefix_name: str, backup_dir: str) -> int:
"""Create a PortProton prefix backup."""
logger = get_logger(__name__)
@@ -203,19 +226,9 @@ def main():
if start_sh is None:
return
if parsed_args.create_backup:
setup_logger(parsed_args.debug_level)
prefix_name, backup_dir = parsed_args.create_backup
backup_exit_code = create_prefix_backup(start_sh, prefix_name, backup_dir)
sys.exit(backup_exit_code)
if parsed_args.restore_prefix and not parsed_args.file_or_url:
setup_logger(parsed_args.debug_level)
sys.exit(1)
if is_restore_prefix_request(parsed_args):
setup_logger(parsed_args.debug_level)
restore_exit_code = restore_prefix_backup(start_sh, parsed_args.file_or_url)
sys.exit(restore_exit_code)
# Handle Steam compatibility mode - launch game directly without GUI.
if is_steam_compat:
@@ -227,10 +240,11 @@ def main():
logger = get_logger(__name__)
setup_logger(parsed_args.debug_level)
logger.info("Running in Steam compatibility mode, launching: %s", exe_path)
logger.info("Steam compatibility launch arguments: %s", parsed_args.launch_args)
# Launch game via PortProton without GUI
env_vars = os.environ.copy()
cmd = start_sh + [exe_path]
cmd = start_sh + [exe_path] + parsed_args.launch_args
try:
subprocess.run(cmd, env=env_vars)
except Exception as e:
@@ -254,9 +268,15 @@ def main():
args = parsed_args
setup_logger(args.debug_level)
logger = get_logger(__name__)
if consume_download_counter_skip():
update_app_version(__app_version__)
elif update_app_version(__app_version__):
notify_download_counter(__app_version__, logger)
fullscreen = args.fullscreen or display_config.get_fullscreen()
ipc_message = "show:fullscreen" if fullscreen else "show"
backup_request = None
restore_prefix_path = None
resolution_from_args = None
if args.resolution:
resolution_from_args = parse_resolution(args.resolution)
@@ -266,16 +286,23 @@ def main():
window_config.set_geometry(resolution_from_args[0], resolution_from_args[1])
logger.info("Saved window resolution: %sx%s", resolution_from_args[0], resolution_from_args[1])
ipc_message = "noop"
if is_silent_launch and args.file_or_url and is_exe_file(args.file_or_url):
if args.create_backup:
prefix_name, backup_dir = args.create_backup
backup_request = (prefix_name, os.path.abspath(os.path.expanduser(backup_dir)))
ipc_message = "backup:{}:{}".format(quote(prefix_name, safe=""), quote(backup_request[1], safe=""))
elif is_silent_launch and args.file_or_url and is_launch_file(args.file_or_url):
run_silent_tray(app, start_sh, normalize_launch_path(args.file_or_url))
sys.exit(app.exec())
elif is_restore_prefix_request(args):
restore_prefix_path = normalize_launch_path(args.file_or_url)
ipc_message = f"restore:{quote(restore_prefix_path, safe='')}"
elif args.file_or_url and is_launch_file(args.file_or_url):
ipc_message = f"open:{normalize_launch_path(args.file_or_url)}"
from PySide6.QtCore import QThread, Signal
from PySide6.QtNetwork import QLocalServer, QLocalSocket
from portprotonqt.main_window import MainWindow
from portprotonqt.port_data_path_selector import ask_portdata_path
from portprotonqt.port_data_path_selector import ask_portdata_path, is_portdata_path_read_write
from portprotonqt.portproton_api import (
PortProtonAPI,
get_user_conf_setting,
@@ -309,8 +336,14 @@ def main():
logger.warning(f"Failed to start local server: {local_server.errorString()}")
return
portdata_warning = None
if portproton_location and not is_portdata_path_read_write(portproton_location):
logger.warning("PORT_DATA_PATH is not readable/writable: %s", portproton_location)
portdata_warning = _("PortProton data folder is not readable and writable. Choose another folder for PortProton data.")
portproton_location = None
if not portproton_location:
portproton_location = ask_portdata_path()
portproton_location = ask_portdata_path(portdata_warning, bool(portdata_warning))
if not portproton_location:
logger.error("PORT_DATA_PATH is not configured, startup aborted")
return
@@ -319,7 +352,7 @@ def main():
logger.warning("Failed to persist PORT_DATA_PATH in PortProtonQt config")
# Check if we have a portproton:// URL or launch file to handle
if args.file_or_url:
if args.file_or_url and not restore_prefix_path:
if is_portproton_url(args.file_or_url):
# Parse the portproton:// URL to get the full download URL
download_url = parse_portproton_url(args.file_or_url)
@@ -366,6 +399,14 @@ def main():
def handle_launch_exe():
window.handle_launch_exe(exe_path)
QTimer.singleShot(0, handle_launch_exe)
elif backup_request:
def handle_create_backup():
window._perform_backup(backup_request[1], backup_request[0])
QTimer.singleShot(0, handle_create_backup)
elif restore_prefix_path:
def handle_restore_prefix():
window._perform_restore(restore_prefix_path)
QTimer.singleShot(0, handle_restore_prefix)
# --- Handle incoming connections ---
def handle_new_connection():
@@ -380,7 +421,12 @@ def main():
def restore_window():
try:
if msg.startswith("show") or msg.startswith("open:"):
if (
msg.startswith("show")
or msg.startswith("open:")
or msg.startswith("restore:")
or msg.startswith("backup:")
):
# Ensure the window is visible and not minimized
window.setWindowState(window.windowState() & ~Qt.WindowState.WindowMinimized)
window.show()
@@ -407,6 +453,22 @@ def main():
window.handle_launch_exe(launch_path)
else:
logger.warning("Invalid launch file via IPC: %s", launch_path)
elif msg.startswith("restore:"):
backup_path = unquote(msg[8:].strip())
if backup_path and is_prefix_backup_file(backup_path):
logger.info("Restoring prefix backup via IPC: %s", backup_path)
window._perform_restore(backup_path)
else:
logger.warning("Invalid prefix backup via IPC: %s", backup_path)
elif msg.startswith("backup:"):
parts = msg.split(":", 2)
if len(parts) == 3:
prefix_name = unquote(parts[1])
backup_dir = unquote(parts[2])
logger.info("Creating prefix backup via IPC: %s", prefix_name)
window._perform_backup(backup_dir, prefix_name)
else:
logger.warning("Invalid prefix backup request via IPC: %s", msg)
except Exception as e:
logger.warning(f"Failed to restore window: {e}")
@@ -419,12 +481,20 @@ def main():
# --- Initial fullscreen state ---
launch_fullscreen = args.fullscreen or display_config.get_fullscreen()
launch_auto_fullscreen = (
display_config.get_auto_fullscreen_gamepad()
and not launch_fullscreen
and getattr(window.input_manager, "gamepad", None) is not None
)
launch_minimized = (
display_config.get_start_minimized()
and not args.fullscreen
and not launch_auto_fullscreen
and window_resolution is None
and exe_path is None
)
and backup_request is None
and restore_prefix_path is None
)
if launch_minimized:
logger.info("Launching in tray")
window.hide()
@@ -434,6 +504,10 @@ def main():
)
display_config.set_fullscreen(True)
window.showFullScreen()
elif launch_auto_fullscreen:
logger.info("Launching in fullscreen mode (gamepad)")
window.input_manager.handle_fullscreen_slot(True)
window.updateControlHints("force")
elif window_resolution:
logger.info(f"Launching with resolution: {window_resolution[0]}x{window_resolution[1]}")
window.resize(window_resolution[0], window_resolution[1])
+70 -18
View File
@@ -2,11 +2,12 @@ import argparse
import os
import re
import shutil
import sys
from pathlib import Path
from portprotonqt.steam_api import get_steam_home
LAUNCH_FILE_EXTENSIONS = ('.exe', '.iso', '.mdf')
LAUNCH_FILE_EXTENSIONS = ('.exe', '.bat', '.cmd', '.msi', '.reg', '.iso', '.mdf', '.nrg')
PREFIX_BACKUP_EXTENSION = '.ppack'
@@ -65,7 +66,7 @@ def parse_args():
parser.add_argument(
"--silent",
action="store_true",
help="Launch .exe file in tray without showing the main window"
help="Launch supported Windows file in tray without showing the main window"
)
parser.add_argument(
"--restore-prefix",
@@ -82,9 +83,25 @@ def parse_args():
parser.add_argument(
'file_or_url',
nargs='?',
help="Launch file path (.exe/.iso/.mdf) or portproton:// URL"
help="Launch file path (.exe/.bat/.cmd/.msi/.reg/.iso/.mdf/.nrg) or portproton:// URL"
)
return parser.parse_args()
if os.environ.get("STEAM_COMPAT") == "1" and "--" in sys.argv[1:]:
separator_index = sys.argv.index("--")
args = parser.parse_args(sys.argv[1:separator_index])
steam_args = sys.argv[separator_index + 1:]
if steam_args:
args.file_or_url = steam_args[0]
launch_args = steam_args[1:]
else:
launch_args = []
elif os.environ.get("STEAM_COMPAT") == "1":
args, launch_args = parser.parse_known_args()
else:
args = parser.parse_args()
launch_args = []
args.launch_args = launch_args
return args
def add_steam_compat_tool(force_install: bool = False) -> bool:
@@ -156,13 +173,41 @@ unset LD_LIBRARY_PATH
export STEAM_COMPAT=1
launch_args=("$@")
case "${1:-}" in
run|waitforexitandrun)
launch_args=("${@:2}")
;;
esac
exe_name="$(basename "$1")"
exe_dir="$(dirname "$1")"
launch_target="${launch_args[0]:-}"
exe_name="$(basename "$launch_target")"
exe_dir="$(dirname "$launch_target")"
# Ignore specific executables
if [[ "$exe_name" == "iscriptevaluator.exe" ]] || \\
[[ "$exe_name" == "d3ddriverquery64.exe" ]]; then
if [[ "$exe_name" == "iscriptevaluator.exe" ]] \\
|| [[ "$exe_name" == "d3ddriverquery64.exe" ]]
then
exit 0
fi
# Activate virtual environment if available
if [[ -n "$PPQT_VENV_PATH" ]]; then
cd "$PPQT_VENV_PATH" || exit 1
source .venv/bin/activate || exit 1
fi
if [[ "$UPDATE_CT_PPQT" != "1" ]]; then
export UPDATE_CT_PPQT="1"
full_command_line=("$(realpath "$0")" "$@")
if [[ -n "$PPQT_BIN_PATH" ]]; then
"$PPQT_BIN_PATH" --reinstall-steam-compat-tool
elif command -v flatpak >/dev/null 2>&1 && flatpak info ru.linux_gaming.PortProtonQt >/dev/null 2>&1; then
flatpak run ru.linux_gaming.PortProtonQt --reinstall-steam-compat-tool
else
portprotonqt --reinstall-steam-compat-tool
fi
exec "${full_command_line[@]}"
exit 0
fi
@@ -212,19 +257,13 @@ if [[ -n "$SteamAppId" ]]; then
fi
fi
# Activate virtual environment if available
if [[ -n "$PPQT_VENV_PATH" ]]; then
cd "$PPQT_VENV_PATH" || exit 1
source .venv/bin/activate || exit 1
fi
# Use AppImage if specified, then Flatpak if installed, otherwise use portprotonqt from PATH
if [[ -n "$PPQT_BIN_PATH" ]]; then
"$PPQT_BIN_PATH" --debug-level INFO "$@"
"$PPQT_BIN_PATH" --debug-level INFO -- "${launch_args[@]}"
elif command -v flatpak >/dev/null 2>&1 && flatpak info ru.linux_gaming.PortProtonQt >/dev/null 2>&1; then
flatpak run ru.linux_gaming.PortProtonQt --debug-level INFO "$@"
flatpak run ru.linux_gaming.PortProtonQt --debug-level INFO -- "${launch_args[@]}"
else
portprotonqt --debug-level INFO "$@"
portprotonqt --debug-level INFO -- "${launch_args[@]}"
fi
''')
@@ -290,9 +329,22 @@ def clear_cache() -> bool:
def reset_settings() -> bool:
"""Reset PortProtonQt settings."""
from portprotonqt.config import reset_main_config
from portprotonqt.config import (
get_portproton_location,
reset_main_config,
)
portproton_location = get_portproton_location()
reset_main_config()
if portproton_location:
user_conf_path = Path(portproton_location) / "data" / "user.conf"
try:
if user_conf_path.is_file():
user_conf_path.unlink()
except OSError as e:
print(f"Failed to delete user.conf: {e}")
return False
print("PortProtonQt settings reset")
return True
+16 -1
View File
@@ -4,17 +4,23 @@ from portprotonqt.config.base import (
CACHE_DIR,
CONFIG_DIR,
CONFIG_FILE,
COUNTER_SKIP_FILE,
PORTPROTON_CONFIG_FILE,
THEMES_DIRS,
consume_download_counter_skip,
reset_main_config,
update_app_version,
)
from portprotonqt.config.cache import CacheConfig, CacheManager
from portprotonqt.config.display import DisplayConfig, apply_xdg_autostart
from portprotonqt.config.favorites import FavoritesConfig, FavoritesFoldersConfig
from portprotonqt.config.favorites import ExeSettingsFavoritesConfig, FavoritesConfig, FavoritesFoldersConfig
from portprotonqt.config.game import GameConfig
from portprotonqt.config.gamepad import GamepadConfig
from portprotonqt.config.portproton import (
PortProtonConfig,
LAUNCH_FILE_EXTENSIONS,
THEMED_LAUNCH_ICON_NAMES,
WINDOWS_LAUNCH_EXTENSIONS,
create_desktop_file,
extract_exec_target_path,
find_game_by_exe,
@@ -40,6 +46,7 @@ display_config = DisplayConfig()
window_config = MainWindowConfig()
favorites_config = FavoritesConfig()
favorites_folders_config = FavoritesFoldersConfig()
exe_settings_favorites_config = ExeSettingsFavoritesConfig()
portproton_config = PortProtonConfig()
__all__ = [
@@ -54,8 +61,13 @@ __all__ = [
"MainWindowConfig",
"FavoritesConfig",
"FavoritesFoldersConfig",
"ExeSettingsFavoritesConfig",
"PortProtonConfig",
"LAUNCH_FILE_EXTENSIONS",
"THEMED_LAUNCH_ICON_NAMES",
"WINDOWS_LAUNCH_EXTENSIONS",
"CONFIG_FILE",
"COUNTER_SKIP_FILE",
"PORTPROTON_CONFIG_FILE",
"CONFIG_DIR",
"THEMES_DIRS",
@@ -70,6 +82,7 @@ __all__ = [
"window_config",
"favorites_config",
"favorites_folders_config",
"exe_settings_favorites_config",
"portproton_config",
"load_theme_metainfo",
"apply_xdg_autostart",
@@ -83,5 +96,7 @@ __all__ = [
"extract_exec_target_path",
"find_game_by_exe",
"create_desktop_file",
"consume_download_counter_skip",
"reset_main_config",
"update_app_version",
]
+56
View File
@@ -13,6 +13,7 @@ __all__ = ["configparser"]
# Configuration file paths
CONFIG_DIR = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
CONFIG_FILE = CONFIG_DIR / "PortProtonQt.conf"
COUNTER_SKIP_FILE = CONFIG_DIR / "PortProtonQt.counter.skip"
PORTPROTON_CONFIG_FILE = CONFIG_DIR / "PortProton.conf"
# Theme directories
@@ -32,6 +33,7 @@ _config_mtime: dict[str, float] = {}
def reset_main_config() -> None:
"""Delete main config file and invalidate cache."""
_mark_download_counter_skip()
if not CONFIG_FILE.exists():
return
try:
@@ -46,6 +48,60 @@ def reset_main_config() -> None:
_config_mtime.pop(config_path, None)
def _mark_download_counter_skip() -> None:
"""Skip the next download counter request."""
try:
COUNTER_SKIP_FILE.parent.mkdir(parents=True, exist_ok=True)
COUNTER_SKIP_FILE.write_text("1", encoding="utf-8")
except OSError as error:
logger.warning("Failed to save counter skip marker: %s", error)
def consume_download_counter_skip() -> bool:
"""Return True once after settings reset."""
if not COUNTER_SKIP_FILE.exists():
return False
try:
COUNTER_SKIP_FILE.unlink()
except OSError as error:
logger.warning("Failed to delete counter skip marker: %s", error)
return True
def update_app_version(app_version: str) -> bool:
"""Store current app version and report whether it changed."""
cp = configparser.ConfigParser()
config_existed = CONFIG_FILE.exists()
if config_existed:
try:
cp.read(CONFIG_FILE, encoding="utf-8")
except configparser.Error as e:
logger.warning("Invalid configuration file format: %s", e)
return False
section = "Application"
old_version = cp.get(section, "version", fallback="")
if config_existed and old_version == app_version:
return False
if section not in cp:
cp[section] = {}
cp[section]["version"] = app_version
try:
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(CONFIG_FILE, "w", encoding="utf-8") as config_file:
cp.write(config_file)
except OSError as error:
logger.warning("Failed to save application version: %s", error)
return False
config_path = str(CONFIG_FILE)
_config_cache.pop(config_path, None)
_config_mtime.pop(config_path, None)
return True
class BaseConfig:
"""Base configuration class providing common functionality."""
+31
View File
@@ -68,3 +68,34 @@ class FavoritesFoldersConfig(BaseConfig):
fav_str = ", ".join([os.path.normpath(f) for f in folders])
cp[self._section]["folders"] = f'"{fav_str}"'
self._save_config(cp)
class ExeSettingsFavoritesConfig(BaseConfig):
"""Favorite executable settings configuration."""
_section = "ExeSettingsFavorites"
def get_keys(self) -> list[str]:
"""Get list of favorite executable setting keys."""
cp = self._read_config()
if cp is None or not cp.has_section(self._section):
return []
keys = cp.get(self._section, "keys", fallback="").strip()
if keys.startswith('"') and keys.endswith('"'):
keys = keys[1:-1]
return [key.strip() for key in keys.split(",") if key.strip()]
def set_keys(self, keys: list[str]) -> None:
"""Set list of favorite executable setting keys."""
if not isinstance(keys, list):
raise ValidationError("keys must be a list", "keys", keys)
for key in keys:
validate_string(key, "key", min_len=1, max_len=255)
cp = self._read_config() or configparser.ConfigParser()
if self._section not in cp:
cp[self._section] = {}
fav_str = ", ".join(keys)
cp[self._section]["keys"] = f'"{fav_str}"'
self._save_config(cp)
+17
View File
@@ -1,7 +1,24 @@
"""Gamepad configuration settings."""
from portprotonqt.config.base import BaseConfig
class GamepadConfig(BaseConfig):
"""Gamepad configuration settings."""
_section = "Gamepad"
def get_gamepad_type(self) -> str:
"""Get configured gamepad type."""
value = self._get_str("type", "auto").lower()
if value in ("auto", "xbox", "playstation"):
return value
if value in ("ps", "sony"):
return "playstation"
return "auto"
def set_gamepad_type(self, gamepad_type: str) -> None:
"""Set configured gamepad type."""
value = gamepad_type.lower()
if value not in ("auto", "xbox", "playstation"):
value = "auto"
self._save_value("type", value, "str")
+147 -7
View File
@@ -3,7 +3,10 @@ import configparser
import os
import re
import shlex
import sys
import shutil
from pathlib import Path
from PySide6.QtCore import QStandardPaths
from portprotonqt.config.base import (
BaseConfig,
CONFIG_FILE,
@@ -143,17 +146,27 @@ def save_portdata_path_to_config(portdata_path: str) -> bool:
def get_portproton_scripts_path() -> str | None:
"""Return PortProton scripts directory path."""
appdir_prefix = os.getenv("APPDIR")
sharun_prefix = os.getenv("SHARUN_DIR")
prefixes = [("system package", Path("/usr")), ("Flatpak package", Path("/app"))]
appimage_path = os.getenv("APPIMAGE", "").strip()
prefixes = []
if appdir_prefix:
prefixes.append(("AppImage appdir", Path(appdir_prefix)))
if sharun_prefix:
prefixes.append(("AppImage", Path(sharun_prefix)))
if appimage_path:
appimage_root = Path(sys.executable).resolve().parent.parent
prefixes.append(("AppImage executable", appimage_root))
if os.getenv("FLATPAK_ID"):
prefixes.append(("Flatpak package", Path("/app")))
prefixes.append(("system package", Path("/usr")))
scripts_dirs = (
("repository", Path.cwd() / "build-aux" / "share" / "portproton" / "scripts"),
*[(source, prefix / "share" / "portproton" / "scripts") for source, prefix in prefixes],
)
for source, scripts_dir in scripts_dirs:
if scripts_dir.exists():
if (scripts_dir / "start.sh").is_file():
logger.info("Using PortProton scripts from %s: %s", source, scripts_dir)
return str(scripts_dir)
logger.info(
@@ -178,6 +191,82 @@ def get_portproton_start_command() -> list[str] | None:
return None
def _get_current_launcher_command() -> list[str] | None:
"""Return the current launcher command for shortcut migration."""
appimage_path = os.getenv("APPIMAGE", "").strip()
if appimage_path and os.path.isfile(appimage_path):
return [appimage_path, "--silent"]
flatpak_id = os.getenv("FLATPAK_ID", "").strip()
if flatpak_id:
return ["flatpak", "run", flatpak_id, "--silent"]
scripts_path = get_portproton_scripts_path()
if scripts_path:
return [os.path.join(scripts_path, "start.sh")]
if shutil.which("portprotonqt"):
return ["portprotonqt", "--silent"]
return None
def _extract_launcher_tail(parts: list[str]) -> list[str] | None:
"""Return shortcut args after the launcher command."""
if not parts:
return None
command_name = os.path.basename(parts[0])
if parts[0].lower().endswith(".appimage") or command_name == "portprotonqt" or command_name == "start.sh":
tail = parts[1:]
if tail[:1] == ["--silent"]:
tail = tail[1:]
return tail
if parts[0] == "flatpak" and len(parts) >= 3 and parts[1] == "run":
tail = parts[3:]
if tail[:1] == ["--silent"]:
tail = tail[1:]
return tail
return None
def _migrate_launcher_line(line: str, launcher_command: list[str] | None) -> str:
"""Update launcher command in desktop Exec or shell script line."""
if not launcher_command:
return line
prefix = "Exec=" if line.startswith("Exec=") else ""
command = line[len(prefix):].strip() if prefix else line.strip()
if not command or command.startswith("#"):
return line
try:
parts = shlex.split(command)
except ValueError:
return line
tail = _extract_launcher_tail(parts)
if tail is None:
return line
updated_parts = launcher_command + tail
if not prefix and updated_parts[-1:] == ["$@"]:
return f'{shlex.join(updated_parts[:-1])} "$@"'
return f"{prefix}{shlex.join(updated_parts)}"
def _get_desktop_paths(desktop_dir: str | None) -> tuple[str, ...]:
"""Return desktop directories to scan for shortcuts."""
if desktop_dir:
return (desktop_dir,)
desktop_path = QStandardPaths.writableLocation(QStandardPaths.StandardLocation.DesktopLocation)
if desktop_path:
return (desktop_path,)
return (os.path.join(os.path.expanduser("~"), "Desktop"),)
def migrate_legacy_shortcut(portproton_path: str, desktop_dir: str | None = None) -> int:
"""Migrate legacy PortProton shortcuts in known desktop directories."""
flatpak_id = os.getenv("FLATPAK_ID", "").strip()
@@ -197,11 +286,11 @@ def migrate_legacy_shortcut(portproton_path: str, desktop_dir: str | None = None
except OSError as error:
logger.warning("Failed to read legacy PortProton config %s: %s", PORTPROTON_CONFIG_FILE, error)
desktop_path = desktop_dir or os.path.join(os.path.expanduser("~"), "Desktop")
launcher_command = _get_current_launcher_command()
desktop_paths = (
portproton_path,
os.path.join(os.path.expanduser("~"), ".local", "share", "applications"),
desktop_path,
os.path.join(user_home, ".local", "share", "applications"),
*_get_desktop_paths(desktop_dir),
)
migrated = 0
for current_path in desktop_paths:
@@ -281,6 +370,9 @@ def migrate_legacy_shortcut(portproton_path: str, desktop_dir: str | None = None
if "--silent" not in parts:
updated_line = f'Exec={shlex.join(["portprotonqt", "--silent", *parts[2:]])}'
if updated_line.startswith("Exec="):
updated_line = _migrate_launcher_line(updated_line, launcher_command)
if updated_line == line_content:
continue
@@ -295,6 +387,40 @@ def migrate_legacy_shortcut(portproton_path: str, desktop_dir: str | None = None
migrated += 1
except OSError as error:
logger.warning("Failed to update desktop file %s: %s", entry.path, error)
steam_scripts_path = os.path.join(portproton_path, "steam_scripts")
if not os.path.isdir(steam_scripts_path):
return migrated
for entry in os.scandir(steam_scripts_path):
if not entry.name.endswith(".sh") or not entry.is_file():
continue
try:
lines = Path(entry.path).read_text(encoding="utf-8").splitlines(keepends=True)
except OSError as error:
logger.warning("Failed to read steam script %s: %s", entry.path, error)
continue
changed = False
for idx, line in enumerate(lines):
line_end = "\r\n" if line.endswith("\r\n") else "\n"
line_content = line[:-len(line_end)] if line.endswith(("\n", "\r\n")) else line
updated_line = _migrate_launcher_line(line_content, launcher_command)
if updated_line == line_content:
continue
lines[idx] = f"{updated_line}{line_end}"
changed = True
if not changed:
continue
try:
Path(entry.path).write_text("".join(lines), encoding="utf-8")
migrated += 1
except OSError as error:
logger.warning("Failed to update steam script %s: %s", entry.path, error)
return migrated
@@ -307,6 +433,17 @@ def parse_desktop_entry(file_path: str) -> configparser.SectionProxy | None:
return cp["Desktop Entry"]
WINDOWS_LAUNCH_EXTENSIONS = (".exe", ".bat", ".cmd", ".msi", ".reg")
DISC_IMAGE_EXTENSIONS = (".iso", ".mdf", ".nrg")
LAUNCH_FILE_EXTENSIONS = WINDOWS_LAUNCH_EXTENSIONS + DISC_IMAGE_EXTENSIONS
THEMED_LAUNCH_ICON_NAMES = {
".bat": "bat",
".cmd": "bat",
".msi": "msi",
".reg": "reg",
}
def extract_exec_target_path(exec_value: str | list[str]) -> str | None:
"""Extract target executable or image path from a desktop Exec value."""
if isinstance(exec_value, str):
@@ -327,7 +464,7 @@ def extract_exec_target_path(exec_value: str | list[str]) -> str | None:
return None
for part in reversed(parts):
if part.lower().endswith((".exe", ".iso", ".mdf")):
if part.lower().endswith(LAUNCH_FILE_EXTENSIONS):
return os.path.expanduser(part)
if parts[0] in ("env", "flatpak"):
@@ -383,12 +520,15 @@ def create_desktop_file(
os.makedirs(os.path.dirname(icon_path), exist_ok=True)
flatpak_id = os.getenv("FLATPAK_ID")
appimage_path = os.getenv("APPIMAGE", "").strip()
if flatpak_id:
exec_str = f'flatpak run {flatpak_id} --silent "{exe_path}"'
elif appimage_path and os.path.isfile(appimage_path):
exec_str = shlex.join([appimage_path, "--silent", exe_path])
else:
exec_str = f'portprotonqt --silent "{exe_path}"'
comment = _('Launch game "{name}" with PortProton').format(name=game_name)
comment = _('Launch "{name}" with PortProton').format(name=game_name)
desktop_entry = (
"[Desktop Entry]\n"
f"Name={game_name}\n"
+79 -22
View File
@@ -124,39 +124,53 @@ class ContextMenuManager:
return hasattr(self.parent, 'target_exe') and self.parent.target_exe == current_exe
def show_folder_context_menu(self, file_explorer, pos):
"""Shows the context menu for a folder in FileExplorer."""
def show_file_explorer_context_menu(self, file_explorer, pos):
"""Shows the context menu for a file or folder in FileExplorer."""
try:
item = file_explorer.file_list.itemAt(pos)
if not item:
logger.debug("No folder selected at position %s", pos)
logger.debug("No item selected at position %s", pos)
return
# Ensure the item is visually selected
file_explorer.file_list.setCurrentItem(item)
file_explorer.handle_item_click(item)
selected = item.text()
if not selected.endswith("/"):
logger.debug("Selected item is not a folder: %s", selected)
return # Only for folders
full_path = os.path.normpath(os.path.join(file_explorer.current_path, selected.rstrip("/")))
if not os.path.isdir(full_path):
logger.debug("Path is not a directory: %s", full_path)
if selected in ("../", "./"):
return
is_folder = selected.endswith("/")
full_path = os.path.normpath(os.path.join(file_explorer.current_path, selected.rstrip("/")))
menu = QMenu(file_explorer)
menu.setWindowFlags(menu.windowFlags() | Qt.WindowType.Popup | Qt.WindowType.FramelessWindowHint)
menu.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
menu.setStyleSheet(self.theme.CONTEXT_MENU_STYLE)
menu.setParent(file_explorer, Qt.WindowType.Popup) # Set transientParent for Wayland
favorite_folders = favorites_folders_config.get_folders()
is_favorite = full_path in favorite_folders
action_text = _("Remove from Favorites") if is_favorite else _("Add to Favorites")
favorite_action = menu.addAction(self._get_safe_icon("star" if is_favorite else "star_full"), action_text)
favorite_action.triggered.connect(lambda: self.toggle_favorite_folder(file_explorer, full_path, not is_favorite))
if is_folder:
favorite_folders = favorites_folders_config.get_folders()
is_favorite = full_path in favorite_folders
action_text = _("Remove from Favorites") if is_favorite else _("Add to Favorites")
favorite_action = menu.addAction(self._get_safe_icon("star" if is_favorite else "star_full"), action_text)
favorite_action.triggered.connect(lambda: self.toggle_favorite_folder(file_explorer, full_path, not is_favorite))
create_folder_action = menu.addAction(self._get_safe_icon("folder"), _("Create Folder"))
create_folder_action.triggered.connect(lambda: self.create_folder(file_explorer))
rename_folder_action = menu.addAction(self._get_safe_icon("edit"), _("Rename Folder"))
rename_folder_action.triggered.connect(lambda: self.rename_folder(file_explorer, full_path))
delete_folder_action = menu.addAction(self._get_safe_icon("delete"), _("Delete Folder"))
delete_folder_action.triggered.connect(lambda: self.delete_folder(file_explorer, full_path))
create_folder_action.triggered.connect(
lambda: self.create_folder(file_explorer, file_explorer.current_path)
)
if is_folder:
rename_action = menu.addAction(self._get_safe_icon("edit"), _("Rename Folder"))
rename_action.triggered.connect(lambda: self.rename_folder(file_explorer, full_path))
delete_action = menu.addAction(self._get_safe_icon("delete"), _("Delete Folder"))
delete_action.triggered.connect(lambda: self.delete_folder(file_explorer, full_path))
else:
rename_action = menu.addAction(self._get_safe_icon("edit"), _("Rename File"))
rename_action.triggered.connect(lambda: self.rename_file(file_explorer, full_path))
delete_action = menu.addAction(self._get_safe_icon("delete"), _("Delete File"))
delete_action.triggered.connect(lambda: self.delete_file(file_explorer, full_path))
# Disconnect file_list signals to prevent navigation during menu interaction
try:
@@ -184,7 +198,7 @@ class ContextMenuManager:
global_pos = file_explorer.file_list.mapToGlobal(pos)
menu.exec(global_pos)
except Exception as e:
logger.error("Error displaying folder context menu: %s", e)
logger.error("Error displaying file explorer context menu: %s", e)
def toggle_favorite_folder(self, file_explorer, folder_path, add):
"""Adds or removes a folder from favorites."""
@@ -280,12 +294,12 @@ class ContextMenuManager:
if hasattr(parent, "file_list") and parent.file_list:
parent.file_list.setFocus(Qt.FocusReason.OtherFocusReason)
def create_folder(self, file_explorer) -> None:
def create_folder(self, file_explorer, parent_path: str | None = None) -> None:
"""Create a new folder in the current directory."""
folder_name = self._prompt_folder_name(file_explorer, _("Create Folder"), _("Folder Name:"))
if not folder_name:
return
target_path = os.path.join(file_explorer.current_path, folder_name)
target_path = os.path.join(parent_path or file_explorer.current_path, folder_name)
if os.path.exists(target_path):
self.signals.show_warning_dialog.emit(_("Error"), _("Folder already exists: {folder_name}").format(folder_name=folder_name))
return
@@ -352,6 +366,49 @@ class ContextMenuManager:
_("Failed to delete folder: {error}").format(error=str(e))
)
def delete_file(self, file_explorer, file_path: str) -> None:
"""Delete selected file after confirmation."""
file_name = os.path.basename(file_path)
msg_box = QMessageBox(file_explorer)
msg_box.setWindowTitle(_("Confirm Deletion"))
msg_box.setText(
_("Are you sure you want to delete file '{file_name}'? This action cannot be undone.")
.format(file_name=file_name)
)
msg_box.setIcon(QMessageBox.Icon.Warning)
msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
msg_box.setButtonText(QMessageBox.StandardButton.Yes, _("Yes"))
msg_box.setButtonText(QMessageBox.StandardButton.No, _("No"))
if msg_box.exec() != QMessageBox.StandardButton.Yes:
return
try:
os.remove(file_path)
file_explorer.update_file_list()
except OSError as e:
self.signals.show_warning_dialog.emit(
_("Error"),
_("Failed to delete file: {error}").format(error=str(e))
)
def rename_file(self, file_explorer, file_path: str) -> None:
"""Rename selected file."""
current_name = os.path.basename(file_path)
new_name = self._prompt_folder_name(file_explorer, _("Rename File"), _("New File Name:"), current_name)
if not new_name or new_name == current_name:
return
target_path = os.path.join(os.path.dirname(file_path), new_name)
if os.path.exists(target_path):
self.signals.show_warning_dialog.emit(_("Error"), _("File already exists: {file_name}").format(file_name=new_name))
return
try:
os.rename(file_path, target_path)
file_explorer.update_file_list()
except OSError as e:
self.signals.show_warning_dialog.emit(
_("Error"),
_("Failed to rename file: {error}").format(error=str(e))
)
def _get_safe_icon(self, icon_name: str) -> QIcon:
"""Returns a QIcon, ensuring it is valid."""
icon = self.theme_manager.get_icon(icon_name)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 KiB

@@ -1,3 +0,0 @@
name=Albion Online
description_ru=Многопользовательская песочница в жанре MMORPG, где игроки могут исследовать открытый мир, заниматься ремеслом, добычей ресурсов и сражаться с другими игроками. Игра предлагает уникальную систему классов, позволяющую игрокам изменять свои роли в зависимости от выбранного снаряжения.
description_en=A multiplayer sandbox MMORPG where players can explore an open world, engage in crafting, gather resources, and battle against other players. The game features a unique class system that allows players to change their roles based on the gear they equip.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

@@ -1,3 +0,0 @@
name=Ankama Launcher
description_ru=Лаунчер для игр Ankama.
description_en=Launcher for Ankama studio games.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 KiB

@@ -1,3 +0,0 @@
name=Anomaly Zone
description_ru=Экшен-игра про сталкеров, где игроки исследуют таинственные миры и сражаются с разнообразными противниками. Игра предлагает захватывающий сюжет и возможность улучшать персонажа, открывая новые способности и снаряжение.
description_en=An action game about stalkers, where players explore mysterious worlds and fight against a variety of opponents. The game offers an exciting storyline and the opportunity to improve the character by unlocking new abilities and equipment.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 KiB

@@ -1,3 +0,0 @@
name=Arizona Games Launcher
description_ru=Лаунчер для игры Arizona Role Play.
description_en=Launcher for the Arizona Role Play game.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

@@ -1,3 +0,0 @@
name=Battle.net Launcher
description_ru=Лаунчер для игр Activision и Blizzard.
description_en=Launcher for Activision and Blizzard studio games.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 KiB

@@ -1,3 +0,0 @@
name=Black Desert Online (RU)
description_ru=Многопользовательская ролевая игра с открытым миром, известная своей потрясающей графикой и глубокой системой кастомизации персонажей. Игроки могут исследовать обширные земли, выполнять задания, участвовать в PvP-сражениях и заниматься различными ремеслами.
description_en=A massively multiplayer online role-playing game set in an open world, renowned for its stunning graphics and deep character customization system. Players can explore vast lands, complete quests, engage in PvP battles, and participate in various crafting activities.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 KiB

@@ -1,3 +0,0 @@
name=Blood and Soul
description_ru=Многопользовательская ролевая игра с богатой системой боя и яркой графикой, вдохновленная восточной мифологией. Игроки могут выбирать из различных классов, исследовать уникальные локации и сражаться с могущественными врагами.
description_en=A multiplayer role-playing game featuring a rich combat system and vibrant graphics, inspired by Eastern mythology. Players can choose from various classes, explore unique locations, and battle powerful foes.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 KiB

@@ -1,3 +0,0 @@
name=Chicken Invaders Universe
description_ru=Захватывающая аркадная игра, в которой игроки сражаются с агрессивными курицами из космоса, защищая свою планету. Игра предлагает множество уровней, кооперативный режим и возможность улучшения космического корабля.
description_en=An exciting arcade game where players battle aggressive space chickens to defend their planet. The game features multiple levels, a cooperative mode, and the ability to upgrade their spaceship.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 KiB

@@ -1,3 +0,0 @@
name=CONTRACT WARS
description_ru=Многопользовательский шутер от первого лица, где игроки участвуют в противостоянии между двумя командами на разнообразных картах. Игра предлагает широкий выбор оружия и возможностей для настройки персонажей, что делает каждый матч уникальным.
description_en=A multiplayer first-person shooter where players engage in battles between two teams on various maps. The game offers a wide selection of weapons and character customization options, making each match unique.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 870 KiB

@@ -1,3 +0,0 @@
name=Age of Empires Online
description_ru=Многопользовательская стратегия в реальном времени, где игроки строят свои цивилизации, собирают ресурсы и сражаются с противниками. Игра предлагает уникальную экономическую систему и возможность развивать свои города с помощью различных миссий и задач.
description_en=A multiplayer real-time strategy game where players build their civilizations, gather resources, and battle against opponents. The game features a unique economic system and the ability to develop cities through various missions and quests.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

@@ -1,3 +0,0 @@
name=Cemu
description_ru=Эмулятор Wii U, который позволяет пользователям запускать и играть в игры, выпущенные на этой консоли, с высокой производительностью и улучшенной графикой.
description_en=A Wii U emulator that allows users to launch and play games released on this console with high performance and enhanced graphics.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 KiB

@@ -1,3 +0,0 @@
name=Secret World Legends (ENG)
description_ru=MMORPG с уникальной историей и сеттингом, основанная на мифах, легендах и тайных обществах, позволяющая игрокам исследовать современный мир, полный сверхъестественных существ и загадок. Игра предлагает свободу в выборе навыков и построении персонажей, а также захватывающие квесты и глубокий сюжет.
description_en=An MMORPG with a unique story and setting based on myths, legends, and secret societies, allowing players to explore a modern world filled with supernatural beings and mysteries. The game offers freedom in skill selection and character building, along with engaging quests and a rich narrative.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 KiB

@@ -1,3 +0,0 @@
name=Broken Ranks (ENG)
description_ru=MMORPG игра, предлагающая глубокий сон и уникальную боевую систему, которая ориентирует внимание на стратегию и деятельность персоны. Игроки исследуют мрачный мир, полный интриг и опасностей, развивая своих героев и принимая ключевые решения, влияющие на ход истории.
description_en=An MMORPG game offering deep sleep and a unique combat system that focuses on the strategy and activities of the person. Players explore a dark world full of intrigue and danger, developing their characters and making key decisions that affect the course of history.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

@@ -1,3 +0,0 @@
name=Dolphin 5.0
description_ru=Мощный эмулятор для игровых консолей Nintendo GameCube и Wii, который позволяет запускать игры на ПК с улучшенной графикой и производительностью. Он поддерживает широкий спектр функций, включая HD-разрешение, множество настройек управления и возможность использования модификаций.
description_en=A powerful emulator for Nintendo GameCube and Wii consoles that allows users to play games on their PCs with enhanced graphics and performance. It supports a wide range of features, including HD resolution, numerous control configurations, and the ability to use modifications.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 KiB

@@ -1,3 +0,0 @@
name=Doomsday
description_ru=Стратегическая игра в реальном времени, где игроки управляют отрядом выживших в постапокалиптическом мире, стремясь восстановить цивилизацию и защититься от различных угроз. Игра предлагает элементы строительства базы, тактические сражения и глубокую проработку сюжета.
description_en=A real-time strategy game where players manage a group of survivors in a post-apocalyptic world, aiming to rebuild civilization and defend against various threats. The game features base-building elements, tactical combat, and a deep narrative experience.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 KiB

@@ -1,3 +0,0 @@
name=Eldevin (ENG)
description_ru=MMORPG с красочной графикой, где игроки исследуют обширный фэнтезийный мир, выполняют квесты и сражаются с врагами, чтобы развивать свои персонажи. Игра предлагает разнообразные классы и навыки, а также системы крафта и группового взаимодействия.
description_en=An MMORPG with vibrant graphics where players explore a vast fantasy world, complete quests, and battle enemies to develop their characters. The game features diverse classes and skills, as well as crafting and group interaction systems.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

@@ -1,3 +0,0 @@
name=Epic Games Launcher
description_ru=Лаунчер для библиотеки игр Epic Games.
description_en=Launcher for the Epic Games game library.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 KiB

@@ -1,3 +0,0 @@
name=STALCRAFT
description_ru=Многопользовательская игра с открытым миром, вдохновленная вселенной S.T.A.L.K.E.R., где игроки исследуют заброшенные зоны, сражаются с мутантами и другими сталкерами, а также выполняют различные квесты. Игра сочетает элементы выживания, RPG и шутера от первого лица, предлагая уникальный опыт в постапокалиптическом мире.
description_en=A multiplayer open-world game inspired by the S.T.A.L.K.E.R. universe, where players explore abandoned zones, battle mutants and other stalkers, and complete various quests. The game combines elements of survival, RPG, and first-person shooter, offering a unique experience in a post-apocalyptic world.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

@@ -1,3 +0,0 @@
name=ExoTanks
description_ru=Многопользовательская боевая игра, в которой игроки управляют экзоскелетами и сражаются в различных аренах, используя мощное вооружение и стратегический подход. Игра предлагает как командные, так и одиночные режимы, а также возможность кастомизации своего экзоскелета для уникального стиля игры.
description_en=A multiplayer battle game where players control exoskeletons and fight in various arenas using powerful weapons and strategic gameplay. The game offers both team and solo modes, along with the ability to customize their exoskeleton for a unique playing style.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 854 KiB

@@ -1,3 +0,0 @@
name=Farlight 84
description_ru=Многопользовательская игра в жанре королевская битва, которая проходит в красочном и футуристическом мире, где игроки сражаются друг с другом с использованием уникальных навыков и оружия. Игра предлагает захватывающий геймплей с элементами строительства, а также возможность использовать различные транспортные средства для перемещения по карте.
description_en=A multiplayer battle royale game set in a colorful and futuristic world where players fight against each other using unique skills and weapons. The game features exciting gameplay with building elements, as well as the ability to utilize various vehicles to navigate the map.
Loaded 100 of 273 files, more files were not shown because too many files have changed in this diff. Show more