Files

148 lines
4.2 KiB
Go

// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package preferences
/*
#include <stdlib.h>
#include "native.h"
*/
import "C"
import (
"strings"
"unsafe"
"git.stormux.org/storm/cthulhu/internal/input"
)
var modifierKeys = []string{"Insert", "KP_Insert", "Caps_Lock"}
func (session *uiSession) setKeyBindings(values Values) {
session.bindingDraft = input.CloneBindingOverrides(values.KeyBindings)
setCheck("generalDesktopButton", values.KeyboardLayout != 2)
setCheck("generalLaptopButton", values.KeyboardLayout == 2)
setModifierKeys(values.CthulhuModifierKeys)
session.bindingLayout = values.KeyboardLayout
if session.bindingLayout != 2 {
session.bindingLayout = 1
}
setCheck("keyBindingDesktopButton", session.bindingLayout == 1)
setCheck("keyBindingLaptopButton", session.bindingLayout == 2)
session.populateKeyBindings(0)
}
func (session *uiSession) refreshKeyBindingLayout() {
layout := 1
if getCheck("keyBindingLaptopButton") {
layout = 2
}
if layout != session.bindingLayout && (layout == 1 || layout == 2) {
session.bindingLayout = layout
session.populateKeyBindings(0)
}
}
func (session *uiSession) populateKeyBindings(selected int) {
session.bindingRows = input.BindingRows(input.KeyboardLayout(session.bindingLayout), session.bindingDraft)
C.prefs_bindings_clear()
for _, row := range session.bindingRows {
scope := "Global"
if row.Scope == "browse" {
scope = "Browse mode"
}
keys := row.Keys
if keys == "" {
keys = "Unbound"
}
label, scopeText, shortcuts, defaults := C.CString(row.Label), C.CString(scope), C.CString(keys), C.CString(row.DefaultKeys)
C.prefs_binding_append(label, scopeText, shortcuts, defaults)
C.free(unsafe.Pointer(label))
C.free(unsafe.Pointer(scopeText))
C.free(unsafe.Pointer(shortcuts))
C.free(unsafe.Pointer(defaults))
}
C.prefs_binding_select(C.int(selected))
// Keep the editor empty when the selected command has been disabled.
if selected >= 0 && selected < len(session.bindingRows) {
id, text := C.CString("keyBindingEntry"), C.CString(session.bindingRows[selected].Keys)
C.prefs_entry_set(id, text)
C.free(unsafe.Pointer(id))
C.free(unsafe.Pointer(text))
}
}
func (session *uiSession) editKeyBinding(action int) {
selected := int(C.prefs_binding_selected())
if action != 7 && (selected < 0 || selected >= len(session.bindingRows)) {
return
}
draft := input.CloneBindingOverrides(session.bindingDraft)
var row input.BindingRow
if selected >= 0 && selected < len(session.bindingRows) {
row = session.bindingRows[selected]
}
kept := draft[:0]
for _, override := range draft {
matches := override.Layout == input.KeyboardLayout(session.bindingLayout) && (action == 7 || (override.Scope == row.Scope && override.Command == row.Command))
if !matches {
kept = append(kept, override)
}
}
draft = kept
if action == 4 || action == 5 {
keys := []string{}
if action == 4 {
id := C.CString("keyBindingEntry")
text := C.GoString(C.prefs_entry_get(id))
C.free(unsafe.Pointer(id))
if strings.TrimSpace(text) != "" {
for _, key := range strings.Split(text, ";") {
chord, err := input.ParseCommandChord(key)
if err != nil {
status(err.Error(), true)
return
}
keys = append(keys, input.FormatCommandChord(chord))
}
}
}
draft = append(draft, input.BindingOverride{Layout: input.KeyboardLayout(session.bindingLayout), Scope: row.Scope, Command: row.Command, Keys: keys})
}
if err := input.ValidateBindingOverrides(draft); err != nil {
status(err.Error(), true)
return
}
session.bindingDraft = draft
session.populateKeyBindings(selected)
status("Binding updated. Apply or OK commits these changes.", true)
}
func setModifierKeys(keys []string) {
for _, key := range modifierKeys {
enabled := false
for _, configured := range keys {
if configured == key {
enabled = true
break
}
}
id := C.CString(key)
C.prefs_modifier_set(id, boolean(enabled))
C.free(unsafe.Pointer(id))
}
}
func getModifierKeys() []string {
keys := []string{}
for _, key := range modifierKeys {
id := C.CString(key)
if C.prefs_modifier_get(id) != 0 {
keys = append(keys, key)
}
C.free(unsafe.Pointer(id))
}
return keys
}