mirror of
https://github.com/lutris/lutris
synced 2024-09-15 22:09:55 +00:00
Stop relying on Gtk being able to refresh a view without crashing
This commit is contained in:
parent
2ff64f92c3
commit
2eb681b30a
|
@ -75,21 +75,23 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
self.application = application
|
||||
self.runtime_updater = RuntimeUpdater()
|
||||
self.threads_stoppers = []
|
||||
self.icon_type = None
|
||||
self.service = None
|
||||
self.window_size = (width, height)
|
||||
self.maximized = settings.read_setting("maximized") == "True"
|
||||
|
||||
self.service = None
|
||||
self.game_actions = GameActions(application=application, window=self)
|
||||
self.search_timer_id = None
|
||||
self.game_store = None
|
||||
self.selected_category = settings.read_setting("selected_category", default="runner:all")
|
||||
self.filters = self.load_filters()
|
||||
self.set_service(self.filters.get("service"))
|
||||
self.icon_type = self.load_icon_type()
|
||||
self.game_store = GameStore(self.service, self.service_media)
|
||||
self.view = Gtk.Box()
|
||||
|
||||
self.connect("delete-event", self.on_window_delete)
|
||||
self.connect("map-event", self.on_load)
|
||||
if self.maximized:
|
||||
self.maximize()
|
||||
self.load_icon_type()
|
||||
|
||||
self.init_template()
|
||||
self._init_actions()
|
||||
|
||||
|
@ -100,12 +102,6 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
lutris_icon = Gtk.Image.new_from_icon_name("lutris", Gtk.IconSize.MENU)
|
||||
lutris_icon.set_margin_right(3)
|
||||
|
||||
self.selected_category = settings.read_setting("selected_category", default="runner:all")
|
||||
self.filters = self.load_filters()
|
||||
self.set_service(self.filters.get("service"))
|
||||
|
||||
self.service_media = self.get_service_media(self.load_icon_type())
|
||||
|
||||
self.sidebar = LutrisSidebar(self.application, selected=self.selected_category)
|
||||
self.sidebar.connect("selected-rows-changed", self.on_sidebar_changed)
|
||||
self.sidebar_scrolled.add(self.sidebar)
|
||||
|
@ -185,9 +181,12 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
if value.accel:
|
||||
app.add_accelerator(value.accel, "win." + name)
|
||||
|
||||
@property
|
||||
def service_media(self):
|
||||
return self.get_service_media(self.load_icon_type())
|
||||
|
||||
def on_load(self, widget, data):
|
||||
"""Finish initializing the view"""
|
||||
self.game_store = GameStore(self.service, self.service_media)
|
||||
self.game_store.media_loader.connect("icons-loaded", self.on_icons_loaded)
|
||||
self.redraw_view()
|
||||
self._bind_zoom_adjustment()
|
||||
|
@ -215,7 +214,7 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
@property
|
||||
def current_view_type(self):
|
||||
"""Returns which kind of view is currently presented (grid or list)"""
|
||||
return "grid" if isinstance(self.view, GameGridView) else "list"
|
||||
return settings.read_setting("view_type") or "grid"
|
||||
|
||||
@property
|
||||
def filter_installed(self):
|
||||
|
@ -306,16 +305,10 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
self.unset_service()
|
||||
return
|
||||
self.service = services.get_services()[service_name]()
|
||||
if self.game_store:
|
||||
self.game_store.service = self.service
|
||||
self._bind_zoom_adjustment()
|
||||
return self.service
|
||||
|
||||
def unset_service(self):
|
||||
self.service = None
|
||||
if self.game_store:
|
||||
self.game_store.service = None
|
||||
self._bind_zoom_adjustment()
|
||||
self.tabs_box.hide()
|
||||
|
||||
@staticmethod
|
||||
|
@ -362,7 +355,6 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
service_name = self.filters.get("service")
|
||||
self.tabs_box.hide()
|
||||
if service_name in services.get_services():
|
||||
self.set_service(service_name)
|
||||
if self.service.online and not self.service.is_authenticated():
|
||||
self.show_label(_("Connect your %s account to access your games") % self.service.name)
|
||||
return []
|
||||
|
@ -371,7 +363,6 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
if self.website_button.props.active:
|
||||
return self.get_api_games()
|
||||
return self.get_service_games(service_name)
|
||||
self.unset_service()
|
||||
dynamic_categories = {
|
||||
"recent": self.get_recent_games,
|
||||
"running": self.get_running_games,
|
||||
|
@ -452,9 +443,9 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
self.game_store.store.clear()
|
||||
for child in self.blank_overlay.get_children():
|
||||
child.destroy()
|
||||
|
||||
games = self.get_games_from_filters()
|
||||
self.view.service = self.service.id if self.service else None
|
||||
self.reload_service_media()
|
||||
GLib.idle_add(self.update_revealer)
|
||||
for game in games:
|
||||
self.game_store.add_game(game)
|
||||
|
@ -493,9 +484,12 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
icon_type = media_services[media_index]
|
||||
if icon_type != self.icon_type:
|
||||
self.save_icon_type(icon_type)
|
||||
self.reload_service_media()
|
||||
self.show_spinner()
|
||||
AsyncCall(self.game_store.load_icons, self.icons_loaded_cb)
|
||||
GLib.timeout_add(100, self._load_icons)
|
||||
|
||||
def _load_icons(self):
|
||||
AsyncCall(self.game_store.load_icons, self.icons_loaded_cb)
|
||||
return False
|
||||
|
||||
def show_label(self, message):
|
||||
"""Display a label in the middle of the UI"""
|
||||
|
@ -522,7 +516,7 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
if error:
|
||||
logger.debug("Failed to reload icons")
|
||||
self.hide_overlay()
|
||||
self.emit("view-updated")
|
||||
self.redraw_view()
|
||||
|
||||
@property
|
||||
def view_type(self):
|
||||
|
@ -569,19 +563,14 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
settings.write_setting(setting_key, self.icon_type)
|
||||
self.redraw_view()
|
||||
|
||||
def reload_service_media(self):
|
||||
self.game_store.set_service_media(
|
||||
self.get_service_media(
|
||||
self.load_icon_type()
|
||||
)
|
||||
)
|
||||
|
||||
def redraw_view(self):
|
||||
"""Completely reconstruct the main view"""
|
||||
if not self.game_store:
|
||||
logger.error("No game store yet")
|
||||
return
|
||||
if self.view:
|
||||
self.view.destroy()
|
||||
self.reload_service_media()
|
||||
|
||||
self.game_store = GameStore(self.service, self.service_media)
|
||||
if self.view_type == "grid":
|
||||
self.view = GameGridView(
|
||||
self.game_store,
|
||||
|
@ -773,7 +762,10 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
|
|||
self.filters.pop(filter_type)
|
||||
if row:
|
||||
self.filters[row.type] = row.id
|
||||
self.emit("view-updated")
|
||||
service_name = self.filters.get("service")
|
||||
self.set_service(service_name)
|
||||
self._bind_zoom_adjustment()
|
||||
self.redraw_view()
|
||||
|
||||
def on_library_button_toggled(self, button):
|
||||
self.update_store()
|
||||
|
|
|
@ -34,7 +34,6 @@ class GameGridView(Gtk.IconView, GameView):
|
|||
self.connect_signals()
|
||||
self.connect("item-activated", self.on_item_activated)
|
||||
self.connect("selection-changed", self.on_selection_changed)
|
||||
store.connect("icons-changed", self.on_icons_changed)
|
||||
|
||||
def select(self):
|
||||
self.select_path(self.current_path)
|
||||
|
@ -59,10 +58,3 @@ class GameGridView(Gtk.IconView, GameView):
|
|||
def on_selection_changed(self, _view):
|
||||
"""Handles selection changes"""
|
||||
self.emit("game-selected", self.get_selected_item())
|
||||
|
||||
def on_icons_changed(self, store):
|
||||
cell_width = max(self.service_media.size[0], self.min_width)
|
||||
self.set_item_width(cell_width)
|
||||
if self.cell_renderer:
|
||||
self.cell_renderer.props.width = cell_width
|
||||
self.queue_draw()
|
||||
|
|
|
@ -11,7 +11,6 @@ from lutris.database.games import get_games
|
|||
from lutris.game import Game
|
||||
from lutris.gui.views.media_loader import MediaLoader
|
||||
from lutris.gui.views.store_item import StoreItem
|
||||
from lutris.gui.widgets.utils import get_pixbuf_for_game
|
||||
from lutris.services.base import BaseService
|
||||
from lutris.util.strings import gtk_safe
|
||||
|
||||
|
@ -174,20 +173,6 @@ class GameStore(GObject.Object):
|
|||
)
|
||||
)
|
||||
|
||||
def set_service_media(self, service_media):
|
||||
"""Change the icon type"""
|
||||
if service_media == self.service_media:
|
||||
return
|
||||
self.service_media = service_media
|
||||
for row in self.store:
|
||||
try:
|
||||
slug = row[COL_SLUG]
|
||||
is_installed = row[COL_INSTALLED]
|
||||
row[COL_ICON] = get_pixbuf_for_game(slug, self.service_media.size, is_installed=is_installed)
|
||||
except TypeError:
|
||||
return
|
||||
self.emit("icons-changed")
|
||||
|
||||
def on_game_updated(self, game):
|
||||
if self.service:
|
||||
db_games = sql.filtered_query(PGA_DB, "service_games", filters=({
|
||||
|
|
|
@ -95,6 +95,8 @@ class SidebarRow(Gtk.ListBoxRow):
|
|||
|
||||
def create_button_box(self):
|
||||
"""Adds buttons in the button box based on the row's actions"""
|
||||
for child in self.btn_box.get_children():
|
||||
child.destroy()
|
||||
for action in self.get_actions():
|
||||
btn = Gtk.Button(tooltip_text=action[1], relief=Gtk.ReliefStyle.NONE, visible=True)
|
||||
image = Gtk.Image.new_from_icon_name(action[0], Gtk.IconSize.MENU)
|
||||
|
@ -128,6 +130,9 @@ class ServiceSidebarRow(SidebarRow):
|
|||
def on_refresh_clicked(self, button):
|
||||
"""Reload the service games"""
|
||||
button.set_sensitive(False)
|
||||
if self.service.online and not self.service.is_connected():
|
||||
self.service.logout()
|
||||
return
|
||||
self.service.wipe_game_cache()
|
||||
AsyncCall(self.service.load, self.service_load_cb)
|
||||
|
||||
|
@ -157,16 +162,11 @@ class OnlineServiceSidebarRow(ServiceSidebarRow):
|
|||
|
||||
def on_connect_clicked(self, button):
|
||||
button.set_sensitive(False)
|
||||
buttons = self.get_buttons()
|
||||
if self.service.is_authenticated():
|
||||
self.service.logout()
|
||||
new_button = buttons["connect"]
|
||||
else:
|
||||
self.service.login()
|
||||
new_button = buttons["disconnect"]
|
||||
button.set_tooltip_text(new_button[1])
|
||||
button.set_image(Gtk.Image.new_from_icon_name(new_button[0], Gtk.IconSize.MENU))
|
||||
button.set_sensitive(True)
|
||||
self.create_button_box()
|
||||
|
||||
|
||||
class RunnerSidebarRow(SidebarRow):
|
||||
|
@ -259,6 +259,7 @@ class LutrisSidebar(Gtk.ListBox):
|
|||
GObject.add_emission_hook(Game, "game-stop", self.on_game_stop)
|
||||
GObject.add_emission_hook(Game, "game-updated", self.update)
|
||||
GObject.add_emission_hook(Game, "game-removed", self.update)
|
||||
GObject.add_emission_hook(BaseService, "service-logout", self.on_service_logout)
|
||||
GObject.add_emission_hook(BaseService, "service-games-load", self.on_service_games_updating)
|
||||
GObject.add_emission_hook(BaseService, "service-games-loaded", self.on_service_games_updated)
|
||||
self.connect("realize", self.on_realize)
|
||||
|
@ -380,8 +381,14 @@ class LutrisSidebar(Gtk.ListBox):
|
|||
self.running_row.hide()
|
||||
return True
|
||||
|
||||
def on_service_logout(self, service):
|
||||
self.service_rows[service.id].create_button_box()
|
||||
self.service_rows[service.id].update_buttons()
|
||||
return True
|
||||
|
||||
def on_service_games_updating(self, service):
|
||||
self.service_rows[service.id].is_updating = True
|
||||
|
||||
self.service_rows[service.id].update_buttons()
|
||||
return True
|
||||
|
||||
|
|
Loading…
Reference in a new issue