fix(autoinstall): fix virtual keyboard open

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-10-12 14:45:52 +05:00
parent 5442100f64
commit 61fae97dad
2 changed files with 32 additions and 148 deletions

View File

@@ -483,17 +483,27 @@ class InputManager(QObject):
if not app or not active:
return
current_tab_index = self._parent.stackedWidget.currentIndex()
if button_code in BUTTONS['confirm'] and isinstance(focused, QLineEdit):
search_edit = getattr(self._parent, 'searchEdit', None)
search_edit = None
if current_tab_index == 0:
search_edit = getattr(self._parent, 'searchEdit', None)
elif current_tab_index == 1:
search_edit = getattr(self._parent, 'autoInstallSearchLineEdit', None)
if focused == search_edit:
keyboard = getattr(self._parent, 'keyboard', None)
if keyboard:
keyboard.show_for_widget(focused)
return
# Handle Y button to focus search
# Handle Y button to focus search
if button_code in BUTTONS['prev_dir']: # Y button
search_edit = getattr(self._parent, 'searchEdit', None)
search_edit = None
if current_tab_index == 0:
search_edit = getattr(self._parent, 'searchEdit', None)
elif current_tab_index == 1:
search_edit = getattr(self._parent, 'autoInstallSearchLineEdit', None)
if search_edit:
search_edit.setFocus()
return
@@ -1022,130 +1032,6 @@ class InputManager(QObject):
elif current_row_idx == 0:
self._parent.tabButtons[0].setFocus(Qt.FocusReason.OtherFocusReason)
# Autoinstall tab navigation(index 1)
if self._parent.stackedWidget.currentIndex() == 1 and code in (ecodes.ABS_HAT0X, ecodes.ABS_HAT0Y):
focused = QApplication.focusWidget()
game_cards = self._parent.autoInstallContainer.findChildren(GameCard)
if not game_cards:
return
scroll_area = self._parent.autoInstallContainer.parentWidget()
while scroll_area and not isinstance(scroll_area, QScrollArea):
scroll_area = scroll_area.parentWidget()
# If no focused widget or not a GameCard, focus the first card
if not isinstance(focused, GameCard) or focused not in game_cards:
game_cards[0].setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(game_cards[0], 50, 50)
return
cards = self._parent.autoInstallContainer.findChildren(GameCard, options=Qt.FindChildOption.FindChildrenRecursively)
if not cards:
return
# Group cards by rows with tolerance for y-position
rows = {}
y_tolerance = 10 # Allow slight variations in y-position
for card in cards:
y = card.pos().y()
matched = False
for row_y in rows:
if abs(y - row_y) <= y_tolerance:
rows[row_y].append(card)
matched = True
break
if not matched:
rows[y] = [card]
sorted_rows = sorted(rows.items(), key=lambda x: x[0])
if not sorted_rows:
return
current_row_idx = None
current_col_idx = None
for row_idx, (_y, row_cards) in enumerate(sorted_rows):
for idx, card in enumerate(row_cards):
if card == focused:
current_row_idx = row_idx
current_col_idx = idx
break
if current_row_idx is not None:
break
# Fallback: if focused card not found, select closest row by y-position
if current_row_idx is None:
if not sorted_rows: # Additional safety check
return
focused_y = focused.pos().y()
current_row_idx = min(range(len(sorted_rows)), key=lambda i: abs(sorted_rows[i][0] - focused_y))
if current_row_idx >= len(sorted_rows): # Safety check
return
current_row = sorted_rows[current_row_idx][1]
focused_x = focused.pos().x() + focused.width() / 2
current_col_idx = min(range(len(current_row)), key=lambda i: abs((current_row[i].pos().x() + current_row[i].width() / 2) - focused_x), default=0) # type: ignore
# Add null checks before using current_row_idx and current_col_idx
if current_row_idx is None or current_col_idx is None or current_row_idx >= len(sorted_rows):
return
current_row = sorted_rows[current_row_idx][1]
if code == ecodes.ABS_HAT0X and value != 0:
if value < 0: # Left
if current_col_idx > 0:
next_card = current_row[current_col_idx - 1]
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
else:
if current_row_idx > 0:
prev_row = sorted_rows[current_row_idx - 1][1]
next_card = prev_row[-1] if prev_row else None
if next_card:
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
elif value > 0: # Right
if current_col_idx < len(current_row) - 1:
next_card = current_row[current_col_idx + 1]
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
else:
if current_row_idx < len(sorted_rows) - 1:
next_row = sorted_rows[current_row_idx + 1][1]
next_card = next_row[0] if next_row else None
if next_card:
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
elif code == ecodes.ABS_HAT0Y and value != 0:
if value > 0: # Down
if current_row_idx < len(sorted_rows) - 1:
next_row = sorted_rows[current_row_idx + 1][1]
current_x = focused.pos().x() + focused.width() / 2
next_card = min(
next_row,
key=lambda c: abs((c.pos().x() + c.width() / 2) - current_x),
default=None
)
if next_card:
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
elif value < 0: # Up
if current_row_idx > 0:
prev_row = sorted_rows[current_row_idx - 1][1]
current_x = focused.pos().x() + focused.width() / 2
next_card = min(
prev_row,
key=lambda c: abs((c.pos().x() + c.width() / 2) - current_x),
default=None
)
if next_card:
next_card.setFocus(Qt.FocusReason.OtherFocusReason)
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
elif current_row_idx == 0:
self._parent.tabButtons[0].setFocus(Qt.FocusReason.OtherFocusReason)
# Vertical navigation in other tabs
elif code == ecodes.ABS_HAT0Y and value != 0:
focused = QApplication.focusWidget()
@@ -1212,21 +1098,6 @@ class InputManager(QObject):
keyboard.on_backspace_pressed()
elif value == 0:
keyboard.stop_backspace_repeat()
elif button_code in BUTTONS['search']: # Кнопка Y/Square - поиск (tab-specific)
if value == 1:
current_index = self._parent.stackedWidget.currentIndex()
search_field = None
if current_index == 0: # Library tab
search_field = self._parent.searchLineEdit
elif current_index == 1: # Auto Install tab
search_field = self._parent.autoInstallSearchLineEdit
else:
return
if search_field:
search_field.setFocus()
keyboard.current_input_widget = search_field
keyboard.show()
def eventFilter(self, obj: QObject, event: QEvent) -> bool:
app = QApplication.instance()

View File

@@ -39,7 +39,7 @@ from portprotonqt.game_library_manager import GameLibraryManager
from portprotonqt.virtual_keyboard import VirtualKeyboard
from PySide6.QtWidgets import (QLineEdit, QMainWindow, QStatusBar, QWidget, QVBoxLayout, QLabel, QHBoxLayout, QStackedWidget, QComboBox,
QDialog, QFormLayout, QFrame, QGraphicsDropShadowEffect, QMessageBox, QApplication, QPushButton, QProgressBar, QCheckBox, QSizePolicy, QGridLayout, QScrollArea)
QDialog, QFormLayout, QFrame, QGraphicsDropShadowEffect, QMessageBox, QApplication, QPushButton, QProgressBar, QCheckBox, QSizePolicy, QGridLayout, QScrollArea, QScroller)
from PySide6.QtCore import Qt, QAbstractAnimation, QUrl, Signal, QTimer, Slot, QProcess
from PySide6.QtGui import QIcon, QPixmap, QColor, QDesktopServices
from typing import cast
@@ -1061,7 +1061,7 @@ class MainWindow(QMainWindow):
def createAutoInstallTab(self):
autoInstallPage = QWidget()
autoInstallPage.setStyleSheet(self.theme.MAIN_WINDOW_STYLE)
autoInstallPage.setStyleSheet(self.theme.LIBRARY_WIDGET_STYLE)
autoInstallLayout = QVBoxLayout(autoInstallPage)
autoInstallLayout.setContentsMargins(0, 0, 0, 0)
autoInstallLayout.setSpacing(0)
@@ -1073,7 +1073,7 @@ class MainWindow(QMainWindow):
headerLayout.setSpacing(10)
# Заголовок
titleLabel = QLabel(_("Auto Install Games"))
titleLabel = QLabel(_("Auto Install"))
titleLabel.setStyleSheet(self.theme.TAB_TITLE_STYLE)
titleLabel.setAlignment(Qt.AlignVCenter | Qt.AlignLeft)
headerLayout.addWidget(titleLabel)
@@ -1103,9 +1103,8 @@ class MainWindow(QMainWindow):
# Скролл
self.autoInstallScrollArea = QScrollArea()
self.autoInstallScrollArea.setWidgetResizable(True)
self.autoInstallScrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.autoInstallScrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.autoInstallScrollArea.setStyleSheet("QScrollArea { border: none; background: transparent; }")
self.autoInstallScrollArea.setStyleSheet(self.theme.SCROLL_AREA_STYLE)
QScroller.grabGesture(self.autoInstallScrollArea.viewport(), QScroller.ScrollerGestureType.LeftMouseButtonGesture)
self.autoInstallContainer = QWidget()
self.autoInstallContainerLayout = FlowLayout(self.autoInstallContainer)
@@ -1163,6 +1162,20 @@ class MainWindow(QMainWindow):
parent=self.autoInstallContainer,
)
# Hide badges and favorite button
if hasattr(card, 'steamLabel'):
card.steamLabel.setVisible(False)
if hasattr(card, 'egsLabel'):
card.egsLabel.setVisible(False)
if hasattr(card, 'portprotonLabel'):
card.portprotonLabel.setVisible(False)
if hasattr(card, 'protondbLabel'):
card.protondbLabel.setVisible(False)
if hasattr(card, 'anticheatLabel'):
card.anticheatLabel.setVisible(False)
if hasattr(card, 'favoriteLabel'):
card.favoriteLabel.setVisible(False)
self.autoInstallGameCards[exe_name] = card
self.allAutoInstallCards.append(card)
self.autoInstallContainerLayout.addWidget(card)