Skip to content

Commit 1a3457e

Browse files
authored
chore: 解决色温没有自动调节的问题 (#262)
使用专业版方案,使用redshift传入经纬度调节色温。 Issue: linuxdeepin/developer-center#10453 Co-authored-by: fuleyi <fuleyi@uniontech.com>
1 parent 5e34e4a commit 1a3457e

2 files changed

Lines changed: 129 additions & 6 deletions

File tree

display/color_temp.go

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import (
88
"bufio"
99
"bytes"
1010
"errors"
11+
"io/ioutil"
12+
"math"
1113
"os"
1214
"os/exec"
1315
"strconv"
16+
"strings"
1417
"sync"
1518
"time"
1619

@@ -28,6 +31,10 @@ const (
2831
ColorTemperatureModeManual
2932
)
3033

34+
const (
35+
timeZoneFile = "/usr/share/zoneinfo/zone1970.tab"
36+
)
37+
3138
func isValidColorTempMode(mode int32) bool {
3239
return mode >= ColorTemperatureModeNone && mode <= ColorTemperatureModeManual
3340
}
@@ -66,6 +73,13 @@ const (
6673
redshiftStateStopped
6774
)
6875

76+
type zoneInfo struct {
77+
country string
78+
latitude float64
79+
longitude float64
80+
distance float64
81+
}
82+
6983
type redshiftRunner struct {
7084
mu sync.Mutex
7185
state int
@@ -75,15 +89,62 @@ type redshiftRunner struct {
7589
cb func(value int)
7690
sysService *dbusutil.Service
7791
geoAgentRegistered bool
92+
93+
zoneInfoMap map[string]*zoneInfo
94+
}
95+
96+
func convertPos(pos string, digits int32) float64 {
97+
if len(pos) < 4 || digits > 9 {
98+
return 0.0
99+
}
100+
101+
integer := pos[:digits+1]
102+
fraction := pos[digits+1:]
103+
t1, _ := strconv.ParseFloat(integer, 64)
104+
t2, _ := strconv.ParseFloat(fraction, 64)
105+
if t1 > 0.0 {
106+
return t1 + t2/math.Pow(10.0, float64(len(fraction)))
107+
} else {
108+
return t1 - t2/math.Pow(10.0, float64(len(fraction)))
109+
}
78110
}
79111

80112
func newRedshiftRunner() *redshiftRunner {
81113
sysService, err := dbusutil.NewSystemService()
82114
if err != nil {
83115
logger.Warning("new sys service failed:", err)
84116
}
117+
zoneInfoMap := make(map[string]*zoneInfo)
118+
contents, err := ioutil.ReadFile(timeZoneFile)
119+
if err != nil {
120+
logger.Warning("Red timezone file failed:", err)
121+
}
122+
lines := bytes.Split(contents, []byte{'\n'})
123+
for _, line := range lines {
124+
if !bytes.HasPrefix(line, []byte{'#'}) {
125+
parts := bytes.Split(line, []byte{'\t'})
126+
if len(parts) >= 3 {
127+
coordinates := string(parts[1])
128+
index := strings.Index(coordinates[3:], "+")
129+
if index == -1 {
130+
index = strings.Index(coordinates[3:], "-")
131+
}
132+
if index > -1 {
133+
latitude := convertPos(coordinates[:index+3], 2)
134+
longitude := convertPos(coordinates[index+3:], 3)
135+
zone_info := &zoneInfo{
136+
country: string(parts[0]),
137+
latitude: latitude,
138+
longitude: longitude,
139+
}
140+
zoneInfoMap[string(parts[2])] = zone_info
141+
}
142+
}
143+
}
144+
}
85145
return &redshiftRunner{
86-
sysService: sysService,
146+
sysService: sysService,
147+
zoneInfoMap: zoneInfoMap,
87148
}
88149
}
89150

@@ -97,12 +158,14 @@ func (r *redshiftRunner) start() {
97158
}
98159
r.state = redshiftStateRunning
99160

100-
err := r.registerGeoClueAgent()
101-
if err != nil {
102-
logger.Warning("register geoClue agent failed:", err)
103-
}
104-
161+
latitude := r.zoneInfoMap[_timeZone].latitude
162+
longitude := r.zoneInfoMap[_timeZone].longitude
163+
geographicalPosition := strconv.FormatFloat(latitude, 'f', -1, 64) + ":" + strconv.FormatFloat(longitude, 'f', -1, 64)
164+
logger.Info("Get geographicalPosition:", geographicalPosition)
105165
cmd := exec.Command("redshift", "-m", "dummy", "-t", "6500:3500", "-r")
166+
if geographicalPosition != "" {
167+
cmd.Args = append(cmd.Args, "-l", geographicalPosition)
168+
}
106169
cmd.Env = append(os.Environ(), "LC_ALL=C")
107170
var errBuf bytes.Buffer
108171
cmd.Stderr = &errBuf
@@ -154,6 +217,55 @@ func (r *redshiftRunner) start() {
154217
return
155218
}
156219

220+
func (m *Manager) listenTimezone() {
221+
jobMatchRule := dbusutil.NewMatchRuleBuilder().ExtPropertiesChanged(
222+
"/org/freedesktop/timedate1", "org.freedesktop.timedate1").Build()
223+
err := jobMatchRule.AddTo(m.sysBus)
224+
if err != nil {
225+
logger.Warning(err)
226+
return
227+
}
228+
sigChan := make(chan *dbus.Signal, 10)
229+
m.sysBus.Signal(sigChan)
230+
231+
defer func() {
232+
m.sysBus.RemoveSignal(sigChan)
233+
err := jobMatchRule.RemoveFrom(m.sysBus)
234+
if err != nil {
235+
logger.Warning(err)
236+
}
237+
}()
238+
239+
for sig := range sigChan {
240+
if sig.Path == "/org/freedesktop/timedate1" &&
241+
sig.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" {
242+
if len(sig.Body) != 3 {
243+
logger.Warning(err)
244+
return
245+
}
246+
247+
props, ok := sig.Body[1].(map[string]dbus.Variant)
248+
if !ok {
249+
logger.Warning(err)
250+
return
251+
}
252+
v, ok := props["Timezone"]
253+
if ok {
254+
timezone, _ := v.Value().(string)
255+
logger.Info("Timezone change to", timezone)
256+
_timeZone = timezone
257+
if m.redshiftRunner.state == redshiftStateRunning {
258+
logger.Info("Redshift is Running")
259+
m.redshiftRunner.stop()
260+
time.AfterFunc(50*time.Millisecond, func() {
261+
m.redshiftRunner.start()
262+
})
263+
}
264+
}
265+
}
266+
}
267+
}
268+
157269
func (r *redshiftRunner) stop() {
158270
r.mu.Lock()
159271
defer r.mu.Unlock()

display/manager.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
inputdevices "github.com/linuxdeepin/go-dbus-factory/system/org.deepin.dde.inputdevices1"
3030
ofdbus "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.dbus"
3131
login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1"
32+
timedate1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.timedate1"
3233
gio "github.com/linuxdeepin/go-gir/gio-2.0"
3334
"github.com/linuxdeepin/go-lib/dbusutil"
3435
"github.com/linuxdeepin/go-lib/gsettings"
@@ -224,6 +225,7 @@ type monitorSizeInfo struct {
224225
}
225226

226227
var _ monitorManagerHooks = (*Manager)(nil)
228+
var _timeZone string
227229

228230
func newManager(service *dbusutil.Service) *Manager {
229231
m := &Manager{
@@ -289,6 +291,15 @@ func newManager(service *dbusutil.Service) *Manager {
289291
m.inputDevices.InitSignalExt(sysSigLoop, true)
290292

291293
m.sysDisplay = sysdisplay.NewDisplay(m.sysBus)
294+
td := timedate1.NewTimedate(m.sysBus)
295+
_timeZone, err = td.Timezone().Get(0)
296+
if err != nil {
297+
logger.Warning(err)
298+
_timeZone = "Asia/Beijing"
299+
}
300+
go func() {
301+
m.listenTimezone()
302+
}()
292303

293304
loginManager := login1.NewManager(m.sysBus)
294305
loginManager.InitSignalExt(sysSigLoop, true)

0 commit comments

Comments
 (0)