1
0
Fork 0
mirror of synced 2024-06-28 03:00:49 +12:00

MainWindow: Handle active downloads when exiting through WM's close button.

When the closed through the WM's close button, `closeEvent()` is
 used directly. In this case the dialog in the `on_exit_app`
slot was skipped.

There is a mishandled case. If coming from logout while there
is an active download (Yes to logout -> No to stop download)
we end up in a weird state which I haven't investigated yet.

Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
This commit is contained in:
loathingKernel 2022-10-22 16:07:58 +03:00
parent ef65e8ce09
commit 28b2b7ea9b
4 changed files with 58 additions and 54 deletions

View file

@ -8,7 +8,7 @@ from datetime import datetime
from typing import Optional from typing import Optional
import requests.exceptions import requests.exceptions
from PyQt5.QtCore import QThreadPool, QTimer from PyQt5.QtCore import QThreadPool, QTimer, pyqtSlot
from PyQt5.QtWidgets import QApplication, QMessageBox from PyQt5.QtWidgets import QApplication, QMessageBox
from requests import HTTPError from requests import HTTPError
@ -78,6 +78,7 @@ class App(RareApp):
dt_now = datetime.utcnow() dt_now = datetime.utcnow()
td = abs(dt_exp - dt_now) td = abs(dt_exp - dt_now)
self.timer.start(int(td.total_seconds() - 60) * 1000) self.timer.start(int(td.total_seconds() - 60) * 1000)
logger.info(f"Renewed session expires at {self.core.lgd.userdata['expires_at']}")
def re_login(self): def re_login(self):
logger.info("Session expires shortly. Renew session") logger.info("Session expires shortly. Renew session")
@ -100,8 +101,12 @@ class App(RareApp):
self.main_window.show() self.main_window.show()
if self.args.test_start: if self.args.test_start:
self.main_window.close()
self.main_window = None
self.exit_app(0) self.exit_app(0)
@pyqtSlot()
@pyqtSlot(int)
def exit_app(self, exit_code=0): def exit_app(self, exit_code=0):
threadpool = QThreadPool.globalInstance() threadpool = QThreadPool.globalInstance()
threadpool.waitForDone() threadpool.waitForDone()
@ -109,9 +114,6 @@ class App(RareApp):
self.timer.stop() self.timer.stop()
self.timer.deleteLater() self.timer.deleteLater()
self.timer = None self.timer = None
if self.main_window is not None:
self.main_window.close()
self.main_window = None
self.rare_core.deleteLater() self.rare_core.deleteLater()
del self.rare_core del self.rare_core
self.processEvents() self.processEvents()

View file

@ -3,7 +3,15 @@ from logging import getLogger
from PyQt5.QtCore import Qt, QSettings, QTimer, QSize, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, QSettings, QTimer, QSize, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QCursor from PyQt5.QtGui import QCloseEvent, QCursor
from PyQt5.QtWidgets import QMainWindow, QApplication, QStatusBar, QScrollArea, QScroller, QComboBox, QMessageBox from PyQt5.QtWidgets import (
QMainWindow,
QApplication,
QStatusBar,
QScrollArea,
QScroller,
QComboBox,
QMessageBox,
)
from rare.components.tabs import TabWidget from rare.components.tabs import TabWidget
from rare.components.tray_icon import TrayIcon from rare.components.tray_icon import TrayIcon
@ -18,6 +26,9 @@ class MainWindow(QMainWindow):
exit_app: pyqtSignal = pyqtSignal(int) exit_app: pyqtSignal = pyqtSignal(int)
def __init__(self, parent=None): def __init__(self, parent=None):
self._exit_code = 0
self._accept_close = False
self._window_launched = False
super(MainWindow, self).__init__(parent=parent) super(MainWindow, self).__init__(parent=parent)
self.setAttribute(Qt.WA_DeleteOnClose, True) self.setAttribute(Qt.WA_DeleteOnClose, True)
self.core = LegendaryCoreSingleton() self.core = LegendaryCoreSingleton()
@ -42,6 +53,7 @@ class MainWindow(QMainWindow):
if not self.args.offline: if not self.args.offline:
try: try:
from rare.utils.rpc import DiscordRPC from rare.utils.rpc import DiscordRPC
self.rpc = DiscordRPC() self.rpc = DiscordRPC()
except ModuleNotFoundError: except ModuleNotFoundError:
logger.warning("Discord RPC module not found") logger.warning("Discord RPC module not found")
@ -51,17 +63,11 @@ class MainWindow(QMainWindow):
self.timer.start(1000) self.timer.start(1000)
self.signals.exit_app.connect(self.on_exit_app) self.signals.exit_app.connect(self.on_exit_app)
self.exit_code = 0
self.accept_close = False
self.tray_icon: TrayIcon = TrayIcon(self) self.tray_icon: TrayIcon = TrayIcon(self)
self.tray_icon.exit_action.triggered.connect(self.on_exit_app) self.tray_icon.exit_action.triggered.connect(self.on_exit_app)
self.tray_icon.start_rare.triggered.connect(self.show) self.tray_icon.start_rare.triggered.connect(self.show)
self.tray_icon.activated.connect( self.tray_icon.activated.connect(lambda r: self.toggle() if r == self.tray_icon.DoubleClick else None)
lambda r: self.toggle()
if r == self.tray_icon.DoubleClick
else None
)
self.signals.send_notification.connect( self.signals.send_notification.connect(
lambda title: self.tray_icon.showMessage( lambda title: self.tray_icon.showMessage(
@ -74,8 +80,6 @@ class MainWindow(QMainWindow):
else None else None
) )
self.window_launched = False
# enable kinetic scrolling # enable kinetic scrolling
for scroll_area in self.findChildren(QScrollArea): for scroll_area in self.findChildren(QScrollArea):
if not scroll_area.property("no_kinetic_scroll"): if not scroll_area.property("no_kinetic_scroll"):
@ -101,16 +105,13 @@ class MainWindow(QMainWindow):
) )
self.resize(window_size) self.resize(window_size)
self.move( self.move(screen_rect.center() - self.rect().adjusted(0, 0, decor_width, decor_height).center())
screen_rect.center()
- self.rect().adjusted(0, 0, decor_width, decor_height).center()
)
def show(self) -> None: def show(self) -> None:
super(MainWindow, self).show() super(MainWindow, self).show()
if not self.window_launched: if not self._window_launched:
self.center_window() self.center_window()
self.window_launched = True self._window_launched = True
def hide(self) -> None: def hide(self) -> None:
if self.settings.value("save_size", False, bool): if self.settings.value("save_size", False, bool):
@ -138,40 +139,41 @@ class MainWindow(QMainWindow):
@pyqtSlot() @pyqtSlot()
@pyqtSlot(int) @pyqtSlot(int)
def on_exit_app(self, exit_code=0) -> None: def on_exit_app(self, exit_code=0) -> None:
# FIXME: Fix this with the download tab redesign self._exit_code = exit_code
if not self.args.offline and self.tab_widget.downloadTab.is_download_active:
question = QMessageBox.question(
self,
self.tr("Close"),
self.tr(
"There is a download active. Do you really want to exit app?"
),
QMessageBox.Yes,
QMessageBox.No,
)
if question == QMessageBox.No:
return
else:
# clear queue
self.tab_widget.downloadTab.queue_widget.update_queue([])
self.tab_widget.downloadTab.stop_download()
# FIXME: End of FIXME
self.exit_code = exit_code
self.close() self.close()
def close(self) -> bool: def close(self) -> bool:
self.accept_close = True self._accept_close = True
return super(MainWindow, self).close() return super(MainWindow, self).close()
def closeEvent(self, e: QCloseEvent): def closeEvent(self, e: QCloseEvent) -> None:
if not self.accept_close: # lk: set to `True` by the `close()` method, overrides exiting to tray in `closeEvent()`
if self.settings.value("sys_tray", True, bool): # lk: ensures exiting when instead of hiding when `close()` is called programmatically
if not self._accept_close:
if self.settings.value("sys_tray", False, bool):
self.hide() self.hide()
e.ignore() e.ignore()
return return
# FIXME: Fix this with the download tab redesign
if not self.args.offline and self.tab_widget.downloads_tab.is_download_active:
reply = QMessageBox.question(
self,
self.tr("Quit {}?").format(QApplication.applicationName()),
self.tr("There are active downloads. Do you really want to exit?"),
buttons=(QMessageBox.Yes | QMessageBox.No),
defaultButton=QMessageBox.No,
)
if reply == QMessageBox.No:
# clear queue
self.tab_widget.downloads_tab.queue_widget.update_queue([])
self.tab_widget.downloads_tab.stop_download()
else:
e.ignore()
return
# FIXME: End of FIXME
self.timer.stop() self.timer.stop()
self.tray_icon.deleteLater() self.tray_icon.deleteLater()
self.hide() self.hide()
self.exit_app.emit(self.exit_code) self.exit_app.emit(self._exit_code)
super(MainWindow, self).closeEvent(e) super(MainWindow, self).closeEvent(e)
e.accept()

View file

@ -29,9 +29,9 @@ class TabWidget(QTabWidget):
if not self.args.offline: if not self.args.offline:
# updates = self.games_tab.default_widget.game_list.updates # updates = self.games_tab.default_widget.game_list.updates
self.downloadTab = DownloadsTab(self.games_tab.updates) self.downloads_tab = DownloadsTab(self.games_tab.updates)
self.addTab( self.addTab(
self.downloadTab, self.downloads_tab,
"Downloads" "Downloads"
+ ( + (
" (" + str(len(self.games_tab.updates)) + ")" " (" + str(len(self.games_tab.updates)) + ")"
@ -89,8 +89,8 @@ class TabWidget(QTabWidget):
def update_dl_tab_text(self): def update_dl_tab_text(self):
num_downloads = len( num_downloads = len(
set( set(
[i.options.app_name for i in self.downloadTab.dl_queue] [i.options.app_name for i in self.downloads_tab.dl_queue]
+ [i for i in self.downloadTab.update_widgets.keys()] + [i for i in self.downloads_tab.update_widgets.keys()]
) )
) )

View file

@ -33,11 +33,11 @@ class AccountWidget(QWidget):
def logout(self): def logout(self):
reply = QMessageBox.question( reply = QMessageBox.question(
self.parent().parent(), self,
"Message", self.tr("Logout"),
self.tr("Do you really want to logout"), self.tr("Do you really want to logout <b>{}</b>?").format(self.core.lgd.userdata.get("display_name")),
QMessageBox.Yes | QMessageBox.No, buttons=(QMessageBox.Yes | QMessageBox.No),
QMessageBox.No, defaultButton=QMessageBox.No,
) )
if reply == QMessageBox.Yes: if reply == QMessageBox.Yes: