fix(maestro): hide mobile key bar when keyboard is dismissed while focused
ci / rust (push) Successful in 5m29s
ci / rust (push) Successful in 5m29s
Focus alone was the wrong signal: dismissing the soft keyboard (e.g. Android back button) keeps the terminal focused, so the key bar lingered. Detect the keyboard's actual visibility from the visual-viewport shrink — while an editable element is focused, a height past a threshold below the focus-free baseline means the keyboard is up — and gate the bar on a new `html.kb-open` class in addition to the per-terminal focus class. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+6
-3
@@ -1192,10 +1192,13 @@ textarea {
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
/* Shown on touch only while the terminal is focused (soft keyboard up) — the
|
||||
`keybar-active` class is toggled on textarea focus/blur in attach.ts. */
|
||||
/* Shown on touch only while *this* terminal is focused (`keybar-active`, toggled
|
||||
on textarea focus/blur in attach.ts) AND the soft keyboard is actually up
|
||||
(`html.kb-open`, detected from the visual-viewport shrink in viewport.ts).
|
||||
Both are needed: dismissing the keyboard doesn't blur the terminal, so focus
|
||||
alone would leave the bar lingering. */
|
||||
@media (pointer: coarse) {
|
||||
.attach-keybar.keybar-active {
|
||||
html.kb-open .attach-keybar.keybar-active {
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,18 +19,42 @@
|
||||
* it, where offsetTop stays non-zero.)
|
||||
*
|
||||
* No-ops where `visualViewport` is unavailable; the CSS falls back to `100%`.
|
||||
*
|
||||
* It also toggles an `html.kb-open` class that reflects whether the soft
|
||||
* keyboard is actually up, used to gate the mobile key bar. Focus is the wrong
|
||||
* signal: dismissing the keyboard (e.g. the Android back button) keeps the
|
||||
* terminal focused, so the bar would linger. Instead we watch the visual
|
||||
* viewport shrink: while an editable element is focused, a height noticeably
|
||||
* below the tallest height seen with nothing focused means the keyboard is open.
|
||||
* The baseline resets whenever nothing is being edited, so it self-corrects
|
||||
* across orientation changes and URL-bar collapse.
|
||||
*/
|
||||
const KB_OPEN_THRESHOLD = 150;
|
||||
|
||||
export function installViewportSizing(): void {
|
||||
const vv = window.visualViewport;
|
||||
if (!vv) return;
|
||||
|
||||
const root = document.documentElement;
|
||||
let raf = 0;
|
||||
let baseline = vv.height;
|
||||
|
||||
const isEditing = () => {
|
||||
const a = document.activeElement as HTMLElement | null;
|
||||
if (!a) return false;
|
||||
return a.tagName === "TEXTAREA" || a.tagName === "INPUT" || a.isContentEditable;
|
||||
};
|
||||
|
||||
const sync = () => {
|
||||
raf = 0;
|
||||
root.style.setProperty("--app-vh", `${Math.round(vv.height)}px`);
|
||||
root.style.setProperty("--app-top", `${Math.round(vv.offsetTop)}px`);
|
||||
|
||||
// Nothing focused ⇒ keyboard can't be open ⇒ this height is the baseline.
|
||||
const editing = isEditing();
|
||||
if (!editing) baseline = vv.height;
|
||||
const kbOpen = editing && baseline - vv.height > KB_OPEN_THRESHOLD;
|
||||
root.classList.toggle("kb-open", kbOpen);
|
||||
};
|
||||
const schedule = () => {
|
||||
if (raf) return;
|
||||
|
||||
Reference in New Issue
Block a user