hyprman/internal/hyprman.go

149 lines
2.8 KiB
Go

package hyprman
import (
"encoding/json"
"fmt"
"log"
"net"
"os"
"os/exec"
"path/filepath"
yaml "github.com/goccy/go-yaml"
)
func DefaultConfigPath() string {
configPath, exists := os.LookupEnv("XDG_CONFIG_HOME")
if !exists {
home, exists := os.LookupEnv("HOME")
if !exists {
log.Fatalln("failed to set default icons.json path is $HOME or $XDG_CONFIG_HOME set?")
}
configPath = filepath.Join(home, ".config")
}
return filepath.Join(configPath, "hyprman", "config.yml")
}
func hyprSocketBase() string {
runtimeDir, exists := os.LookupEnv("XDG_RUNTIME_DIR")
if !exists {
log.Fatalln("XDG_RUNTIME_DIR not set")
}
instanceSig, exists := os.LookupEnv("HYPRLAND_INSTANCE_SIGNATURE")
if !exists {
log.Fatalln("HYPRLAND_INSTANCE_SIGNATURE not set")
}
return filepath.Join(runtimeDir, "hypr", instanceSig)
}
func hyprSocket() string {
return filepath.Join(hyprSocketBase(), ".socket.sock")
}
func hyprSocket2() string {
return filepath.Join(hyprSocketBase(), ".socket2.sock")
}
type Workspace struct {
Name string
Id int
}
type Client struct {
Class string
Workspace Workspace
}
type Icons map[string]string
type Hyprman struct {
Config Config
}
type Config struct {
Classes Icons
NoClientIcon string `yaml:"no-client"`
DefaultIcon string `yaml:"default-icon"`
}
func (hm *Hyprman) LoadConfig(path string) {
var config Config
data, err := os.ReadFile(path)
if err != nil {
log.Fatal(fmt.Errorf("failed to read config at %s:\n%w", path, err))
}
if err := yaml.Unmarshal([]byte(data), &config); err != nil {
log.Fatal(fmt.Errorf("failed to read config at %s:\n%w", path, err))
}
hm.Config = config
}
func hyprctl(cmd string) []byte {
socketPath := hyprSocket()
conn, err := net.Dial("unix", socketPath)
if err != nil {
log.Fatalln("Error connecting to hyprland IPC:", err)
}
defer conn.Close()
_, err = conn.Write([]byte(cmd))
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1024*8) // Bigger?
n, err := conn.Read(buf)
if err != nil {
log.Fatal(err)
}
return buf[0:n]
}
type ActiveWorkspace struct {
Name string
Id int
}
type Monitor struct {
ActiveWorkspace ActiveWorkspace
Id int
}
// generic or interface?
func getMonitors() []Monitor {
data := hyprctl("[-j]/monitors")
var monitors []Monitor
err := json.Unmarshal(data, &monitors)
if err != nil {
log.Fatalln(err)
}
return monitors
}
func getClients() []Client {
data := hyprctl("[-j]/clients")
var clients []Client
err := json.Unmarshal(data, &clients)
if err != nil {
log.Fatalln(err)
}
return clients
}
func openWorkspaces(monitors []Monitor) []int {
open := make([]int, len(monitors))
for i, m := range monitors {
open[i] = m.ActiveWorkspace.Id
}
return open
}
func notify(message string) {
cmd := exec.Command(
"notify-send",
"--app-name=hyprman",
"--transient",
message,
)
cmd.Run()
}