From cf9ff36d50df4ab03b1b0ed00aa066395922990a Mon Sep 17 00:00:00 2001 From: Mathieu Comandon Date: Wed, 22 Jan 2020 23:46:22 -0800 Subject: [PATCH] Prevent InstallerWindow duplicates --- lutris/game_actions.py | 6 +----- lutris/gui/application.py | 21 +++++++++++---------- lutris/gui/dialogs/__init__.py | 15 +++++++++++++-- lutris/gui/lutriswindow.py | 3 ++- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lutris/game_actions.py b/lutris/game_actions.py index de0ee1ab9..3cffb70be 100644 --- a/lutris/game_actions.py +++ b/lutris/game_actions.py @@ -219,11 +219,7 @@ class GameActions: def on_install_clicked(self, *_args): """Install a game""" # Install the currently selected game in the UI - return InstallerWindow( - parent=self.window, - game_slug=self.game.slug, - application=self.application, - ) + self.application.show_window(InstallerWindow, parent=self.window, game_slug=self.game.slug) def on_add_manually(self, _widget, *_args): """Callback that presents the Add game dialog""" diff --git a/lutris/gui/application.py b/lutris/gui/application.py index 1bf4ed060..edf719325 100644 --- a/lutris/gui/application.py +++ b/lutris/gui/application.py @@ -34,7 +34,7 @@ from gi.repository import Gio, GLib, Gtk from lutris import pga from lutris.game import Game from lutris import settings -from lutris.gui.dialogs import ErrorDialog, InstallOrPlayDialog +from lutris.gui.dialogs import ErrorDialog, InstallOrPlayDialog, GtkBuilderDialog from lutris.gui.dialogs.issue import IssueReportWindow from lutris.gui.installerwindow import InstallerWindow from lutris.gui.widgets.status_icon import LutrisStatusIcon @@ -177,20 +177,21 @@ class Application(Gtk.Application): # accordingly self.run_in_background = False - def show_window(self, window_class): + def show_window(self, window_class, **kwargs): """Instanciate a window keeping 1 instance max""" - window_key = str(window_class) + window_key = str(window_class) + str(kwargs) if self.app_windows.get(window_key): self.app_windows[window_key].present() else: - window_inst = window_class(application=self) - window_inst.connect("destroy", self.on_app_window_destroyed) + window_inst = window_class(application=self, **kwargs) + window_inst.connect("destroy", self.on_app_window_destroyed, str(kwargs)) self.app_windows[window_key] = window_inst - def on_app_window_destroyed(self, app_window): + def on_app_window_destroyed(self, app_window, kwargs_str): """Remove the reference to the window when it has been destroyed""" - window_key = str(app_window.__class__) + window_key = str(app_window.__class__) + kwargs_str del self.app_windows[window_key] + return True @staticmethod def _print(command_line, string): @@ -348,12 +349,12 @@ class Application(Gtk.Application): action = "install" if action == "install": - InstallerWindow( + self.show_window( + InstallerWindow, + parent=self.window, game_slug=game_slug, installer_file=installer_file, revision=revision, - parent=self.window, - application=self, ) elif action in ("rungame", "rungameid"): if not db_game or not db_game["id"]: diff --git a/lutris/gui/dialogs/__init__.py b/lutris/gui/dialogs/__init__.py index 99e7b4f76..f673f68ba 100644 --- a/lutris/gui/dialogs/__init__.py +++ b/lutris/gui/dialogs/__init__.py @@ -26,6 +26,12 @@ class Dialog(Gtk.Dialog): class GtkBuilderDialog(GObject.Object): + dialog_object = NotImplemented + + __gsignals__ = { + "destroy": (GObject.SignalFlags.RUN_LAST, None, ()), + } + def __init__(self, parent=None, **kwargs): super().__init__() ui_filename = os.path.join(datapath.get(), "ui", self.glade_file) @@ -40,14 +46,19 @@ class GtkBuilderDialog(GObject.Object): if parent: self.dialog.set_transient_for(parent) self.dialog.show_all() - self.dialog.connect("delete-event", lambda *x: x[0].destroy()) + self.dialog.connect("delete-event", self.on_close) self.initialize(**kwargs) def initialize(self, **kwargs): - pass + """Implement further customizations in subclasses""" + + def present(self): + self.dialog.present() def on_close(self, *args): + """Propagate the destroy event after closing the dialog""" self.dialog.destroy() + self.emit("destroy") def on_response(self, widget, response): if response == Gtk.ResponseType.DELETE_EVENT: diff --git a/lutris/gui/lutriswindow.py b/lutris/gui/lutriswindow.py index 1503d7ed3..8474535d6 100644 --- a/lutris/gui/lutriswindow.py +++ b/lutris/gui/lutriswindow.py @@ -612,6 +612,7 @@ class LutrisWindow(Gtk.ApplicationWindow): if game.is_installed: self.application.launch(game) else: + self.application.show_window(InstallerWindow, parent=self, game_slug=game.slug) InstallerWindow( parent=self, game_slug=game.slug, application=self.application, ) @@ -676,7 +677,7 @@ class LutrisWindow(Gtk.ApplicationWindow): @GtkTemplate.Callback def on_manage_runners(self, *args): - return RunnersDialog(transient_for=self) + self.application.show_window(RunnersDialog, transient_for=self) def invalidate_game_filter(self): """Refilter the game view based on current filters"""