16 Commits

Author SHA1 Message Date
85e9aba836 bump ver
All checks were successful
Build AppImage, Arch and Fedora Packages / Build AppImage (push) Successful in 2m52s
Build AppImage, Arch and Fedora Packages / Build Arch Package (push) Successful in 1m19s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (41) (push) Successful in 58s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (42) (push) Successful in 1m1s
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (rawhide) (push) Successful in 52s
Code check / Check code (push) Successful in 1m27s
Build AppImage, Arch and Fedora Packages / Create and Publish Release (push) Successful in 49s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-21 15:09:15 +05:00
4d3499d2c1 chore(appimage): use appimage builder from git
All checks were successful
Build Check - AppImage, Arch, Fedora / changes (pull_request) Successful in 20s
Code check / Check code (pull_request) Successful in 1m24s
Build Check - AppImage, Arch, Fedora / Build AppImage (pull_request) Successful in 2m55s
Build Check - AppImage, Arch, Fedora / Build Fedora RPM (41) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora / Build Fedora RPM (42) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora / Build Fedora RPM (rawhide) (pull_request) Has been skipped
Build Check - AppImage, Arch, Fedora / Build Arch Package (pull_request) Has been skipped
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-21 14:55:23 +05:00
a13c15bc28 chore(ci): add Gitea workflow for AppImage, Arch & Fedora builds test
Some checks failed
Build AppImage, Arch and Fedora Packages / Build AppImage (push) Has been cancelled
Build AppImage, Arch and Fedora Packages / Build Arch Package (push) Has been cancelled
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (41) (push) Has been cancelled
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (42) (push) Has started running
Build AppImage, Arch and Fedora Packages / Build Fedora RPM (rawhide) (push) Has been cancelled
Build AppImage, Arch and Fedora Packages / Create and Publish Release (push) Has been cancelled
Code and build check / Check code (push) Successful in 1m26s
Code and build check / Build with uv (push) Successful in 49s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-20 23:48:40 +05:00
83076d3dfc chore(changelog): update
All checks were successful
Code and build check / Check code (push) Successful in 1m25s
Code and build check / Build with uv (push) Successful in 48s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-20 12:34:06 +05:00
04aaf68e36 fix: Allow context menu for PortProton games without valid exe
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-20 12:31:36 +05:00
e91037708a fix(main_window): prevent RuntimeError when modifying deleted QVBoxLayout in HLTB callback
All checks were successful
Code and build check / Check code (push) Successful in 1m35s
Code and build check / Build with uv (push) Successful in 52s
renovate / renovate (push) Successful in 22s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-18 20:54:45 +05:00
1b743026c2 chore(build): clean appimage more agressive
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-18 15:26:51 +05:00
30b4cec4d1 chore(todo): fix typos
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-18 00:02:11 +05:00
db68c9050c chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-16 20:16:02 +05:00
1a93d5b82c chore(build): rework appimage dependency list
All checks were successful
Code and build check / Check code (push) Successful in 1m31s
Code and build check / Build with uv (push) Successful in 50s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-16 20:04:56 +05:00
cc0690cf9e fix: added perllib to appimage for fix exiftool work
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-16 19:58:56 +05:00
809ba2c976 chore(readme): mention all licences
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-16 19:42:22 +05:00
68c9636e10 chore(todo): update
All checks were successful
Code and build check / Check code (push) Successful in 2m28s
Code and build check / Build with uv (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-16 16:56:18 +05:00
f0df1f89be chore(changelog): update
All checks were successful
Code and build check / Check code (push) Successful in 1m34s
Code and build check / Build with uv (push) Successful in 53s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-14 20:04:34 +05:00
f25224b668 refactor(cli): remove unused --session flag
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-14 20:00:43 +05:00
0cda47fdfd fix(input_manager): disable fullscreen toggle from keyboard/gamepad in gamescope session
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-14 19:58:05 +05:00
18 changed files with 686 additions and 485 deletions

View File

@@ -17,10 +17,12 @@ jobs:
- name: Install required dependencies - name: Install required dependencies
run: | run: |
sudo apt update sudo apt update
sudo apt install -y binutils coreutils desktop-file-utils gtk-update-icon-cache fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-dev python3-setuptools squashfs-tools strace util-linux zsync sudo apt install -y binutils coreutils desktop-file-utils gtk-update-icon-cache fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-dev python3-setuptools squashfs-tools strace util-linux zsync git
- name: Install tools - name: Install tools
run: pip3 install appimage-builder uv run: |
pip3 install git+https://github.com/Frederic98/appimage-builder.git
pip3 install uv
- name: Build AppImage - name: Build AppImage
run: | run: |

View File

@@ -8,7 +8,7 @@ on:
env: env:
# Common version, will be used for tagging the release # Common version, will be used for tagging the release
VERSION: 0.1.3 VERSION: 0.1.4
PKGDEST: "/tmp/portprotonqt" PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt" PACKAGE: "portprotonqt"
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
@@ -23,10 +23,12 @@ jobs:
- name: Install required dependencies - name: Install required dependencies
run: | run: |
sudo apt update sudo apt update
sudo apt install -y binutils coreutils desktop-file-utils gtk-update-icon-cache fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-dev python3-setuptools squashfs-tools strace util-linux zsync sudo apt install -y binutils coreutils desktop-file-utils gtk-update-icon-cache fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-dev python3-setuptools squashfs-tools strace util-linux zsync git
- name: Install tools - name: Install tools
run: pip3 install appimage-builder uv run: |
pip3 install git+https://github.com/Frederic98/appimage-builder.git
pip3 install uv
- name: Build AppImage - name: Build AppImage
run: | run: |

View File

@@ -0,0 +1,187 @@
name: Build Check - AppImage, Arch, Fedora
on:
workflow_dispatch:
pull_request:
paths:
- 'build-aux/**'
env:
PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt"
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@v4
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/AppImageBuilder.yml" 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'
steps:
- uses: https://gitea.com/actions/checkout@v4
- name: Install required dependencies
run: |
sudo apt update
sudo apt install -y binutils coreutils desktop-file-utils gtk-update-icon-cache fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-dev python3-setuptools squashfs-tools strace util-linux zsync git
- name: Install tools
run: |
pip3 install git+https://github.com/Frederic98/appimage-builder.git
pip3 install uv
- name: Build AppImage
run: |
cd build-aux
appimage-builder
- name: Upload AppImage
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-AppImage
path: build-aux/PortProtonQt*.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: [41, 42, rawhide]
container:
image: fedora:${{ matrix.fedora_version }}
options: --privileged
steps:
- name: Install build dependencies
run: |
dnf install -y git rpmdevtools python3-devel python3-wheel python3-pip \
python3-build pyproject-rpm-macros python3-setuptools \
redhat-rpm-config nodejs npm
- 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@v4
- name: Copy fedora-git.spec
run: |
cp 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
volumes:
- /usr:/usr-host
- /opt:/opt-host
options: --privileged
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: Build
run: |
cd /__w/portproton-repo
git clone https://git.linux-gaming.ru/Boria138/PortProtonQt.git
cd /__w/portproton-repo/PortProtonQt/build-aux
chown user -R ..
su user -c "yes '' | makepkg --noconfirm -s -p PKGBUILD-git"
- name: Checkout
uses: https://gitea.com/actions/checkout@v4
- name: Upload Arch package
uses: https://gitea.com/actions/gitea-upload-artifact@v4
with:
name: PortProtonQt-Arch
path: ${{ env.PKGDEST }}/*

View File

@@ -1,4 +1,4 @@
name: Code and build check name: Code check
on: on:
pull_request: pull_request:
@@ -35,20 +35,3 @@ jobs:
run: | run: |
source .venv/bin/activate source .venv/bin/activate
pre-commit run --show-diff-on-failure --color=always --all-files pre-commit run --show-diff-on-failure --color=always --all-files
build-uv:
name: Build with uv
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/actions/checkout@v4
- name: Install uv
uses: https://github.com/astral-sh/setup-uv@v6
with:
enable-cache: true
- name: Sync dependencies
run: uv sync
- name: Build project
run: uv build

View File

@@ -3,7 +3,7 @@
Все заметные изменения в этом проекте фиксируются в этом файле. Все заметные изменения в этом проекте фиксируются в этом файле.
Формат основан на [Keep a Changelog](https://keepachangelog.com/) и придерживается принципов [Semantic Versioning](https://semver.org/). Формат основан на [Keep a Changelog](https://keepachangelog.com/) и придерживается принципов [Semantic Versioning](https://semver.org/).
## [Unreleased] ## [0.1.4] - 2025-07-21
### Added ### Added
- Переводы в переопределениях (за подробностями в документацию) - Переводы в переопределениях (за подробностями в документацию)
@@ -15,10 +15,15 @@
- Оптимизированны обложки автоинсталлов - Оптимизированны обложки автоинсталлов
- Папка custom_data исключена из сборки модуля для уменьшение его размера - Папка custom_data исключена из сборки модуля для уменьшение его размера
- Бейдж PortProton теперь открывает PortProtonDB - Бейдж PortProton теперь открывает PortProtonDB
- Отключено переключение полноэкранного режима через F11 или кнопку Select на геймпаде в gamescope сессии
- Удалён аргумент `--session` так как тестирование gamescope сессии завершено
- В контекстном меню игр без exe файла теперь отображается только пункт "Удалить из PortProton"
### Fixed ### Fixed
- Запрос к GitHub API при загрузке legendary теперь не игнорирует настройки прокси - Запрос к GitHub API при загрузке legendary теперь не игнорирует настройки прокси
- Путь к portprotonqt-session-select в оверлее - Путь к portprotonqt-session-select в оверлее
- Работа exiftool в AppImage
- Открытие контекстного меню у игр без exe
### Contributors ### Contributors
- @Vector_null - @Vector_null

View File

@@ -51,11 +51,11 @@ pre-commit run --all-files
PortProtonQt использует код и зависимости от следующих проектов: PortProtonQt использует код и зависимости от следующих проектов:
- [Legendary](https://github.com/derrod/legendary) — инструмент для работы с Epic Games Store, лицензия [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.html). - [Legendary](https://github.com/derrod/legendary) — инструмент для работы с Epic Games Store, лицензия [GPL-3.0](https://github.com/derrod/legendary/blob/master/LICENSE).
- [Icoextract](https://github.com/jlu5/icoextract) — библиотека для извлечения иконок, лицензия [MIT](https://opensource.org/licenses/MIT). - [Icoextract](https://github.com/jlu5/icoextract) — библиотека для извлечения иконок, лицензия [MIT](https://github.com/jlu5/icoextract/blob/master/LICENSE).
- [PortProton 2.0](https://git.linux-gaming.ru/CastroFidel/PortProton_2.0) — библиотека для взаимодействия с PortProton, лицензия [MIT](https://opensource.org/licenses/MIT). - [HowLongToBeat Python API](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI) — библиотека для взаимодействия с HowLongToBeat, лицензия [MIT](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/LICENSE.md).
Полный текст лицензий см. в файлах [LICENSE](LICENSE), [LICENSE-icoextract](documentation/licenses/icoextract), [LICENSE-portproton](documentation/licenses/portproton), [LICENSE-legendary](documentation/licenses/legendary). Полный текст лицензий см. в файле [LICENSE](LICENSE).
> [!WARNING] > [!WARNING]
> Проект находится на стадии WIP (work in progress) корректная работоспособность не гарантирована > Проект находится на стадии WIP (work in progress) корректная работоспособность не гарантирована

View File

@@ -17,7 +17,6 @@
- [ ] Убрать логи Steam API в релизной версии, так как они замедляют выполнение кода - [ ] Убрать логи Steam API в релизной версии, так как они замедляют выполнение кода
- [X] Решить проблему с ограничением Steam API в 50 тысяч игр за один запрос (иногда нужные игры не попадают в выборку и остаются без обложки) - [X] Решить проблему с ограничением Steam API в 50 тысяч игр за один запрос (иногда нужные игры не попадают в выборку и остаются без обложки)
- [X] Избавиться от вызовов yad - [X] Избавиться от вызовов yad
- [ ] Реализовать собственный механизм запрета ухода в спящий режим вместо использования механизма PortProton
- [X] Реализовать собственный системный трей вместо использования трея PortProton - [X] Реализовать собственный системный трей вместо использования трея PortProton
- [X] Добавить экранную клавиатуру в поиск (реализация собственной клавиатуры слишком затратна, поэтому используется встроенная в DE клавиатура: Maliit в KDE, gjs-osk в GNOME, Squeekboard в Phosh, клавиатура SteamOS и т.д.) - [X] Добавить экранную клавиатуру в поиск (реализация собственной клавиатуры слишком затратна, поэтому используется встроенная в DE клавиатура: Maliit в KDE, gjs-osk в GNOME, Squeekboard в Phosh, клавиатура SteamOS и т.д.)
- [X] Добавить сортировку карточек по различным критериям (доступны: по недавности, количеству наигранного времени, избранному или алфавиту) - [X] Добавить сортировку карточек по различным критериям (доступны: по недавности, количеству наигранного времени, избранному или алфавиту)
@@ -42,7 +41,7 @@
- [X] Получать slug через GraphQL [запрос](https://launcher.store.epicgames.com/graphql) - [X] Получать slug через GraphQL [запрос](https://launcher.store.epicgames.com/graphql)
- [X] Добавить на карточку бейдж, указывающий, что игра из Steam - [X] Добавить на карточку бейдж, указывающий, что игра из Steam
- [X] Добавить поддержку версий Steam для Flatpak и Snap - [X] Добавить поддержку версий Steam для Flatpak и Snap
- [ ] Реализовать добавлление игры как сторонней в Steam без - [ ] Реализовать добавление игры как сторонней в Steam без перезапуска
- [X] Отображать данные о самом последнем пользователе Steam, а не первом попавшемся - [X] Отображать данные о самом последнем пользователе Steam, а не первом попавшемся
- [X] Исправить склонения в детальном выводе времени, например, не «3 часов назад», а «3 часа назад» - [X] Исправить склонения в детальном выводе времени, например, не «3 часов назад», а «3 часа назад»
- [X] Добавить перевод через gettext [Документация](documentation/localization_guide) - [X] Добавить перевод через gettext [Документация](documentation/localization_guide)
@@ -65,6 +64,5 @@
- [X] Скопировать логику управления с D-pad на стрелки с клавиатуры - [X] Скопировать логику управления с D-pad на стрелки с клавиатуры
- [ ] Доделать светлую тему - [ ] Доделать светлую тему
- [ ] Добавить подсказки к управлению с геймпада - [ ] Добавить подсказки к управлению с геймпада
- [ ] Добавить загрузку звуков в темы например для добавления звука запуска в тему и тд
- [X] Добавить миниатюры к выбору файлов в диалоге добавления игры - [X] Добавить миниатюры к выбору файлов в диалоге добавления игры
- [X] Добавить быстрый доступ к смонтированным дискам к выбору файлов в диалоге добавления игры - [X] Добавить быстрый доступ к смонтированным дискам к выбору файлов в диалоге добавления игры

View File

@@ -1,5 +1,4 @@
version: 1 version: 1
script: script:
# 1) чистим старый AppDir # 1) чистим старый AppDir
- rm -rf AppDir || true - rm -rf AppDir || true
@@ -17,26 +16,45 @@ script:
- rm -f AppDir/usr/local/lib/python3.10/dist-packages/PySide6/{Qt3D*,QtBluetooth*,QtCharts*,QtConcurrent*,QtDataVisualization*,QtDesigner*,QtHelp*,QtMultimedia*,QtNetwork*,QtOpenGL*,QtPositioning*,QtPrintSupport*,QtQml*,QtQuick*,QtRemoteObjects*,QtScxml*,QtSensors*,QtSerialPort*,QtSql*,QtStateMachine*,QtTest*,QtWeb*,QtXml*} - rm -f AppDir/usr/local/lib/python3.10/dist-packages/PySide6/{Qt3D*,QtBluetooth*,QtCharts*,QtConcurrent*,QtDataVisualization*,QtDesigner*,QtHelp*,QtMultimedia*,QtNetwork*,QtOpenGL*,QtPositioning*,QtPrintSupport*,QtQml*,QtQuick*,QtRemoteObjects*,QtScxml*,QtSensors*,QtSerialPort*,QtSql*,QtStateMachine*,QtTest*,QtWeb*,QtXml*}
- shopt -s extglob - shopt -s extglob
- rm -rf AppDir/usr/local/lib/python3.10/dist-packages/PySide6/Qt/lib/!(libQt6Core*|libQt6Gui*|libQt6Widgets*|libQt6OpenGL*|libQt6XcbQpa*|libQt6Wayland*|libQt6Egl*|libicudata*|libicuuc*|libicui18n*|libQt6DBus*|libQt6Svg*|libQt6Qml*|libQt6Network*) - rm -rf AppDir/usr/local/lib/python3.10/dist-packages/PySide6/Qt/lib/!(libQt6Core*|libQt6Gui*|libQt6Widgets*|libQt6OpenGL*|libQt6XcbQpa*|libQt6Wayland*|libQt6Egl*|libicudata*|libicuuc*|libicui18n*|libQt6DBus*|libQt6Svg*|libQt6Qml*|libQt6Network*)
AppDir: AppDir:
path: ./AppDir path: ./AppDir
after_bundle:
# Документация, справка, примеры
- rm -rf $TARGET_APPDIR/usr/share/man || true
- rm -rf $TARGET_APPDIR/usr/share/doc || true
- rm -rf $TARGET_APPDIR/usr/share/doc-base || true
- rm -rf $TARGET_APPDIR/usr/share/info || true
- rm -rf $TARGET_APPDIR/usr/share/help || true
- rm -rf $TARGET_APPDIR/usr/share/gtk-doc || true
- rm -rf $TARGET_APPDIR/usr/share/devhelp || true
- rm -rf $TARGET_APPDIR/usr/share/examples || true
- rm -rf $TARGET_APPDIR/usr/share/pkgconfig || true
- rm -rf $TARGET_APPDIR/usr/share/bash-completion || true
- rm -rf $TARGET_APPDIR/usr/share/pixmaps || true
- rm -rf $TARGET_APPDIR/usr/share/mime || true
- rm -rf $TARGET_APPDIR/usr/share/metainfo || true
- rm -rf $TARGET_APPDIR/usr/include || true
- rm -rf $TARGET_APPDIR/usr/lib/pkgconfig || true
# Статика и отладка
- find $TARGET_APPDIR -type f \( -name '*.a' -o -name '*.la' -o -name '*.h' -o -name '*.cmake' -o -name '*.pdb' \) -delete || true
# Strip ELF бинарников (исключая Python extensions)
- "find $TARGET_APPDIR -type f -executable -exec file {} \\; | grep ELF | grep -v '/dist-packages/' | grep -v '/site-packages/' | cut -d: -f1 | xargs strip --strip-unneeded || true"
# Удаление пустых папок
- find $TARGET_APPDIR -type d -empty -delete || true
app_info: app_info:
id: ru.linux_gaming.PortProtonQt id: ru.linux_gaming.PortProtonQt
name: PortProtonQt name: PortProtonQt
icon: ru.linux_gaming.PortProtonQt icon: ru.linux_gaming.PortProtonQt
version: 0.1.3 version: 0.1.4
exec: usr/bin/python3 exec: usr/bin/python3
exec_args: "-m portprotonqt.app $@" exec_args: "-m portprotonqt.app $@"
apt: apt:
arch: amd64 arch: amd64
sources: sources:
- sourceline: 'deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse' - sourceline: 'deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c' key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c'
include: include:
- python3 - python3-minimal
- python3-pkg-resources - python3-pkg-resources
- libopengl0 - libopengl0
- libk5crypto3 - libk5crypto3
@@ -45,13 +63,24 @@ AppDir:
- libxcb-cursor0 - libxcb-cursor0
- libimage-exiftool-perl - libimage-exiftool-perl
- xdg-utils - xdg-utils
exclude: [] exclude:
# Документация и man-страницы
- "*-doc"
- "*-man"
- manpages
- mandb
# Статические библиотеки
- "*-dev"
- "*-static"
# Дебаг-символы
- "*-dbg"
- "*-dbgsym"
runtime: runtime:
env: env:
PYTHONHOME: '${APPDIR}/usr' PYTHONHOME: '${APPDIR}/usr'
PYTHONPATH: '${APPDIR}/usr/local/lib/python3.10/dist-packages' PYTHONPATH: '${APPDIR}/usr/local/lib/python3.10/dist-packages'
PERLLIB: '${APPDIR}/usr/share/perl5:${APPDIR}/usr/lib/x86_64-linux-gnu/perl/5.34:${APPDIR}/usr/share/perl/5.34'
AppImage: AppImage:
sign-key: None sign-key: None
comp: xz
arch: x86_64 arch: x86_64

View File

@@ -1,5 +1,5 @@
pkgname=portprotonqt pkgname=portprotonqt
pkgver=0.1.3 pkgver=0.1.4
pkgrel=1 pkgrel=1
pkgdesc="Modern GUI for managing and launching games from PortProton, Steam, and Epic Games Store" pkgdesc="Modern GUI for managing and launching games from PortProton, Steam, and Epic Games Store"
arch=('any') arch=('any')

View File

@@ -1,5 +1,5 @@
%global pypi_name portprotonqt %global pypi_name portprotonqt
%global pypi_version 0.1.3 %global pypi_version 0.1.4
%global oname PortProtonQt %global oname PortProtonQt
%global _python_no_extras_requires 1 %global _python_no_extras_requires 1

View File

@@ -9,7 +9,7 @@ _portprotonqt() {
esac esac
if [[ "$cur" == -* ]]; then if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '--fullscreen --session' -- "$cur" ) ) COMPREPLY=( $( compgen -W '--fullscreen' -- "$cur" ) )
return 0 return 0
fi fi

View File

@@ -1,6 +1,4 @@
import sys import sys
import os
import subprocess
from PySide6.QtCore import QLocale, QTranslator, QLibraryInfo from PySide6.QtCore import QLocale, QTranslator, QLibraryInfo
from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QIcon from PySide6.QtGui import QIcon
@@ -14,7 +12,7 @@ logger = get_logger(__name__)
__app_id__ = "ru.linux_gaming.PortProtonQt" __app_id__ = "ru.linux_gaming.PortProtonQt"
__app_name__ = "PortProtonQt" __app_name__ = "PortProtonQt"
__app_version__ = "0.1.3" __app_version__ = "0.1.4"
def main(): def main():
app = QApplication(sys.argv) app = QApplication(sys.argv)
@@ -35,13 +33,6 @@ def main():
window = MainWindow() window = MainWindow()
if args.session:
gamescope_cmd = os.getenv("GAMESCOPE_CMD", "gamescope -f --xwayland-count 2")
cmd = f"{gamescope_cmd} -- portprotonqt"
logger.info(f"Executing: {cmd}")
subprocess.Popen(cmd, shell=True)
sys.exit(0)
if args.fullscreen: if args.fullscreen:
logger.info("Launching in fullscreen mode due to --fullscreen flag") logger.info("Launching in fullscreen mode due to --fullscreen flag")
save_fullscreen_config(True) save_fullscreen_config(True)

View File

@@ -13,9 +13,4 @@ def parse_args():
action="store_true", action="store_true",
help="Запустить приложение в полноэкранном режиме и сохранить эту настройку" help="Запустить приложение в полноэкранном режиме и сохранить эту настройку"
) )
parser.add_argument(
"--session",
action="store_true",
help="Запустить приложение с использованием gamescope"
)
return parser.parse_args() return parser.parse_args()

View File

@@ -148,10 +148,7 @@ class ContextMenuManager:
return False return False
current_exe = os.path.basename(exe_path) current_exe = os.path.basename(exe_path)
# Check if the current_exe matches the target_exe in MainWindow return hasattr(self.parent, 'target_exe') and self.parent.target_exe == current_exe
if hasattr(self.parent, 'target_exe') and self.parent.target_exe == current_exe:
return True
return False
def show_context_menu(self, game_card, pos: QPoint): def show_context_menu(self, game_card, pos: QPoint):
""" """
@@ -161,7 +158,6 @@ class ContextMenuManager:
game_card: The GameCard instance requesting the context menu. game_card: The GameCard instance requesting the context menu.
pos: The position (in widget coordinates) where the menu should appear. pos: The position (in widget coordinates) where the menu should appear.
""" """
def get_safe_icon(icon_name: str) -> QIcon: def get_safe_icon(icon_name: str) -> QIcon:
icon = self.theme_manager.get_icon(icon_name) icon = self.theme_manager.get_icon(icon_name)
if isinstance(icon, QIcon): if isinstance(icon, QIcon):
@@ -173,7 +169,18 @@ class ContextMenuManager:
menu = QMenu(self.parent) menu = QMenu(self.parent)
menu.setStyleSheet(self.theme.CONTEXT_MENU_STYLE) menu.setStyleSheet(self.theme.CONTEXT_MENU_STYLE)
# Check if the game is running # For non-Steam and non-Epic games, check if exe exists
if game_card.game_source not in ("steam", "epic"):
exec_line = self._get_exec_line(game_card.name, game_card.exec_line)
exe_path = self._parse_exe_path(exec_line, game_card.name) if exec_line else None
if not exe_path:
# Show only "Delete from PortProton" if no valid exe
delete_action = menu.addAction(get_safe_icon("delete"), _("Delete from PortProton"))
delete_action.triggered.connect(lambda: self.delete_game(game_card.name, game_card.exec_line))
menu.exec(game_card.mapToGlobal(pos))
return
# Normal menu for games with valid exe or from Steam/Epic
is_running = self._is_game_running(game_card) is_running = self._is_game_running(game_card)
action_text = _("Stop Game") if is_running else _("Launch Game") action_text = _("Stop Game") if is_running else _("Launch Game")
action_icon = "stop" if is_running else "play" action_icon = "stop" if is_running else "play"
@@ -697,15 +704,12 @@ Icon={icon_path}
return None return None
return exec_line return exec_line
def _parse_exe_path(self, exec_line, game_name): def _parse_exe_path(self, exec_line: str, game_name: str) -> str | None:
"""Parse the executable path from exec_line.""" """Parse the executable path from exec_line."""
try: try:
entry_exec_split = shlex.split(exec_line) entry_exec_split = shlex.split(exec_line)
if not entry_exec_split: if not entry_exec_split:
self.signals.show_warning_dialog.emit( logger.debug("Invalid executable command for '%s': %s", game_name, exec_line)
_("Error"),
_("Invalid executable command: {exec_line}").format(exec_line=exec_line)
)
return None return None
if entry_exec_split[0] == "env" and len(entry_exec_split) >= 3: if entry_exec_split[0] == "env" and len(entry_exec_split) >= 3:
exe_path = entry_exec_split[2] exe_path = entry_exec_split[2]
@@ -714,17 +718,11 @@ Icon={icon_path}
else: else:
exe_path = entry_exec_split[-1] exe_path = entry_exec_split[-1]
if not exe_path or not os.path.exists(exe_path): if not exe_path or not os.path.exists(exe_path):
self.signals.show_warning_dialog.emit( logger.debug("Executable not found for '%s': %s", game_name, exe_path or "None")
_("Error"),
_("Executable not found: {path}").format(path=exe_path or "None")
)
return None return None
return exe_path return exe_path
except Exception as e: except Exception as e:
self.signals.show_warning_dialog.emit( logger.debug("Failed to parse executable for '%s': %s", game_name, e)
_("Error"),
_("Failed to parse executable: {error}").format(error=str(e))
)
return None return None
def _remove_file(self, file_path, error_message, success_message, game_name, location=""): def _remove_file(self, file_path, error_message, success_message, game_name, location=""):

View File

@@ -111,6 +111,8 @@ class InputManager(QObject):
self.stick_value = 0 # Текущее значение стика (для плавности) self.stick_value = 0 # Текущее значение стика (для плавности)
self.dead_zone = 8000 # Мертвая зона стика self.dead_zone = 8000 # Мертвая зона стика
self._is_gamescope_session = 'gamescope' in os.environ.get('DESKTOP_SESSION', '').lower()
# Add variables for continuous D-pad movement # Add variables for continuous D-pad movement
self.dpad_timer = QTimer(self) self.dpad_timer = QTimer(self)
self.dpad_timer.timeout.connect(self.handle_dpad_repeat) self.dpad_timer.timeout.connect(self.handle_dpad_repeat)
@@ -849,7 +851,7 @@ class InputManager(QObject):
return True return True
# Toggle fullscreen with F11 # Toggle fullscreen with F11
if key == Qt.Key.Key_F11: if key == Qt.Key.Key_F11 and not self._is_gamescope_session:
self.toggle_fullscreen.emit(not self._is_fullscreen) self.toggle_fullscreen.emit(not self._is_fullscreen)
return True return True
@@ -946,7 +948,7 @@ class InputManager(QObject):
continue continue
now = time.time() now = time.time()
if event.type == ecodes.EV_KEY and event.value == 1: if event.type == ecodes.EV_KEY and event.value == 1:
if event.code in BUTTONS['menu']: if event.code in BUTTONS['menu'] and not self._is_gamescope_session:
self.toggle_fullscreen.emit(not self._is_fullscreen) self.toggle_fullscreen.emit(not self._is_fullscreen)
else: else:
self.button_pressed.emit(event.code) self.button_pressed.emit(event.code)

View File

@@ -1518,6 +1518,8 @@ class MainWindow(QMainWindow):
self._animations = {} self._animations = {}
imageLabel = QLabel() imageLabel = QLabel()
imageLabel.setFixedSize(300, 400) imageLabel.setFixedSize(300, 400)
self._detail_page_active = True
self._current_detail_page = detailPage
if cover_path: if cover_path:
def on_pixmap_ready(pixmap): def on_pixmap_ready(pixmap):
@@ -1768,6 +1770,11 @@ class MainWindow(QMainWindow):
# Время прохождения (Main Story, Main + Sides, Completionist) # Время прохождения (Main Story, Main + Sides, Completionist)
def on_hltb_results(results): def on_hltb_results(results):
if not hasattr(self, '_detail_page_active') or not self._detail_page_active:
return
if not self._current_detail_page or self._current_detail_page.isHidden() or not self._current_detail_page.parent():
return
if results: if results:
game = results[0] # Берем первый результат game = results[0] # Берем первый результат
main_story_time = hltb.format_game_time(game, "main_story") main_story_time = hltb.format_game_time(game, "main_story")
@@ -1941,6 +1948,8 @@ class MainWindow(QMainWindow):
def goBackDetailPage(self, page: QWidget | None) -> None: def goBackDetailPage(self, page: QWidget | None) -> None:
if page is None or page != self.stackedWidget.currentWidget(): if page is None or page != self.stackedWidget.currentWidget():
return return
self._detail_page_active = False
self._current_detail_page = None
self.stackedWidget.setCurrentIndex(0) self.stackedWidget.setCurrentIndex(0)
self.stackedWidget.removeWidget(page) self.stackedWidget.removeWidget(page)
page.deleteLater() page.deleteLater()

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "portprotonqt" name = "portprotonqt"
version = "0.1.3" version = "0.1.4"
description = "A project to rewrite PortProton (PortWINE) using PySide" description = "A project to rewrite PortProton (PortWINE) using PySide"
readme = "README.md" readme = "README.md"
license = { text = "GPL-3.0" } license = { text = "GPL-3.0" }

808
uv.lock generated

File diff suppressed because it is too large Load Diff