1package macos
2
3import (
4 _ "embed"
5 "fmt"
6 "os"
7 "os/exec"
8 "path/filepath"
9 "runtime"
10 "strings"
11)
12
13//go:embed appearance.swift
14var appearanceSwift string
15
16type MacOSAppearance struct {
17 DarkMode bool
18 AccentColor string
19}
20
21// GetAppearance fetches the current macOS appearance (dark mode and accent color).
22func GetAppearance() (*MacOSAppearance, error) {
23 if runtime.GOOS != "darwin" {
24 return nil, fmt.Errorf("GetAppearance is only supported on macOS")
25 }
26
27 tmpDir, err := os.MkdirTemp("", "matcha-appearance")
28 if err != nil {
29 return nil, err
30 }
31 defer os.RemoveAll(tmpDir) //nolint:errcheck
32
33 swiftFile := filepath.Join(tmpDir, "appearance.swift")
34 if err := os.WriteFile(swiftFile, []byte(appearanceSwift), 0644); err != nil {
35 return nil, err
36 }
37
38 binFile := filepath.Join(tmpDir, "appearance")
39
40 // Compile
41 cmd := exec.Command("swiftc", swiftFile, "-o", binFile) //nolint:noctx
42 if out, err := cmd.CombinedOutput(); err != nil {
43 return nil, fmt.Errorf("failed to compile appearance helper: %w\n%s", err, string(out))
44 }
45
46 // Run
47 out, err := exec.Command(binFile).Output() //nolint:noctx
48 if err != nil {
49 return nil, fmt.Errorf("failed to run appearance helper: %w", err)
50 }
51
52 parts := strings.Fields(string(out))
53 if len(parts) < 2 {
54 return nil, fmt.Errorf("unexpected output from appearance helper: %s", string(out))
55 }
56
57 return &MacOSAppearance{
58 DarkMode: parts[0] == "true",
59 AccentColor: parts[1],
60 }, nil
61}