diff --git a/lutris/gui/config/base_config_box.py b/lutris/gui/config/base_config_box.py index f100dbac1..d7b7bf47c 100644 --- a/lutris/gui/config/base_config_box.py +++ b/lutris/gui/config/base_config_box.py @@ -10,6 +10,14 @@ from lutris.gui.widgets.common import VBox class BaseConfigBox(VBox): settings_accelerators = {} + def __init__(self): + super().__init__(visible=True, spacing=12) + self.accelerators = None + self.set_margin_top(50) + self.set_margin_bottom(50) + self.set_margin_right(80) + self.set_margin_left(80) + def get_section_label(self, text: str) -> Gtk.Label: label = Gtk.Label(visible=True) label.set_markup("%s" % text) @@ -24,13 +32,14 @@ class BaseConfigBox(VBox): label.set_alignment(0, 0.5) return label - def __init__(self): - super().__init__(visible=True) - self.accelerators = None - self.set_margin_top(50) - self.set_margin_bottom(50) - self.set_margin_right(80) - self.set_margin_left(80) + def _get_framed_options_list_box(self, items): + frame = Gtk.Frame(visible=True, shadow_type=Gtk.ShadowType.ETCHED_IN) + list_box = Gtk.ListBox(visible=True, selection_mode=Gtk.SelectionMode.NONE) + frame.add(list_box) + + for item in items: + list_box.add(Gtk.ListBoxRow(child=item, visible=True, activatable=False)) + return frame def get_setting_box(self, setting_key: str, label: str, default: bool = False, diff --git a/lutris/gui/config/preferences_dialog.py b/lutris/gui/config/preferences_dialog.py index 46a5460c0..7cef288ac 100644 --- a/lutris/gui/config/preferences_dialog.py +++ b/lutris/gui/config/preferences_dialog.py @@ -38,7 +38,7 @@ class PreferencesDialog(GameDialogCommon): sidebar.add(self.get_sidebar_button("services-stack", _("Sources"), "application-x-addon-symbolic")) sidebar.add(self.get_sidebar_button("accounts-stack", _("Accounts"), "system-users-symbolic")) sidebar.add(self.get_sidebar_button("updates-stack", _("Updates"), "system-software-install-symbolic")) - sidebar.add(self.get_sidebar_button("sysinfo-stack", _("Hardware information"), "computer-symbolic")) + sidebar.add(self.get_sidebar_button("sysinfo-stack", _("System"), "computer-symbolic")) sidebar.add(self.get_sidebar_button("system-stack", _("Global options"), "emblem-system-symbolic")) hbox.pack_start(sidebar, False, False, 0) self.stack = Gtk.Stack(visible=True) diff --git a/lutris/gui/config/sysinfo_box.py b/lutris/gui/config/sysinfo_box.py index a776b4c75..6f1f9d177 100644 --- a/lutris/gui/config/sysinfo_box.py +++ b/lutris/gui/config/sysinfo_box.py @@ -2,29 +2,29 @@ from gettext import gettext as _ from gi.repository import Gdk, Gtk +from lutris.gui.config.base_config_box import BaseConfigBox from lutris.gui.widgets.log_text_view import LogTextView +from lutris.util import linux, system +from lutris.util.graphics.vkquery import is_vulkan_supported from lutris.util.linux import gather_system_info_str +from lutris.util.wine.wine import is_esync_limit_set, is_fsync_supported, is_installed_systemwide -class SystemBox(Gtk.Box): - settings_options = { - "hide_client_on_game_start": _("Minimize client when a game is launched"), - "hide_text_under_icons": _("Hide text under icons"), - "hide_badges_on_icons": _("Hide badges on icons"), - "show_tray_icon": _("Show Tray Icon"), - } +class SystemBox(BaseConfigBox): def __init__(self): - super().__init__( - orientation=Gtk.Orientation.VERTICAL, - visible=True, - spacing=6, - margin_top=40, - margin_bottom=40, - margin_right=100, - margin_left=100) + super().__init__() self._clipboard_buffer = None + self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + + self.add(self.get_section_label(_("System features"))) + feature_widgets = self.get_feature_widgets() + self.add(self._get_framed_options_list_box(feature_widgets)) + + sysinfo_label = Gtk.Label(halign=Gtk.Align.START, visible=True) + sysinfo_label.set_markup(_("System information")) + self.pack_start(sysinfo_label, False, False, 0) sysinfo_frame = Gtk.Frame(visible=True) scrolled_window = Gtk.ScrolledWindow(visible=True) @@ -34,16 +34,63 @@ class SystemBox(Gtk.Box): self.sysinfo_view.set_cursor_visible(False) scrolled_window.add(self.sysinfo_view) sysinfo_frame.add(scrolled_window) - - self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + self.pack_start(sysinfo_frame, True, True, 0) button_copy = Gtk.Button(_("Copy to Clipboard"), halign=Gtk.Align.START, visible=True) button_copy.connect("clicked", self._copy_text) - sysinfo_label = Gtk.Label(halign=Gtk.Align.START, visible=True) - sysinfo_label.set_markup(_("System information")) - self.pack_start(sysinfo_label, False, False, 0) # 60, 0) - self.pack_start(sysinfo_frame, True, True, 0) # 60, 24) - self.pack_start(button_copy, False, False, 0) # 60, 486) + + self.pack_start(button_copy, False, False, 0) + + def get_feature_widgets(self): + """Return a list of labels related to this system's features""" + yes = _("YES") + no = _("NO") + labels = [] + features = [ + { + "label": _("Vulkan support:\t%s"), + "callable": is_vulkan_supported, + }, + { + "label": _("Esync support:\t%s"), + "callable": is_esync_limit_set, + }, + { + "label": _("Fsync support:\t%s"), + "callable": is_fsync_supported, + }, + { + "label": _("Wine installed:\t%s"), + "callable": is_installed_systemwide, + }, + { + "label": _("Gamescope:\t\t%s"), + "callable": system.can_find_executable, + "args": ("gamescope", ) + }, + { + "label": _("Mangohud:\t\t%s"), + "callable": system.can_find_executable, + "args": ("mangohud", ) + }, + { + "label": _("Gamemode:\t\t%s"), + "callable": linux.LINUX_SYSTEM.gamemode_available + }, + { + "label": _("Steam:\t\t\t%s"), + "callable": linux.LINUX_SYSTEM.has_steam + }, + { + "label": _("In Flatpak:\t\t\t%s"), + "callable": linux.LINUX_SYSTEM.is_flatpak + }, + ] + for feature in features: + label = Gtk.Label(visible=True, xalign=0) + label.set_markup(feature["label"] % (yes if feature["callable"](*feature.get("args", ())) else no)) + labels.append(label) + return labels def populate(self): sysinfo_str = gather_system_info_str() @@ -52,5 +99,5 @@ class SystemBox(Gtk.Box): text_buffer.set_text(sysinfo_str) self._clipboard_buffer = sysinfo_str - def _copy_text(self, widget): # pylint: disable=unused-argument + def _copy_text(self, _widget): self.clipboard.set_text(self._clipboard_buffer, -1) diff --git a/lutris/gui/config/updates_box.py b/lutris/gui/config/updates_box.py index 2811d85cb..ef63a5287 100644 --- a/lutris/gui/config/updates_box.py +++ b/lutris/gui/config/updates_box.py @@ -116,15 +116,6 @@ class UpdatesBox(BaseConfigBox): label.props.wrap = True return radio_button - def _get_framed_options_list_box(self, items): - frame = Gtk.Frame(visible=True, shadow_type=Gtk.ShadowType.ETCHED_IN) - list_box = Gtk.ListBox(visible=True, selection_mode=Gtk.SelectionMode.NONE) - frame.add(list_box) - - for item in items: - list_box.add(Gtk.ListBoxRow(child=item, visible=True, activatable=False)) - return frame - def on_download_media_clicked(self, _widget): self.update_media_box.show_running_markup(_("Checking for missing media...")) AsyncCall(sync_media, self.on_media_updated) diff --git a/lutris/runners/steam.py b/lutris/runners/steam.py index 9f45fdb89..73fbb0a80 100644 --- a/lutris/runners/steam.py +++ b/lutris/runners/steam.py @@ -114,7 +114,7 @@ class steam(Runner): @property def runnable_alone(self): - return not linux.LINUX_SYSTEM.is_flatpak + return not linux.LINUX_SYSTEM.is_flatpak() @property def appid(self): @@ -144,7 +144,7 @@ class steam(Runner): return appmanifests[0] def get_executable(self) -> str: - if linux.LINUX_SYSTEM.is_flatpak: + if linux.LINUX_SYSTEM.is_flatpak(): # Fallback to xgd-open for Steam URIs in Flatpak return system.find_executable("xdg-open") if self.runner_config.get("lsi_steam") and system.can_find_executable("lsi-steam"): @@ -221,7 +221,7 @@ class steam(Runner): command = [binary_path] else: # Start through steam - if linux.LINUX_SYSTEM.is_flatpak: + if linux.LINUX_SYSTEM.is_flatpak(): if game_args: steam_uri = "steam://run/%s//%s/" % (self.appid, game_args) else: diff --git a/lutris/runners/web.py b/lutris/runners/web.py index c1a5bf7c3..4b17459c2 100644 --- a/lutris/runners/web.py +++ b/lutris/runners/web.py @@ -253,7 +253,7 @@ class web(Runner): if self.runner_config.get("user_agent"): command.append("--user-agent") command.append(self.runner_config.get("user_agent")) - if linux.LINUX_SYSTEM.is_flatpak: + if linux.LINUX_SYSTEM.is_flatpak(): command.append("--no-sandbox") return {"command": command, "env": self.get_env(False)} diff --git a/lutris/services/__init__.py b/lutris/services/__init__.py index d8196ea8d..8a7363373 100644 --- a/lutris/services/__init__.py +++ b/lutris/services/__init__.py @@ -42,9 +42,9 @@ def get_services(): } if BNET_ENABLED: _services["battlenet"] = BattleNetService - if not LINUX_SYSTEM.is_flatpak: + if not LINUX_SYSTEM.is_flatpak(): _services["xdg"] = XDGService - if LINUX_SYSTEM.has_steam: + if LINUX_SYSTEM.has_steam(): _services["steam"] = SteamService _services["steamwindows"] = SteamWindowsService if system.path_exists(DOLPHIN_GAME_CACHE_FILE): diff --git a/lutris/util/graphics/vkquery.py b/lutris/util/graphics/vkquery.py index 9bedb426d..2b4ee7190 100644 --- a/lutris/util/graphics/vkquery.py +++ b/lutris/util/graphics/vkquery.py @@ -243,7 +243,7 @@ class VkPhysicalDeviceProperties(Structure): @lru_cache(maxsize=None) -def is_vulkan_supported(): +def is_vulkan_supported() -> bool: """ Returns True iff vulkan library can be loaded, initialized, and reports at least one physical device available. diff --git a/lutris/util/linux.py b/lutris/util/linux.py index f6e0ab483..76977e780 100644 --- a/lutris/util/linux.py +++ b/lutris/util/linux.py @@ -236,7 +236,6 @@ class LinuxSystem: # pylint: disable=too-many-public-methods logger.exception("Unable to determine NVidia version: %s", ex) return False - @property def has_steam(self): """Return whether Steam is installed locally""" return ( @@ -250,7 +249,6 @@ class LinuxSystem: # pylint: disable=too-many-public-methods """Return the display server used""" return os.environ.get("XDG_SESSION_TYPE", "unknown") - @property def is_flatpak(self): """Check is we are running inside Flatpak sandbox""" return system.path_exists("/.flatpak-info") diff --git a/lutris/util/xdgshortcuts.py b/lutris/util/xdgshortcuts.py index febc659ce..a2f3ed8d2 100644 --- a/lutris/util/xdgshortcuts.py +++ b/lutris/util/xdgshortcuts.py @@ -15,7 +15,7 @@ from lutris.util.log import logger def get_lutris_executable(): - if LINUX_SYSTEM.is_flatpak: + if LINUX_SYSTEM.is_flatpak(): return "flatpak run net.lutris.Lutris" return "lutris" @@ -101,7 +101,7 @@ def create_launcher(game_slug, game_id, game_name, launch_config_name=None, desk logger.debug("Creating Desktop icon in %s", launcher_path) shutil.copy(tmp_launcher_path, launcher_path) if menu: - user_dir = os.path.expanduser("~/.local/share") if LINUX_SYSTEM.is_flatpak else GLib.get_user_data_dir() + user_dir = os.path.expanduser("~/.local/share") if LINUX_SYSTEM.is_flatpak() else GLib.get_user_data_dir() menu_path = os.path.join(user_dir, "applications") os.makedirs(menu_path, exist_ok=True) launcher_path = os.path.join(menu_path, launcher_filename)