Compare commits

...

2 Commits

Author SHA1 Message Date
9bea148d40 IsReachable and WaitUntilReachable implemented 2024-02-19 10:02:33 +01:00
cfc682a36f renamed instance to client 2024-02-15 14:41:37 +01:00
6 changed files with 65 additions and 28 deletions

37
check_reachable.go Normal file
View File

@ -0,0 +1,37 @@
package hypr
import (
"context"
"strings"
"time"
)
// IsReachable pings the unix socket to check
// if Hyprland is ready to accept incoming requests
func (c *Client) IsReachable() bool {
str, err := readSocketString(c.SocketPath(), strings.NewReader("dispatch exec echo"))
if err != nil {
return false
}
return str == "ok"
}
// WaitUntilReachable periodically calls IsReachable
// and returns true as soon as IsReachable returns true.
// When ctx is closed before Hyprland is reachable, false is returned
func (c *Client) WaitUntilReachable(ctx context.Context) bool {
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
select {
case <-ticker.C:
if c.IsReachable() {
return true
}
case <-ctx.Done():
return false
}
return false
}

View File

@ -6,12 +6,12 @@ import (
"strings" "strings"
) )
func (i *Instance) Dispatch(cmd string) (io.ReadCloser, error) { func (c *Client) Dispatch(cmd string) (io.ReadCloser, error) {
return readSocketRaw(i.SocketPath(), strings.NewReader(fmt.Sprintf("dispatch %s", cmd))) return readSocketRaw(c.SocketPath(), strings.NewReader(fmt.Sprintf("dispatch %s", cmd)))
} }
func (i *Instance) DispatchExpectOK(cmd string) error { func (c *Client) DispatchExpectOK(cmd string) error {
str, err := readSocketString(i.SocketPath(), strings.NewReader(fmt.Sprintf("dispatch %s", cmd))) str, err := readSocketString(c.SocketPath(), strings.NewReader(fmt.Sprintf("dispatch %s", cmd)))
if err != nil { if err != nil {
return err return err
} }

View File

@ -12,7 +12,7 @@ import (
"git.milar.in/milarin/slices" "git.milar.in/milarin/slices"
) )
func GetInstance(signature string) (*Instance, error) { func GetClient(signature string) (*Client, error) {
lockFilePath := fmt.Sprintf("/tmp/hypr/%s.lock", signature) lockFilePath := fmt.Sprintf("/tmp/hypr/%s.lock", signature)
file, err := os.Open(lockFilePath) file, err := os.Open(lockFilePath)
@ -33,38 +33,38 @@ func GetInstance(signature string) (*Instance, error) {
return nil, err return nil, err
} }
return &Instance{ return &Client{
Signature: signature, Signature: signature,
PID: pid, PID: pid,
WaylandSocket: lines[1], WaylandSocket: lines[1],
}, nil }, nil
} }
func GetDefaultInstance() (*Instance, error) { func GetDefaultClient() (*Client, error) {
signature, ok := os.LookupEnv("HYPRLAND_INSTANCE_SIGNATURE") signature, ok := os.LookupEnv("HYPRLAND_INSTANCE_SIGNATURE")
if !ok { if !ok {
return nil, errors.New("default instance not found because HYPRLAND_INSTANCE_SIGNATURE is not set") return nil, errors.New("default instance not found because HYPRLAND_INSTANCE_SIGNATURE is not set")
} }
return GetInstance(signature) return GetClient(signature)
} }
func GetInstances() ([]*Instance, error) { func GetClients() ([]*Client, error) {
entries, err := os.ReadDir("/tmp/hypr") entries, err := os.ReadDir("/tmp/hypr")
if err != nil { if err != nil {
return nil, err return nil, err
} }
entries = slices.Filter(entries, fs.DirEntry.IsDir) entries = slices.Filter(entries, fs.DirEntry.IsDir)
instances := make([]*Instance, 0, len(entries)) clients := make([]*Client, 0, len(entries))
for _, entry := range entries { for _, entry := range entries {
instance, err := GetInstance(entry.Name()) client, err := GetClient(entry.Name())
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
continue continue
} }
instances = append(instances, instance) clients = append(clients, client)
} }
return instances, nil return clients, nil
} }

View File

@ -4,30 +4,30 @@ import (
"strings" "strings"
) )
func (i *Instance) GetActiveWindow() (*Window, error) { func (i *Client) GetActiveWindow() (*Window, error) {
return readSocket[*Window](i.SocketPath(), strings.NewReader("j/activewindow")) return readSocket[*Window](i.SocketPath(), strings.NewReader("j/activewindow"))
} }
func (i *Instance) GetActiveWorkspace() (*Workspace, error) { func (i *Client) GetActiveWorkspace() (*Workspace, error) {
return readSocket[*Workspace](i.SocketPath(), strings.NewReader("j/activeworkspace")) return readSocket[*Workspace](i.SocketPath(), strings.NewReader("j/activeworkspace"))
} }
func (i *Instance) GetBinds() ([]*Bind, error) { func (i *Client) GetBinds() ([]*Bind, error) {
return readSocket[[]*Bind](i.SocketPath(), strings.NewReader("j/binds")) return readSocket[[]*Bind](i.SocketPath(), strings.NewReader("j/binds"))
} }
func (i *Instance) GetWindows() ([]*Window, error) { func (i *Client) GetWindows() ([]*Window, error) {
return readSocket[[]*Window](i.SocketPath(), strings.NewReader("j/clients")) return readSocket[[]*Window](i.SocketPath(), strings.NewReader("j/clients"))
} }
func (i *Instance) GetCursorPos() (Point, error) { func (i *Client) GetCursorPos() (Point, error) {
return readSocket[Point](i.SocketPath(), strings.NewReader("j/cursorpos")) return readSocket[Point](i.SocketPath(), strings.NewReader("j/cursorpos"))
} }
func (i *Instance) GetMonitors() ([]*Monitor, error) { func (i *Client) GetMonitors() ([]*Monitor, error) {
return readSocket[[]*Monitor](i.SocketPath(), strings.NewReader("j/monitors")) return readSocket[[]*Monitor](i.SocketPath(), strings.NewReader("j/monitors"))
} }
func (i *Instance) GetWorkspaces() ([]*Workspace, error) { func (i *Client) GetWorkspaces() ([]*Workspace, error) {
return readSocket[[]*Workspace](i.SocketPath(), strings.NewReader("j/workspaces")) return readSocket[[]*Workspace](i.SocketPath(), strings.NewReader("j/workspaces"))
} }

View File

@ -5,21 +5,21 @@ import (
"fmt" "fmt"
) )
type Instance struct { type Client struct {
Signature string `json:"instance"` Signature string `json:"instance"`
PID int `json:"pid"` PID int `json:"pid"`
WaylandSocket string `json:"wl_socket"` WaylandSocket string `json:"wl_socket"`
} }
func (i Instance) String() string { func (c Client) String() string {
data, _ := json.MarshalIndent(i, "", "\t") data, _ := json.MarshalIndent(c, "", "\t")
return string(data) return string(data)
} }
func (i Instance) SocketPath() string { func (c Client) SocketPath() string {
return fmt.Sprintf("/tmp/hypr/%s/.socket.sock", i.Signature) return fmt.Sprintf("/tmp/hypr/%s/.socket.sock", c.Signature)
} }
func (i Instance) EventSocketPath() string { func (c Client) EventSocketPath() string {
return fmt.Sprintf("/tmp/hypr/%s/.socket2.sock", i.Signature) return fmt.Sprintf("/tmp/hypr/%s/.socket2.sock", c.Signature)
} }

View File

@ -8,7 +8,7 @@ import (
"git.milar.in/milarin/slices" "git.milar.in/milarin/slices"
) )
func (i *Instance) Subscribe(ctx context.Context, events ...EventType) (<-chan Event, error) { func (i *Client) Subscribe(ctx context.Context, events ...EventType) (<-chan Event, error) {
r, err := readSocketRaw(i.EventSocketPath(), strings.NewReader("")) r, err := readSocketRaw(i.EventSocketPath(), strings.NewReader(""))
if err != nil { if err != nil {
return nil, err return nil, err