package main import ( "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "strings" "syscall" "time" "unsafe" "github.com/getlantern/systray" "golang.org/x/sys/windows/registry" ) // Set Windows dark/light mode via registry func setMode(light bool) { key, _ := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.SET_VALUE) defer key.Close() val := uint32(0) if light { val = 1 } key.SetDWordValue("AppsUseLightTheme", val) key.SetDWordValue("SystemUsesLightTheme", val) } // Restart Explorer to fully apply theme func restartExplorer() { exec.Command("taskkill", "/f", "/im", "explorer.exe").Run() time.Sleep(1 * time.Second) exec.Command("explorer.exe").Start() } // Get current theme mode from registry func getCurrentMode() string { key, _ := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) defer key.Close() val, _, _ := key.GetIntegerValue("AppsUseLightTheme") if val == 1 { return "light" } return "dark" } // Find image in same dir with any supported extension func findImageFile(name string) string { exePath, _ := os.Executable() dir := filepath.Dir(exePath) matches, _ := filepath.Glob(filepath.Join(dir, name+".*")) for _, f := range matches { ext := strings.ToLower(filepath.Ext(f)) if ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp" || ext == ".webp" { return f } } return "" } // Get current wallpaper path from registry func getCurrentWallpaper() string { key, _ := registry.OpenKey(registry.CURRENT_USER, `Control Panel\Desktop`, registry.QUERY_VALUE) defer key.Close() val, _, _ := key.GetStringValue("Wallpaper") return val } // Set desktop wallpaper via Windows API func setWallpaper(path string) { user32 := syscall.NewLazyDLL("user32.dll") sysParam := user32.NewProc("SystemParametersInfoW") p, _ := syscall.UTF16PtrFromString(path) sysParam.Call(0x0014, 0, uintptr(unsafe.Pointer(p)), uintptr(0x01|0x02)) } // Main background loop func backgroundLoop() { lightImg := findImageFile("light") darkImg := findImageFile("dark") lastMode := getCurrentMode() for { hour := time.Now().Hour() newMode := "dark" var targetImg string if hour >= 6 && hour < 18 { newMode = "light" targetImg = lightImg } else { targetImg = darkImg } if newMode != lastMode { setMode(newMode == "light") restartExplorer() lastMode = newMode } if targetImg != "" && getCurrentWallpaper() != targetImg { setWallpaper(targetImg) } time.Sleep(60 * time.Second) } } // Load icon from local directory (icon.ico) func getIconBytes() []byte { exePath, _ := os.Executable() iconPath := filepath.Join(filepath.Dir(exePath), "icon.ico") data, err := ioutil.ReadFile(iconPath) if err != nil { fmt.Println("icon.ico not found or unreadable.") return nil } return data } // Systray startup func onReady() { icon := getIconBytes() if icon != nil { systray.SetIcon(icon) } systray.SetTitle("Auto Theme") systray.SetTooltip("Auto Theme + Wallpaper Switcher") mQuit := systray.AddMenuItem("Quit", "Exit the program") go func() { go backgroundLoop() <-mQuit.ClickedCh systray.Quit() }() } func onExit() {} func main() { systray.Run(onReady, onExit) }