mirror of
https://github.com/gabrielkheisa/auto_dark_light_windows.git
synced 2025-04-27 00:19:06 +07:00
145 lines
3.3 KiB
Go
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)
|
|
}
|