feat(app-binding): lier les presets aux applications

Ajoute la configuration des associations application/preset, le service de suivi du focus, l'intégration GUI et les fichiers d'installation nécessaires.

Ajoute les tests unitaires ciblés des bindings, du service de focus, des migrations et des composants GUI associés.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 23:52:34 +02:00
parent 0ab77d2a64
commit 9ef2c1439c
42 changed files with 4353 additions and 12 deletions

View File

@ -23,8 +23,9 @@ from __future__ import annotations
import copy
import json
import os
from typing import Optional
from typing import List, Optional
from inputremapper.configs.app_binding import AppBinding
from inputremapper.configs.paths import PathUtils
from inputremapper.logging.logger import logger, VERSION
from inputremapper.user import UserUtils
@ -37,6 +38,8 @@ NONE = "none"
INITIAL_CONFIG = {
"version": VERSION,
"autoload": {},
"app_binding_enabled": False,
"app_bindings": [],
}
@ -87,6 +90,32 @@ class GlobalConfig:
return self._config.get("autoload", {}).get(group_key) == preset
def get_app_binding_enabled(self) -> bool:
"""Whether focus-driven preset binding is enabled."""
return bool(self._config.get("app_binding_enabled", False))
def set_app_binding_enabled(self, enabled: bool) -> None:
"""Enable or disable focus-driven preset binding."""
self._config["app_binding_enabled"] = bool(enabled)
self._save_config()
def get_app_bindings(self) -> List[AppBinding]:
"""Get the configured application bindings as model objects."""
bindings = []
for raw in self._config.get("app_bindings", []):
try:
bindings.append(AppBinding(**raw))
except (TypeError, ValueError) as error:
logger.error("Ignoring invalid app_binding %s: %s", raw, str(error))
return bindings
def set_app_bindings(self, bindings: List[AppBinding]) -> None:
"""Persist the given application bindings."""
self._config["app_bindings"] = [
json.loads(binding.json()) for binding in bindings
]
self._save_config()
def load_config(self, path: Optional[str] = None):
"""Load the config from the file system.
Parameters