mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
feat: FlatpakOverridePage WIP
This commit is contained in:
1 parent
e286f02342
commit
01b3babdf5
6 files changed
+108
-19
No files matched your search
@@ -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"""
|
"""Loads to the menu screen with the selected mods; used for AFK/pre-joining"""
|
||||||
concat = concat_mods(mods)
|
concat = concat_mods(mods)
|
||||||
client_args = concat_bash_args(client)
|
client_args = concat_bash_args(client)
|
||||||
|
logger.debug(f"Setting client arguments to: {client_args}")
|
||||||
params = [
|
params = [
|
||||||
"-applaunch",
|
"-applaunch",
|
||||||
str(appid),
|
str(appid),
|
||||||
|
|||||||
+10
-2
@@ -3,7 +3,13 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from dataclasses import dataclass
|
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
|
@dataclass
|
||||||
@@ -53,10 +59,12 @@ def get_xdg_paths() -> dict:
|
|||||||
"XDG_DATA_HOME": home / ".local" / "share",
|
"XDG_DATA_HOME": home / ".local" / "share",
|
||||||
"XDG_CACHE_HOME": home / ".cache",
|
"XDG_CACHE_HOME": home / ".cache",
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved_paths = {}
|
resolved_paths = {}
|
||||||
for path in xdg_paths:
|
for path in xdg_paths:
|
||||||
real_path = os.environ.get(path)
|
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):
|
if real_path is not None and is_writeable(real_path):
|
||||||
new_path = Path(real_path)
|
new_path = Path(real_path)
|
||||||
else:
|
else:
|
||||||
|
|||||||
+11
-3
@@ -1,7 +1,8 @@
|
|||||||
import psutil
|
|
||||||
import subprocess
|
|
||||||
import shutil
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import psutil
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from dzgui.const.constants import (
|
from dzgui.const.constants import (
|
||||||
APP_NAME,
|
APP_NAME,
|
||||||
@@ -26,7 +27,14 @@ def is_steam_running(cmd: str) -> bool:
|
|||||||
raise TypeError("Not a valid Steam client selection")
|
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:
|
def is_flatpak_steam_running() -> bool:
|
||||||
|
if is_sandboxed():
|
||||||
|
return True
|
||||||
if has_cmd(FLATPAK_CMD) is False:
|
if has_cmd(FLATPAK_CMD) is False:
|
||||||
return False
|
return False
|
||||||
proc = subprocess.check_output(
|
proc = subprocess.check_output(
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ title_intro = "Welcome"
|
|||||||
blurb_intro = """
|
blurb_intro = """
|
||||||
This wizard will help you set up some common config options before launching the application.
|
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
|
### SteamPathPage
|
||||||
heading_steam_path = "Steam path"
|
heading_steam_path = "Steam path"
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
|
from dzgui.const.constants import STEAM_CMD
|
||||||
|
from dzgui.init.proc import is_sandboxed
|
||||||
|
|
||||||
|
|
||||||
def concat_bash_args(command: str) -> list[str]:
|
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)
|
return shlex.split(command)
|
||||||
@@ -12,13 +12,13 @@ from dzgui.const.constants import (
|
|||||||
APP_NAME,
|
APP_NAME,
|
||||||
APP_NAME_LOWER,
|
APP_NAME_LOWER,
|
||||||
HERO_PATH,
|
HERO_PATH,
|
||||||
FLATPAK_STEAM_PATH,
|
FLATPAK_ROOT_PATH,
|
||||||
LEGACY_CONFIG_PATH,
|
LEGACY_CONFIG_PATH,
|
||||||
)
|
)
|
||||||
from dzgui.const.boilerplate import config_boilerplate
|
from dzgui.const.boilerplate import config_boilerplate
|
||||||
from dzgui.const.endpoints import STEAM_API_SETUP
|
from dzgui.const.endpoints import STEAM_API_SETUP
|
||||||
from dzgui.config import freedesktop
|
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.init.migrate import migrate_legacy_conf
|
||||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||||
from dzgui.strings import wizard
|
from dzgui.strings import wizard
|
||||||
@@ -45,7 +45,8 @@ class PageNum(Enum):
|
|||||||
STEAM_API = 4
|
STEAM_API = 4
|
||||||
USER_PREFS = 5
|
USER_PREFS = 5
|
||||||
SHORTCUTS = 6
|
SHORTCUTS = 6
|
||||||
FINAL = 7
|
FLATPAK = 7
|
||||||
|
FINAL = 8
|
||||||
|
|
||||||
|
|
||||||
class OptionalPageMixin:
|
class OptionalPageMixin:
|
||||||
@@ -144,7 +145,7 @@ class NotificationFrame(Gtk.Frame):
|
|||||||
margin_start=50,
|
margin_start=50,
|
||||||
margin_end=50,
|
margin_end=50,
|
||||||
)
|
)
|
||||||
wrapped = textwrap.fill(label, width=80)
|
wrapped = textwrap.fill(label, width=60)
|
||||||
self.label = Gtk.Label(
|
self.label = Gtk.Label(
|
||||||
label=wrapped,
|
label=wrapped,
|
||||||
justify=Gtk.Justification.CENTER,
|
justify=Gtk.Justification.CENTER,
|
||||||
@@ -158,7 +159,7 @@ class NotificationFrame(Gtk.Frame):
|
|||||||
add_class(self, "error-frame")
|
add_class(self, "error-frame")
|
||||||
|
|
||||||
def set_text(self, text: str) -> None:
|
def set_text(self, text: str) -> None:
|
||||||
wrapped = textwrap.fill(text, width=80)
|
wrapped = textwrap.fill(text, width=60)
|
||||||
self.label.set_markup(wrapped)
|
self.label.set_markup(wrapped)
|
||||||
|
|
||||||
|
|
||||||
@@ -243,12 +244,23 @@ class IntroductionPage(EnumeratedWizardPage):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
enum=PageNum.INTRO,
|
enum=PageNum.INTRO,
|
||||||
heading=f"Welcome to {APP_NAME}!",
|
heading=wizard.welcome.format(APP_NAME),
|
||||||
description=wizard.blurb_intro,
|
description=wizard.blurb_intro,
|
||||||
)
|
)
|
||||||
self.page_type = Gtk.AssistantPageType.INTRO
|
self.page_type = Gtk.AssistantPageType.INTRO
|
||||||
self.set_title(wizard.title_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):
|
class Heading(Gtk.Label):
|
||||||
def __init__(self, label: str):
|
def __init__(self, label: str):
|
||||||
@@ -405,6 +417,43 @@ class PreferencesPage(EnumeratedWizardPage):
|
|||||||
EMITTER.emit("step_complete")
|
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):
|
class CompletionPage(EnumeratedWizardPage):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -437,6 +486,7 @@ class Assistant(Gtk.Assistant):
|
|||||||
self.page_api = SteamValidationPage()
|
self.page_api = SteamValidationPage()
|
||||||
self.page_prefs = PreferencesPage()
|
self.page_prefs = PreferencesPage()
|
||||||
self.page_shortcuts = ShortcutCreationPage(XDG.shortcut)
|
self.page_shortcuts = ShortcutCreationPage(XDG.shortcut)
|
||||||
|
self.page_flatpak = FlatpakOverridePage(XDG)
|
||||||
self.page_completion = CompletionPage()
|
self.page_completion = CompletionPage()
|
||||||
|
|
||||||
self.set_forward_page_func(self._advance_page)
|
self.set_forward_page_func(self._advance_page)
|
||||||
@@ -456,6 +506,7 @@ class Assistant(Gtk.Assistant):
|
|||||||
self.page_api,
|
self.page_api,
|
||||||
self.page_prefs,
|
self.page_prefs,
|
||||||
self.page_shortcuts,
|
self.page_shortcuts,
|
||||||
|
self.page_flatpak,
|
||||||
self.page_completion,
|
self.page_completion,
|
||||||
):
|
):
|
||||||
# NOTE: skip config migration page if no legacy config file
|
# 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:
|
def write_config(self, config: dict[str, Any]) -> None:
|
||||||
write_json(config, self.config_path)
|
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]
|
return self.pages[self.page_shortcuts]
|
||||||
|
|
||||||
def _advance_page(self, index: int) -> int:
|
def _advance_page(self, index: int) -> int:
|
||||||
@@ -489,7 +543,7 @@ class Assistant(Gtk.Assistant):
|
|||||||
sp = page.migrated_conf["default_steam_path"]
|
sp = page.migrated_conf["default_steam_path"]
|
||||||
self.page_shortcuts.set_steam_path(sp)
|
self.page_shortcuts.set_steam_path(sp)
|
||||||
self.config_values = self.page_migration.migrated_conf
|
self.config_values = self.page_migration.migrated_conf
|
||||||
return self.get_final_page()
|
return self.get_shortcuts_page()
|
||||||
case SteamPathPage():
|
case SteamPathPage():
|
||||||
path = page.get_path_from_radio()
|
path = page.get_path_from_radio()
|
||||||
self.config_values["default_steam_path"] = path
|
self.config_values["default_steam_path"] = path
|
||||||
@@ -506,10 +560,22 @@ class Assistant(Gtk.Assistant):
|
|||||||
)
|
)
|
||||||
case ShortcutCreationPage():
|
case ShortcutCreationPage():
|
||||||
page.create_shortcuts()
|
page.create_shortcuts()
|
||||||
|
if not self.needs_flatpak_override():
|
||||||
|
return self.get_completion_page()
|
||||||
|
case FlatpakOverridePage():
|
||||||
|
pass
|
||||||
case _:
|
case _:
|
||||||
raise AttributeError("Trying to advance a non-canonical page")
|
raise AttributeError("Trying to advance a non-canonical page")
|
||||||
return index + 1
|
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:
|
def is_setup_complete(self) -> bool:
|
||||||
return self.setup_complete
|
return self.setup_complete
|
||||||
|
|
||||||
@@ -625,12 +691,6 @@ class ShortcutCreationPage(OptionalPageMixin, EnumeratedWizardPage): # type: ig
|
|||||||
self.add_start(self.checks_area)
|
self.add_start(self.checks_area)
|
||||||
self.show_all()
|
self.show_all()
|
||||||
self.connect("map", self._on_map)
|
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:
|
def _on_start_menu_toggled(self, button: Gtk.CheckButton) -> None:
|
||||||
state = button.get_active()
|
state = button.get_active()
|
||||||
@@ -641,6 +701,9 @@ class ShortcutCreationPage(OptionalPageMixin, EnumeratedWizardPage): # type: ig
|
|||||||
def set_steam_path(self, path: Path) -> None:
|
def set_steam_path(self, path: Path) -> None:
|
||||||
self.steam_path = path
|
self.steam_path = path
|
||||||
|
|
||||||
|
def is_steam_checkbox_active(self) -> None:
|
||||||
|
return self.steam_checkbox.get_active()
|
||||||
|
|
||||||
def create_shortcuts(self) -> None:
|
def create_shortcuts(self) -> None:
|
||||||
# NOTE: best-effort, permissive even on failure (page is already marked as complete)
|
# NOTE: best-effort, permissive even on failure (page is already marked as complete)
|
||||||
if self.steam_checkbox.get_active():
|
if self.steam_checkbox.get_active():
|
||||||
|
|||||||
Reference in new issue
Block a user