mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6282e4401 | ||
|
|
a9ae5f59b5 | ||
|
|
cdec81071d | ||
|
|
97b5c0e6ee | ||
|
|
67c19fb90d | ||
|
|
d9d3f747bb | ||
|
|
1440871819 | ||
|
|
761988d8c2 | ||
|
|
ab5637ae3b | ||
|
|
682532a867 | ||
|
|
d577ba0970 | ||
|
|
c2993ad289 | ||
|
|
edb87893f9 | ||
|
|
519e6c354d | ||
|
|
01b3babdf5 | ||
|
|
e286f02342 | ||
|
|
9f3c39fdd6 | ||
|
|
0359aacd54 | ||
|
|
80e127889e | ||
|
|
da98b1d5b1 | ||
|
|
33869158de |
No files matched your search
@@ -10,7 +10,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from dzgui.api.steam import find_user_id_32
|
||||
from dzgui.const.constants import APP_NAME, APP_NAME_LOWER, GTK_APP_ID, IMAGES_PATH
|
||||
from dzgui.const.constants import APP_NAME, APP_NAME_LOWER, IMAGES_PATH
|
||||
from dzgui.util.dirs import copy_dzgui_to_xdg_data, make_parents
|
||||
from dzgui.util.strings import unknown
|
||||
|
||||
@@ -158,7 +158,7 @@ class Shortcuts:
|
||||
NEW_ENTRY["DevkitGameID"] = ""
|
||||
NEW_ENTRY["DevkitOverrideAppID"] = 0
|
||||
NEW_ENTRY["LastPlayTime"] = 0
|
||||
NEW_ENTRY["FlatpakAppID"] = GTK_APP_ID
|
||||
NEW_ENTRY["FlatpakAppID"] = ""
|
||||
|
||||
NEW_ENTRY["sortas"] = ""
|
||||
NEW_ENTRY["tags"] = {}
|
||||
|
||||
@@ -13,6 +13,7 @@ from warnings import deprecated
|
||||
|
||||
from dzgui.api.acf import ACF
|
||||
from dzgui.init.prereqs import has_any_client
|
||||
from dzgui.init.proc import has_cmd
|
||||
from dzgui.const.constants import (
|
||||
APPID_DAYZ,
|
||||
APPID_DAYZ_EXP,
|
||||
@@ -22,6 +23,7 @@ from dzgui.const.constants import (
|
||||
DEBIAN_STEAM_PATH,
|
||||
DEFAULT_STEAM_PATH,
|
||||
DOWNLOADS_PATH,
|
||||
FLATPAK_CMD,
|
||||
FLATPAK_STEAM_PATH,
|
||||
LIBRARYFOLDERS_PATH,
|
||||
UBUNTU_STEAM_PATH,
|
||||
@@ -82,6 +84,8 @@ def get_steam_paths() -> list[tuple[Path, str]]:
|
||||
}
|
||||
|
||||
for path in DEFAULT_PATH, FLATPAK_PATH, UBUNTU_PATH, DEBIAN_PATH:
|
||||
if path is FLATPAK_PATH and has_cmd(FLATPAK_CMD) is False:
|
||||
continue
|
||||
if path.joinpath(VDF_PATH).is_file():
|
||||
paths.append((path, human[path]))
|
||||
return paths
|
||||
@@ -198,6 +202,7 @@ def load_to_menu(client: str, appid: int, name: str, mods: list[str]) -> int:
|
||||
"""Loads to the menu screen with the selected mods; used for AFK/pre-joining"""
|
||||
concat = concat_mods(mods)
|
||||
client_args = concat_bash_args(client)
|
||||
logger.debug(f"Setting client arguments to: {client_args}")
|
||||
params = [
|
||||
"-applaunch",
|
||||
str(appid),
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ def load_gui(version: str, is_debug: bool) -> None:
|
||||
migrate_cols_file(XDG.columns)
|
||||
copy_state_files(xdg_paths["XDG_STATE_HOME"])
|
||||
# TODO: add logging inside wizard
|
||||
wizard = SetupWizard(_is_steam_deck, XDG)
|
||||
wizard = SetupWizard(_is_steam_deck, XDG, xdg_paths)
|
||||
|
||||
if not wizard.is_setup_complete():
|
||||
return
|
||||
|
||||
+10
-2
@@ -3,7 +3,13 @@ import os
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
|
||||
from dzgui.const.constants import APP_NAME_LOWER, DEBUG_LOG, SYSTEM_LOG
|
||||
from dzgui.const.constants import (
|
||||
APP_NAME_LOWER,
|
||||
DEBUG_LOG,
|
||||
FLATPAK_ROOT_PATH,
|
||||
SYSTEM_LOG,
|
||||
)
|
||||
from dzgui.init.proc import is_sandboxed
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -53,10 +59,12 @@ def get_xdg_paths() -> dict:
|
||||
"XDG_DATA_HOME": home / ".local" / "share",
|
||||
"XDG_CACHE_HOME": home / ".cache",
|
||||
}
|
||||
|
||||
resolved_paths = {}
|
||||
for path in xdg_paths:
|
||||
real_path = os.environ.get(path)
|
||||
if real_path is not None and is_sandboxed():
|
||||
search_string = FLATPAK_ROOT_PATH + "/"
|
||||
real_path = real_path.replace(search_string, "")
|
||||
if real_path is not None and is_writeable(real_path):
|
||||
new_path = Path(real_path)
|
||||
else:
|
||||
|
||||
+10
-3
@@ -1,7 +1,8 @@
|
||||
import psutil
|
||||
import subprocess
|
||||
import shutil
|
||||
import logging
|
||||
import os
|
||||
import psutil
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from dzgui.const.constants import (
|
||||
APP_NAME,
|
||||
@@ -26,7 +27,13 @@ def is_steam_running(cmd: str) -> bool:
|
||||
raise TypeError("Not a valid Steam client selection")
|
||||
|
||||
|
||||
def is_sandboxed() -> bool:
|
||||
return bool(os.environ.get("FLATPAK_ID"))
|
||||
|
||||
|
||||
def is_flatpak_steam_running() -> bool:
|
||||
if is_sandboxed():
|
||||
return True
|
||||
if has_cmd(FLATPAK_CMD) is False:
|
||||
return False
|
||||
proc = subprocess.check_output(
|
||||
|
||||
@@ -17,3 +17,10 @@ fullscreen_eventbox = "This option is not available on Steam Deck."
|
||||
save_button = "Save"
|
||||
|
||||
api_failed = "API validation failed"
|
||||
|
||||
flatpak_label = "Flatpak client"
|
||||
flatpak_standard = "Standard"
|
||||
flatpak_container = "Containerized (flatpak-spawn --host)"
|
||||
flatpak_info = (
|
||||
"Containerized mode is used on certain distributions. May have side effects."
|
||||
)
|
||||
+15
-1
@@ -3,6 +3,8 @@ title_intro = "Welcome"
|
||||
blurb_intro = """
|
||||
This wizard will help you set up some common config options before launching the application.
|
||||
"""
|
||||
error_sandbox = "Setup cannot be run from inside Flatpak sandbox.\nPlease launch the application directly."
|
||||
welcome = "Welcome to {0}!"
|
||||
|
||||
### SteamPathPage
|
||||
heading_steam_path = "Steam path"
|
||||
@@ -70,7 +72,8 @@ checkbox_steam_shortcut = (
|
||||
(
|
||||
"This creates a standalone copy of DZGUI and adds it to Steam. "
|
||||
"You <b>must restart Steam</b> for the shortcut to appear. This will not replace or update existing shortcuts. "
|
||||
"If you update DZGUI when it is launched via Steam, updates will be applied to the Steam version."
|
||||
"If you update DZGUI when it is launched via Steam, updates will be applied to the Steam version. "
|
||||
"Not available if you selected the Flatpak client as your Steam default."
|
||||
),
|
||||
)
|
||||
checkbox_start_menu = (
|
||||
@@ -79,6 +82,17 @@ checkbox_start_menu = (
|
||||
)
|
||||
checkbox_desktop_shortcut = ("Add a desktop shortcut", "Depends on the option above.")
|
||||
|
||||
### Flatpak page
|
||||
heading_flatpak = "Flatpak sandbox overrides"
|
||||
blurb_flatpak = (
|
||||
"You chose to add a shortcut directly to Flatpak Steam. "
|
||||
"To launch DZGUI from Flatpak's sandbox, you must grant "
|
||||
"permission to read from and write to the following locations."
|
||||
)
|
||||
tree_column = "Paths"
|
||||
overrides_applied = "Overrides applied."
|
||||
button_flatpak = "Grant permissions"
|
||||
|
||||
### Completion page
|
||||
heading_completion = "Setup complete"
|
||||
blurb_completion = "Configuration completed successfully. Click 'Close' to close this dialog and launch DZGUI."
|
||||
@@ -1,5 +1,12 @@
|
||||
import shlex
|
||||
|
||||
from dzgui.const.constants import STEAM_CMD
|
||||
from dzgui.init.proc import is_sandboxed
|
||||
|
||||
|
||||
def concat_bash_args(command: str) -> list[str]:
|
||||
# NOTE: NSGs spawned from sandbox cannot access host application commands,
|
||||
# so fallback to Steam internal URIs
|
||||
if is_sandboxed():
|
||||
return [STEAM_CMD]
|
||||
return shlex.split(command)
|
||||
@@ -0,0 +1,31 @@
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
from dzgui.const.constants import APP_NAME, FLATPAK_APPID, GTK_APP_ID
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
|
||||
def apply_overrides(xdg: dict[str, str]) -> None:
|
||||
try:
|
||||
# NOTE: D-Bus registration required for sandbox
|
||||
args = [
|
||||
"flatpak",
|
||||
"--user",
|
||||
"override",
|
||||
f"--own-name={GTK_APP_ID}",
|
||||
FLATPAK_APPID,
|
||||
]
|
||||
subprocess.run([*args], capture_output=True)
|
||||
|
||||
for path in xdg.values():
|
||||
args = [
|
||||
"flatpak",
|
||||
"--user",
|
||||
"override",
|
||||
f"--filesystem={path}",
|
||||
FLATPAK_APPID,
|
||||
]
|
||||
subprocess.run([*args], capture_output=True)
|
||||
except Exception as e:
|
||||
logger.critical(e)
|
||||
@@ -12,21 +12,24 @@ from dzgui.const.constants import (
|
||||
APP_NAME,
|
||||
APP_NAME_LOWER,
|
||||
HERO_PATH,
|
||||
FLATPAK_ROOT_PATH,
|
||||
LEGACY_CONFIG_PATH,
|
||||
)
|
||||
from dzgui.const.boilerplate import config_boilerplate
|
||||
from dzgui.const.endpoints import STEAM_API_SETUP
|
||||
from dzgui.config import freedesktop
|
||||
from dzgui.init.proc import path_to_steam_cmd
|
||||
from dzgui.init.proc import is_sandboxed, path_to_steam_cmd
|
||||
from dzgui.init.migrate import migrate_legacy_conf
|
||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||
from dzgui.strings import wizard
|
||||
from dzgui.util._json import write_json
|
||||
from dzgui.util.flatpak import apply_overrides
|
||||
from dzgui.util.open_links import open_link_by_url
|
||||
from dzgui.util.css import add_class, load_css
|
||||
from dzgui.views.components.buttons import WebButton
|
||||
from dzgui.views.components.entry import APIEntry
|
||||
from dzgui.views.mixins.colorscheme import ColorAwareApp
|
||||
from dzgui.views.trees.tree_simple import SimpleTree
|
||||
|
||||
import gi
|
||||
|
||||
@@ -44,7 +47,8 @@ class PageNum(Enum):
|
||||
STEAM_API = 4
|
||||
USER_PREFS = 5
|
||||
SHORTCUTS = 6
|
||||
FINAL = 7
|
||||
FLATPAK = 7
|
||||
FINAL = 8
|
||||
|
||||
|
||||
class OptionalPageMixin:
|
||||
@@ -143,7 +147,7 @@ class NotificationFrame(Gtk.Frame):
|
||||
margin_start=50,
|
||||
margin_end=50,
|
||||
)
|
||||
wrapped = textwrap.fill(label, width=80)
|
||||
wrapped = textwrap.fill(label, width=60)
|
||||
self.label = Gtk.Label(
|
||||
label=wrapped,
|
||||
justify=Gtk.Justification.CENTER,
|
||||
@@ -157,7 +161,7 @@ class NotificationFrame(Gtk.Frame):
|
||||
add_class(self, "error-frame")
|
||||
|
||||
def set_text(self, text: str) -> None:
|
||||
wrapped = textwrap.fill(text, width=80)
|
||||
wrapped = textwrap.fill(text, width=60)
|
||||
self.label.set_markup(wrapped)
|
||||
|
||||
|
||||
@@ -242,12 +246,23 @@ class IntroductionPage(EnumeratedWizardPage):
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
enum=PageNum.INTRO,
|
||||
heading=f"Welcome to {APP_NAME}!",
|
||||
heading=wizard.welcome.format(APP_NAME),
|
||||
description=wizard.blurb_intro,
|
||||
)
|
||||
self.page_type = Gtk.AssistantPageType.INTRO
|
||||
self.set_title(wizard.title_intro)
|
||||
|
||||
self.error_box = NotificationFrame(wizard.error_sandbox, error=True)
|
||||
self.add_start(self.error_box)
|
||||
|
||||
self.connect("map", self._on_map)
|
||||
|
||||
def _on_map(self, page: "EnumeratedWizardPage") -> None:
|
||||
self.error_box.hide()
|
||||
if is_sandboxed():
|
||||
self.error_box.show()
|
||||
EMITTER.emit("step_pending")
|
||||
|
||||
|
||||
class Heading(Gtk.Label):
|
||||
def __init__(self, label: str):
|
||||
@@ -404,6 +419,42 @@ class PreferencesPage(EnumeratedWizardPage):
|
||||
EMITTER.emit("step_complete")
|
||||
|
||||
|
||||
class FlatpakOverridePage(EnumeratedWizardPage):
|
||||
def __init__(self, xdg_paths: dict[str, str]) -> None:
|
||||
super().__init__(
|
||||
enum=PageNum.FLATPAK,
|
||||
heading=wizard.heading_flatpak,
|
||||
description=wizard.blurb_flatpak,
|
||||
)
|
||||
self.xdg_paths = xdg_paths
|
||||
self.page_type = Gtk.AssistantPageType.INTRO
|
||||
|
||||
store = Gtk.ListStore(str)
|
||||
for path in xdg_paths.values():
|
||||
store.append((str(path),))
|
||||
tree = SimpleTree(store, wizard.tree_column)
|
||||
tree.set_halign(Gtk.Align.CENTER)
|
||||
|
||||
self.authorize_button = Gtk.Button(
|
||||
label=wizard.button_flatpak, halign=Gtk.Align.CENTER
|
||||
)
|
||||
self.authorize_button.connect("clicked", self._on_authorize)
|
||||
|
||||
self.notice = NotificationFrame(wizard.overrides_applied)
|
||||
self.connect("map", self._on_map)
|
||||
|
||||
for el in tree, self.authorize_button, self.notice:
|
||||
self.add_start(el)
|
||||
|
||||
def _on_map(self, page: "EnumeratedWizardPage") -> None:
|
||||
self.notice.hide()
|
||||
|
||||
def _on_authorize(self, button: Gtk.Button) -> None:
|
||||
apply_overrides(self.xdg_paths)
|
||||
self.notice.show()
|
||||
EMITTER.emit("step_complete")
|
||||
|
||||
|
||||
class CompletionPage(EnumeratedWizardPage):
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
@@ -417,7 +468,7 @@ class CompletionPage(EnumeratedWizardPage):
|
||||
|
||||
|
||||
class Assistant(Gtk.Assistant):
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg"):
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]):
|
||||
super().__init__()
|
||||
if is_deck:
|
||||
# NOTE: deemed to be "safe" dimensions that exclude taskbar size
|
||||
@@ -436,6 +487,7 @@ class Assistant(Gtk.Assistant):
|
||||
self.page_api = SteamValidationPage()
|
||||
self.page_prefs = PreferencesPage()
|
||||
self.page_shortcuts = ShortcutCreationPage(XDG.shortcut)
|
||||
self.page_flatpak = FlatpakOverridePage(xdg_paths)
|
||||
self.page_completion = CompletionPage()
|
||||
|
||||
self.set_forward_page_func(self._advance_page)
|
||||
@@ -455,6 +507,7 @@ class Assistant(Gtk.Assistant):
|
||||
self.page_api,
|
||||
self.page_prefs,
|
||||
self.page_shortcuts,
|
||||
self.page_flatpak,
|
||||
self.page_completion,
|
||||
):
|
||||
# NOTE: skip config migration page if no legacy config file
|
||||
@@ -475,7 +528,10 @@ class Assistant(Gtk.Assistant):
|
||||
def write_config(self, config: dict[str, Any]) -> None:
|
||||
write_json(config, self.config_path)
|
||||
|
||||
def get_final_page(self) -> int:
|
||||
def get_completion_page(self) -> int:
|
||||
return self.pages[self.page_completion]
|
||||
|
||||
def get_shortcut_page(self) -> int:
|
||||
return self.pages[self.page_shortcuts]
|
||||
|
||||
def _advance_page(self, index: int) -> int:
|
||||
@@ -488,7 +544,7 @@ class Assistant(Gtk.Assistant):
|
||||
sp = page.migrated_conf["default_steam_path"]
|
||||
self.page_shortcuts.set_steam_path(sp)
|
||||
self.config_values = self.page_migration.migrated_conf
|
||||
return self.get_final_page()
|
||||
return self.get_shortcut_page()
|
||||
case SteamPathPage():
|
||||
path = page.get_path_from_radio()
|
||||
self.config_values["default_steam_path"] = path
|
||||
@@ -505,10 +561,22 @@ class Assistant(Gtk.Assistant):
|
||||
)
|
||||
case ShortcutCreationPage():
|
||||
page.create_shortcuts()
|
||||
if not self.needs_flatpak_override():
|
||||
return self.get_completion_page()
|
||||
case FlatpakOverridePage():
|
||||
pass
|
||||
case _:
|
||||
raise AttributeError("Trying to advance a non-canonical page")
|
||||
return index + 1
|
||||
|
||||
def needs_flatpak_override(self) -> bool:
|
||||
if (
|
||||
self.page_shortcuts.is_steam_checkbox_active()
|
||||
and FLATPAK_ROOT_PATH in self.config_values["default_steam_path"]
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_setup_complete(self) -> bool:
|
||||
return self.setup_complete
|
||||
|
||||
@@ -634,6 +702,9 @@ class ShortcutCreationPage(OptionalPageMixin, EnumeratedWizardPage): # type: ig
|
||||
def set_steam_path(self, path: Path) -> None:
|
||||
self.steam_path = path
|
||||
|
||||
def is_steam_checkbox_active(self) -> bool:
|
||||
return self.steam_checkbox.get_active()
|
||||
|
||||
def create_shortcuts(self) -> None:
|
||||
# NOTE: best-effort, permissive even on failure (page is already marked as complete)
|
||||
if self.steam_checkbox.get_active():
|
||||
@@ -702,10 +773,10 @@ class SteamPathPage(EnumeratedWizardPage):
|
||||
|
||||
|
||||
class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg") -> None:
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None:
|
||||
super().__init__()
|
||||
GLib.set_prgname(APP_NAME)
|
||||
self.win = Window(is_deck, XDG)
|
||||
self.win = Window(is_deck, XDG, xdg_paths)
|
||||
Gtk.main()
|
||||
|
||||
def is_setup_complete(self) -> int:
|
||||
@@ -713,9 +784,9 @@ class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
|
||||
|
||||
|
||||
class Window(Gtk.Window):
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg") -> None:
|
||||
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None:
|
||||
super().__init__(title=APP_NAME, icon_name=APP_NAME)
|
||||
self.assistant = Assistant(is_deck, XDG)
|
||||
self.assistant = Assistant(is_deck, XDG, xdg_paths)
|
||||
|
||||
|
||||
class Emitter(GObject.GObject):
|
||||
|
||||
@@ -9,6 +9,9 @@ from dzgui.const.constants import (
|
||||
APPID_DAYZ_EXP,
|
||||
APPNAME_DAYZ,
|
||||
APPNAME_DAYZ_EXP_HUMAN,
|
||||
FLATPAK_RUN_CMD,
|
||||
FLATPAK_SANDBOX,
|
||||
FLATPAK_STEAM_PATH,
|
||||
NO_EXPAND,
|
||||
NO_FILL,
|
||||
NO_PADDING,
|
||||
@@ -246,6 +249,26 @@ class ToggleField(Gtk.Box):
|
||||
el.set_sensitive(state)
|
||||
|
||||
|
||||
class FlatpakToggleField(ToggleField):
|
||||
def __init__(
|
||||
self,
|
||||
controller: "Controller",
|
||||
) -> None:
|
||||
super().__init__(
|
||||
controller,
|
||||
first_option=options.flatpak_standard,
|
||||
second_option=options.flatpak_container,
|
||||
context=Preferences.CLIENT,
|
||||
)
|
||||
self.add(InfoEventBox(options.flatpak_info, self.controller))
|
||||
self.controller = controller
|
||||
self.radio1.connect("toggled", self._on_radio_toggled, Preferences.CLIENT)
|
||||
|
||||
def _on_radio_toggled(self, button: Gtk.RadioButton, context: Preferences) -> None:
|
||||
cmd = FLATPAK_RUN_CMD if self.radio1.get_active() else FLATPAK_SANDBOX
|
||||
self.controller.update_config(context, cmd)
|
||||
|
||||
|
||||
class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
def __init__(self, controller: "Controller"):
|
||||
super().__init__(
|
||||
@@ -274,6 +297,7 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
self.player_box.set_halign(Gtk.Align.START)
|
||||
self.player_box.get_children()[0].set_width_chars(30) # type: ignore
|
||||
|
||||
self.flatpak_toggle = FlatpakToggleField(self.controller)
|
||||
self.fullscreen_toggle = ToggleField(
|
||||
self.controller,
|
||||
strings.options.last_used,
|
||||
@@ -309,6 +333,12 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
[LeftLabel(options.start_tab), start_tab_hbox],
|
||||
[LeftLabel(strings.options.name), self.player_box],
|
||||
]
|
||||
default = self.controller.query_config(Preferences.DEFAULT)
|
||||
if FLATPAK_STEAM_PATH in default:
|
||||
pref_rows.insert(
|
||||
0,
|
||||
[LeftLabel(options.flatpak_label), self.flatpak_toggle],
|
||||
)
|
||||
|
||||
self.dayz_version_label = Gtk.Label(label=strings.null)
|
||||
self.dayz_exp_version_label = Gtk.Label(label=strings.null)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.model.model_factory import FastInsertListStore
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
|
||||
|
||||
class SimpleTree(Gtk.ScrolledWindow):
|
||||
"""Simple scrollable 1-column tree"""
|
||||
|
||||
def __init__(
|
||||
self, model: Union[Gtk.ListStore, "FastInsertListStore"], title: str
|
||||
) -> None:
|
||||
super().__init__(
|
||||
overlay_scrolling=False,
|
||||
propagate_natural_width=True,
|
||||
propagate_natural_height=True,
|
||||
)
|
||||
|
||||
self.tree = Gtk.TreeView(model=model, enable_search=False)
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn(title, renderer, text=0)
|
||||
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
|
||||
column.set_resizable(False)
|
||||
column.set_sort_column_id(0)
|
||||
self.tree.append_column(column)
|
||||
|
||||
self.add(self.tree)
|
||||
|
||||
def get_tree(self) -> Gtk.TreeView:
|
||||
return self.tree
|
||||
+2
-1
@@ -110,10 +110,11 @@ config-settings-package = { pygobject-stubs = { config = "Gtk3,Gdk3,Soup2" } }
|
||||
markers = [
|
||||
"apitest: checks remote endpoints",
|
||||
"config: config file keys/values",
|
||||
"realconfig: depends on actual generated local config file",
|
||||
"flatpak: depends on local flatpak installation",
|
||||
"mods: tests mod metadata/link creation",
|
||||
"pefile: validate PE files",
|
||||
"post_install: requires a completed installation",
|
||||
"realconfig: depends on actual generated local config file",
|
||||
"redact: log redaction mechanisms",
|
||||
"slow: long-running tests",
|
||||
"webtest: depends on remote endpoint",
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import configparser
|
||||
import pytest
|
||||
|
||||
from dzgui.const.constants import FLATPAK_APPID, GTK_APP_ID
|
||||
from dzgui.config.xdg import get_xdg_paths
|
||||
from dzgui.util.flatpak import apply_overrides
|
||||
|
||||
PATHS_KEY = "Context"
|
||||
PATHS_SUBKEY = "filesystems"
|
||||
BUS_KEY = "Session Bus Policy"
|
||||
|
||||
pytestmark = pytest.mark.flatpak
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xdg_paths() -> dict[str, str]:
|
||||
return get_xdg_paths()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def override(xdg_paths) -> None:
|
||||
apply_overrides(xdg_paths)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config(xdg_paths) -> configparser.ConfigParser:
|
||||
conf_path = xdg_paths["XDG_DATA_HOME"].parent.joinpath(
|
||||
f"flatpak/overrides/{FLATPAK_APPID}"
|
||||
)
|
||||
config = configparser.ConfigParser()
|
||||
config.read(conf_path)
|
||||
return config
|
||||
|
||||
|
||||
def test_session_bus(override, config) -> None:
|
||||
bus = config[BUS_KEY][GTK_APP_ID]
|
||||
assert bus == "own"
|
||||
|
||||
|
||||
def test_paths(override, xdg_paths, config) -> None:
|
||||
expect = xdg_paths
|
||||
paths = config[PATHS_KEY][PATHS_SUBKEY].split(";")
|
||||
assert all(str(path) in paths for path in expect.values())
|
||||
@@ -0,0 +1,30 @@
|
||||
import pytest
|
||||
|
||||
from dzgui.const.constants import FLATPAK_RUN_CMD, FLATPAK_SANDBOX
|
||||
from dzgui.const.enum import Preferences
|
||||
from dzgui.views.pages.options import FlatpakToggleField
|
||||
|
||||
|
||||
class MockController:
|
||||
def __init__(self) -> None:
|
||||
self.command: str
|
||||
|
||||
def update_config(self, context: Preferences, cmd: str) -> None:
|
||||
self.command = cmd
|
||||
|
||||
def get_command(self) -> str:
|
||||
return self.command
|
||||
|
||||
|
||||
@pytest.mark.parametrize("index, expect", [(0, FLATPAK_RUN_CMD), (1, FLATPAK_SANDBOX)])
|
||||
def test_toggle(index: int, expect: str) -> None:
|
||||
controller = MockController()
|
||||
toggle = FlatpakToggleField(controller)
|
||||
match index:
|
||||
case 0:
|
||||
toggle.radio2.set_active(True)
|
||||
toggle.radio1.set_active(True)
|
||||
case 1:
|
||||
toggle.radio1.set_active(True)
|
||||
toggle.radio2.set_active(True)
|
||||
assert controller.get_command() == expect
|
||||
@@ -1,3 +1,5 @@
|
||||
import pytest
|
||||
|
||||
from dzgui.api.servers import Details
|
||||
from dzgui.views.dialogs.servers import ServerDetailsDialog
|
||||
|
||||
@@ -21,6 +23,7 @@ class MockController:
|
||||
return None
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
|
||||
def test_html_escaping() -> None:
|
||||
name = "Test server"
|
||||
desc = "<Server description> Game & mods"
|
||||
@@ -31,5 +34,7 @@ def test_html_escaping() -> None:
|
||||
controller = MockController()
|
||||
dialog = ServerDetailsDialog(controller, details)
|
||||
dialog.destroy()
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
|
||||
assert dialog.description.get_text() == desc
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -6,10 +7,11 @@ from dzgui.const.constants import (
|
||||
FLATPAK_ROOT_PATH,
|
||||
FLATPAK_RUN_CMD,
|
||||
FLATPAK_SANDBOX,
|
||||
STEAM_CMD,
|
||||
)
|
||||
from dzgui.init import proc
|
||||
|
||||
pytestmark = pytest.mark.flatpak
|
||||
|
||||
|
||||
class TestSteamDetection(unittest.TestCase):
|
||||
def test_flatpak_detection_with_multiple_running_apps(self):
|
||||
|
||||
Reference in new issue
Block a user