3 Commits

Author SHA1 Message Date
7e9a0be150 fix: restore theme tab after theme change
All checks were successful
Code and build check / Check code (push) Successful in 1m18s
Code and build check / Build with uv (push) Successful in 45s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 07:35:40 +05:00
4e057c204c chore(readme): update todo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 07:21:23 +05:00
b35a1b8dfe fix: prevent game card overlap in all\ display filter
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 07:20:24 +05:00
2 changed files with 50 additions and 27 deletions

View File

@@ -64,7 +64,7 @@
- [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?) - [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?)
- [ ] Добавить виброотдачу на геймпаде при запуске игры (?) - [ ] Добавить виброотдачу на геймпаде при запуске игры (?)
- [ ] Исправить некорректную работу слайдера увеличения размера карточек([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63) - [ ] Исправить некорректную работу слайдера увеличения размера карточек([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63)
- [ ] Исправить баг с наложением карточек друг на друга при изменении фильтра отображения ([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63)) - [X] Исправить баг с наложением карточек друг на друга при изменении фильтра отображения ([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63))
- [ ] Скопировать логику управления с D-pad на стрелки с клавиатуры - [ ] Скопировать логику управления с D-pad на стрелки с клавиатуры
### Установка (devel) ### Установка (devel)

View File

@@ -274,9 +274,10 @@ class MainWindow(QMainWindow):
seen = set() seen = set()
games = [] games = []
for game in portproton_games + steam_games: for game in portproton_games + steam_games:
name = game[0] # Уникальный ключ: имя + exec_line
if name not in seen: key = (game[0], game[4])
seen.add(name) if key not in seen:
seen.add(key)
games.append(game) games.append(game)
self.games_loaded.emit(games) self.games_loaded.emit(games)
self._load_portproton_games_async( self._load_portproton_games_async(
@@ -629,18 +630,19 @@ class MainWindow(QMainWindow):
self.gamesListWidget.updateGeometry() self.gamesListWidget.updateGeometry()
return return
# Создаем словарь текущих игр для быстрого поиска # Создаем словарь текущих игр с уникальным ключом (name + exec_line)
current_games = {game_data[0]: game_data for game_data in games_list} current_games = {(game_data[0], game_data[4]): game_data for game_data in games_list}
# Проверяем, изменился ли список игр или размер карточек # Проверяем, изменился ли список игр или размер карточек
current_game_names = set(current_games.keys()) current_game_keys = set(current_games.keys())
cached_game_names = set(self.game_card_cache.keys()) cached_game_keys = set(self.game_card_cache.keys())
card_width_changed = self.card_width != getattr(self, '_last_card_width', None) card_width_changed = self.card_width != getattr(self, '_last_card_width', None)
if current_game_names == cached_game_names and not card_width_changed: if current_game_keys == cached_game_keys and not card_width_changed:
# Список игр и размер карточек не изменились, обновляем только видимость # Список игр и размер карточек не изменились, обновляем только видимость
search_text = self.searchEdit.text().strip().lower() search_text = self.searchEdit.text().strip().lower()
for game_name, card in self.game_card_cache.items(): for game_key, card in self.game_card_cache.items():
game_name = game_key[0]
card.setVisible(search_text in game_name.lower() or not search_text) card.setVisible(search_text in game_name.lower() or not search_text)
self.loadVisibleImages() self.loadVisibleImages()
return return
@@ -664,10 +666,11 @@ class MainWindow(QMainWindow):
# Добавляем новые карточки и обновляем существующие # Добавляем новые карточки и обновляем существующие
for game_data in games_list: for game_data in games_list:
game_name = game_data[0] game_name = game_data[0]
game_key = (game_name, game_data[4])
search_text = self.searchEdit.text().strip().lower() search_text = self.searchEdit.text().strip().lower()
should_be_visible = search_text in game_name.lower() or not search_text should_be_visible = search_text in game_name.lower() or not search_text
if game_name not in self.game_card_cache: if game_key not in self.game_card_cache:
# Создаем новую карточку # Создаем новую карточку
card = GameCard( card = GameCard(
*game_data, *game_data,
@@ -686,24 +689,26 @@ class MainWindow(QMainWindow):
card.addToSteamRequested.connect(self.context_menu_manager.add_to_steam) card.addToSteamRequested.connect(self.context_menu_manager.add_to_steam)
card.removeFromSteamRequested.connect(self.context_menu_manager.remove_from_steam) card.removeFromSteamRequested.connect(self.context_menu_manager.remove_from_steam)
card.openGameFolderRequested.connect(self.context_menu_manager.open_game_folder) card.openGameFolderRequested.connect(self.context_menu_manager.open_game_folder)
self.game_card_cache[game_name] = card self.game_card_cache[game_key] = card
self.gamesListLayout.addWidget(card) self.gamesListLayout.addWidget(card)
layout_changed = True layout_changed = True
else: else:
# Обновляем видимость существующей карточки # Обновляем видимость существующей карточки
card = self.game_card_cache[game_name] card = self.game_card_cache[game_key]
card.setVisible(should_be_visible) card.setVisible(should_be_visible)
# Сохраняем текущий card_width # Сохраняем текущий card_width
self._last_card_width = self.card_width self._last_card_width = self.card_width
# Принудительно обновляем макет
if layout_changed:
self.gamesListLayout.update()
self.gamesListWidget.updateGeometry()
self.gamesListWidget.update()
# Загружаем изображения для видимых карточек # Загружаем изображения для видимых карточек
self.loadVisibleImages() self.loadVisibleImages()
# Обновляем геометрию только при необходимости
if layout_changed:
self.gamesListWidget.updateGeometry()
def clearLayout(self, layout): def clearLayout(self, layout):
"""Удаляет все виджеты из layout.""" """Удаляет все виджеты из layout."""
while layout.count(): while layout.count():
@@ -1230,9 +1235,13 @@ class MainWindow(QMainWindow):
os.path.join(os.path.expanduser("~"), ".local", "share")) os.path.join(os.path.expanduser("~"), ".local", "share"))
state_file = os.path.join(xdg_data_home, "PortProtonQt", "state.txt") state_file = os.path.join(xdg_data_home, "PortProtonQt", "state.txt")
os.makedirs(os.path.dirname(state_file), exist_ok=True) os.makedirs(os.path.dirname(state_file), exist_ok=True)
try:
with open(state_file, "w", encoding="utf-8") as f: with open(state_file, "w", encoding="utf-8") as f:
f.write("theme_tab\n") f.write("theme_tab\n")
logger.info(f"State saved to {state_file}")
QTimer.singleShot(500, lambda: self.restart_application()) QTimer.singleShot(500, lambda: self.restart_application())
except Exception as e:
logger.error(f"Failed to save state to {state_file}: {e}")
else: else:
self.statusBar().showMessage(_("Error applying theme '{0}'").format(selected_theme), 3000) self.statusBar().showMessage(_("Error applying theme '{0}'").format(selected_theme), 3000)
@@ -1250,14 +1259,28 @@ class MainWindow(QMainWindow):
def restore_state(self): def restore_state(self):
"""Восстанавливает состояние приложения после перезапуска.""" """Восстанавливает состояние приложения после перезапуска."""
xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share"))
state_file = os.path.join(xdg_cache_home, "PortProtonQt", "state.txt") state_file = os.path.join(xdg_data_home, "PortProtonQt", "state.txt")
logger.info(f"Checking for state file: {state_file}")
if os.path.exists(state_file): if os.path.exists(state_file):
try:
with open(state_file, encoding="utf-8") as f: with open(state_file, encoding="utf-8") as f:
state = f.read().strip() state = f.read().strip()
logger.info(f"State file contents: '{state}'")
if state == "theme_tab": if state == "theme_tab":
logger.info("Restoring to theme tab (index 5)")
if self.stackedWidget.count() > 5:
self.switchTab(5) self.switchTab(5)
else:
logger.warning("Theme tab (index 5) not available yet")
else:
logger.warning(f"Unexpected state value: '{state}'")
os.remove(state_file) os.remove(state_file)
logger.info(f"State file {state_file} removed")
except Exception as e:
logger.error(f"Failed to read or process state file {state_file}: {e}")
else:
logger.info(f"State file {state_file} does not exist")
# ЛОГИКА ДЕТАЛЬНОЙ СТРАНИЦЫ ИГРЫ # ЛОГИКА ДЕТАЛЬНОЙ СТРАНИЦЫ ИГРЫ
def getColorPalette_async(self, cover_path, num_colors=5, sample_step=10, callback=None): def getColorPalette_async(self, cover_path, num_colors=5, sample_step=10, callback=None):