Added resolution settings and updater modal with rollback functionality for launcher versions.
This commit is contained in:
@@ -16,21 +16,27 @@ from .paths import AppPaths
|
||||
|
||||
SETTINGS_SCHEMA = 1
|
||||
_TITLE_FRAME_DEFAULT_MIGRATION_KEY = "title_frame_default_migrated"
|
||||
UI_SCALE_CHOICES = frozenset({"auto", "100", "125", "150", "175", "200"})
|
||||
_RETIRED_DISPLAY_SETTINGS = frozenset(
|
||||
{
|
||||
"width",
|
||||
"height",
|
||||
"output_width",
|
||||
"output_height",
|
||||
"refresh_rate",
|
||||
"fullscreen",
|
||||
"scaler",
|
||||
"filter",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Settings:
|
||||
realm: str = "Babel"
|
||||
width: int = 1600
|
||||
height: int = 900
|
||||
output_width: int = 1600
|
||||
output_height: int = 900
|
||||
refresh_rate: int = 60
|
||||
fullscreen: bool = False
|
||||
ui_scale: str = "auto"
|
||||
borderless: bool = False
|
||||
suppress_unresponsive_warnings: bool = True
|
||||
scaler: str = "fit"
|
||||
filter: str = "linear"
|
||||
runtime: str = "auto"
|
||||
proton_sync: str = "auto"
|
||||
proton_path: str | None = None
|
||||
@@ -136,20 +142,13 @@ def _read_settings_object(path: Path) -> dict[str, object] | None:
|
||||
def _settings_from_object(value: dict[str, object]) -> Settings:
|
||||
settings = Settings(
|
||||
realm=_string(value, "realm", "Babel").strip(),
|
||||
width=_integer(value, "width", 1600),
|
||||
height=_integer(value, "height", 900),
|
||||
output_width=_integer(value, "output_width", 1600),
|
||||
output_height=_integer(value, "output_height", 900),
|
||||
refresh_rate=_integer(value, "refresh_rate", 60),
|
||||
fullscreen=_boolean(value, "fullscreen", False),
|
||||
ui_scale=_string(value, "ui_scale", "auto"),
|
||||
borderless=_migrated_borderless(value),
|
||||
suppress_unresponsive_warnings=_boolean(
|
||||
value,
|
||||
"suppress_unresponsive_warnings",
|
||||
True,
|
||||
),
|
||||
scaler=_string(value, "scaler", "fit"),
|
||||
filter=_string(value, "filter", "linear"),
|
||||
runtime=_string(value, "runtime", "auto"),
|
||||
proton_sync=_string(value, "proton_sync", "auto"),
|
||||
proton_path=_optional_string(value, "proton_path"),
|
||||
@@ -192,6 +191,7 @@ def _settings_need_migration(value: dict[str, object]) -> bool:
|
||||
value.get("schema") != SETTINGS_SCHEMA
|
||||
or not _SETTINGS_FIELD_NAMES.issubset(value)
|
||||
or value.get(_TITLE_FRAME_DEFAULT_MIGRATION_KEY) is not True
|
||||
or bool(_RETIRED_DISPLAY_SETTINGS.intersection(value))
|
||||
)
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ def _write_settings(
|
||||
existing: dict[str, object] | None,
|
||||
) -> None:
|
||||
payload = dict(existing or {})
|
||||
for name in _RETIRED_DISPLAY_SETTINGS:
|
||||
payload.pop(name, None)
|
||||
payload.update(asdict(settings))
|
||||
payload["schema"] = SETTINGS_SCHEMA
|
||||
payload[_TITLE_FRAME_DEFAULT_MIGRATION_KEY] = True
|
||||
@@ -242,33 +244,13 @@ def _validate(settings: Settings) -> None:
|
||||
or any(ord(character) < 32 for character in settings.realm)
|
||||
):
|
||||
raise ValueError("realm must be a non-empty display name")
|
||||
for name, value in (
|
||||
("width", settings.width),
|
||||
("height", settings.height),
|
||||
("output_width", settings.output_width),
|
||||
("output_height", settings.output_height),
|
||||
):
|
||||
if value < 640 or value > 16384:
|
||||
raise ValueError(f"{name} must be between 640 and 16384")
|
||||
if settings.refresh_rate < 24 or settings.refresh_rate > 1000:
|
||||
raise ValueError("refresh_rate must be between 24 and 1000")
|
||||
if settings.scaler not in {"auto", "integer", "fit", "fill", "stretch"}:
|
||||
raise ValueError(f"unsupported legacy scaler setting: {settings.scaler}")
|
||||
if settings.filter not in {"linear", "nearest", "fsr", "nis", "pixel"}:
|
||||
raise ValueError(f"unsupported legacy filter setting: {settings.filter}")
|
||||
if settings.ui_scale not in UI_SCALE_CHOICES:
|
||||
raise ValueError(f"unsupported launcher UI scale: {settings.ui_scale}")
|
||||
if settings.runtime not in {"auto", "proton7", "proton7-container", "umu"}:
|
||||
raise ValueError(f"unsupported runtime selection: {settings.runtime}")
|
||||
if settings.proton_sync not in {"auto", "fsync", "esync"}:
|
||||
raise ValueError(f"unsupported Proton synchronization mode: {settings.proton_sync}")
|
||||
|
||||
|
||||
def _integer(value: dict[str, object], key: str, default: int) -> int:
|
||||
item = value.get(key, default)
|
||||
if isinstance(item, bool) or not isinstance(item, int):
|
||||
raise ValueError(f"{key} must be an integer")
|
||||
return item
|
||||
|
||||
|
||||
def _boolean(value: dict[str, object], key: str, default: bool) -> bool:
|
||||
item = value.get(key, default)
|
||||
if not isinstance(item, bool):
|
||||
|
||||
Reference in New Issue
Block a user