frontend: Sprung holt keine Bildschirmtastatur mehr herauf
Nach dem Sprung erschien auf Touch-Geräten sofort die virtuelle Tastatur und nahm den halben Bildschirm — auch bei angeschlossener Bluetooth-Tastatur. Das ist kein Fehler der App: Eine Webseite erfährt nichts über verbundene Tastaturen, sie fordert nur Fokus an; alles Weitere entscheidet das OS (Android hat dafür den Schalter „Bildschirmtastatur anzeigen" unter Physische Tastatur, vielerorts an). Statt darauf zu verweisen, fordert der Sprung sie erst gar nicht an: - `jumpToLine()` setzt vor dem Fokussieren `inputmode="none"` — das unterdrückt nur die VIRTUELLE Tastatur, Hardware-Tastaturen tippen unverändert weiter. - Die Sperre fällt, sobald der Nutzer das Textfeld selbst antippt (`pointerdown` läuft vor dem Fokus). Der Sprung ist damit „hinschauen", der erste Tipp ins Textfeld „bearbeiten". - `newDoc()` hebt die Sperre ausdrücklich auf — bei einem neuen, leeren Dokument ist Tippen gemeint. Verifiziert im Browser: Sprung setzt inputmode=none bei Fokus im Textfeld und korrekter Zeilenmarkierung; Feld bleibt editierbar (nicht readOnly/disabled); eigenes pointerdown entfernt das Attribut; erneuter Sprung setzt es wieder; „Neues Dokument" fokussiert ohne Sperre. Vitest 37/37. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bbdecce75a
commit
4061362922
@@ -565,3 +565,24 @@ mehr markieren — bewusst in Kauf genommen, die Geste ist dort vergeben.
|
|||||||
Lehre für die Prüfung: Synthetische `TouchEvent`s beweisen nur die eigene
|
Lehre für die Prüfung: Synthetische `TouchEvent`s beweisen nur die eigene
|
||||||
Ereignis-Logik. Weder die Nutzergesten-Regel noch die nativen Langdruck-Gesten
|
Ereignis-Logik. Weder die Nutzergesten-Regel noch die nativen Langdruck-Gesten
|
||||||
lassen sich so auslösen — beides fiel erst auf echter Hardware auf.
|
lassen sich so auslösen — beides fiel erst auf echter Hardware auf.
|
||||||
|
|
||||||
|
**Der Sprung holt keine Bildschirmtastatur (Nachtrag).** Auf Touch-Geräten
|
||||||
|
erschien nach dem Sprung sofort die virtuelle Tastatur und nahm den halben
|
||||||
|
Bildschirm — auch bei angeschlossener Bluetooth-Tastatur. Das ist kein Fehler
|
||||||
|
der App: Eine Webseite erfährt nichts über verbundene Tastaturen; sie fordert
|
||||||
|
nur **Fokus** an, alles Weitere entscheidet das Betriebssystem (Android hat
|
||||||
|
dafür den Schalter „Bildschirmtastatur anzeigen" unter *Physische Tastatur*,
|
||||||
|
auf vielen Geräten voreingestellt an; iPadOS unterdrückt sie von selbst).
|
||||||
|
|
||||||
|
Entscheidung: Der Sprung **fordert sie erst gar nicht an**. `jumpToLine()` setzt
|
||||||
|
vor dem Fokussieren `inputmode="none"` am Textfeld — das unterdrückt nur die
|
||||||
|
**virtuelle** Tastatur, Hardware-Tastaturen tippen unverändert. Die Sperre fällt,
|
||||||
|
sobald der Nutzer das Textfeld **selbst antippt** (`pointerdown`, läuft vor dem
|
||||||
|
Fokus). Damit ist der Sprung „hinschauen" und der erste Tipp ins Textfeld
|
||||||
|
„bearbeiten". `newDoc()` hebt die Sperre ausdrücklich auf — bei einem neuen,
|
||||||
|
leeren Dokument ist Tippen gemeint.
|
||||||
|
|
||||||
|
Verworfen: die Tastatur zuzulassen und auf die OS-Einstellung zu verweisen (löst
|
||||||
|
es nur auf einem Gerät), sowie ein eigener Umschalter dafür (weiteres
|
||||||
|
Bedienelement in einer engen Kopfzeile plus i18n in 9 Sprachen, für ein
|
||||||
|
Verhalten, das kaum jemand umstellen will).
|
||||||
|
|||||||
+3
-1
@@ -234,7 +234,9 @@ verknüpft (siehe D25):
|
|||||||
Textfeld). Tastatur: **Alt+Enter** am fokussierten Knoten. Auf Touch-Geräten:
|
Textfeld). Tastatur: **Alt+Enter** am fokussierten Knoten. Auf Touch-Geräten:
|
||||||
**langer Druck** — nach ≥ 500 ms zeigt der Knoten einen Petrol-Ring („scharf"),
|
**langer Druck** — nach ≥ 500 ms zeigt der Knoten einen Petrol-Ring („scharf"),
|
||||||
der Sprung erfolgt beim **Loslassen**; ein Wischen bricht ab. Ist das
|
der Sprung erfolgt beim **Loslassen**; ein Wischen bricht ab. Ist das
|
||||||
Editor-Panel zugeklappt, öffnet der Sprung es zuerst.
|
Editor-Panel zugeklappt, öffnet der Sprung es zuerst. Der Sprung ist
|
||||||
|
„hinschauen": Er holt **keine Bildschirmtastatur** herauf — die erscheint erst,
|
||||||
|
wenn das Textfeld selbst angetippt wird.
|
||||||
- **Text → Diagramm:** Der Knoten der **Cursor-Zeile** wird im Diagramm
|
- **Text → Diagramm:** Der Knoten der **Cursor-Zeile** wird im Diagramm
|
||||||
hervorgehoben (weißer Halo + Ring in Tinte) und beim Zeilenwechsel ins Bild
|
hervorgehoben (weißer Halo + Ring in Tinte) und beim Zeilenwechsel ins Bild
|
||||||
gescrollt. Zeilen ohne Knoten (Kommentar, Leerzeile, ausgeblendetes
|
gescrollt. Zeilen ohne Knoten (Kommentar, Leerzeile, ausgeblendetes
|
||||||
|
|||||||
@@ -148,6 +148,11 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
|
|||||||
`user-select:none` per `@media (hover:none) and (pointer:coarse)` und
|
`user-select:none` per `@media (hover:none) and (pointer:coarse)` und
|
||||||
`-webkit-touch-callout:none` (nur iOS). Synthetische `TouchEvent`s prüfen
|
`-webkit-touch-callout:none` (nur iOS). Synthetische `TouchEvent`s prüfen
|
||||||
davon **nichts** — nur die eigene Ereignis-Logik.
|
davon **nichts** — nur die eigene Ereignis-Logik.
|
||||||
|
- Bildschirmtastatur (D25): `jumpToLine()` setzt vor dem Fokus `inputmode="none"`
|
||||||
|
(`keyboardOnJump(true)`) — der Sprung ist „hinschauen". Der `pointerdown`-
|
||||||
|
Handler am Textfeld hebt das wieder auf (läuft vor dem Fokus). Wer sonst
|
||||||
|
irgendwo `src.focus()` ergänzt und dabei Tippen meint, muss vorher
|
||||||
|
`keyboardOnJump(false)` rufen — so wie `newDoc()`.
|
||||||
- Kleiner Bildschirm: `body.mobile` (per `matchMedia`, ≤ 640 px) stapelt
|
- Kleiner Bildschirm: `body.mobile` (per `matchMedia`, ≤ 640 px) stapelt
|
||||||
Diagramm/Editor mit **stufenlosem** Splitter (kein Snap/Collapse wie auf
|
Diagramm/Editor mit **stufenlosem** Splitter (kein Snap/Collapse wie auf
|
||||||
Desktop): der Gutter-Drag ruft `setMobileDrow()` (klemmt `--drow` zwischen den
|
Desktop): der Gutter-Drag ruft `setMobileDrow()` (klemmt `--drow` zwischen den
|
||||||
|
|||||||
@@ -371,12 +371,24 @@ function revealEditor(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Der Sprung ist „hinschauen", nicht „bearbeiten": `inputmode="none"` hält die
|
||||||
|
**virtuelle** Tastatur unten, die sonst beim Fokussieren den halben
|
||||||
|
Bildschirm nimmt. Hardware-Tastaturen (BT) tippen unverändert weiter. Sobald
|
||||||
|
der Nutzer das Textfeld selbst antippt, ist Bearbeiten gemeint — `pointerdown`
|
||||||
|
läuft vor dem Fokus, die Sperre fällt also rechtzeitig. */
|
||||||
|
function keyboardOnJump(off){
|
||||||
|
if(off) src.setAttribute('inputmode', 'none');
|
||||||
|
else src.removeAttribute('inputmode');
|
||||||
|
}
|
||||||
|
src.addEventListener('pointerdown', () => keyboardOnJump(false));
|
||||||
|
|
||||||
/* Diagramm -> Text: ganze Zeile markieren (die native Auswahl ist die einzige
|
/* Diagramm -> Text: ganze Zeile markieren (die native Auswahl ist die einzige
|
||||||
Hervorhebung, die ein <textarea> kennt — und sie verschwindet beim Tippen). */
|
Hervorhebung, die ein <textarea> kennt — und sie verschwindet beim Tippen). */
|
||||||
function jumpToLine(line){
|
function jumpToLine(line){
|
||||||
const r = lineRange(line);
|
const r = lineRange(line);
|
||||||
if(!r) return;
|
if(!r) return;
|
||||||
revealEditor();
|
revealEditor();
|
||||||
|
keyboardOnJump(true);
|
||||||
src.focus({preventScroll: true});
|
src.focus({preventScroll: true});
|
||||||
src.setSelectionRange(r.start, r.end);
|
src.setSelectionRange(r.start, r.end);
|
||||||
scrollEditorToOffset(r.start);
|
scrollEditorToOffset(r.start);
|
||||||
@@ -1446,6 +1458,7 @@ function newDoc(){
|
|||||||
activeId = d.id;
|
activeId = d.id;
|
||||||
loadActiveIntoEditor();
|
loadActiveIntoEditor();
|
||||||
persistDocs();
|
persistDocs();
|
||||||
|
keyboardOnJump(false); /* neues, leeres Dokument = tippen ist gemeint */
|
||||||
src.focus();
|
src.focus();
|
||||||
}
|
}
|
||||||
function renameDoc(){
|
function renameDoc(){
|
||||||
|
|||||||
Reference in New Issue
Block a user