From 16a99f75baa3f0e9ff8dc36afaac3b68819a68b4 Mon Sep 17 00:00:00 2001 From: Dan Johnson Date: Tue, 10 Oct 2023 18:10:35 -0400 Subject: [PATCH] Basic error handling for many signal handlers in LutrisWindow. It beats crashing the entire program if something goes wrong. --- lutris/gui/lutriswindow.py | 26 ++++++++++++++++++++++++++ lutris/runtime.py | 1 - 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lutris/gui/lutriswindow.py b/lutris/gui/lutriswindow.py index b266acf42..76705b207 100644 --- a/lutris/gui/lutriswindow.py +++ b/lutris/gui/lutriswindow.py @@ -256,6 +256,7 @@ class LutrisWindow(Gtk.ApplicationWindow, """Grab the initial focus after the sidebar is initialized - so the view is ready.""" self.current_view.grab_focus() + @watch_errors() def on_drag_data_received(self, widget, drag_context, x, y, data, info, time): """Handler for drop event""" file_paths = [unquote(urlparse(uri).path) for uri in data.get_uris()] @@ -624,6 +625,7 @@ class LutrisWindow(Gtk.ApplicationWindow, self.zoom_adjustment.props.value = value self.zoom_adjustment.connect("value-changed", self.on_zoom_changed) + @watch_errors() def on_zoom_changed(self, adjustment): """Handler for zoom modification""" media_index = round(adjustment.props.value) @@ -788,6 +790,7 @@ class LutrisWindow(Gtk.ApplicationWindow, settings.write_setting("filter_installed", bool(filter_installed)) self.filters["installed"] = filter_installed + @watch_errors() def on_service_games_updated(self, service): """Request a view update when service games are loaded""" if self.service and service.id == self.service.id: @@ -812,6 +815,7 @@ class LutrisWindow(Gtk.ApplicationWindow, if self.window_x and self.window_y: self.move(int(self.window_x), int(self.window_y)) + @watch_errors() def on_service_login(self, service): service.start_reload(self._service_reloaded_cb) return True @@ -820,11 +824,13 @@ class LutrisWindow(Gtk.ApplicationWindow, if error: dialogs.ErrorDialog(error, parent=self) + @watch_errors() def on_service_logout(self, service): if self.service and service.id == self.service.id: self.emit("view-updated") return True + @watch_errors() @GtkTemplate.Callback def on_resize(self, widget, *_args): """Size-allocate signal. @@ -859,6 +865,7 @@ class LutrisWindow(Gtk.ApplicationWindow, stopper() @GtkTemplate.Callback + @watch_errors() def on_hide(self, *_args): self.save_window_state() @@ -867,6 +874,7 @@ class LutrisWindow(Gtk.ApplicationWindow, self.restore_window_position() @GtkTemplate.Callback + @watch_errors() def on_preferences_activate(self, *_args): """Callback when preferences is activated.""" self.application.show_window(PreferencesDialog, parent=self) @@ -878,6 +886,7 @@ class LutrisWindow(Gtk.ApplicationWindow, self.emit("view-updated") @GtkTemplate.Callback + @watch_errors() def on_search_entry_changed(self, entry): """Callback for the search input keypresses""" if self.search_timer_id: @@ -886,6 +895,7 @@ class LutrisWindow(Gtk.ApplicationWindow, self.search_timer_id = GLib.timeout_add(500, self.update_store) @GtkTemplate.Callback + @watch_errors() def on_search_entry_key_press(self, widget, event): if event.keyval == Gdk.KEY_Down: if self.current_view_type == 'grid': @@ -899,10 +909,12 @@ class LutrisWindow(Gtk.ApplicationWindow, self.current_view.grab_focus() @GtkTemplate.Callback + @watch_errors() def on_about_clicked(self, *_args): """Open the about dialog.""" dialogs.AboutDialog(parent=self) + @watch_errors() def on_game_unhandled_error(self, game, error): """Called when a game has sent the 'game-error' signal""" @@ -915,11 +927,13 @@ class LutrisWindow(Gtk.ApplicationWindow, return True @GtkTemplate.Callback + @watch_errors() def on_add_game_button_clicked(self, *_args): """Add a new game manually with the AddGameDialog.""" self.application.show_window(AddGamesWindow, parent=self) return True + @watch_errors() def on_toggle_viewtype(self, *args): view_type = "list" if self.current_view_type == "grid" else "grid" logger.debug("View type changed to %s", view_type) @@ -928,26 +942,31 @@ class LutrisWindow(Gtk.ApplicationWindow, self.redraw_view() self._bind_zoom_adjustment() + @watch_errors() def on_icontype_state_change(self, action, value): action.set_state(value) self._set_icon_type(value.get_string()) + @watch_errors() def on_view_sorting_state_change(self, action, value): self.actions["view-sorting"].set_state(value) value = str(value).strip("'") settings.write_setting("view_sorting", value) self.emit("view-updated") + @watch_errors() def on_view_sorting_direction_change(self, action, value): self.actions["view-sorting-ascending"].set_state(value) settings.write_setting("view_sorting_ascending", bool(value)) self.emit("view-updated") + @watch_errors() def on_view_sorting_installed_first_change(self, action, value): self.actions["view-sorting-installed-first"].set_state(value) settings.write_setting("view_sorting_installed_first", bool(value)) self.emit("view-updated") + @watch_errors() def on_side_panel_state_change(self, action, value): """Callback to handle side panel toggle""" action.set_state(value) @@ -955,6 +974,7 @@ class LutrisWindow(Gtk.ApplicationWindow, settings.write_setting("side_panel_visible", bool(side_panel_visible)) self.sidebar_revealer.set_reveal_child(side_panel_visible) + @watch_errors() def on_sidebar_changed(self, widget): """Handler called when the selected element of the sidebar changes""" for filter_type in ("category", "dynamic_category", "service", "runner", "platform"): @@ -971,6 +991,7 @@ class LutrisWindow(Gtk.ApplicationWindow, self._bind_zoom_adjustment() self.redraw_view() + @watch_errors() def on_game_selection_changed(self, view, selection): if not selection: GLib.idle_add(self.update_revealer) @@ -996,12 +1017,14 @@ class LutrisWindow(Gtk.ApplicationWindow, GLib.idle_add(self.update_revealer, game) return False + @watch_errors() def on_toggle_badges(self, _widget, _data): """Event handler to toggle badge visibility""" state = settings.read_setting("hide_badges_on_icons").lower() == "true" settings.write_setting("hide_badges_on_icons", not state) self.on_settings_changed(None, "hide_badges_on_icons") + @watch_errors() def on_settings_changed(self, dialog, settings_key): if settings_key == "hide_text_under_icons": self.rebuild_view("grid") @@ -1029,6 +1052,7 @@ class LutrisWindow(Gtk.ApplicationWindow, return True + @watch_errors() def on_game_updated(self, game): """Updates an individual entry in the view when a game is updated""" add_to_path_cache(game) @@ -1048,6 +1072,7 @@ class LutrisWindow(Gtk.ApplicationWindow, return True + @watch_errors() def on_game_stopped(self, game): """Updates the game list when a game stops; this keeps the 'running' page updated.""" selected_row = self.sidebar.get_selected_row() @@ -1060,6 +1085,7 @@ class LutrisWindow(Gtk.ApplicationWindow, def on_game_installed(self, game): return True + @watch_errors() def on_game_removed(self, game): """Simple method used to refresh the view""" remove_from_path_cache(game) diff --git a/lutris/runtime.py b/lutris/runtime.py index 998fb5e15..7e38ac1b4 100644 --- a/lutris/runtime.py +++ b/lutris/runtime.py @@ -281,7 +281,6 @@ class RuntimeUpdater: self.status_text = _(f"Extracting {name}") extract_archive(archive_download_path, runner_path) - get_installed_wine_versions.cache_clear() def percentage_completed(self) -> float: