// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package input import "testing" func TestOCRReaderShortcutsAndConfigurableSources(t *testing.T) { for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { modifiers := uint16(0) if layout == LaptopKeyboardLayout { modifiers = 1 } bindings := DefaultCommandBindings(layout) if bindings[CommandChord{Symbol: 'o', Modifiers: modifiers, CthulhuModifier: true}] != OCRWindow { t.Fatal("missing primary OCR shortcut") } pending := OCRPendingBindings(bindings) if pending[CommandChord{Symbol: downKeySymbol}] != "" || pending[CommandChord{Symbol: 0xff1b}] != OCRDismiss { t.Fatal("pending OCR claimed navigation") } for _, command := range []Command{OCRObject, OCRWindow, OCRDesktop, OCRClipboard} { if err := ValidateBindingOverrides([]BindingOverride{{Layout: layout, Scope: "global", Command: command, Keys: []string{"Cthulhu+F8"}}}); err != nil { t.Fatal(err) } found := false for _, row := range BindingRows(layout, nil) { if row.Command == command && row.Scope == "global" { found = true if command == OCRWindow && row.DefaultKeys == "" { t.Fatal("window OCR shortcut missing from preferences") } } } if !found { t.Fatalf("missing configurable source %s", command) } } } } func TestOCRBindingsPreserveGlobalAndLaptopReview(t *testing.T) { for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { global := DefaultCommandBindings(layout) bindings := OCRCommandBindings(global) if bindings[CommandChord{Symbol: 0xffc2, CthulhuModifier: true}] != OCRRefresh || bindings[CommandChord{Symbol: 0xff55}] != OCRPreviousPage || bindings[CommandChord{Symbol: 0xff56}] != OCRNextPage { t.Fatal("OCR refresh or page navigation binding missing") } for chord, command := range global { if chord.CthulhuModifier && bindings[chord] != command { t.Fatalf("global changed: %v", chord) } } for _, symbol := range []uint32{'h', 'b', 'l', 'o', 'x'} { if bindings[CommandChord{Symbol: symbol}] != "" { t.Fatalf("OCR claimed structural key %c", symbol) } } router := NewCommandRouter([]uint32{0xff63}, bindings) for _, test := range []struct { symbol uint32 modifiers uint16 want Command }{ {leftKeySymbol, 0, OCRPreviousCharacter}, {rightKeySymbol, 1 | controlModifier, OCRNextWord}, {downKeySymbol, 0, OCRNextLine}, {'a', controlModifier, OCRSelectAll}, {'c', controlModifier, OCRCopySelection}, {0xff09, 1, OCRDismissAndPass}, {0xff1b, 0, OCRDismiss}, } { consume, command := router.Handle(test.symbol, 42, test.modifiers, true) if !consume || command != test.want { t.Fatalf("chord got %v %s, want %s", consume, command, test.want) } consume, command = router.Handle(test.symbol, 42, test.modifiers, false) if !consume || command != "" { t.Fatal("lost held release") } } if layout == LaptopKeyboardLayout && bindings[CommandChord{Symbol: 'o', CthulhuModifier: true}] != ReviewNextLine { t.Fatal("laptop next line changed") } } }