• Updates IDE settings for improved file nesting and exclusions • Introduces biome configuration file for consistent project formatting • Implements brightness service and UI component for monitor brightness control • Refactors layout and code formatting for consistency across components
113 lines
2.7 KiB
TypeScript
113 lines
2.7 KiB
TypeScript
import { exec } from 'astal'
|
|
import GObject, { register, property, signal } from 'astal/gobject'
|
|
|
|
@register({ GTypeName: 'BrightnessService' })
|
|
export default class BrightnessService extends GObject.Object {
|
|
private declare _value: number
|
|
private declare _buses: string[]
|
|
private declare _max: number
|
|
|
|
@property(Number)
|
|
get value() {
|
|
return this._value
|
|
}
|
|
|
|
set value(value: number) {
|
|
// Ensure value is between 0-100
|
|
this._value = Math.min(100, Math.max(0, Math.round(value)))
|
|
|
|
console.log(`Setting brightness to ${this._value}%`)
|
|
this._buses.forEach((bus) => {
|
|
exec(`ddcutil setvcp 10 ${this._value} --bus ${bus}`)
|
|
})
|
|
|
|
this.emit('value_changed', this._value)
|
|
this.refreshUI()
|
|
}
|
|
|
|
@property(String)
|
|
get iconName() {
|
|
if (this._value < 25) {
|
|
return 'display-brightness-low-symbolic'
|
|
} else if (this._value < 75) {
|
|
return 'display-brightness-medium-symbolic'
|
|
} else {
|
|
return 'display-brightness-high-symbolic'
|
|
}
|
|
}
|
|
|
|
constructor() {
|
|
super()
|
|
this._value = 0
|
|
this._max = 100 // DDC brightness is typically 0-100
|
|
this._buses = this.detectBuses()
|
|
|
|
// Initialize
|
|
this.init()
|
|
}
|
|
|
|
detectBuses() {
|
|
try {
|
|
const detectOutput = exec('ddcutil detect')
|
|
const busRegex = /I2C bus:\s+\/dev\/i2c-(\d+)/g
|
|
|
|
const buses = []
|
|
let match
|
|
while ((match = busRegex.exec(detectOutput)) !== null) {
|
|
buses.push(match[1])
|
|
}
|
|
|
|
return buses
|
|
} catch (error) {
|
|
console.error('Error detecting monitors:', error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
// Initial setup - validate monitors and get initial brightness
|
|
init() {
|
|
if (this._buses.length === 0) {
|
|
console.warn('No valid DDC monitors detected')
|
|
return
|
|
}
|
|
|
|
// Get initial brightness values from monitors
|
|
this.fetchBrightness()
|
|
}
|
|
|
|
// Fetch actual brightness values from monitors
|
|
fetchBrightness() {
|
|
let totalBrightness = 0
|
|
let validMonitors = 0
|
|
|
|
console.log('Fetching brightness from monitors...')
|
|
|
|
// Get brightness from each monitor
|
|
this._buses.forEach((bus) => {
|
|
try {
|
|
const brightnessOutput = exec(`ddcutil getvcp 10 --bus ${bus}`)
|
|
const match = brightnessOutput.match(/current value\s*=\s*(\d+)/)
|
|
if (match) {
|
|
totalBrightness += parseInt(match[1], 10)
|
|
validMonitors++
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error getting brightness for bus ${bus}:`, error)
|
|
}
|
|
})
|
|
|
|
if (validMonitors > 0) {
|
|
this._value = Math.round(totalBrightness / validMonitors)
|
|
this.refreshUI()
|
|
}
|
|
}
|
|
|
|
refreshUI() {
|
|
this.notify('icon-name')
|
|
this.notify('value')
|
|
this.emit('value-changed', this._value)
|
|
}
|
|
|
|
@signal(Number)
|
|
declare valueChanged: (value: Number) => void
|
|
}
|