fix(focus): détecter correctement l'unfocus sur les backends Wayland

Le suivi du focus laissait les injections app-controlled actives lors d'une
perte de focus réelle (fermeture de la fenêtre courante, retour à un bureau
vide). On corrige la détection sur toute la chaîne :

- FocusService: un app_id vide est désormais traité comme un unfocus réel
  (et non un focus transitoire ignoré), ce qui stoppe les injections liées
  à l'application.
- Sway: on ignore les events 'new' (pas un changement de focus) et on relit
  le focus courant sur un event 'title' non focused.
- WlrForeignToplevelBackend: suit _current_handle, le clear sur stop() et
  émet un FocusEvent vide quand le toplevel actuellement focus se ferme.

Tests: test_focus_service + test_focus_watcher (67) OK; lot feature
historique (295) OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 00:42:15 +02:00
parent 53fe0cc369
commit af10ec8bd1
5 changed files with 139 additions and 11 deletions

View File

@ -171,10 +171,14 @@ class SwayFocusBackend(FocusBackend):
return
change = data.get("change")
if change not in ("focus", "title", "new"):
if change not in ("focus", "title"):
return
event = _container_to_event(data.get("container") or {})
if change == "title" and not (data.get("container") or {}).get("focused"):
event = self.get_current()
else:
event = _container_to_event(data.get("container") or {})
if event is not None and self._on_focus is not None:
self._on_focus(event)