mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-13 18:28:14 +02:00
Client: Windows support
This commit is contained in:
1 parent
de362bacd0
commit
954bf39c8f
3 files changed
+58
-7
No files matched your search
+54
-6
@@ -44,8 +44,20 @@ AppName = "SaraView"
|
||||
BundledFontFamily = "Fixedsys Excelsior"
|
||||
ActiveFontFamily = BundledFontFamily # set by ApplyAppearance, read by BuildTheme
|
||||
|
||||
IsWindows = sys.platform == "win32"
|
||||
|
||||
# Each system's own per-user folders, like SaraSuite's: ~/.config, ~/.cache
|
||||
# and ~/.local/share on Linux; %APPDATA% and %LOCALAPPDATA% on Windows.
|
||||
Home = Path.home()
|
||||
SharedConfigDir = Home / ".config" / "SaraSuite"
|
||||
if IsWindows:
|
||||
ConfigHome = Path(os.environ.get("APPDATA") or Home / "AppData" / "Roaming")
|
||||
DataHome = Path(os.environ.get("LOCALAPPDATA") or Home / "AppData" / "Local")
|
||||
CacheHome = DataHome
|
||||
else:
|
||||
ConfigHome = Path(os.environ.get("XDG_CONFIG_HOME") or Home / ".config")
|
||||
DataHome = Path(os.environ.get("XDG_DATA_HOME") or Home / ".local" / "share")
|
||||
CacheHome = Path(os.environ.get("XDG_CACHE_HOME") or Home / ".cache")
|
||||
SharedConfigDir = ConfigHome / "SaraSuite"
|
||||
ThemesDir = SharedConfigDir / "Themes"
|
||||
SharedConfigPath = SharedConfigDir / "Config.toml"
|
||||
ConfigDir = SharedConfigDir / AppName
|
||||
@@ -54,8 +66,7 @@ ConfigPath = ConfigDir / "Config.toml"
|
||||
# never carries it.
|
||||
SessionPath = ConfigDir / "Session.toml"
|
||||
# Server files opened in another program are downloaded here first.
|
||||
CacheDir = Home / ".cache" / AppName
|
||||
DataHome = Home / ".local" / "share"
|
||||
CacheDir = CacheHome / AppName / "Cache" if IsWindows else CacheHome / AppName
|
||||
|
||||
# Inside a PyInstaller build, bundled files are unpacked to sys._MEIPASS.
|
||||
BundleDir = Path(getattr(sys, "_MEIPASS", Path(__file__).resolve().parent))
|
||||
@@ -307,16 +318,53 @@ def ChildEnvironment() -> dict[str, str]:
|
||||
Environment.pop("LD_LIBRARY_PATH", None)
|
||||
for Key in ("PYTHONHOME", "PYTHONPATH"):
|
||||
Environment.pop(Key, None)
|
||||
if IsWindows:
|
||||
Environment["PYTHONUTF8"] = "1" # every Sara program reads and writes UTF-8
|
||||
return Environment
|
||||
|
||||
|
||||
def OpenExternally(FilePath: Path) -> None:
|
||||
"""Hands a file to the system's default program. Raises OSError."""
|
||||
if IsWindows:
|
||||
os.startfile(str(FilePath))
|
||||
return
|
||||
subprocess.Popen(["xdg-open", str(FilePath)], env=ChildEnvironment(), start_new_session=True)
|
||||
|
||||
|
||||
def _WindowsFonts() -> set[str]:
|
||||
"""Font families from the system and per-user Fonts registry keys
|
||||
("Arial Bold (TrueType)" -> "Arial")."""
|
||||
import re
|
||||
import winreg
|
||||
|
||||
Families: set[str] = set()
|
||||
Key = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
|
||||
for Root in (winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER):
|
||||
try:
|
||||
with winreg.OpenKey(Root, Key) as Fonts:
|
||||
Index = 0
|
||||
while True:
|
||||
try:
|
||||
Name = winreg.EnumValue(Fonts, Index)[0]
|
||||
except OSError:
|
||||
break
|
||||
Index += 1
|
||||
Name = re.sub(r"\s*\(.*\)$", "", Name)
|
||||
Name = re.sub(r"\s+(Bold|Italic|Light|Semibold|SemiBold|Black|Regular|Medium|Thin)\b.*$", "", Name)
|
||||
if Name and "&" not in Name:
|
||||
Families.add(Name.strip())
|
||||
except OSError:
|
||||
continue
|
||||
return Families
|
||||
|
||||
|
||||
def InstalledFontFamilies() -> list[str]:
|
||||
"""Font families fontconfig knows about, with the bundled font first."""
|
||||
"""Font families fontconfig (or, on Windows, the registry) knows about,
|
||||
with the bundled font first."""
|
||||
if IsWindows:
|
||||
Families = _WindowsFonts()
|
||||
Families.discard(BundledFontFamily)
|
||||
return [BundledFontFamily] + sorted(Families, key=str.lower)
|
||||
try:
|
||||
Result = subprocess.run(
|
||||
["fc-list", ":", "family"], capture_output=True, text=True, timeout=5, env=ChildEnvironment(),
|
||||
@@ -489,9 +537,9 @@ def HumanSize(NumBytes: Optional[int]) -> str:
|
||||
|
||||
|
||||
def DisplayPath(PathText: str) -> str:
|
||||
"""/home/sarah/Notes -> ~/Notes, for labels."""
|
||||
"""/home/sarah/Notes -> ~/Notes, for labels (C:\\Users\\x\\Notes -> ~\\Notes)."""
|
||||
HomeText = str(Home)
|
||||
if PathText == HomeText or PathText.startswith(HomeText + "/"):
|
||||
if PathText == HomeText or PathText.startswith(HomeText + os.sep):
|
||||
return "~" + PathText[len(HomeText):]
|
||||
return PathText
|
||||
|
||||
|
||||
+4
-1
@@ -5,6 +5,7 @@ the right."""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
import flet as ft
|
||||
@@ -22,7 +23,7 @@ from Settings import ShowSettingsDialog
|
||||
def _SetCursorThemeFallback() -> None:
|
||||
"""GTK reads XCURSOR_THEME directly and doesn't always inherit it (shows as
|
||||
'Unable to load ... from the cursor theme'). Same fix as SaraFem's."""
|
||||
if os.environ.get("XCURSOR_THEME"):
|
||||
if os.environ.get("XCURSOR_THEME") or sys.platform == "win32": # GTK/GNOME only
|
||||
return
|
||||
try:
|
||||
Result = subprocess.run(["gsettings", "get", "org.gnome.desktop.interface", "cursor-theme"],
|
||||
@@ -48,6 +49,8 @@ def Main(Page: ft.Page) -> None:
|
||||
Page.bgcolor = Palette.Base
|
||||
Page.window.width = 1180
|
||||
Page.window.height = 760
|
||||
if sys.platform == "win32":
|
||||
Page.window.icon = str(AssetsDir / "Icon.ico") # taskbar/title bar (Linux: the desktop entry)
|
||||
Page.window.min_width = 720
|
||||
Page.window.min_height = 480
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
Reference in new issue
Block a user