mirror of
https://git.srhtnin.garden/sarah/SaraSuite.git
synced 2026-10-13 18:18:12 +02:00
68 lines
2.8 KiB
Python
68 lines
2.8 KiB
Python
"""Give a Flet program's window its own app ID on Linux, so the desktop can
|
|
match it to the program's .desktop entry (icon, name) instead of showing
|
|
every Flet program as "com.appveyor.flet" with a generic icon.
|
|
|
|
The Flet client's ID is a string built into its small launcher binary
|
|
(`flet`, ~24 KB); the client sets it as both its GTK application ID and its
|
|
process name, so Flet's own FLET_APP_ID (which only changes argv[0]) can't
|
|
override it, on Wayland or X11. Instead this makes a per-program copy of the
|
|
client in ~/.cache/SaraSuite/FletClient/ with that string replaced; the big
|
|
parts (lib/, data/, share/) are symlinks to the original, so a copy costs
|
|
~24 KB. Pointing FLET_VIEW_PATH at it makes Flet use the copy.
|
|
|
|
Used two ways:
|
|
- SaraSuite imports it and calls ClientFor() before ft.run.
|
|
- Installed programs' launchers run it with their own venv's python:
|
|
export FLET_VIEW_PATH="$(python FletIdentity.py srhtnin.SaraFem)"
|
|
It prints the copy's folder, or nothing if anything goes wrong, in which
|
|
case Flet just uses its normal client.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
OriginalId = b"com.appveyor.flet"
|
|
CopiesDir = Path.home() / ".cache" / "SaraSuite" / "FletClient"
|
|
|
|
|
|
def ClientFor(AppId: str) -> str:
|
|
"""Folder of a client copy whose app ID is AppId ("" if not possible).
|
|
AppId needs a dot (a GTK rule) and at most 17 characters, the length of
|
|
the original it replaces in place."""
|
|
try:
|
|
Encoded = AppId.encode("ascii")
|
|
if "." not in AppId or not 0 < len(Encoded) <= len(OriginalId):
|
|
return ""
|
|
from flet_desktop import ensure_client_cached # the program's own Flet version
|
|
|
|
Original = Path(ensure_client_cached()) / "flet"
|
|
Binary = (Original / "flet").read_bytes()
|
|
Copy = CopiesDir / f"{Original.parent.name}-{AppId}" / "flet"
|
|
Patched = Binary.replace(
|
|
b"\x00" + OriginalId + b"\x00",
|
|
b"\x00" + Encoded.ljust(len(OriginalId), b"\x00") + b"\x00",
|
|
)
|
|
if Binary.count(b"\x00" + OriginalId + b"\x00") != 1:
|
|
return "" # not the client layout this was written for
|
|
|
|
Target = Copy / "flet"
|
|
if not (Target.exists() and Target.read_bytes() == Patched):
|
|
Copy.mkdir(parents=True, exist_ok=True)
|
|
for Part in ("lib", "data", "share"):
|
|
Link = Copy / Part
|
|
if Link.is_symlink() or Link.exists():
|
|
Link.unlink()
|
|
if (Original / Part).exists():
|
|
Link.symlink_to(Original / Part)
|
|
Temporary = Target.with_suffix(".new")
|
|
Temporary.write_bytes(Patched)
|
|
Temporary.chmod(0o755)
|
|
Temporary.replace(Target)
|
|
return str(Copy)
|
|
except Exception:
|
|
return ""
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(ClientFor(sys.argv[1]) if len(sys.argv) > 1 else "")
|