148 lines
2.8 KiB
Go
148 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()
|
|
}
|