feat(maestro): mobile special-key bar for web attach (NAP-342)
On touch devices the soft keyboard omits the keys terminals depend on (Esc, Tab, Ctrl, arrows, Home/End, PgUp/PgDn). Add a Termux-style scrollable key bar to the attach view that injects the right xterm sequences into the existing PTY input path. - Ctrl is a one-shot sticky modifier: arm it and the next character — tapped here or typed on the soft keyboard — is sent as its control code, so Ctrl+C and friends work on mobile. - Taps preventDefault on pointerdown so the terminal keeps focus and the keyboard stays open. - Bar is revealed only on coarse-pointer devices; a physical keyboard already has these keys. - Shell height now tracks the visual viewport (installViewportSizing) so the bar lands above the soft keyboard instead of behind it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+70
-1
@@ -209,7 +209,10 @@ body {
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
/* `--app-vh` tracks the *visual* viewport (set by installViewportSizing) so
|
||||
the shell stays above the mobile soft keyboard; falls back to the layout
|
||||
viewport where `visualViewport` is unavailable. */
|
||||
height: var(--app-vh, 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
@@ -1168,6 +1171,72 @@ textarea {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* ---------- mobile special-key bar (Termux-style) ---------- */
|
||||
|
||||
/* Hidden on devices with a precise pointer (a physical keyboard already has
|
||||
these keys). Revealed on touch, where the soft keyboard omits them. The shell
|
||||
tracks the visual viewport (see `#app`), so this row lands above the keyboard. */
|
||||
.attach-keybar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (pointer: coarse) {
|
||||
.attach-keybar {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: stretch;
|
||||
gap: var(--sp-1);
|
||||
padding: var(--sp-1) var(--sp-2);
|
||||
padding-bottom: calc(var(--sp-1) + env(safe-area-inset-bottom, 0px));
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
overscroll-behavior-x: contain;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.attach-keybar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.attach-keybar .keycap {
|
||||
flex: 0 0 auto;
|
||||
min-width: var(--tap);
|
||||
height: var(--tap);
|
||||
padding: 0 var(--sp-3);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--fs-14);
|
||||
color: var(--ink);
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--r-1);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background var(--dur-fast) var(--ease-out),
|
||||
border-color var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.attach-keybar .keycap:active {
|
||||
background: var(--surface-3);
|
||||
border-color: var(--border-strong);
|
||||
}
|
||||
|
||||
/* Armed sticky Ctrl: lit in signal-green until it folds into the next key. */
|
||||
.attach-keybar .keycap-mod[aria-pressed="true"] {
|
||||
color: var(--accent-ink);
|
||||
background: var(--accent);
|
||||
border-color: var(--accent-strong);
|
||||
}
|
||||
|
||||
/* ---------- modal ---------- */
|
||||
|
||||
.modal-backdrop {
|
||||
|
||||
Reference in New Issue
Block a user