Read shared SaraSuite settings; single menu category

This commit is contained in:
sarah committed 2026-09-24 23:40:22 +02:00
1 parent 89c24aab9e
commit 7018d57dbc
4 files changed
+87 -9

No files matched your search

+62 -3
View File
@@ -14,7 +14,11 @@ import flet as ft
import tomlkit import tomlkit
AppName = "SaraSuite" AppName = "SaraSuite"
FontFamily = "Fixedsys Excelsior" # Bundled in assets/fonts and always registered, so it works as FontFamily
# without being installed. Any other FontFamily is looked up among the
# system's installed fonts.
BundledFontFamily = "Fixedsys Excelsior"
ActiveFontFamily = BundledFontFamily # set by ApplyAppearance, read by BuildTheme
Home = Path.home() Home = Path.home()
ConfigHome = Home / ".config" ConfigHome = Home / ".config"
@@ -25,6 +29,9 @@ SharedConfigDir = ConfigHome / "SaraSuite"
ThemesDir = SharedConfigDir / "Themes" ThemesDir = SharedConfigDir / "Themes"
ConfigDir = SharedConfigDir / "SaraSuite" ConfigDir = SharedConfigDir / "SaraSuite"
ConfigPath = ConfigDir / "Config.toml" ConfigPath = ConfigDir / "Config.toml"
# Settings shared by every SaraSuite program (theme, font, window title bar).
# Same key names as the matching fields in each program's own Config.toml.
SharedConfigPath = SharedConfigDir / "Config.toml"
# Everything SaraSuite itself keeps about installed programs. Nothing in here # Everything SaraSuite itself keeps about installed programs. Nothing in here
# is user-edited, so it's all fair game to delete when a program is removed. # is user-edited, so it's all fair game to delete when a program is removed.
@@ -89,7 +96,13 @@ def ApplyTheme(ThemeName: str) -> None:
@dataclass @dataclass
class AppConfig: class AppConfig:
# True: Theme, FontFamily and HideWindowTitleBar come from the shared
# ~/.config/SaraSuite/Config.toml (edited in SaraFem's Settings, SaraSuite
# tab). False: SaraSuite uses its own values below instead.
UseSharedSettings: bool = True
Theme: str = "CatppuccinMocha" # matches a file in ~/.config/SaraSuite/Themes/ Theme: str = "CatppuccinMocha" # matches a file in ~/.config/SaraSuite/Themes/
FontFamily: str = BundledFontFamily
HideWindowTitleBar: bool = False
# Where the Sara repos live (Gitea on SpineS); manifests # Where the Sara repos live (Gitea on SpineS); manifests
# use it as {GitHost}. # use it as {GitHost}.
GitHost: str = "https://git.srhtnin.garden/sarah" GitHost: str = "https://git.srhtnin.garden/sarah"
@@ -112,6 +125,52 @@ def LoadConfig() -> AppConfig:
return AppConfig(**{Key: Value for Key, Value in Data.items() if Key in KnownFields}) return AppConfig(**{Key: Value for Key, Value in Data.items() if Key in KnownFields})
@dataclass
class SharedSettings:
"""~/.config/SaraSuite/Config.toml, shared by every SaraSuite program.
Same schema and fallback rules as SaraFem's SharedSettings."""
Theme: str = "CatppuccinMocha"
FontFamily: str = BundledFontFamily
HideWindowTitleBar: bool = False
def Save(self) -> None:
SharedConfigDir.mkdir(parents=True, exist_ok=True)
SharedConfigPath.write_text(tomlkit.dumps(asdict(self)))
def _OwnSettings(Config: AppConfig) -> SharedSettings:
return SharedSettings(Config.Theme, Config.FontFamily, Config.HideWindowTitleBar)
def LoadSharedSettings(Config: AppConfig) -> SharedSettings:
"""The shared file, created from this program's own values if missing."""
if not SharedConfigPath.exists():
Shared = _OwnSettings(Config)
Shared.Save()
return Shared
Result = _OwnSettings(Config) # fallback for keys the file doesn't have
try:
Data = tomlkit.parse(SharedConfigPath.read_text()).unwrap()
except tomlkit.exceptions.TOMLKitError:
return Result
for Key in SharedSettings.__dataclass_fields__:
if Key in Data:
setattr(Result, Key, Data[Key])
return Result
def EffectiveSettings(Config: AppConfig) -> SharedSettings:
return LoadSharedSettings(Config) if Config.UseSharedSettings else _OwnSettings(Config)
def ApplyAppearance(Settings: SharedSettings) -> None:
"""Theme colours and font; must run before anything reads Palette.X."""
global ActiveFontFamily
ApplyTheme(Settings.Theme)
ActiveFontFamily = Settings.FontFamily or BundledFontFamily
def ChildEnvironment() -> dict[str, str]: def ChildEnvironment() -> dict[str, str]:
"""The environment for child processes (systemctl, pip, python3 -m venv). """The environment for child processes (systemctl, pip, python3 -m venv).
A PyInstaller build points LD_LIBRARY_PATH at its own bundled libraries A PyInstaller build points LD_LIBRARY_PATH at its own bundled libraries
@@ -158,7 +217,7 @@ def BuildTheme() -> ft.Theme:
on_error=Palette.Crust, on_error=Palette.Crust,
) )
return ft.Theme( return ft.Theme(
font_family=FontFamily, font_family=ActiveFontFamily,
color_scheme=ColorScheme, color_scheme=ColorScheme,
use_material3=True, use_material3=True,
scaffold_bgcolor=Palette.Base, scaffold_bgcolor=Palette.Base,
@@ -166,7 +225,7 @@ def BuildTheme() -> ft.Theme:
dialog_theme=ft.DialogTheme( dialog_theme=ft.DialogTheme(
bgcolor=Palette.Mantle, bgcolor=Palette.Mantle,
shape=ft.RoundedRectangleBorder(radius=8, side=ft.BorderSide(1, Palette.Mauve)), shape=ft.RoundedRectangleBorder(radius=8, side=ft.BorderSide(1, Palette.Mauve)),
title_text_style=ft.TextStyle(color=Palette.Mauve, size=18, font_family=FontFamily), title_text_style=ft.TextStyle(color=Palette.Mauve, size=18, font_family=ActiveFontFamily),
), ),
) )
+7 -5
View File
@@ -10,8 +10,8 @@ from typing import Callable
import flet as ft import flet as ft
from Core import ( from Core import (
AppName, ApplyTheme, AssetsDir, BuildTheme, ChipButtonStyle, DataDir, DataHome, FontFamily, AppName, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, ChipButtonStyle, DataDir,
LoadConfig, Palette, DataHome, EffectiveSettings, LoadConfig, Palette,
) )
from Dialogs import ShowInstallDialog, ShowRemoveDialog, ShowUpdateDialog from Dialogs import ShowInstallDialog, ShowRemoveDialog, ShowUpdateDialog
from Installer import Apply, Fetch, GetStatus, PlanConfigs, PlanRemoval, Remove, SourceVersion from Installer import Apply, Fetch, GetStatus, PlanConfigs, PlanRemoval, Remove, SourceVersion
@@ -38,19 +38,21 @@ def _SetMenuEntry(Enabled: bool) -> None:
"[Desktop Entry]\nType=Application\nName=SaraSuite\n" "[Desktop Entry]\nType=Application\nName=SaraSuite\n"
"Comment=Install, update and remove Sara programs\n" "Comment=Install, update and remove Sara programs\n"
f"Exec={_AppImage}\nIcon={_MenuIcon}\nTerminal=false\n" f"Exec={_AppImage}\nIcon={_MenuIcon}\nTerminal=false\n"
"Categories=System;Settings;\nStartupNotify=true\n" "Categories=System;\nStartupNotify=true\n"
) )
def Main(Page: ft.Page) -> None: def Main(Page: ft.Page) -> None:
Config = LoadConfig() Config = LoadConfig()
ApplyTheme(Config.Theme) # must run before anything reads Palette.X Appearance = EffectiveSettings(Config) # shared SaraSuite settings, or SaraSuite's own
ApplyAppearance(Appearance) # must run before anything reads Palette.X
Page.title = AppName Page.title = AppName
Page.theme_mode = ft.ThemeMode.DARK Page.theme_mode = ft.ThemeMode.DARK
Page.theme = BuildTheme() Page.theme = BuildTheme()
Page.dark_theme = BuildTheme() Page.dark_theme = BuildTheme()
Page.fonts = {FontFamily: "fonts/Fixedsys_Excelsior_Regular.ttf"} Page.fonts = {BundledFontFamily: "fonts/Fixedsys_Excelsior_Regular.ttf"}
Page.window.title_bar_hidden = Appearance.HideWindowTitleBar
Page.padding = 0 Page.padding = 0
Page.bgcolor = Palette.Base Page.bgcolor = Palette.Base
Page.window.width = 960 Page.window.width = 960
+1 -1
View File
@@ -29,7 +29,7 @@ Comment=Install, update and remove Sara programs
Exec=SaraSuite Exec=SaraSuite
Icon=SaraSuite Icon=SaraSuite
Terminal=false Terminal=false
Categories=System;Settings; Categories=System;
DESKTOP DESKTOP
mkdir -p dist mkdir -p dist
+17
View File
@@ -30,6 +30,23 @@ GitHost = "https://git.srhtnin.garden/sarah"
The only thing a program needs from the system is `python3` (for its venv). The only thing a program needs from the system is `python3` (for its venv).
## Shared settings
Settings every SaraSuite program shares live in `~/.config/SaraSuite/Config.toml`:
```toml
Theme = "CatppuccinMocha" # a file in ~/.config/SaraSuite/Themes/
FontFamily = "Fixedsys Excelsior" # the bundled font, or any installed font family
HideWindowTitleBar = false
```
Each program's own `~/.config/SaraSuite/<Program>/Config.toml` has the same three keys plus
`UseSharedSettings` (default `true`). With it on, the program reads the shared file; with it
off, it uses its own values instead. SaraFem edits both in its Settings (the SaraSuite tab
for the shared file, the General tab for its own); for SaraSuite itself, edit its
`Config.toml` directly. Whichever program starts first creates the shared file from its own
values.
## Running and building ## Running and building
- AppImage: `Packaging/BuildAppImage.sh` builds `dist/SaraSuite-x86_64.AppImage` - AppImage: `Packaging/BuildAppImage.sh` builds `dist/SaraSuite-x86_64.AppImage`