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 {