package hypr import ( "context" "errors" "fmt" "io" "io/fs" "os" "strconv" "strings" "git.milar.in/milarin/slices" ) func GetClient(signature string) (*Client, error) { lockFilePath := fmt.Sprintf("/run/user/1000/hypr/%s/hyprland.lock", signature) file, err := os.Open(lockFilePath) if err != nil { return nil, err } defer file.Close() data, err := io.ReadAll(file) if err != nil { return nil, err } lines := strings.Split(string(data), "\n") pid, err := strconv.Atoi(lines[0]) if err != nil { return nil, err } return &Client{ Signature: signature, PID: pid, WaylandSocket: lines[1], }, nil } func GetDefaultClient() (*Client, error) { signature, ok := os.LookupEnv("HYPRLAND_INSTANCE_SIGNATURE") if !ok { return nil, errors.New("default instance not found because HYPRLAND_INSTANCE_SIGNATURE is not set") } return GetClient(signature) } func GetClients() ([]*Client, error) { entries, err := os.ReadDir("/run/user/1000/hypr") if err != nil { return nil, err } entries = slices.Filter(entries, fs.DirEntry.IsDir) clients := make([]*Client, 0, len(entries)) for _, entry := range entries { client, err := GetClient(entry.Name()) if err != nil { fmt.Println(err) continue } clients = append(clients, client) } return clients, nil } func WaitForClient(ctx context.Context, signature string) (*Client, error) { lockFilePath := fmt.Sprintf("/run/user/1000/hypr/%s/hyprland.lock", signature) lockFileExists := !waitFor(ctx, func() bool { _, err := os.Stat(lockFilePath) return !errors.Is(err, os.ErrNotExist) }) if !lockFileExists { return nil, errors.New("hyprland lock file not found") } client, err := GetClient(signature) if err != nil { return nil, err } if client.WaitUntilReachable(context.Background()) { return nil, errors.New("hyprland not reachable") } return client, nil }