REVAMP : Firefox handling
All checks were successful
release / build (push) Successful in 25s
release / verify-windows (push) Successful in 1m15s

This commit is contained in:
jeanotx32
2026-08-12 01:46:14 +02:00
parent 3bd4d5f2ba
commit 77bfa0b8c5
14 changed files with 1223 additions and 108 deletions

View File

@@ -1,5 +1,6 @@
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import type { FullscreenOutcome } from './fullscreen.ts';
import { resolveXauthority, sessionEnv } from './x11.ts';
const run = promisify(execFile);
@@ -11,11 +12,6 @@ export interface HotkeyRequest {
windowMatch: string;
}
export interface HotkeyResult {
method: string;
window?: string;
}
/**
* Jeu de touches autorisé. Ces valeurs viennent de la configuration serveur et
* finissent dans une ligne de commande : on refuse tout ce qui sort du lot
@@ -42,7 +38,7 @@ function assertKey(key: string): string {
* on injecte la touche via XTEST. Sur une VM d'enregistrement dédiée c'est sans
* conséquence, mais ça vole le focus si quelqu'un est en train de s'en servir.
*/
export async function sendHotkey(request: HotkeyRequest): Promise<HotkeyResult> {
export async function sendHotkey(request: HotkeyRequest): Promise<FullscreenOutcome> {
const key = assertKey(request.key);
const match = request.windowMatch.trim();
if (!match) throw new Error('Aucun titre de fenêtre à cibler (windowMatch vide)');
@@ -197,10 +193,9 @@ function describeNoMatch(match: string, windows: VisibleWindow[]): string {
return (
`Session Wayland : côté X11, seule la fenêtre technique du compositeur est visible ` +
`(${only}). Firefox y tourne en client Wayland natif — xdotool ne peut ni le voir ni ` +
'lui envoyer de touche. Deux issues : relancer Firefox sous XWayland (ferme toutes ses ' +
"fenêtres d'abord, l'agent pose MOZ_ENABLE_WAYLAND=0 au lancement ; une instance déjà " +
"ouverte en Wayland récupérerait l'URL et le réglage resterait sans effet), ou ouvrir " +
'une session Xorg depuis l\'écran de connexion GDM.'
'lui envoyer de touche, et aucun réglage ne changera cela. Passe le pilotage du ' +
'navigateur en mode « WebDriver BiDi » dans la configuration de cet agent : l\'agent ' +
'parle alors à Firefox directement, sans passer par le serveur d\'affichage.'
);
}
@@ -212,14 +207,14 @@ function describeNoMatch(match: string, windows: VisibleWindow[]): string {
);
}
async function sendLinux(key: string, match: string): Promise<HotkeyResult> {
async function sendLinux(key: string, match: string): Promise<FullscreenOutcome> {
const env = sessionEnv();
const target = await findWindow(env, match);
await run('xdotool', ['windowactivate', '--sync', target.id], { env, timeout: 5000 });
await run('xdotool', ['key', '--clearmodifiers', key], { env, timeout: 5000 });
return { method: 'xdotool', window: target.title };
return { method: 'xdotool', target: target.title };
}
// --- Windows ----------------------------------------------------------------
@@ -229,7 +224,7 @@ function psLiteral(value: string): string {
return `'${value.replace(/'/g, "''")}'`;
}
async function sendWindows(key: string, match: string): Promise<HotkeyResult> {
async function sendWindows(key: string, match: string): Promise<FullscreenOutcome> {
// SendKeys interprète certains caractères ; les touches nommées se notent {F11}.
const sendKeysArg = key.length === 1 ? key.toLowerCase() : `{${key.toUpperCase()}}`;
@@ -282,7 +277,7 @@ Write-Output $script:foundTitle
['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', encoded],
{ timeout: 20_000, windowsHide: true },
);
return { method: 'SendKeys', window: stdout.trim() || undefined };
return { method: 'SendKeys', target: stdout.trim() || undefined };
} catch (err) {
const stderr = (err as { stderr?: string }).stderr?.trim();
throw new Error(stderr || `Envoi de « ${key} » impossible vers « ${match} »`);
@@ -291,7 +286,7 @@ Write-Output $script:foundTitle
// --- macOS (confort de développement) ---------------------------------------
async function sendDarwin(key: string, match: string): Promise<HotkeyResult> {
async function sendDarwin(key: string, match: string): Promise<FullscreenOutcome> {
const script = `
tell application "System Events"
set matches to (every process whose name contains "${match.replace(/["\\]/g, '')}")
@@ -304,7 +299,7 @@ end tell`;
try {
await run('osascript', ['-e', script], { timeout: 15_000 });
return { method: 'osascript', window: match };
return { method: 'osascript', target: match };
} catch (err) {
const stderr = (err as { stderr?: string }).stderr?.trim();
throw new Error(stderr || `Envoi de « ${key} » impossible vers « ${match} »`);