package services import ( "cmbone/internal/models" hotkey "cmbone/platform" "log" "sync" "github.com/wailsapp/wails/v3/pkg/application" ) type HotkeyService struct { store *SuiStore } func NewHotkeyService(store *SuiStore) *HotkeyService { return &HotkeyService{ store: store, } } func (cs *HotkeyService) UpHotkey(id int, key int, modifier int) error { var oldKey, oldModifier uint32 if err := cs.store.DB.QueryRow("SELECT keycode, modifiers FROM hotkeys WHERE id = ?", id).Scan(&oldKey, &oldModifier); err != nil { return err } _, err := cs.store.DB.Exec(` UPDATE hotkeys SET keycode = ?, modifiers = ? WHERE id = ? `, key, modifier, id) if err == nil { LoadAndRegisterHotkeysFrom(cs.store, id) hotkey.UnregisterHotKey(oldKey, oldModifier) } return err } func (cs *HotkeyService) GetHotkeys() ([]models.Hotkey, error) { rows, err := cs.store.DB.Query("SELECT id, keycode, modifiers FROM hotkeys") if err != nil { return nil, err } defer rows.Close() var hotkeys []models.Hotkey for rows.Next() { var hk models.Hotkey if err := rows.Scan(&hk.ID, &hk.KeyCode, &hk.Modifiers); err != nil { return nil, err } hotkeys = append(hotkeys, hk) } if err := rows.Err(); err != nil { return nil, err } return hotkeys, nil } type hotkeyEntry struct { ID int Hotkey models.Hotkey Window application.Window Callback func() } var ( hotkeys = make(map[int]*hotkeyEntry) mutex sync.RWMutex ) func RegisterHotkeyEntry(id int, keycode, modifiers uint32, win application.Window, cb func()) { mutex.Lock() defer mutex.Unlock() hotkeys[id] = &hotkeyEntry{ ID: id, Hotkey: models.Hotkey{ KeyCode: keycode, Modifiers: modifiers, }, Window: win, Callback: cb, } hotkey.RegisterHotKeyWithCallback(keycode, modifiers, cb) } func LoadAndRegisterHotkeysFrom(m *SuiStore, id int) { var hk models.Hotkey err := m.DB.QueryRow("SELECT keycode, modifiers FROM hotkeys where id = ?", id).Scan(&hk.KeyCode, &hk.Modifiers) if err != nil { log.Printf("load hotkey %d failed: %v", id, err) return } mutex.RLock() entry, ok := hotkeys[id] mutex.RUnlock() if !ok { log.Printf("hotkey %d has no registered window callback", id) return } hotkey.UnregisterHotKey(hk.KeyCode, hk.Modifiers) RegisterHotkeyEntry(id, hk.KeyCode, hk.Modifiers, entry.Window, entry.Callback) } func RegisterWindowAndCallback(id int, win application.Window, cb hotkey.HotKeyCallback) { mutex.Lock() hotkeys[id] = &hotkeyEntry{ ID: id, Hotkey: models.Hotkey{ KeyCode: 0, Modifiers: 0, }, Window: win, Callback: cb, } mutex.Unlock() }