fix : various stuff
All checks were successful
release / build (push) Successful in 21s
release / verify-windows (push) Successful in 1m24s

This commit is contained in:
jeanotx32
2026-08-12 17:18:36 +02:00
parent 2dc3009432
commit 29645c04ca
5 changed files with 201 additions and 25 deletions

View File

@@ -265,10 +265,14 @@ async function startCapture(params: Record<string, unknown>): Promise<unknown> {
// une fenêtre non maximisée que ne rien capturer du tout.
fullscreenResult = await restoreFullscreen(fullscreen)
.then((outcome) => {
// `skipped` prime sur `confirmed` : un envoi non renvoyé n'est jamais
// un échec de ce côté-ci, quel que soit le sort de celui qu'il a
// réutilisé.
const failed = !outcome.skipped && outcome.confirmed === false;
report(
outcome.confirmed === false ? 'warn' : 'info',
failed ? 'warn' : 'info',
describeFullscreen(outcome, fullscreen.key),
outcome.confirmed === false ? 'fullscreen.failed' : 'fullscreen.restored',
failed ? 'fullscreen.failed' : 'fullscreen.restored',
);
return outcome;
})
@@ -411,17 +415,62 @@ function driver(): FirefoxController | null {
return browserSettings.mode === 'bidi' ? firefox : null;
}
/**
* Au-delà de ce délai depuis le dernier envoi, un nouveau rappel est à
* nouveau autorisé. Choisi généreux face au 1200 ms que `restoreFullscreen`
* attend en interne avant de relire l'état : le but n'est pas de couvrir
* l'animation, mais la fenêtre où le flux public vient tout juste de démarrer
* et peut encore vaciller (bref retour en privé, requalification du statut).
*/
const FULLSCREEN_COOLDOWN_MS = 10_000;
/** Aucun rappel encore envoyé sur cette instance d'agent. */
let lastFullscreenAt = 0;
/** Deux appels concurrents doivent partager le même envoi, pas en déclencher deux. */
let fullscreenInFlight: Promise<FullscreenOutcome> | null = null;
/**
* Rappelle le plein écran par la voie correspondant au mode de pilotage.
*
* En BiDi, la demande part dans Firefox et son effet est relu dans la page. En
* `launch`, on en reste à une touche envoyée au serveur d'affichage, sans
* moyen de savoir ce qu'elle a produit — d'où le `confirmed` absent.
*
* Point de passage unique, et c'est voulu : deux mécanismes indépendants
* peuvent réclamer ce rappel — la séquence d'ouverture ({@link startCapture})
* et {@link StreamWatcher}, qui le redemande de lui-même après un show privé.
* Sans coordination, un flux qui vacille juste après le démarrage (un retour
* bref en privé pendant que la séquence d'ouverture patiente encore) fait
* partir les deux envois à quelques secondes d'écart. La touche du lecteur
* basculant l'affichage plutôt que le forçant, le second envoi annule le
* premier au lieu de le confirmer — d'où une fenêtre qui, au lieu de
* s'agrandir, finit par rétrécir. Le garde-fou vit ici et non chez l'un des
* deux appelants : c'est le seul endroit que les deux traversent forcément.
*/
async function restoreFullscreen(settings: FullscreenSettings): Promise<FullscreenOutcome> {
// Un envoi est déjà en cours : partager son résultat, pas en déclencher un
// second. Marqué `skipped` malgré le succès qu'il rapporte — c'est cette
// marque, et non la réussite, qui doit gouverner le message affiché à
// l'appelant (voir describeFullscreen) : sans elle, les deux appelants
// journalisent chacun « touche envoyée » pour un seul envoi réel, ce qui
// se lit comme deux rappels distincts alors qu'il n'y en a eu qu'un.
if (fullscreenInFlight) {
const outcome = await fullscreenInFlight;
return { ...outcome, skipped: true };
}
const sinceLast = Date.now() - lastFullscreenAt;
if (lastFullscreenAt > 0 && sinceLast < FULLSCREEN_COOLDOWN_MS) {
return { method: 'ignoré (rappel trop rapproché)', skipped: true };
}
const bidi = driver();
if (bidi) return bidi.restoreFullscreen(settings);
return sendHotkey({ key: settings.key, windowMatch: settings.windowMatch });
fullscreenInFlight = (
bidi ? bidi.restoreFullscreen(settings) : sendHotkey({ key: settings.key, windowMatch: settings.windowMatch })
).finally(() => {
fullscreenInFlight = null;
lastFullscreenAt = Date.now();
});
return fullscreenInFlight;
}
/**