2025-04-25 21:43:37 +07:00

145 lines
3.3 KiB
Go

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(5 * 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)
}