// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package input import ( "git.stormux.org/storm/fenrir/internal/command" "testing" ) func TestModifierConflictsUsePhysicalAliases(t *testing.T) { for _, pair := range [][2]string{ {"KEY_INSERT", "KEY_INSERT"}, {"KEY_KP0", "KEY_KP0"}, {"KEY_CAPSLOCK", "KEY_CAPSLOCK"}, {"KEY_META", "KEY_LEFTMETA"}, {"KEY_META", "KEY_RIGHTMETA"}, {"KEY_RIGHTMETA", "KEY_META"}, } { if err := Validate_modifier_keys([]string{pair[0]}, []string{pair[1]}); err == nil { t.Fatal("accepted overlap", pair) } } r := desktop_router(t) if err := r.Configure_modifiers(nil, []string{"KEY_META"}); err != nil { t.Fatal(err) } if r.reader_modifier(KeyMeta, false) || r.reader_modifier(KeyRightMeta, false) || !r.scriptKeys[KeyMeta] || !r.scriptKeys[KeyRightMeta] { t.Fatal("default reader stole explicit script key") } if err := r.Configure_modifiers([]string{"KEY_META"}, []string{"KEY_RIGHTMETA"}); err == nil { t.Fatal("explicit conflict accepted") } if !r.scriptKeys[KeyMeta] || r.reader_modifier(KeyMeta, false) { t.Fatal("failed reconfiguration changed keys") } if err := r.Configure_modifiers([]string{"KEY_META"}, []string{"KEY_COMPOSE"}); err != nil { t.Fatal("could not move script key to reader", err) } if r.scriptKeys[KeyMeta] || !r.reader_modifier(KeyRightMeta, false) { t.Fatal("old assignment survived") } } func TestConfigurableScriptModifiersAndNumLock(t *testing.T) { for _, key := range []uint16{KeyInsert, KeyKP0, KeyCapsLock, KeyMeta, KeyRightMeta} { r := desktop_router(t) if err := r.Configure_modifiers([]string{"KEY_CAPSLOCK"}, []string{Key_name(key)}); err != nil { if key != KeyCapsLock { t.Fatal(err) } if err := r.Configure_modifiers([]string{"KEY_INSERT"}, []string{Key_name(key)}); err != nil { t.Fatal(err) } } if err := r.Configure_scripts([]string{Key_name(key)}, []ScriptBinding{{ID: "script:example", Keys: []string{"KEY_SCRIPT", "KEY_U"}}}); err != nil { t.Fatal(err) } if got := r.Key(0, key, 1, false, false); got.Forward || got.Command != "" { t.Fatal(key, got) } if got := r.Key(0, 22, 1, false, false); got.Command != "script:example" || got.Forward { t.Fatal(key, got) } r.Key(0, key, 0, false, false) if got := r.Key(0, 22, 0, false, false); got.Forward { t.Fatal(key, got) } if key == KeyKP0 { if got := r.Key(0, key, 1, true, false); !got.Forward || !got.Typing { t.Fatal("numeric keypad zero consumed", got) } if got := r.Key(0, 22, 1, true, false); !got.Forward || got.Command != "" || !got.Typing { t.Fatal("NumLock zero became modifier", got) } } } } func TestCapsLockScriptModifierKeepsShiftToggle(t *testing.T) { r := desktop_router(t) if err := r.Configure_modifiers([]string{"KEY_INSERT"}, []string{"KEY_CAPSLOCK"}); err != nil { t.Fatal(err) } r.Key(0, KeyShift, 1, false, false) if got := r.Key(0, KeyCapsLock, 1, false, false); got.Forward { t.Fatal(got) } if got := r.Key(0, KeyCapsLock, 0, false, false); !got.ToggleCapsLock { t.Fatal(got) } r.Key(0, KeyShift, 0, false, false) r.Key(0, KeyCapsLock, 1, false, false) if got := r.Key(0, 22, 1, false, false); got.Command != command.Unbound { t.Fatal(got) } if got := r.Key(0, KeyCapsLock, 0, false, false); got.ToggleCapsLock { t.Fatal("script chord toggled capitalization", got) } } func TestModifierReconfigurationPreservesInstalledScriptBindings(t *testing.T) { r := desktop_router(t) if err := r.Configure_modifiers([]string{"KEY_INSERT"}, []string{"KEY_COMPOSE"}); err != nil { t.Fatal(err) } if err := r.Configure_scripts([]string{"KEY_COMPOSE"}, []ScriptBinding{{ID: "script:example", Keys: []string{"KEY_SCRIPT", "KEY_U"}}}); err != nil { t.Fatal(err) } if err := r.Configure_modifiers([]string{"KEY_META"}, []string{"KEY_CAPSLOCK"}); err != nil { t.Fatal(err) } r.Key(0, KeyCapsLock, 1, false, false) if got := r.Key(0, 22, 1, false, false); got.Command != "script:example" { t.Fatal("script binding lost", got) } }