From de4ff71544cb30f5a50a73aa2aadbdf6b82f8285 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 12 Sep 2020 18:22:08 +0900 Subject: [PATCH] devicescale: Read ~/.config/cinnamon-monitors.xml on Cinnamon Updates #1307 --- internal/devicescale/impl_unix.go | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/internal/devicescale/impl_unix.go b/internal/devicescale/impl_unix.go index 90b64b34a..2694a52dd 100644 --- a/internal/devicescale/impl_unix.go +++ b/internal/devicescale/impl_unix.go @@ -19,8 +19,10 @@ package devicescale import ( + "encoding/xml" "os" "os/exec" + "path/filepath" "regexp" "strconv" "strings" @@ -58,6 +60,8 @@ func currentDesktop() desktop { var gsettingsRe = regexp.MustCompile(`\Auint32 (\d+)\s*\z`) func gnomeScale() float64 { + // TODO: Should 'monitors.xml' be loaded? + out, err := exec.Command("gsettings", "get", "org.gnome.desktop.interface", "scaling-factor").Output() if err != nil { if err == exec.ErrNotFound { @@ -76,7 +80,65 @@ func gnomeScale() float64 { return float64(s) } +type xmlBool bool + +func (b *xmlBool) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var s string + if err := d.DecodeElement(&s, &start); err != nil { + return err + } + *b = xmlBool(s == "yes") + return nil +} + +func cinnamonScaleFromXML() (float64, error) { + type cinnamonMonitors struct { + XMLName xml.Name `xml:"monitors"` + Version string `xml:"version,attr"` + Configuration struct { + BaseScale float64 `xml:"base_scale"` + Output []struct { + Scale float64 `xml:"scale"` + Primary xmlBool `xml:"primary"` + } `xml:"output"` + } `xml:"configuration"` + } + + home, err := os.UserHomeDir() + if err != nil { + return 0, err + } + f, err := os.Open(filepath.Join(home, ".config", "cinnamon-monitors.xml")) + if err != nil { + return 0, err + } + defer f.Close() + + d := xml.NewDecoder(f) + + var monitors cinnamonMonitors + if err = d.Decode(&monitors); err != nil { + return 0, err + } + + scale := monitors.Configuration.BaseScale + for _, v := range monitors.Configuration.Output { + // TODO: Get the monitor at the specified position. + if v.Primary { + if v.Scale != 0.0 { + scale = v.Scale + } + break + } + } + return scale, nil +} + func cinnamonScale() float64 { + if s, err := cinnamonScaleFromXML(); err == nil && s > 0 { + return s + } + out, err := exec.Command("gsettings", "get", "org.cinnamon.desktop.interface", "scaling-factor").Output() if err != nil { if err == exec.ErrNotFound {