initial commit

This commit is contained in:
milarin 2023-10-07 16:21:49 +02:00
commit 8345de3597
9 changed files with 277 additions and 0 deletions

16
event.go Normal file
View File

@ -0,0 +1,16 @@
package sway
import (
"encoding/json"
"git.milar.in/milarin/adverr"
)
type Event struct {
Change string `json:"change"`
Container Node `json:"container"`
}
func (e Event) String() string {
return string(adverr.Must(json.MarshalIndent(e, "", "\t")))
}

9
event_type.go Normal file
View File

@ -0,0 +1,9 @@
package sway
type EventType string
const (
EventTypeWindow EventType = "window"
EventTypeWorkspace EventType = "workspace"
// TODO
)

23
get_tree.go Normal file
View File

@ -0,0 +1,23 @@
package sway
import (
"context"
"encoding/json"
"os/exec"
)
func GetTree(ctx context.Context) (*Node, error) {
cmd := exec.CommandContext(ctx, "swaymsg", "-t", "get_tree")
data, err := cmd.Output()
if err != nil {
return nil, err
}
var root Node
if err := json.Unmarshal(data, &root); err != nil {
return nil, err
}
return &root, nil
}

16
get_tree_test.go Normal file
View File

@ -0,0 +1,16 @@
package sway
import (
"context"
"fmt"
"testing"
)
func TestGetTree(t *testing.T) {
root, err := GetTree(context.Background())
if err != nil {
t.Fatal(err)
}
fmt.Println(root.ID, root.Name)
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.milar.in/milarin/sway
go 1.21.1
require git.milar.in/milarin/adverr v1.1.1

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
git.milar.in/milarin/adverr v1.1.1 h1:ENtBcqT7CncLsVfaLC3KzX8QSSGiSpsC7I7wDqladu8=
git.milar.in/milarin/adverr v1.1.1/go.mod h1:joU9sBb7ySyNv4SpTXB0Z4o1mjXsArBw4N27wjgzj9E=

150
node.go Normal file
View File

@ -0,0 +1,150 @@
package sway
type Node struct {
ID NodeID `json:"id"`
Type NodeType `json:"type"`
Orientation Orientation `json:"orientation"`
Percentage float64 `json:"percent"`
Urgent bool `json:"urgent"`
Marks []string `json:"marks"`
Focused bool `json:"focused"`
Layout string `json:"layout"`
Border BorderStyle `json:"border"`
CurrentBorderWidth int `json:"current_border_width"`
Rect Rect `json:"rect"`
DecoRect Rect `json:"deco_rect"`
WindowRect Rect `json:"window_rect"`
Geometry Rect `json:"geometry"`
Name string `json:"name"`
XorgWindowID *int64 `json:"window"`
Nodes []Node `json:"nodes"`
FloatingNodes []Node `json:"floating_nodes"`
Focus []NodeID `json:"focus"`
FullscreenMode FullscreenMode `json:"fullscreen_mode"`
Sticky bool `json:"sticky"`
PID int64 `json:"pid"`
AppID string `json:"app_id"`
Visible bool `json:"visible"`
MaxRenderTimeMilli int64 `json:"max_render_time"`
Shell string `json:"shell"`
InhibitIdle bool `json:"inhibit_idle"`
IdleInhibitors IdleInhibitors `json:"idle_inhibitors"`
// NodeTypeOutput only
Primary bool `json:"primary"`
Make string `json:"make"`
Model string `json:"model"`
Serial string `json:"serial"`
Modes []OutputMode `json:"modes"`
NonDesktop bool `json:"non_desktop"`
Active bool `json:"active"`
DPMS bool `json:"dpms"`
Power bool `json:"power"`
Scale float64 `json:"scale"`
ScaleFilter ScaleFilter `json:"scale_filter"`
Transform Transform `json:"transform"`
AdaptiveSync string `json:"adaptive_sync_status"`
LayerShellSurfaces []LayerShellSurface `json:"layer_shell_surfaces"`
CurrentWorkspace string `json:"current_workspace"`
CurrentMode OutputMode `json:"current_mode"`
}
type NodeID int64
type NodeType string
const (
NodeTypeRoot NodeType = "root"
NodeTypeOutput NodeType = "output"
NodeTypeCon NodeType = "con"
NodeTypeFloatingCon NodeType = "floating_con"
NodeTypeWorkspace NodeType = "workspace"
NodeTypeDockarea NodeType = "dockarea"
)
type Rect struct {
Y int `json:"y"`
X int `json:"x"`
Width int `json:"width"`
Height int `json:"height"`
}
type BorderStyle string
const (
BorderStyleNormal BorderStyle = "normal"
BorderStyleNo BorderStyle = "none"
BorderStylePixel BorderStyle = "pixel"
)
type Layout string
const (
LayoutSplitH Layout = "splith"
LayoutSplitV Layout = "splitv"
LayoutStacked Layout = "stacked"
LayoutTabbed Layout = "tabbed"
LayoutDockarea Layout = "dockarea"
LayoutOutput Layout = "output"
)
type FullscreenMode int64
const (
FullscreenNone FullscreenMode = 0
FullscreenOutput FullscreenMode = 1
FullscreenGlobal FullscreenMode = 2
)
type IdleInhibitors struct {
User string `json:"user"`
Application string `json:"application"`
}
type OutputMode struct {
Width int `json:"width"`
Height int `json:"height"`
RefreshRate int `json:"refresh"`
AspectRatio string `json:"picture_aspect_ratio"`
}
type ScaleFilter string
const (
ScaleFilterNearest ScaleFilter = "nearest"
ScaleFilterLinear ScaleFilter = "linear"
ScaleFilterSmart ScaleFilter = "smart"
)
type Transform string
const (
TransformNormal Transform = "normal"
Transform90 Transform = "90"
Transform180 Transform = "180"
Transform270 Transform = "270"
TransformFlipped Transform = "flipped"
TransformFlipped90 Transform = "flipped-90"
TransformFlipped180 Transform = "flipped-180"
TransformFlipped270 Transform = "flipped-270"
)
type LayerShellSurface struct {
Namespace string `json:"namespace"`
Layer string `json:"layer"`
Extent Rect `json:"extenct"`
Effects []Effect `json:"effects"`
}
type Effect string
const (
EffectBlur Effect = "blur"
)
type Orientation string
const (
OrientationHorizontal Orientation = "horizontal"
OrientationVertical Orientation = "vertical"
)

38
subscribe.go Normal file
View File

@ -0,0 +1,38 @@
package sway
import (
"context"
"encoding/json"
"os/exec"
)
func Subscribe(ctx context.Context, events ...EventType) (<-chan Event, error) {
data, err := json.Marshal(events)
if err != nil {
return nil, err
}
cmd := exec.CommandContext(ctx, "swaymsg", "-t", "subscribe", "-m", string(data))
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
out := make(chan Event, 10)
go func() {
defer cmd.Wait()
dec := json.NewDecoder(stdout)
var event Event
for err := dec.Decode(&event); err == nil; err = dec.Decode(&event) {
out <- event
}
}()
if err := cmd.Start(); err != nil {
return nil, err
}
return out, nil
}

18
subscribe_test.go Normal file
View File

@ -0,0 +1,18 @@
package sway
import (
"context"
"fmt"
"testing"
)
func TestSubscribe(t *testing.T) {
events, err := Subscribe(context.Background(), EventTypeWindow, EventTypeWorkspace)
if err != nil {
t.Fatal(err)
}
for event := range events {
fmt.Println(event)
}
}