-
Notifications
You must be signed in to change notification settings - Fork 0
FR 02 Fonctionnement
Ce document décrit le comportement runtime de Copilot_Key+.exe
(Sources/CopilotKey.c) : comment il démarre, comment il détecte
la touche Copilot, comment il la transforme, et comment il se configure/s'arrête.
(Pour compiler ce même code, voir 🛠️ 03-Build-Compilation.md.)
Le même .exe se comporte différemment selon ses arguments de ligne de commande :
| Commande | Fonction | Rôle |
|---|---|---|
Copilot_Key+.exe |
mode par défaut | 👻 s'installe en résident (voir plus bas) |
Copilot_Key+.exe -config |
RunInstall() |
🎛️ assistant interactif en console (capture + réglages) |
Copilot_Key+.exe -quit |
RunQuit() |
🛑 demande à l'instance résidente de s'arrêter proprement |
-
Instance unique :
CreateMutexA("Global\CopilotKeyPlus")- si le mutex existe déjà, l'exe se termine aussitôt (code 0), pas de doublon possible. -
Priorité haute (
HIGH_PRIORITY_CLASS) pour limiter la gigue du hook clavier sous forte charge CPU, sans les risques système deREALTIME_PRIORITY_CLASS. -
Fenêtre cachée de classe
CopilotKeyPlusCtl(HWND_MESSAGE) : sert de cible pour-quit(viaWM_CLOSE) et, en mode HID, reçoit les événementsWM_INPUT. -
Chargement des réglages (
LoadRegistrySettings) depuisHKCU\Software\CopilotKey+(voir plus bas). -
Pose du hook clavier bas niveau :
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, ...)- intercepte toutes les touches du système avant Windows.
-
Boucle de messages standard (
GetMessage/DispatchMessage) jusqu'àWM_QUIT(déclenché par-quit) ouWM_ENDSESSION(fermeture de session Windows) - dans les deux cas, relâche proprement la touche Copilot synthétique si elle était enfoncée, puis retire le hook et le mutex.
| Valeur | Type | Contenu |
|---|---|---|
Mode |
DWORD | 0 = désactivée, 1 = CTRL droit (défaut), 2 = Menu contextuel |
Arrows |
DWORD | 1 = remap flèches actif (défaut), 0 = désactivé |
Signature |
REG_SZ | Salve de scancodes apprise (chemin scancode classique) |
HIDconsumer |
REG_SZ | Usage HID Consumer en hex (chemin touche matérielle dédiée) - mutuellement exclusif avec Signature
|
Burst |
DWORD | Fenêtre de confirmation de la salve (ms), mesurée à l'install |
Grace |
DWORD | Fenêtre de grâce flèches (ms), calibrée à l'install |
Il n'existe pas de table figée par constructeur : chaque clavier envoie une
combinaison différente à l'appui de Copilot (Win+C, Win+Maj+F23,
Win+Ctrl+F23, etc. - table indicative en tête de CopilotKey.c, non utilisée
par le code). La combinaison réelle (jusqu'à MAX_SIG = 6 touches) est apprise
à l'installation (-config) et stockée dans Signature.
Chaque touche de la signature est classée en deux catégories (SigSlot.modifier,
voir IsSafeModifierScanCode) :
- Modificateur "sûr" (Shift/Ctrl/Alt gauche ou droit) : scancode universel, transmis immédiatement à Windows sans latence (usage normal préservé : frappe rapide, jeu...). Son état est juste suivi pour savoir si la salve est complète.
-
Touche "retenue" (typiquement
Win, ou une toucheF23/F24peu utilisée seule) : avalée (non transmise) et mise en attente de confirmation.
Machine à états (burstState : IDLE → PENDING → ACTIVE) dans KeyboardProc :
-
IDLE: rien ne se passe. - Une touche "retenue" de la signature s'enfonce →
PENDING, démarre un timerg_pendingWindowMs(mesuré/doublé à l'install, borné 25–200 ms). - Si toutes les touches de la signature sont "bas" avant expiration du
timer (
TryConfirmBurst) →ACTIVE: les modificateurs "sûrs" déjà transmis sont neutralisés ponctuellement (unKEYUPsynthétique) pour que l'application au premier plan reçoive une touche Copilot propre (ex.CTRL droitseul, pasMaj+CTRL droit) - sauf un modificateur déjà tenu avant le début de la salve (preHeld), qui reste transmis normalement : c'est ce qui permetCopilot + Maj + FlèchequandMajfait partie de la signature matérielle de la machine (cf. avertissement README sur l'ordre d'appui). Une foisACTIVE,SendCopilotKey(TRUE)injecte la vraie touche cible (CTRL droitpar scancode, ouMenu contextuelpar code virtuel) viaSendInput. - Si le timer expire avant complétion (
PendingTimeoutProc→AbortPendingBurst) : les touches avalées jusque-là sont rejouées telles quelles vers l'OS - elles redeviennent des touches "normales". - Au relâchement de la dernière touche encore tenue de la signature
(
EndActiveCombo) : relâche la touche Copilot synthétique, restaure vers l'OS l'état réel des modificateurs neutralisés, retour àIDLE.
Certains claviers récents envoient un usage HID Consumer Page 0x0C (usage
0x0D8 typiquement) au lieu d'une salve de scancodes classique - invisible pour
WH_KEYBOARD_LL. Repli automatique : si la capture scancode ne détecte rien à
l'installation, le programme écoute en Raw Input (RegisterRawInputDevices
-
WM_INPUTdansHiddenWndProc) et apprend dynamiquement l'usage réellement vu (jamais figé en dur - un usage différent de0x0D8fonctionnerait quand même). Ce mode n'active le Raw Input que siHIDconsumerest présent en registre : zéro overhead pour les autres utilisateurs. Pas de machine à états temporisée ici :down/upde l'usage HID pilotent directementSendCopilotKey.
Tant que la combinaison est ACTIVE - ou dans une fenêtre de grâce
g_arrowGraceMs après un relâchement naturel de la salve (certains claviers
relâchent leur salve matérielle après quelques centaines de ms indépendamment de
la tenue physique réelle, cf. calibration Grace) - les flèches
←/→/↑/↓ sont interceptées et remplacées par Home/End/PgUp/PgDn (scancodes
injectés via SendInput). La touche Copilot synthétique est brièvement relâchée
puis restaurée autour de l'injection de la flèche, pour éviter qu'elle ne se
combine avec CTRL droit. Les modificateurs physiques (Maj/Ctrl) restent
transmis normalement en parallèle par Windows, d'où les combinaisons
sélection/document entier décrites dans le README (« Copilot MULTI »).
Assistant interactif en console (alloue une console même si l'exe est en mode GUI) :
- Choix de la langue (FR par défaut).
-
Capture de la signature : jusqu'à 4 essais, chacun avec un hook
WH_KEYBOARD_LLdédié (CaptureOneAttempt) qui enregistre toutes les touches vues pendant l'appui puis attend un silence deCAPTURE_QUIET_MS(700 ms) ou un timeout deCAPTURE_TIMEOUT_MS(5 s). Si aucune touche scancode n'est vue, tente la capture HID Consumer (CaptureOneHidAttempt). Deux essais consécutifs doivent produire le même ensemble de touches (même type scancode/HID) pour confirmer la signature - sinon on recommence. - Avertissements si la combinaison ne contient que des modificateurs Shift/Ctrl/Alt (aucune touche distinctive → détection par l'ancien mécanisme, délai possible), ou si un modificateur arrive après la touche distinctive dans la salve (risque de pollution occasionnelle de la touche synthétique).
- Choix du comportement de Copilot seul (CTRL droit / Menu / Rien).
- Activation ou non du remap flèches (O/N).
- Si activé : calibration de la fenêtre de grâce - demande à l'utilisateur
de tenir Copilot ~2,5 s puis de relâcher normalement, pour distinguer un
auto-relâchement matériel d'un relâchement volontaire (
CalibrateArrowGrace). - Écriture de tous les réglages dans
HKCU\Software\CopilotKey+(avec nettoyage des résidus de l'autre chemin, scancode ↔ HID, en cas de réinstallation après changement de clavier). -
Relance l'instance résidente : envoie
-quità l'instance en cours (si présente) puis relance un nouveau process pour appliquer immédiatement les réglages - c'est pour ça qu'un rebuild +-config(ou un simple changement de réglage) prend effet tout de suite, sans étape manuelle côté utilisateur final (contrairement à un rebuild Release brut sans-config, qui reste chargé en mémoire tant que-quitn'a pas été envoyé).
Cherche la fenêtre cachée CopilotKeyPlusCtl (FindWindowExA) et lui poste un
WM_CLOSE - pas de kill par nom de process. HiddenWndProc traduit ce
WM_CLOSE en PostQuitMessage(0), ce qui fait sortir la boucle de messages de
l'instance résidente et déclenche l'arrêt propre décrit plus haut. Code retour :
0 si une instance a été trouvée et sollicitée, 1 sinon.