chore(android): drop the keyboard diagnostic, and the field only jumps if it must

The trace has served: it named the cause where two rounds of reasoning had
missed it. Out with it, and out with the viewport measurement it proved
worthless here - a value that is always zero reads as a mechanism, and the
next person would trust it.

adjustResize goes too. Measured to do nothing: Android ignores the mode for a
fullscreen window, which FMX's is. Leaving it in the manifest would suggest it
carries something.

A field already near the top of the panel - the settings ones - stays where it
is. It was visible as it was, and lifting it only moved under the eye what was
already fine.

The plan keeps what the measurement cost: on this screen, instrument first.
This commit is contained in:
r-zakarya
2026-08-21 15:46:06 +01:00
parent ad8a037e29
commit 131bf44b36
3 changed files with 54 additions and 64 deletions
+23 -54
View File
@@ -75,7 +75,7 @@
.scroll { flex: 1; overflow-y: auto; overflow-x: hidden;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
padding: 0 12px calc(16px + var(--kb, 0px)); }
padding: 0 12px 16px; }
/* DE LA PLACE SOUS LE CONTENU PENDANT QU'ON TAPE, et rien a mesurer.
Le clavier recouvre la page sans que rien ne le dise : ni la fenetre, qui
reste en plein ecran, ni visualViewport, qui rapporte la meme hauteur
@@ -684,66 +684,35 @@ addEventListener('scroll', function (ev) {
if (box && box.scrollLeft && box.id !== 'folders') box.scrollLeft = 0;
}, true);
// LE CLAVIER RECOUVRE LA PAGE, IL NE LA RETRECIT PAS.
// LE CLAVIER RECOUVRE LA PAGE, ET PERSONNE NE LE DIT.
//
// Le cadre est cloue a l'ecran entier (position:fixed, inset:0) et le moteur ne
// le redimensionne pas quand le clavier monte : la page garde sa hauteur, le
// clavier passe par-dessus, et le tiers du bas devient inatteignable. Rien ne
// depassait, donc rien ne defilait - le champ mot de passe du formulaire ne se
// voyait qu'en repliant le clavier.
// Le cadre est cloue a l'ecran entier et le moteur ne le redimensionne pas
// quand le clavier monte. Trois sources ont ete interrogees sur ce qu'il
// recouvre - visualViewport, innerHeight, la fenetre elle-meme via
// windowSoftInputMode - et les trois repondent comme s'il n'existait pas :
// clavier leve, la boite defilante montrait 659 pour 659 de contenu. Aucun
// debordement, donc rien a faire defiler, et le bas du formulaire restait
// sous le clavier definitivement.
//
// visualViewport donne la hauteur REELLEMENT visible. La reporter sur le corps
// retrecit les vues, le panneau defilant retrouve du contenu en trop, et le
// moteur peut de nouveau amener a l'ecran le champ qui prend le focus.
if (window.visualViewport) {
var vv = window.visualViewport;
// Ce que le clavier RECOUVRE, en pixels. Zero quand il est replie - et zero
// aussi si le moteur retrecit reellement la fenetre, auquel cas le panneau
// deborde tout seul et n'a besoin de rien. La meme mesure repond donc juste
// dans les deux cas, sans qu'on ait a savoir lequel s'applique.
var measureKeyboard = function () {
var hidden = Math.max(0, Math.round(window.innerHeight - vv.height));
document.documentElement.style.setProperty('--kb', hidden + 'px');
reportBox('keyboard');
};
vv.addEventListener('resize', measureKeyboard);
measureKeyboard();
} else {
window._noVisualViewport = true;
}
// DIAGNOSTIC, temporaire. Deux corrections posees a l'aveugle n'ont rien
// change ; celle-ci dit ce que la page mesure vraiment, dans le journal plutot
// qu'en message fugace, pour qu'on puisse la lire apres coup.
function reportBox(why) {
// PM n'existe pas encore au chargement : cette fonction tourne aussi avant
// lui, et on ne va pas casser la page pour une trace.
// Les trois vues sont TOUTES dans le document - c'est un rail, rien n'est
// masque - donc la vue active se designe par son nom, pas par sa visibilite.
if (!window.PM || !PM.log) return;
var box = document.getElementById(view);
box = box && box.querySelector('.scroll');
var vh = window.visualViewport ? Math.round(window.visualViewport.height) : -1;
var sc = document.body.className || '(none)';
if (!box) { PM.log(why + ': no scroll box, body=' + sc); return; }
// clientHeight = ce que la boite montre, scrollHeight = ce qu'elle contient.
// Egaux, il n'y a rien a faire defiler, et c'est TOUT le probleme.
PM.log(why + ': inner ' + window.innerHeight + ' visual ' + vh
+ ' | box client ' + box.clientHeight + ' scroll ' + box.scrollHeight
+ ' | body=' + sc);
}
// On cesse donc de demander. Le temps de la saisie, le panneau reserve de la
// place sous son contenu (body.typing, plus haut) - c'est du debordement, donc
// ca defile - et le champ focalise remonte en haut, la ou aucun clavier ne
// peut l'atteindre quelle que soit sa hauteur.
document.addEventListener('focusin', function (ev) {
var el = ev.target;
if (!el.classList || !el.classList.contains('field-in')) return;
document.body.classList.add('typing');
// Le champ remonte EN HAUT du panneau : la ou le clavier ne peut pas
// l'atteindre, quelle que soit sa hauteur. Differe d'un tour, sinon la place
// reservee ci-dessus n'est pas encore prise en compte et il n'y a nulle part
// ou remonter.
// Differe d'un tour : la place reservee ci-dessus n'est pas encore prise en
// compte, et il n'y aurait nulle part ou remonter.
setTimeout(function () {
var row = el.closest ? el.closest('.field, .in-wrap') : null;
if (row && row.scrollIntoView) row.scrollIntoView({ block: 'start' });
reportBox('focus');
var row = el.closest && el.closest('.field, .in-wrap');
var box = el.closest && el.closest('.scroll');
if (!row || !box || !row.scrollIntoView) return;
// NE BOUGER QUE SI C'EST UTILE. Un champ deja dans le haut du panneau -
// celui des reglages, par exemple - est visible tel quel, et le faire
// sauter quand meme ne fait que deplacer sous l'oeil ce qui allait bien.
var top = row.getBoundingClientRect().top - box.getBoundingClientRect().top;
if (top > box.clientHeight * 0.4) row.scrollIntoView({ block: 'start' });
}, 250);
});
document.addEventListener('focusout', function () {