feat: FlatpakOverridePage WIP

This commit is contained in:
aclist committed 2026-10-23 11:23:28 +09:00
1 parent e286f02342
commit 01b3babdf5
6 files changed
+108 -19

No files matched your search

+1
View File
@@ -198,6 +198,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),
+10 -2
View File
@@ -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 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:
+11 -3
View File
@@ -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,14 @@ def is_steam_running(cmd: str) -> bool:
raise TypeError("Not a valid Steam client selection")
def is_sandboxed() -> bool:
logger.debug("Inside Flatpak sandbox")
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(
+2
View File
@@ -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"
+7
View File
@@ -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)
+77 -14
View File
@@ -12,13 +12,13 @@ from dzgui.const.constants import (
APP_NAME,
APP_NAME_LOWER,
HERO_PATH,
FLATPAK_STEAM_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
@@ -45,7 +45,8 @@ class PageNum(Enum):
STEAM_API = 4
USER_PREFS = 5
SHORTCUTS = 6
FINAL = 7
FLATPAK = 7
FINAL = 8
class OptionalPageMixin:
@@ -144,7 +145,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,
@@ -158,7 +159,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)
@@ -243,12 +244,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):
@@ -405,6 +417,43 @@ class PreferencesPage(EnumeratedWizardPage):
EMITTER.emit("step_complete")
class FlatpakOverridePage(EnumeratedWizardPage):
def __init__(self, xdg: "Xdg") -> None:
# TODO: strings
super().__init__(
enum=PageNum.FLATPAK,
heading="Flatpak overrides",
description="Enable overrides",
)
self.xdg = xdg
self.page_type = Gtk.AssistantPageType.INTRO
# TODO: labels, blurbs
# You chose to add a DZGUI shortcut directly to Steam.
# Your Steam client selection is Flatpak Steam.
# To launch DZGUI from Flatpak's sandbox, you must
# grant permission for the sandbox to read from and write to the
# following locations.
# Click below to whitelist these paths and enable Steam to register the DZGUI application.
# XDG.config, XDG.share, XDG.state, /tmp?
self.label = Gtk.Label(label="Whitelist")
self.authorize_button = Gtk.Button(
label="Grant permissions", halign=Gtk.Align.CENTER
)
self.authorize_button.connect("clicked", self._on_authorize)
for el in self.label, self.authorize_button:
self.add_start(el)
def _on_authorize(self, button: Gtk.Button) -> None:
# TODO: apply flatpak overrides via module
print(self.xdg)
EMITTER.emit("step_complete")
class CompletionPage(EnumeratedWizardPage):
def __init__(self) -> None:
super().__init__(
@@ -437,6 +486,7 @@ class Assistant(Gtk.Assistant):
self.page_api = SteamValidationPage()
self.page_prefs = PreferencesPage()
self.page_shortcuts = ShortcutCreationPage(XDG.shortcut)
self.page_flatpak = FlatpakOverridePage(XDG)
self.page_completion = CompletionPage()
self.set_forward_page_func(self._advance_page)
@@ -456,6 +506,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
@@ -476,7 +527,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:
@@ -489,7 +543,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_shortcuts_page()
case SteamPathPage():
path = page.get_path_from_radio()
self.config_values["default_steam_path"] = path
@@ -506,10 +560,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) -> None:
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
@@ -625,12 +691,6 @@ class ShortcutCreationPage(OptionalPageMixin, EnumeratedWizardPage): # type: ig
self.add_start(self.checks_area)
self.show_all()
self.connect("map", self._on_map)
self.connect("map", self._toggle_checkbox)
def _toggle_checkbox(self, page: "EnumeratedWizardPage") -> None:
if FLATPAK_STEAM_PATH in str(self.steam_path):
self.steam_checkbox.set_active(False)
self.steam_checkbox.set_sensitive(False)
def _on_start_menu_toggled(self, button: Gtk.CheckButton) -> None:
state = button.get_active()
@@ -641,6 +701,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) -> None:
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():