-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbrightness_windows.go
140 lines (121 loc) · 3.63 KB
/
brightness_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"fmt"
"log"
"math"
"strings"
"syscall"
"time"
retry "github.com/avast/retry-go/v4"
"github.com/gek64/displayController"
rl "github.com/gen2brain/raylib-go/raylib"
)
type BrightnessCommand int
const (
DecreaseBrightness BrightnessCommand = iota
IncreaseBrightness
)
type Monitor interface {
getBrightness() (int, error)
setBrightness(int)
getInstanceName() string
getPosition() rl.Vector2
}
type MonitorInfo struct {
name string
brightness int
monitor *Monitor
}
var currentMonitor MonitorInfo
func getCursorMonitor() Monitor {
hMonitor, monitorDisplayName, pos, err := cursorOnMonitor()
if err != nil {
log.Fatal(err)
}
// Suffixing with `\\Monitor0` is needed otherwise it'd report some other device ID.
// 0 and 1 are options provided by https://github.com/posthumz/DisplayDevices (see readme).
display := getDisplayFromName(monitorDisplayName+"\\Monitor0", 0)
if display == nil {
log.Fatal(fmt.Errorf("couldn't retrieve display's ID"))
}
deviceInstanceID := strings.Split(display.DeviceIDString(), "\\")[1] // no idx checking was done here
monitorInstanceName, err := getMonitorInstanceName(deviceInstanceID)
if err != nil {
log.Fatal(err)
}
isWMIMonitor, err := isTypeWMIMonitor(monitorInstanceName)
if err != nil {
log.Fatal(err)
}
if isWMIMonitor {
return WMIMonitor{name: monitorInstanceName, pos: pos}
} else {
physicalMonitor, err := displayController.GetPhysicalMonitor(syscall.Handle(*hMonitor))
if err != nil {
log.Fatal(err)
}
return DDCMonitor{name: monitorInstanceName, physicalMonitor: &physicalMonitor, pos: pos}
}
}
func brightnessSetter(commandChan <-chan BrightnessCommand, popupVisibleChan chan<- bool, popupPosChan chan<- rl.Vector2) {
resetTimer := make(chan bool)
go clearCurrentMonitor(¤tMonitor, resetTimer, popupVisibleChan)
for {
command := <-commandChan
m := getCursorMonitor()
if currentMonitor.name != m.getInstanceName() {
b, err := retry.DoWithData(
func() (int, error) {
return m.getBrightness()
},
retry.Attempts(uint(5)),
retry.OnRetry(func(attempt uint, err error) {
log.Println("retrying", attempt+1, "time to get brightness")
}))
if err != nil {
log.Fatal(fmt.Errorf("getting monitor brightness failed: %v", err))
}
resetTimer <- true
// popup could be visible on other monitor, so we should hide it before revising its position, otherwise:
// - it may cause a flicker because we're repositioning it, and
// - we may also see brightness level of the previous monitor for some ms
popupVisibleChan <- false
popupPosChan <- m.getPosition()
currentMonitor.name = m.getInstanceName()
currentMonitor.brightness = b
currentMonitor.monitor = &m
} else {
resetTimer <- true
}
popupVisibleChan <- true
prevBrightness := currentMonitor.brightness
switch command {
case DecreaseBrightness:
currentMonitor.brightness =
clamp(0, 100,
int(math.Floor(
snapNumber(6.25)(float64(currentMonitor.brightness)-6.25))))
case IncreaseBrightness:
currentMonitor.brightness =
clamp(0, 100,
int(math.Floor(
snapNumber(6.25)(float64(currentMonitor.brightness)+6.25))))
}
if currentMonitor.brightness != prevBrightness {
go m.setBrightness(currentMonitor.brightness)
}
}
}
func clearCurrentMonitor(currentMonitor *MonitorInfo, resetTimer <-chan bool, popupVisibleChan chan<- bool) {
t := time.AfterFunc(0, func() {})
for {
<-resetTimer
t.Stop()
t = time.AfterFunc(1*time.Second+200*time.Millisecond, func() {
popupVisibleChan <- false
currentMonitor.name = ""
currentMonitor.brightness = 0
currentMonitor.monitor = nil
})
}
}