forked from Boria138/PortProtonQt
Compare commits
22 Commits
593db00166
...
d0eea92139
Author | SHA1 | Date | |
---|---|---|---|
d0eea92139
|
|||
04726491c0
|
|||
bd1b7c07ae
|
|||
e6161d2e3f
|
|||
b82080600f
|
|||
05693514aa
|
|||
1c2835a933
|
|||
d229914fb6
|
|||
ce69a18249
|
|||
4d58830910 | |||
016ba537be
|
|||
6eeb93f6ba
|
|||
3f5d058740
|
|||
1a9228b76d
|
|||
e9e0bea854
|
|||
f7d9f5c150
|
|||
bcb5987d31
|
|||
b1aa987e4e
|
|||
f4c8b70bd0
|
|||
ff960df77c
|
|||
a57f509295
|
|||
32bbe89911
|
13
CHANGELOG.md
13
CHANGELOG.md
@@ -6,13 +6,17 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Аргумент `--session` для запуска приложения в gamescope с GAMESCOPE_CMD
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Удалены сборки для Fedora 40
|
- Удалены сборки для Fedora 40
|
||||||
- Перенесены параметры анимации GameCard в `styles.py` с подробной документацией для поддержки кастомизации тем.
|
- Перенесены параметры анимации GameCard в `styles.py` с подробной документацией для поддержки кастомизации тем.
|
||||||
|
- Статус выделения и наведения на карточки теперь взаимоисключают друг друга
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Дублирование обводки выделения карточек при быстром перемешении мыши
|
- Дублирование обводки выделения карточек при быстром перемешении мыши
|
||||||
|
- Завершение приложения при закритие окна
|
||||||
|
- Использование системной палитры в темах
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -77,6 +81,10 @@
|
|||||||
- Корректная обработка событий геймпада во время игры
|
- Корректная обработка событий геймпада во время игры
|
||||||
- Убийсво всех процессов "зомби" при закрытии программы
|
- Убийсво всех процессов "зомби" при закрытии программы
|
||||||
|
|
||||||
|
### Contributors
|
||||||
|
- @Vector_null
|
||||||
|
- @Dervart
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [0.1.1] – 2025-05-17
|
## [0.1.1] – 2025-05-17
|
||||||
@@ -97,6 +105,11 @@
|
|||||||
- Зависание GUI
|
- Зависание GUI
|
||||||
- Сбой при повреждённом Steam
|
- Сбой при повреждённом Steam
|
||||||
|
|
||||||
|
### Contributors
|
||||||
|
- @Vector_null
|
||||||
|
- @Dervart
|
||||||
|
- @alex2844
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
> См. подробности по каждому коммиту в истории репозитория.
|
> См. подробности по каждому коммиту в истории репозитория.
|
||||||
|
10
README.md
10
README.md
@@ -4,7 +4,6 @@
|
|||||||
<p align="center">Удобный графический интерфейс для управления и запуска игр из PortProton, Steam и Epic Games Store. Оно объединяет библиотеки игр в единый центр для лёгкой навигации и организации. Лёгкая структура и кроссплатформенная поддержка обеспечивают цельный игровой опыт без необходимости использования нескольких лаунчеров. Интеграция с PortProton упрощает запуск Windows-игр на Linux с минимальной настройкой.</p>
|
<p align="center">Удобный графический интерфейс для управления и запуска игр из PortProton, Steam и Epic Games Store. Оно объединяет библиотеки игр в единый центр для лёгкой навигации и организации. Лёгкая структура и кроссплатформенная поддержка обеспечивают цельный игровой опыт без необходимости использования нескольких лаунчеров. Интеграция с PortProton упрощает запуск Windows-игр на Linux с минимальной настройкой.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## В планах
|
## В планах
|
||||||
|
|
||||||
- [X] Адаптировать структуру проекта для поддержки инструментов сборки
|
- [X] Адаптировать структуру проекта для поддержки инструментов сборки
|
||||||
@@ -15,7 +14,8 @@
|
|||||||
- [X] Вынести все константы, такие как уровень закругления карточек, в темы (частично выполнено)
|
- [X] Вынести все константы, такие как уровень закругления карточек, в темы (частично выполнено)
|
||||||
- [X] Добавить метаданные для тем (скриншоты, описание, домашняя страница и автор)
|
- [X] Добавить метаданные для тем (скриншоты, описание, домашняя страница и автор)
|
||||||
- [ ] Продумать систему вкладок вместо текущей
|
- [ ] Продумать систему вкладок вместо текущей
|
||||||
- [X] [Добавить сессию Gamescope, аналогичную той, что используется в SteamOS](https://git.linux-gaming.ru/Boria138/gamescope-session-portprotonqt)
|
- [ ] [Добавить сессию Gamescope, аналогичную той, что используется в SteamOS](https://git.linux-gaming.ru/Boria138/gamescope-session-portprotonqt)
|
||||||
|
- [ ] Разобраться почему теряется часть стилей в Gamescope
|
||||||
- [ ] Разработать адаптивный дизайн (за эталон берётся Steam Deck с разрешением 1280×800)
|
- [ ] Разработать адаптивный дизайн (за эталон берётся Steam Deck с разрешением 1280×800)
|
||||||
- [ ] Переделать скриншоты для соответствия [гайдлайнам Flathub](https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines/quality-guidelines#screenshots)
|
- [ ] Переделать скриншоты для соответствия [гайдлайнам Flathub](https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines/quality-guidelines#screenshots)
|
||||||
- [X] Получать описания и названия игр из базы данных Steam
|
- [X] Получать описания и названия игр из базы данных Steam
|
||||||
@@ -41,7 +41,10 @@
|
|||||||
- [X] Добавить парсинг ярлыков из Steam
|
- [X] Добавить парсинг ярлыков из Steam
|
||||||
- [X] Добавить парсинг ярлыков из EGS (скрыто для переработки)
|
- [X] Добавить парсинг ярлыков из EGS (скрыто для переработки)
|
||||||
- [ ] Избавиться от бинарника legendary
|
- [ ] Избавиться от бинарника legendary
|
||||||
- [ ] Добавить запуск и скачивание игр из EGS
|
- [X] Добавить запуск игр из EGS
|
||||||
|
- [ ] Добавить скачивание игр из EGS
|
||||||
|
- [ ] Добавить поддержку запуска сторонних игр из EGS
|
||||||
|
- [ ] Добавить поддержку запуска игр с EOS
|
||||||
- [ ] Добавить авторизацию в EGS через WebView вместо ручного ввода
|
- [ ] Добавить авторизацию в EGS через WebView вместо ручного ввода
|
||||||
- [X] Получать описания для игр из EGS через их [API](https://store-content.ak.epicgames.com/api)
|
- [X] Получать описания для игр из EGS через их [API](https://store-content.ak.epicgames.com/api)
|
||||||
- [X] Получать slug через GraphQL [запрос](https://launcher.store.epicgames.com/graphql)
|
- [X] Получать slug через GraphQL [запрос](https://launcher.store.epicgames.com/graphql)
|
||||||
@@ -68,6 +71,7 @@
|
|||||||
- [X] Скопировать логику управления с D-pad на стрелки с клавиатуры
|
- [X] Скопировать логику управления с D-pad на стрелки с клавиатуры
|
||||||
- [ ] Доделать светлую тему
|
- [ ] Доделать светлую тему
|
||||||
- [ ] Добавить подсказки к управлению с геймпада
|
- [ ] Добавить подсказки к управлению с геймпада
|
||||||
|
- [ ] Добавить загрузку звуков в темы например для добавления звука запуска в тему и тд
|
||||||
|
|
||||||
### Установка (devel)
|
### Установка (devel)
|
||||||
|
|
||||||
|
8
config.js
Normal file
8
config.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
"endpoint": "https://git.linux-gaming.ru/api/v1",
|
||||||
|
"gitAuthor": "Renovate Bot <noreply@linux-gaming.ru>",
|
||||||
|
"platform": "gitea",
|
||||||
|
"onboardingConfigFileName": "renovate.json",
|
||||||
|
"autodiscover": true,
|
||||||
|
"optimizeForDisabled": true,
|
||||||
|
};
|
@@ -1,4 +1,6 @@
|
|||||||
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
|
||||||
@@ -33,6 +35,13 @@ 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)
|
||||||
|
@@ -13,4 +13,9 @@ 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()
|
||||||
|
@@ -26,6 +26,7 @@ class GameCard(QFrame):
|
|||||||
removeFromSteamRequested = Signal(str, str) # name, exec_line
|
removeFromSteamRequested = Signal(str, str) # name, exec_line
|
||||||
openGameFolderRequested = Signal(str, str) # name, exec_line
|
openGameFolderRequested = Signal(str, str) # name, exec_line
|
||||||
hoverChanged = Signal(str, bool)
|
hoverChanged = Signal(str, bool)
|
||||||
|
focusChanged = Signal(str, bool)
|
||||||
|
|
||||||
def __init__(self, name, description, cover_path, appid, controller_support, exec_line,
|
def __init__(self, name, description, cover_path, appid, controller_support, exec_line,
|
||||||
last_launch, formatted_playtime, protondb_tier, anticheat_status, last_launch_ts, playtime_seconds, game_source,
|
last_launch, formatted_playtime, protondb_tier, anticheat_status, last_launch_ts, playtime_seconds, game_source,
|
||||||
@@ -476,6 +477,8 @@ class GameCard(QFrame):
|
|||||||
def enterEvent(self, event):
|
def enterEvent(self, event):
|
||||||
self._hovered = True
|
self._hovered = True
|
||||||
self.hoverChanged.emit(self.name, True)
|
self.hoverChanged.emit(self.name, True)
|
||||||
|
self.setFocus(Qt.FocusReason.MouseFocusReason)
|
||||||
|
|
||||||
self.thickness_anim.stop()
|
self.thickness_anim.stop()
|
||||||
if self._isPulseAnimationConnected:
|
if self._isPulseAnimationConnected:
|
||||||
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
||||||
@@ -520,42 +523,47 @@ class GameCard(QFrame):
|
|||||||
super().leaveEvent(event)
|
super().leaveEvent(event)
|
||||||
|
|
||||||
def focusInEvent(self, event):
|
def focusInEvent(self, event):
|
||||||
self._focused = True
|
if not self._hovered:
|
||||||
self.thickness_anim.stop()
|
self._focused = True
|
||||||
if self._isPulseAnimationConnected:
|
self.focusChanged.emit(self.name, True)
|
||||||
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
|
||||||
self._isPulseAnimationConnected = False
|
|
||||||
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve"]]))
|
|
||||||
self.thickness_anim.setStartValue(self._borderWidth)
|
|
||||||
self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["focus_border_width"])
|
|
||||||
self.thickness_anim.finished.connect(self.startPulseAnimation)
|
|
||||||
self._isPulseAnimationConnected = True
|
|
||||||
self.thickness_anim.start()
|
|
||||||
|
|
||||||
if self.gradient_anim:
|
self.thickness_anim.stop()
|
||||||
self.gradient_anim.stop()
|
if self._isPulseAnimationConnected:
|
||||||
self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle"))
|
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
||||||
self.gradient_anim.setDuration(self.theme.GAME_CARD_ANIMATION["gradient_anim_duration"])
|
self._isPulseAnimationConnected = False
|
||||||
self.gradient_anim.setStartValue(self.theme.GAME_CARD_ANIMATION["gradient_start_angle"])
|
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve"]]))
|
||||||
self.gradient_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["gradient_end_angle"])
|
self.thickness_anim.setStartValue(self._borderWidth)
|
||||||
self.gradient_anim.setLoopCount(-1)
|
self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["focus_border_width"])
|
||||||
self.gradient_anim.start()
|
self.thickness_anim.finished.connect(self.startPulseAnimation)
|
||||||
|
self._isPulseAnimationConnected = True
|
||||||
|
self.thickness_anim.start()
|
||||||
|
|
||||||
|
if self.gradient_anim:
|
||||||
|
self.gradient_anim.stop()
|
||||||
|
self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle"))
|
||||||
|
self.gradient_anim.setDuration(self.theme.GAME_CARD_ANIMATION["gradient_anim_duration"])
|
||||||
|
self.gradient_anim.setStartValue(self.theme.GAME_CARD_ANIMATION["gradient_start_angle"])
|
||||||
|
self.gradient_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["gradient_end_angle"])
|
||||||
|
self.gradient_anim.setLoopCount(-1)
|
||||||
|
self.gradient_anim.start()
|
||||||
|
|
||||||
super().focusInEvent(event)
|
super().focusInEvent(event)
|
||||||
|
|
||||||
def focusOutEvent(self, event):
|
def focusOutEvent(self, event):
|
||||||
self._focused = False
|
self._focused = False
|
||||||
if not self._hovered: # Сохраняем анимацию, если есть наведение
|
self.focusChanged.emit(self.name, False)
|
||||||
|
if not self._hovered:
|
||||||
if self.gradient_anim:
|
if self.gradient_anim:
|
||||||
self.gradient_anim.stop()
|
self.gradient_anim.stop()
|
||||||
self.gradient_anim = None
|
self.gradient_anim = None
|
||||||
self.thickness_anim.stop()
|
|
||||||
if self._isPulseAnimationConnected:
|
|
||||||
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
|
||||||
self._isPulseAnimationConnected = False
|
|
||||||
if self.pulse_anim:
|
if self.pulse_anim:
|
||||||
self.pulse_anim.stop()
|
self.pulse_anim.stop()
|
||||||
self.pulse_anim = None
|
self.pulse_anim = None
|
||||||
|
if self.thickness_anim:
|
||||||
|
self.thickness_anim.stop()
|
||||||
|
if self._isPulseAnimationConnected:
|
||||||
|
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
|
||||||
|
self._isPulseAnimationConnected = False
|
||||||
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve_out"]]))
|
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve_out"]]))
|
||||||
self.thickness_anim.setStartValue(self._borderWidth)
|
self.thickness_anim.setStartValue(self._borderWidth)
|
||||||
self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["default_border_width"])
|
self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["default_border_width"])
|
||||||
|
@@ -52,10 +52,12 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
QApplication.setStyle("Fusion")
|
||||||
self.setAcceptDrops(True)
|
self.setAcceptDrops(True)
|
||||||
self.current_exec_line = None
|
self.current_exec_line = None
|
||||||
self.currentDetailPage = None
|
self.currentDetailPage = None
|
||||||
self.current_play_button = None
|
self.current_play_button = None
|
||||||
|
self.current_focused_card = None
|
||||||
self.pending_games = []
|
self.pending_games = []
|
||||||
self.game_card_cache = {}
|
self.game_card_cache = {}
|
||||||
self.pending_images = {}
|
self.pending_images = {}
|
||||||
@@ -242,10 +244,39 @@ class MainWindow(QMainWindow):
|
|||||||
self.updateGameGrid()
|
self.updateGameGrid()
|
||||||
self.progress_bar.setVisible(False)
|
self.progress_bar.setVisible(False)
|
||||||
|
|
||||||
|
def _on_card_focused(self, game_name: str, is_focused: bool):
|
||||||
|
"""Обработчик сигнала focusChanged от GameCard."""
|
||||||
|
card_key = None
|
||||||
|
for key, card in self.game_card_cache.items():
|
||||||
|
if card.name == game_name:
|
||||||
|
card_key = key
|
||||||
|
break
|
||||||
|
|
||||||
|
if not card_key:
|
||||||
|
return
|
||||||
|
|
||||||
|
card = self.game_card_cache[card_key]
|
||||||
|
|
||||||
|
if is_focused:
|
||||||
|
# Если карточка получила фокус
|
||||||
|
if self.current_hovered_card and self.current_hovered_card != card:
|
||||||
|
# Сбрасываем текущую hovered карточку
|
||||||
|
self.current_hovered_card._hovered = False
|
||||||
|
self.current_hovered_card.leaveEvent(None)
|
||||||
|
self.current_hovered_card = None
|
||||||
|
if self.current_focused_card and self.current_focused_card != card:
|
||||||
|
# Сбрасываем текущую focused карточку
|
||||||
|
self.current_focused_card._focused = False
|
||||||
|
self.current_focused_card.clearFocus()
|
||||||
|
self.current_focused_card = card
|
||||||
|
else:
|
||||||
|
# Если карточка потеряла фокус
|
||||||
|
if self.current_focused_card == card:
|
||||||
|
self.current_focused_card = None
|
||||||
|
|
||||||
def _on_card_hovered(self, game_name: str, is_hovered: bool):
|
def _on_card_hovered(self, game_name: str, is_hovered: bool):
|
||||||
"""Обработчик сигнала hoverChanged от GameCard."""
|
"""Обработчик сигнала hoverChanged от GameCard."""
|
||||||
card_key = None
|
card_key = None
|
||||||
# Находим ключ карточки по имени игры
|
|
||||||
for key, card in self.game_card_cache.items():
|
for key, card in self.game_card_cache.items():
|
||||||
if card.name == game_name:
|
if card.name == game_name:
|
||||||
card_key = key
|
card_key = key
|
||||||
@@ -258,10 +289,14 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
if is_hovered:
|
if is_hovered:
|
||||||
# Если мышь наведена на карточку
|
# Если мышь наведена на карточку
|
||||||
|
if self.current_focused_card and self.current_focused_card != card:
|
||||||
|
# Сбрасываем текущую focused карточку
|
||||||
|
self.current_focused_card._focused = False
|
||||||
|
self.current_focused_card.clearFocus()
|
||||||
if self.current_hovered_card and self.current_hovered_card != card:
|
if self.current_hovered_card and self.current_hovered_card != card:
|
||||||
# Сбрасываем предыдущую выделенную карточку
|
# Сбрасываем предыдущую hovered карточку
|
||||||
self.current_hovered_card._hovered = False
|
self.current_hovered_card._hovered = False
|
||||||
self.current_hovered_card.leaveEvent(None) # Принудительно вызываем leaveEvent
|
self.current_hovered_card.leaveEvent(None)
|
||||||
self.current_hovered_card = card
|
self.current_hovered_card = card
|
||||||
else:
|
else:
|
||||||
# Если мышь покинула карточку
|
# Если мышь покинула карточку
|
||||||
@@ -709,6 +744,7 @@ class MainWindow(QMainWindow):
|
|||||||
context_menu_manager=self.context_menu_manager
|
context_menu_manager=self.context_menu_manager
|
||||||
)
|
)
|
||||||
card.hoverChanged.connect(self._on_card_hovered)
|
card.hoverChanged.connect(self._on_card_hovered)
|
||||||
|
card.focusChanged.connect(self._on_card_focused)
|
||||||
# Подключаем сигналы контекстного меню
|
# Подключаем сигналы контекстного меню
|
||||||
card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut)
|
card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut)
|
||||||
card.deleteGameRequested.connect(self.context_menu_manager.delete_game)
|
card.deleteGameRequested.connect(self.context_menu_manager.delete_game)
|
||||||
@@ -1881,7 +1917,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""Завершает все дочерние процессы и сохраняет настройки при закрытии окна."""
|
"""Завершает все дочерние процессы и сохраняет настройки при закрытии окна."""
|
||||||
# Завершаем все игровые процессы
|
|
||||||
for proc in self.game_processes:
|
for proc in self.game_processes:
|
||||||
try:
|
try:
|
||||||
parent = psutil.Process(proc.pid)
|
parent = psutil.Process(proc.pid)
|
||||||
@@ -1922,4 +1957,5 @@ class MainWindow(QMainWindow):
|
|||||||
self.checkProcessTimer.deleteLater()
|
self.checkProcessTimer.deleteLater()
|
||||||
self.checkProcessTimer = None
|
self.checkProcessTimer = None
|
||||||
|
|
||||||
|
QApplication.quit()
|
||||||
event.accept()
|
event.accept()
|
||||||
|
@@ -20,8 +20,12 @@ class SystemOverlay(QDialog):
|
|||||||
self.theme_manager = ThemeManager()
|
self.theme_manager = ThemeManager()
|
||||||
self.setStyleSheet(self.theme.OVERLAY_WINDOW_STYLE)
|
self.setStyleSheet(self.theme.OVERLAY_WINDOW_STYLE)
|
||||||
|
|
||||||
# Убираем рамку окна
|
# Make window stay on top and frameless
|
||||||
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.Dialog)
|
self.setWindowFlags(
|
||||||
|
Qt.WindowType.FramelessWindowHint |
|
||||||
|
Qt.WindowType.Dialog |
|
||||||
|
Qt.WindowType.WindowStaysOnTopHint
|
||||||
|
)
|
||||||
|
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.setContentsMargins(20, 20, 20, 20)
|
layout.setContentsMargins(20, 20, 20, 20)
|
||||||
|
26
renovate.json
Normal file
26
renovate.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": ["config:best-practices"],
|
||||||
|
"rebaseWhen": "never",
|
||||||
|
"lockFileMaintenance": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchUpdateTypes": ["minor", "patch"],
|
||||||
|
"automerge": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"automerge": true,
|
||||||
|
"matchUpdateTypes": ["pin", "pinDigest"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled": false,
|
||||||
|
"matchFileNames": [".gitea/workflows/**.yaml", ".gitea/workflows/**.yml"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled": false,
|
||||||
|
"matchFileNames": [".python-version"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Reference in New Issue
Block a user