mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-04 04:28:30 -04:00
evdev: resolve capslock state from any available keyboard
fixes #2991 port 1.5
This commit is contained in:
@@ -48,7 +48,7 @@ func NewManager() (*Manager, error) {
|
||||
return nil, fmt.Errorf("failed to find keyboards: %w", err)
|
||||
}
|
||||
|
||||
initialCapsLock := readInitialCapsLockState(devices[0])
|
||||
initialCapsLock, _ := capsLockFromDevices(devices)
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
@@ -85,14 +85,21 @@ func NewManager() (*Manager, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func readInitialCapsLockState(device EvdevDevice) bool {
|
||||
ledStates, err := device.State(evLedType)
|
||||
if err != nil {
|
||||
log.Debugf("Could not read LED state: %v", err)
|
||||
return false
|
||||
func capsLockFromDevices(devices []EvdevDevice) (bool, bool) {
|
||||
for _, device := range devices {
|
||||
if device == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ledStates, err := device.State(evLedType)
|
||||
if err != nil || len(ledStates) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return ledStates[ledCapslockKey], true
|
||||
}
|
||||
|
||||
return ledStates[ledCapslockKey]
|
||||
return false, false
|
||||
}
|
||||
|
||||
func findKeyboards() ([]EvdevDevice, error) {
|
||||
@@ -297,25 +304,22 @@ func (m *Manager) readAndUpdateCapsLockState(deviceIndex int) {
|
||||
m.devicesMutex.RUnlock()
|
||||
return
|
||||
}
|
||||
device := m.devices[deviceIndex]
|
||||
ordered := make([]EvdevDevice, 0, len(m.devices))
|
||||
ordered = append(ordered, m.devices[deviceIndex])
|
||||
for i, device := range m.devices {
|
||||
if i == deviceIndex {
|
||||
continue
|
||||
}
|
||||
ordered = append(ordered, device)
|
||||
}
|
||||
m.devicesMutex.RUnlock()
|
||||
|
||||
ledStates, err := device.State(evLedType)
|
||||
if err != nil {
|
||||
log.Warnf("Failed to read LED state: %v", err)
|
||||
capsLockState, ok := capsLockFromDevices(ordered)
|
||||
if !ok {
|
||||
log.Debug("No LED-capable device available for caps lock state")
|
||||
return
|
||||
}
|
||||
|
||||
if len(ledStates) == 0 {
|
||||
log.Debug("No LED state available (empty map)")
|
||||
|
||||
// This means the device either:
|
||||
// - doesn't support LED reporting at all, or
|
||||
// - the kernel returned an empty state
|
||||
return
|
||||
}
|
||||
|
||||
capsLockState := ledStates[ledCapslockKey]
|
||||
m.updateCapsLockStateDirect(capsLockState)
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ func TestNotifySubscribers(t *testing.T) {
|
||||
m.Close()
|
||||
}
|
||||
|
||||
func TestReadInitialCapsLockState(t *testing.T) {
|
||||
func TestCapsLockFromDevices(t *testing.T) {
|
||||
t.Run("caps lock is on", func(t *testing.T) {
|
||||
mockDevice := mocks.NewMockEvdevDevice(t)
|
||||
ledState := evdev.StateMap{
|
||||
@@ -314,7 +314,8 @@ func TestReadInitialCapsLockState(t *testing.T) {
|
||||
}
|
||||
mockDevice.EXPECT().State(evdev.EvType(evLedType)).Return(ledState, nil).Once()
|
||||
|
||||
result := readInitialCapsLockState(mockDevice)
|
||||
result, ok := capsLockFromDevices([]EvdevDevice{mockDevice})
|
||||
assert.True(t, ok)
|
||||
assert.True(t, result)
|
||||
})
|
||||
|
||||
@@ -325,7 +326,8 @@ func TestReadInitialCapsLockState(t *testing.T) {
|
||||
}
|
||||
mockDevice.EXPECT().State(evdev.EvType(evLedType)).Return(ledState, nil).Once()
|
||||
|
||||
result := readInitialCapsLockState(mockDevice)
|
||||
result, ok := capsLockFromDevices([]EvdevDevice{mockDevice})
|
||||
assert.True(t, ok)
|
||||
assert.False(t, result)
|
||||
})
|
||||
|
||||
@@ -333,9 +335,25 @@ func TestReadInitialCapsLockState(t *testing.T) {
|
||||
mockDevice := mocks.NewMockEvdevDevice(t)
|
||||
mockDevice.EXPECT().State(evdev.EvType(evLedType)).Return(nil, errors.New("read error")).Once()
|
||||
|
||||
result := readInitialCapsLockState(mockDevice)
|
||||
result, ok := capsLockFromDevices([]EvdevDevice{mockDevice})
|
||||
assert.False(t, ok)
|
||||
assert.False(t, result)
|
||||
})
|
||||
|
||||
t.Run("falls back past device without LED state", func(t *testing.T) {
|
||||
noLedDevice := mocks.NewMockEvdevDevice(t)
|
||||
noLedDevice.EXPECT().State(evdev.EvType(evLedType)).Return(evdev.StateMap{}, nil).Once()
|
||||
|
||||
ledDevice := mocks.NewMockEvdevDevice(t)
|
||||
ledState := evdev.StateMap{
|
||||
ledCapslockKey: true,
|
||||
}
|
||||
ledDevice.EXPECT().State(evdev.EvType(evLedType)).Return(ledState, nil).Once()
|
||||
|
||||
result, ok := capsLockFromDevices([]EvdevDevice{noLedDevice, nil, ledDevice})
|
||||
assert.True(t, ok)
|
||||
assert.True(t, result)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHasInputGroupAccess(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user