1
0
Fork 0
mirror of synced 2024-06-16 17:44:44 +12:00

AccountWidget: Add a Quit button in the widget in case the system tray

is unavailable (for example running in a gamescope session)

* Do not show the launch window while instantiating the application. This
probably was causing numerous issues because it was running outside of
the applications event loop. This also fixes the exit button on the login
dialog requiring `sys.exit()` to quit Rare. Now it goes through the
proper cleanup procedures.

* Make slot and signal names more uniform

* Fix a problem with RareCore connecting RareGames to the same signals
multiple times when the library was refreshed.
This commit is contained in:
loathingKernel 2023-09-13 21:36:11 +03:00
parent 8d46a3e353
commit c3c9b0f059
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
7 changed files with 76 additions and 60 deletions

View file

@ -55,14 +55,9 @@ class Rare(RareApp):
self.launch_dialog: Optional[LaunchDialog] = None
self.timer: Optional[QTimer] = None
# launch app
self.launch_dialog = LaunchDialog(parent=None)
self.launch_dialog.quit_app.connect(self.launch_dialog.close)
self.launch_dialog.quit_app.connect(lambda x: sys.exit(x))
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.start_app.connect(self.launch_dialog.close)
self.launch_dialog.login()
# This launches the application after it has been instantiated.
# The timer's signal will be serviced once we call `exec()` on the application
QTimer.singleShot(0, self.launch_app)
def poke_timer(self):
dt_exp = datetime.fromisoformat(self.core.lgd.userdata['expires_at'][:-1]).replace(tzinfo=timezone.utc)
@ -80,13 +75,23 @@ class Rare(RareApp):
return
self.poke_timer()
@pyqtSlot()
def launch_app(self):
self.launch_dialog = LaunchDialog(parent=None)
self.launch_dialog.exit_app.connect(self.launch_dialog.close)
self.launch_dialog.exit_app.connect(self.__on_exit_app)
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.start_app.connect(self.launch_dialog.close)
self.launch_dialog.login()
@pyqtSlot()
def start_app(self):
self.timer = QTimer()
self.timer.timeout.connect(self.re_login)
self.poke_timer()
self.main_window = MainWindow()
self.main_window.exit_app.connect(self.on_exit_app)
self.main_window.exit_app.connect(self.__on_exit_app)
if not self.args.silent:
self.main_window.show()
@ -94,11 +99,11 @@ class Rare(RareApp):
if self.args.test_start:
self.main_window.close()
self.main_window = None
self.on_exit_app(0)
self.__on_exit_app(0)
@pyqtSlot()
@pyqtSlot(int)
def on_exit_app(self, exit_code=0):
def __on_exit_app(self, exit_code=0):
threadpool = QThreadPool.globalInstance()
threadpool.waitForDone()
if self.timer is not None:
@ -119,9 +124,7 @@ def start(args) -> int:
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
app = Rare(args)
exit_code = app.exec_()
# if not restart
# restart app
exit_code = app.exec()
del app
if exit_code != -133742:
break

View file

@ -14,7 +14,7 @@ logger = getLogger("LaunchDialog")
class LaunchDialog(QDialog):
quit_app = pyqtSignal(int)
exit_app = pyqtSignal(int)
start_app = pyqtSignal()
def __init__(self, parent=None):
@ -74,7 +74,7 @@ class LaunchDialog(QDialog):
self.show()
self.launch()
else:
self.quit_app.emit(0)
self.exit_app.emit(0)
def launch(self):
self.progress_info.setText(self.tr("Preparing Rare"))

View file

@ -1,7 +1,6 @@
from dataclasses import dataclass
from logging import getLogger
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QLayout, QDialog, QMessageBox, QFrame
from legendary.core import LegendaryCore
@ -15,13 +14,6 @@ from .import_login import ImportLogin
logger = getLogger("LoginDialog")
@dataclass
class LoginPages:
landing: int
browser: int
import_egl: int
class LandingPage(QFrame):
def __init__(self, parent=None):
super(LandingPage, self).__init__(parent=parent)
@ -31,8 +23,7 @@ class LandingPage(QFrame):
class LoginDialog(QDialog):
logged_in: bool = False
pages = LoginPages(landing=0, browser=1, import_egl=2)
exit_app: pyqtSignal = pyqtSignal(int)
def __init__(self, core: LegendaryCore, parent=None):
super(LoginDialog, self).__init__(parent=parent)
@ -51,6 +42,8 @@ class LoginDialog(QDialog):
self.ui = Ui_LoginDialog()
self.ui.setupUi(self)
self.logged_in: bool = False
self.core = core
self.args = ArgumentsSingleton()
@ -59,16 +52,16 @@ class LoginDialog(QDialog):
self.ui.login_stack_layout.addWidget(self.login_stack)
self.landing_page = LandingPage(self.login_stack)
self.login_stack.insertWidget(self.pages.landing, self.landing_page)
self.login_stack.insertWidget(0, self.landing_page)
self.browser_page = BrowserLogin(self.core, self.login_stack)
self.login_stack.insertWidget(self.pages.browser, self.browser_page)
self.login_stack.insertWidget(1, self.browser_page)
self.browser_page.success.connect(self.login_successful)
self.browser_page.changed.connect(
lambda: self.ui.next_button.setEnabled(self.browser_page.is_valid())
)
self.import_page = ImportLogin(self.core, self.login_stack)
self.login_stack.insertWidget(self.pages.import_egl, self.import_page)
self.login_stack.insertWidget(2, self.import_page)
self.import_page.success.connect(self.login_successful)
self.import_page.changed.connect(lambda: self.ui.next_button.setEnabled(self.import_page.is_valid()))
@ -84,34 +77,34 @@ class LoginDialog(QDialog):
self.ui.back_button.clicked.connect(self.back_clicked)
self.ui.next_button.clicked.connect(self.next_clicked)
self.login_stack.setCurrentIndex(self.pages.landing)
self.login_stack.setCurrentWidget(self.landing_page)
self.layout().setSizeConstraint(QLayout.SetFixedSize)
def back_clicked(self):
self.ui.back_button.setEnabled(False)
self.ui.next_button.setEnabled(True)
self.login_stack.slideInIndex(self.pages.landing)
self.login_stack.slideInWidget(self.landing_page)
def browser_radio_clicked(self):
self.login_stack.slideInIndex(self.pages.browser)
self.login_stack.slideInWidget(self.browser_page)
self.ui.back_button.setEnabled(True)
self.ui.next_button.setEnabled(False)
def import_radio_clicked(self):
self.login_stack.slideInIndex(self.pages.import_egl)
self.login_stack.slideInWidget(self.import_page)
self.ui.back_button.setEnabled(True)
self.ui.next_button.setEnabled(self.import_page.is_valid())
def next_clicked(self):
if self.login_stack.currentIndex() == self.pages.landing:
if self.login_stack.currentWidget() is self.landing_page:
if self.landing_page.ui.login_browser_radio.isChecked():
self.browser_radio_clicked()
if self.landing_page.ui.login_import_radio.isChecked():
self.import_radio_clicked()
elif self.login_stack.currentIndex() == self.pages.browser:
elif self.login_stack.currentWidget() is self.browser_page:
self.browser_page.do_login()
elif self.login_stack.currentIndex() == self.pages.import_egl:
elif self.login_stack.currentWidget() is self.import_page:
self.import_page.do_login()
def login(self):

View file

@ -44,7 +44,7 @@ class MainWindow(QMainWindow):
self.setWindowTitle("Rare - GUI for legendary")
self.tab_widget = MainTabWidget(self)
self.tab_widget.exit_app.connect(self.on_exit_app)
self.tab_widget.exit_app.connect(self.__on_exit_app)
self.setCentralWidget(self.tab_widget)
# Set up status bar stuff (jumping through a lot of hoops)
@ -112,7 +112,7 @@ class MainWindow(QMainWindow):
self.timer.start()
self.tray_icon: TrayIcon = TrayIcon(self)
self.tray_icon.exit_app.connect(self.on_exit_app)
self.tray_icon.exit_app.connect(self.__on_exit_app)
self.tray_icon.show_app.connect(self.show)
self.tray_icon.activated.connect(lambda r: self.toggle() if r == self.tray_icon.DoubleClick else None)
@ -203,7 +203,7 @@ class MainWindow(QMainWindow):
@pyqtSlot()
@pyqtSlot(int)
def on_exit_app(self, exit_code=0) -> None:
def __on_exit_app(self, exit_code=0) -> None:
self.__exit_code = exit_code
self.close()

View file

@ -51,7 +51,7 @@ class MainTabWidget(QTabWidget):
self.setTabEnabled(button_index, False)
self.account_widget = AccountWidget(self)
self.account_widget.logout.connect(self.logout)
self.account_widget.exit_app.connect(self.__on_exit_app)
account_action = QWidgetAction(self)
account_action.setDefaultWidget(self.account_widget)
account_button = TabButtonWidget("mdi.account-circle", "Account", fallback_icon="fa.user")
@ -93,25 +93,28 @@ class MainTabWidget(QTabWidget):
self.tab_bar.setMinimumWidth(self.width())
super(MainTabWidget, self).resizeEvent(event)
@pyqtSlot()
def logout(self):
@pyqtSlot(int)
def __on_exit_app(self, exit_code: int):
# FIXME: Don't allow logging out if there are active downloads
if self.downloads_tab.is_download_active:
QMessageBox.warning(
self,
self.tr("Logout"),
self.tr("There are active downloads. Stop them before logging out."),
self.tr("Quit") if exit_code == self.account_widget.ExitCodes.EXIT else self.tr("Logout"),
self.tr("There are active downloads. Stop them before trying to quit."),
)
return
# FIXME: End of FIXME
reply = QMessageBox.question(
self,
self.tr("Logout"),
self.tr("Do you really want to logout <b>{}</b>?").format(self.core.lgd.userdata.get("display_name")),
buttons=(QMessageBox.Yes | QMessageBox.No),
defaultButton=QMessageBox.No,
)
if exit_code == self.account_widget.ExitCodes.LOGOUT:
reply = QMessageBox.question(
self,
self.tr("Logout"),
self.tr("Do you really want to logout <b>{}</b>?").format(self.core.lgd.userdata.get("display_name")),
buttons=(QMessageBox.Yes | QMessageBox.No),
defaultButton=QMessageBox.No,
)
if reply == QMessageBox.Yes:
self.core.lgd.invalidate_userdata()
self.exit_app.emit(-133742) # restart exit code
if reply == QMessageBox.Yes:
self.core.lgd.invalidate_userdata()
else:
return
self.exit_app.emit(exit_code) # restart exit code

View file

@ -1,15 +1,21 @@
import webbrowser
from enum import IntEnum
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
from rare.utils.misc import icon
class AccountWidget(QWidget):
exit_app: pyqtSignal = pyqtSignal(int)
logout: pyqtSignal = pyqtSignal()
class ExitCodes(IntEnum):
EXIT = 0
LOGOUT = -133742
def __init__(self, parent):
super(AccountWidget, self).__init__(parent=parent)
self.core = LegendaryCoreSingleton()
@ -25,11 +31,22 @@ class AccountWidget(QWidget):
"https://www.epicgames.com/account/personal?productName=epicgames"
)
)
self.logout_button = QPushButton(self.tr("Logout"))
self.logout_button.clicked.connect(self.logout)
self.logout_button = QPushButton(self.tr("Logout"), parent=self)
self.logout_button.clicked.connect(self.__on_logout)
self.quit_button = QPushButton(self.tr("Quit"), parent=self)
self.quit_button.clicked.connect(self.__on_quit)
layout = QVBoxLayout(self)
layout.addWidget(QLabel(self.tr("Account")))
layout.addWidget(QLabel(self.tr("Logged in as <b>{}</b>").format(username)))
layout.addWidget(self.open_browser)
layout.addWidget(self.logout_button)
layout.addWidget(self.quit_button)
@pyqtSlot()
def __on_quit(self):
self.exit_app.emit(AccountWidget.ExitCodes.EXIT)
@pyqtSlot()
def __on_logout(self):
self.exit_app.emit(AccountWidget.ExitCodes.LOGOUT)

View file

@ -179,8 +179,8 @@ class RareCore(QObject):
del self.__args
self.__args = None
del self.__eos_overlay
RareCore.__instance = None
super(RareCore, self).deleteLater()
def __validate_install(self, rgame: RareGame):