mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-17 16:45:19 -04:00
refactor(niri): Normalize key bindings to be case insensitive within DMS
This commit is contained in:
@@ -166,7 +166,7 @@ func (n *NiriProvider) convertKeybind(kb *NiriKeyBinding, subcategory string, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if source == "dms-default" && conflicts != nil {
|
if source == "dms-default" && conflicts != nil {
|
||||||
if conflictKb, ok := conflicts[keyStr]; ok {
|
if conflictKb, ok := conflicts[normalizeNiriBindKey(keyStr)]; ok {
|
||||||
bind.Conflict = &keybinds.Keybind{
|
bind.Conflict = &keybinds.Keybind{
|
||||||
Key: keyStr,
|
Key: keyStr,
|
||||||
Description: conflictKb.Description,
|
Description: conflictKb.Description,
|
||||||
@@ -249,7 +249,7 @@ func (n *NiriProvider) SetBind(key, action, description string, options map[stri
|
|||||||
existingBinds = make(map[string]*overrideBind)
|
existingBinds = make(map[string]*overrideBind)
|
||||||
}
|
}
|
||||||
|
|
||||||
existingBinds[key] = &overrideBind{
|
existingBinds[normalizeNiriBindKey(key)] = &overrideBind{
|
||||||
Key: key,
|
Key: key,
|
||||||
Action: action,
|
Action: action,
|
||||||
Description: description,
|
Description: description,
|
||||||
@@ -265,7 +265,7 @@ func (n *NiriProvider) RemoveBind(key string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(existingBinds, key)
|
delete(existingBinds, normalizeNiriBindKey(key))
|
||||||
return n.writeOverrideBinds(existingBinds)
|
return n.writeOverrideBinds(existingBinds)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ func (n *NiriProvider) loadOverrideBinds() (map[string]*overrideBind, error) {
|
|||||||
action = n.formatRawAction(kb.Action, kb.Args)
|
action = n.formatRawAction(kb.Action, kb.Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
binds[keyStr] = &overrideBind{
|
binds[normalizeNiriBindKey(keyStr)] = &overrideBind{
|
||||||
Key: keyStr,
|
Key: keyStr,
|
||||||
Action: action,
|
Action: action,
|
||||||
Description: kb.Description,
|
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) {
|
func (p *NiriParser) Parse() (*NiriSection, error) {
|
||||||
dmsBindsPath := filepath.Join(p.configDir, "dms", "binds.kdl")
|
dmsBindsPath := filepath.Join(p.configDir, "dms", "binds.kdl")
|
||||||
if _, err := os.Stat(dmsBindsPath); err == nil {
|
if _, err := os.Stat(dmsBindsPath); err == nil {
|
||||||
@@ -213,24 +221,25 @@ func (p *NiriParser) finalizeBinds() []NiriKeyBinding {
|
|||||||
|
|
||||||
func (p *NiriParser) addBind(kb *NiriKeyBinding) {
|
func (p *NiriParser) addBind(kb *NiriKeyBinding) {
|
||||||
key := p.formatBindKey(kb)
|
key := p.formatBindKey(kb)
|
||||||
|
normalizedKey := normalizeNiriBindKey(key)
|
||||||
isDMSBind := strings.Contains(kb.Source, "dms/binds.kdl")
|
isDMSBind := strings.Contains(kb.Source, "dms/binds.kdl")
|
||||||
|
|
||||||
if isDMSBind {
|
if isDMSBind {
|
||||||
p.dmsBindKeys[key] = true
|
p.dmsBindKeys[normalizedKey] = true
|
||||||
p.dmsBindMap[key] = kb
|
p.dmsBindMap[normalizedKey] = kb
|
||||||
} else if p.dmsBindKeys[key] {
|
} else if p.dmsBindKeys[normalizedKey] {
|
||||||
p.bindsAfterDMS++
|
p.bindsAfterDMS++
|
||||||
p.conflictingConfigs[key] = kb
|
p.conflictingConfigs[normalizedKey] = kb
|
||||||
p.configBindKeys[key] = true
|
p.configBindKeys[normalizedKey] = true
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
p.configBindKeys[key] = true
|
p.configBindKeys[normalizedKey] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := p.bindMap[key]; !exists {
|
if _, exists := p.bindMap[normalizedKey]; !exists {
|
||||||
p.bindOrder = append(p.bindOrder, key)
|
p.bindOrder = append(p.bindOrder, normalizedKey)
|
||||||
}
|
}
|
||||||
p.bindMap[key] = kb
|
p.bindMap[normalizedKey] = kb
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *NiriParser) formatBindKey(kb *NiriKeyBinding) string {
|
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) {
|
func TestNiriParseMultipleArgs(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
configFile := filepath.Join(tmpDir, "config.kdl")
|
configFile := filepath.Join(tmpDir, "config.kdl")
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ func TestNiriEmptyArgsPreservation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for key, expected := range binds {
|
for key, expected := range binds {
|
||||||
loaded, ok := loadedBinds[key]
|
loaded, ok := loadedBinds[normalizeNiriBindKey(key)]
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("Missing bind for key %s", key)
|
t.Errorf("Missing bind for key %s", key)
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user