1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-08 12:13:31 -04:00

refactor(niri): Normalize key bindings to be case insensitive within DMS

This commit is contained in:
purian23
2026-05-21 00:38:31 -04:00
parent 37c98220a9
commit 078c9b4890
4 changed files with 102 additions and 14 deletions
+4 -4
View File
@@ -166,7 +166,7 @@ func (n *NiriProvider) convertKeybind(kb *NiriKeyBinding, subcategory string, co
}
if source == "dms-default" && conflicts != nil {
if conflictKb, ok := conflicts[keyStr]; ok {
if conflictKb, ok := conflicts[normalizeNiriBindKey(keyStr)]; ok {
bind.Conflict = &keybinds.Keybind{
Key: keyStr,
Description: conflictKb.Description,
@@ -249,7 +249,7 @@ func (n *NiriProvider) SetBind(key, action, description string, options map[stri
existingBinds = make(map[string]*overrideBind)
}
existingBinds[key] = &overrideBind{
existingBinds[normalizeNiriBindKey(key)] = &overrideBind{
Key: key,
Action: action,
Description: description,
@@ -265,7 +265,7 @@ func (n *NiriProvider) RemoveBind(key string) error {
return nil
}
delete(existingBinds, key)
delete(existingBinds, normalizeNiriBindKey(key))
return n.writeOverrideBinds(existingBinds)
}
@@ -316,7 +316,7 @@ func (n *NiriProvider) loadOverrideBinds() (map[string]*overrideBind, error) {
action = n.formatRawAction(kb.Action, kb.Args)
}
binds[keyStr] = &overrideBind{
binds[normalizeNiriBindKey(keyStr)] = &overrideBind{
Key: keyStr,
Action: action,
Description: kb.Description,
@@ -162,6 +162,14 @@ func NewNiriParser(configDir string) *NiriParser {
}
}
func normalizeNiriBindKey(key string) string {
parts := strings.Split(key, "+")
for i := range parts {
parts[i] = strings.ToLower(strings.TrimSpace(parts[i]))
}
return strings.Join(parts, "+")
}
func (p *NiriParser) Parse() (*NiriSection, error) {
dmsBindsPath := filepath.Join(p.configDir, "dms", "binds.kdl")
if _, err := os.Stat(dmsBindsPath); err == nil {
@@ -213,24 +221,25 @@ func (p *NiriParser) finalizeBinds() []NiriKeyBinding {
func (p *NiriParser) addBind(kb *NiriKeyBinding) {
key := p.formatBindKey(kb)
normalizedKey := normalizeNiriBindKey(key)
isDMSBind := strings.Contains(kb.Source, "dms/binds.kdl")
if isDMSBind {
p.dmsBindKeys[key] = true
p.dmsBindMap[key] = kb
} else if p.dmsBindKeys[key] {
p.dmsBindKeys[normalizedKey] = true
p.dmsBindMap[normalizedKey] = kb
} else if p.dmsBindKeys[normalizedKey] {
p.bindsAfterDMS++
p.conflictingConfigs[key] = kb
p.configBindKeys[key] = true
p.conflictingConfigs[normalizedKey] = kb
p.configBindKeys[normalizedKey] = true
return
} else {
p.configBindKeys[key] = true
p.configBindKeys[normalizedKey] = true
}
if _, exists := p.bindMap[key]; !exists {
p.bindOrder = append(p.bindOrder, key)
if _, exists := p.bindMap[normalizedKey]; !exists {
p.bindOrder = append(p.bindOrder, normalizedKey)
}
p.bindMap[key] = kb
p.bindMap[normalizedKey] = kb
}
func (p *NiriParser) formatBindKey(kb *NiriKeyBinding) string {
@@ -526,6 +526,85 @@ binds {
}
}
func TestNiriKeyIdentityIsCaseInsensitive(t *testing.T) {
tmpDir := t.TempDir()
dmsDir := filepath.Join(tmpDir, "dms")
if err := os.MkdirAll(dmsDir, 0o755); err != nil {
t.Fatalf("Failed to create dms dir: %v", err)
}
config := `binds {
Alt+Space hotkey-overlay-title="Spotlight Bar" { spawn "dms" "ipc" "call" "spotlight-bar" "toggle"; }
}
include "dms/binds.kdl"
`
if err := os.WriteFile(filepath.Join(tmpDir, "config.kdl"), []byte(config), 0o644); err != nil {
t.Fatalf("Failed to write config: %v", err)
}
include := `binds {
Alt+space hotkey-overlay-title="Default Launcher" { spawn "dms" "ipc" "call" "spotlight" "toggle"; }
}
`
if err := os.WriteFile(filepath.Join(dmsDir, "binds.kdl"), []byte(include), 0o644); err != nil {
t.Fatalf("Failed to write binds include: %v", err)
}
result, err := ParseNiriKeys(tmpDir)
if err != nil {
t.Fatalf("ParseNiriKeys failed: %v", err)
}
var altSpaceBinds []NiriKeyBinding
parser := NewNiriParser("")
for _, kb := range result.Section.Keybinds {
if normalizeNiriBindKey(parser.formatBindKey(&kb)) == "alt+space" {
altSpaceBinds = append(altSpaceBinds, kb)
}
}
if len(altSpaceBinds) != 1 {
t.Fatalf("Expected one Alt+Space identity, got %d", len(altSpaceBinds))
}
if got := altSpaceBinds[0].Args; len(got) < 5 || got[3] != "spotlight" || got[4] != "toggle" {
t.Fatalf("Expected later DMS include to win with spotlight toggle, got action=%s args=%v", altSpaceBinds[0].Action, got)
}
}
func TestNiriOverrideBindsUseCaseInsensitiveKeys(t *testing.T) {
tmpDir := t.TempDir()
dmsDir := filepath.Join(tmpDir, "dms")
if err := os.MkdirAll(dmsDir, 0o755); err != nil {
t.Fatalf("Failed to create dms dir: %v", err)
}
path := filepath.Join(dmsDir, "binds.kdl")
if err := os.WriteFile(path, []byte(`binds {
Alt+space hotkey-overlay-title="Default Launcher" { spawn "dms" "ipc" "call" "spotlight" "toggle"; }
}
`), 0o644); err != nil {
t.Fatalf("Failed to write override binds: %v", err)
}
provider := NewNiriProvider(tmpDir)
if err := provider.SetBind("Alt+Space", "spawn dms ipc call spotlight-bar toggle", "Spotlight Bar", nil); err != nil {
t.Fatalf("SetBind failed: %v", err)
}
binds, err := provider.loadOverrideBinds()
if err != nil {
t.Fatalf("loadOverrideBinds failed: %v", err)
}
if len(binds) != 1 {
t.Fatalf("Expected one normalized override bind, got %d", len(binds))
}
bind := binds["alt+space"]
if bind == nil {
t.Fatal("Expected normalized alt+space bind")
}
if bind.Key != "Alt+Space" || bind.Action != "spawn dms ipc call spotlight-bar toggle" {
t.Fatalf("Unexpected bind after SetBind: %+v", bind)
}
}
func TestNiriParseMultipleArgs(t *testing.T) {
tmpDir := t.TempDir()
configFile := filepath.Join(tmpDir, "config.kdl")
@@ -367,7 +367,7 @@ func TestNiriEmptyArgsPreservation(t *testing.T) {
}
for key, expected := range binds {
loaded, ok := loadedBinds[key]
loaded, ok := loadedBinds[normalizeNiriBindKey(key)]
if !ok {
t.Errorf("Missing bind for key %s", key)
continue