// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package input import ( "testing" "git.stormux.org/storm/fenrir/internal/command" ) func TestScreenRangeChordsConsumePressHoldAndBothReleaseOrders(t *testing.T) { for _, layout := range []string{"desktop", "laptop"} { bindings, _, err := Load_bindings([]string{"../../config/keyboard/" + layout + ".toml"}) if err != nil { t.Fatal(err) } for _, trial := range []struct { desktop, laptop uint16 want command.ID }{ {KeyKP8, 23, command.ScreenBeforeCursor}, {KeyKP2, 51, command.ScreenAfterCursor}, } { for _, modifierFirst := range []bool{false, true} { for _, numLock := range []bool{false, true} { router, err := New_router(bindings) if err != nil { t.Fatal(err) } keyCode := trial.desktop modifiers := []uint16{KeyInsert} if layout == "laptop" { keyCode = trial.laptop modifiers = append(modifiers, KeyShift) } for _, modifier := range modifiers { router.Key(0, modifier, 1, numLock, false) } if got := router.Key(0, keyCode, 1, numLock, false); got.Command != trial.want || got.Forward || !got.Interrupt { t.Fatal(layout, trial.want, numLock, got) } // Like ReadScreen, a held range key must not restart long speech. if got := router.Key(0, keyCode, 2, numLock, false); got.Command != "" || got.Forward || got.Interrupt { t.Fatal("range repeated", got) } releases := append([]uint16{keyCode}, modifiers...) if modifierFirst { releases = append(modifiers, keyCode) } for _, code := range releases { // Ordinary Shift is forwarded as a balanced press/release. if got := router.Key(0, code, 0, numLock, false); got.Forward != (code == KeyShift) || got.Command != "" { t.Fatal("release leaked", got) } } if router.Held(0) { t.Fatal("stuck key after range command") } if got := router.Key(0, 30, 1, numLock, false); !got.Forward || got.Command != "" { t.Fatal("ordinary typing after range chord", got) } } } } } }