Skip to content

Commit

Permalink
Merge pull request #6 from BradLewis/main
Browse files Browse the repository at this point in the history
refactor: rework implementation to push menu updates through a channel
  • Loading branch information
TheDen authored Oct 17, 2023
2 parents 605663d + e744125 commit 2500b3a
Showing 1 changed file with 77 additions and 56 deletions.
133 changes: 77 additions & 56 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func getStateFromCondition(ac bool, battery bool) BatteryState {
}

var lowPowerMode = ""
var inChan = make(chan BatteryState)
var currentState BatteryState

func getHardwareUUID() (string, error) {
cmd := exec.Command("system_profiler", "SPHardwareDataType")
Expand Down Expand Up @@ -89,63 +91,78 @@ func setLowPowerMode(str string) error {
return err
}

func updateLowPowerStateMenu(hardwareUUID string) {
func getState(plistPath string) (BatteryState, error) {
cmd := exec.Command("defaults", "read", plistPath)
out, err := cmd.Output()
if err != nil {
return NEVER, err
}

var config map[string]interface{}
_, err = plist.Unmarshal(out, &config)
if err != nil {
return NEVER, err
}

// extract the LowPowerMode values for Battery and AC
batteryLowPowerModeStr := config["Battery Power"].(map[string]interface{})["LowPowerMode"].(string)
batteryLowPowerMode, err := strconv.ParseBool(batteryLowPowerModeStr)
if err != nil {
return NEVER, err
}

acLowPowerModeStr := config["AC Power"].(map[string]interface{})["LowPowerMode"].(string)
acLowPowerMode, err := strconv.ParseBool(acLowPowerModeStr)
if err != nil {
return NEVER, err
}

// Get the state for the current condition
state := getStateFromCondition(acLowPowerMode, batteryLowPowerMode)
return state, nil
}

func pollLowPowerState(hardwareUUID string) {
log.Printf("Hardware UUID is %s\n", hardwareUUID)
plistPath := fmt.Sprintf(
"/Library/Preferences/com.apple.PowerManagement.%s.plist",
hardwareUUID,
)
var currentState BatteryState
tick := time.Tick(1 * time.Second)
var err error
currentState, err = getState(plistPath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
err = setMenu(currentState)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
tick := time.Tick(15 * time.Second)

for range tick {
cmd := exec.Command("defaults", "read", plistPath)
out, err := cmd.Output()
if err != nil {
log.Println(err)
continue
}

var config map[string]interface{}
_, err = plist.Unmarshal(out, &config)
if err != nil {
log.Println(err)
continue
}

// extract the LowPowerMode values for Battery and AC
batteryLowPowerModeStr := config["Battery Power"].(map[string]interface{})["LowPowerMode"].(string)
batteryLowPowerMode, err := strconv.ParseBool(batteryLowPowerModeStr)
state, err := getState(plistPath)
if err != nil {
log.Println(err)
continue
}

acLowPowerModeStr := config["AC Power"].(map[string]interface{})["LowPowerMode"].(string)
acLowPowerMode, err := strconv.ParseBool(acLowPowerModeStr)
if err != nil {
log.Println(err)
continue
}

// Get the state for the current condition
state := getStateFromCondition(acLowPowerMode, batteryLowPowerMode)
// Only update if state has changed
if state != currentState {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(state.String(), true)
inChan <- state
log.Printf("Updated state from %s to %s\n", currentState, state)
currentState = state
}
}
}

func updateCurrentState(currentIconState string) string {
func getIcon() (string, error) {
cmd := exec.Command("pmset", "-g")
output, err := cmd.Output()
if err != nil {
log.Println(err)
return currentIconState
return "", err
}

lines := strings.Split(string(output), "\n")
Expand All @@ -154,13 +171,13 @@ func updateCurrentState(currentIconState string) string {
fields := strings.Fields(line)
if fields[1] == "1" {
lowPowerMode = "ON"
return boltIconFilled
return boltIconFilled, nil
}
lowPowerMode = "OFF"
return boltIconOutline
return boltIconOutline, nil
}
}
return currentIconState
return "", errors.New("low power mode not found")
}

func setMenuStatesFalse() {
Expand Down Expand Up @@ -191,8 +208,7 @@ func menuItems() []menuet.MenuItem {
Clicked: func() {
err := setLowPowerMode("sudo pmset -a lowpowermode 1")
if err == nil {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(ALWAYS.String(), true)
inChan <- ALWAYS
}
},
State: alwaysState,
Expand All @@ -203,8 +219,7 @@ func menuItems() []menuet.MenuItem {
Clicked: func() {
err := setLowPowerMode("sudo pmset -a lowpowermode 0")
if err == nil {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(NEVER.String(), true)
inChan <- NEVER
}
},
State: neverState,
Expand All @@ -215,8 +230,7 @@ func menuItems() []menuet.MenuItem {
Clicked: func() {
err := setLowPowerMode("sudo pmset -c lowpowermode 0; sudo pmset -b lowpowermode 1")
if err == nil {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(BATTERY_ONLY.String(), true)
inChan <- BATTERY_ONLY
}
},
State: batteryOnlyState,
Expand All @@ -227,8 +241,7 @@ func menuItems() []menuet.MenuItem {
Clicked: func() {
err := setLowPowerMode("sudo pmset -c lowpowermode 1; sudo pmset -b lowpowermode 0")
if err == nil {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(POWER_ONLY.String(), true)
inChan <- POWER_ONLY
}
},
State: powerOnlyState,
Expand All @@ -237,18 +250,26 @@ func menuItems() []menuet.MenuItem {
return items
}

func setMenu(state BatteryState) error {
setMenuStatesFalse()
menuet.Defaults().SetBoolean(state.String(), true)
icon, err := getIcon()
if err != nil {
return err
}
menuet.App().SetMenuState(&menuet.MenuState{
Image: icon,
})
menuet.App().MenuChanged()
currentState = state
return nil
}

func menu() {
currentIconState := ""
newIconState := ""
tick := time.Tick(1 * time.Second)
for range tick {
newIconState = updateCurrentState(currentIconState)
if currentIconState != newIconState {
menuet.App().SetMenuState(&menuet.MenuState{
Image: newIconState,
})
menuet.App().MenuChanged()
currentIconState = newIconState
for state := range inChan {
err := setMenu(state)
if err != nil {
log.Println(err)
}
}
}
Expand All @@ -260,7 +281,7 @@ func main() {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
go updateLowPowerStateMenu(hardwareUUID)
go pollLowPowerState(hardwareUUID)

app := menuet.App()
app.Name = "Galvani"
Expand Down

0 comments on commit 2500b3a

Please sign in to comment.