renovate the code, update to go 1.26 and satisfy linter (#3)

This commit is contained in:
T. von Dein
2026-08-22 17:59:59 +02:00
parent 9cd6e4a6b9
commit 6d9763a0a9
77 changed files with 681 additions and 227 deletions

104
.golangci.yml Normal file
View File

@@ -0,0 +1,104 @@
version: "2"
linters:
enable:
- errcheck
- govet
- ineffassign
- staticcheck
- unused
- arangolint
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- clickhouselint
- containedctx
- copyloopvar
- cyclop
- decorder
- dogsled
- dupword
- durationcheck
- embeddedstructfieldcheck
- errchkjson
- errname
- exhaustive
- exptostd
- fatcontext
- funcorder
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoinits
- gochecksumtype
- gocritic
- gocyclo
- godoclint
- goheader
- gomoddirectives
- gomodguard_v2
- goprintffuncname
- gosmopolitan
- grouper
- iface
- importas
- inamedparam
- interfacebloat
- intrange
- iotamixing
- lll
- loggercheck
- makezero
- misspell
- modernize
- nakedret
- nestif
- nilerr
- nilnesserr
- nlreturn
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- promlinter
- protogetter
- reassign
- recvcheck
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- tagalign
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unqueryvet
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wsl_v5
- zerologlint
settings:
varnamelen:
ignore-names:
- err
- wg
- mu
- ts
- to
- es
- op
- fd
- id
- fn

View File

@@ -2,7 +2,10 @@ matrix:
platform: platform:
- linux/amd64 - linux/amd64
goversion: goversion:
- 1.24 - 1.26
lintversion:
- v2.12.2
labels: labels:
platform: ${platform} platform: ${platform}
@@ -21,7 +24,7 @@ steps:
event: [push] event: [push]
image: golang:${goversion} image: golang:${goversion}
commands: commands:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0 - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin ${lintversion}
- golangci-lint --version - golangci-lint --version
- golangci-lint run ./... - golangci-lint run ./...
depends_on: [build] depends_on: [build]

5
Makefile Normal file
View File

@@ -0,0 +1,5 @@
all:
go build .
lint:
golangci-lint run --show-stats=false

88
_examples/Makefile Normal file
View File

@@ -0,0 +1,88 @@
examples: example-current_workspace example-events example-find_focused_window example-get_bars example-get_config example-get_inputs example-get_marks example-get_outputs example-get_seats example-get_tree example-get_version example-get_workspaces example-run_command example-run_global_command
clean: clean-example-current_workspace clean-example-events clean-example-find_focused_window clean-example-get_bars clean-example-get_config clean-example-get_inputs clean-example-get_marks clean-example-get_outputs clean-example-get_seats clean-example-get_tree clean-example-get_version clean-example-get_workspaces clean-example-run_command clean-example-run_global_command
example-current_workspace:
make -C current_workspace
example-events:
make -C events
example-find_focused_window:
make -C find_focused_window
example-get_bars:
make -C get_bars
example-get_config:
make -C get_config
example-get_inputs:
make -C get_inputs
example-get_marks:
make -C get_marks
example-get_outputs:
make -C get_outputs
example-get_seats:
make -C get_seats
example-get_tree:
make -C get_tree
example-get_version:
make -C get_version
example-get_workspaces:
make -C get_workspaces
example-run_command:
make -C run_command
example-run_global_command:
make -C run_global_command
clean-example-current_workspace:
make -C current_workspace clean
clean-example-events:
make -C events clean
clean-example-find_focused_window:
make -C find_focused_window clean
clean-example-get_bars:
make -C get_bars clean
clean-example-get_config:
make -C get_config clean
clean-example-get_inputs:
make -C get_inputs clean
clean-example-get_marks:
make -C get_marks clean
clean-example-get_outputs:
make -C get_outputs clean
clean-example-get_seats:
make -C get_seats clean
clean-example-get_tree:
make -C get_tree clean
clean-example-get_version:
make -C get_version clean
clean-example-get_workspaces:
make -C get_workspaces clean
clean-example-run_command:
make -C run_command clean
clean-example-run_global_command:
make -C run_global_command clean

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f current_workspace

View File

@@ -0,0 +1,9 @@
module current_workspace
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f events

9
_examples/events/go.mod Normal file
View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

2
_examples/events/go.sum Normal file
View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -9,8 +9,8 @@ import (
"fmt" "fmt"
"log" "log"
"codeberg.org/scip/swayipc/v2"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1"
) )
// Event callback function, needs to implement each subscribed events, // Event callback function, needs to implement each subscribed events,
@@ -18,11 +18,11 @@ import (
func ProcessTick(event *swayipc.RawResponse) error { func ProcessTick(event *swayipc.RawResponse) error {
var err error var err error
switch event.PayloadType { switch event.PayloadType {
case swayipc.EV_Tick: case swayipc.EvTick:
ev := &swayipc.EventTick{} ev := &swayipc.EventTick{}
err = json.Unmarshal(event.Payload, &ev) err = json.Unmarshal(event.Payload, &ev)
repr.Println(ev) repr.Println(ev)
case swayipc.EV_Window: case swayipc.EvWindow:
ev := &swayipc.EventWindow{} ev := &swayipc.EventWindow{}
err = json.Unmarshal(event.Payload, &ev) err = json.Unmarshal(event.Payload, &ev)
repr.Println(ev) repr.Println(ev)

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f find_focused_window

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {
@@ -25,6 +25,6 @@ func main() {
if focused != nil { if focused != nil {
fmt.Printf("focused node: %s\n id: %d\n Geometry: %dx%d\n", fmt.Printf("focused node: %s\n id: %d\n Geometry: %dx%d\n",
focused.Name, focused.Id, focused.Geometry.Width, focused.Geometry.Height) focused.Name, focused.ID, focused.Geometry.Width, focused.Geometry.Height)
} }
} }

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_bars

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -9,7 +9,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_config

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"log" "log"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_inputs

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_marks

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_outputs

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_seats

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_tree

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -4,7 +4,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_version

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f get_workspaces

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -8,7 +8,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f run_command

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -9,8 +9,8 @@ package main
import ( import (
"log" "log"
"codeberg.org/scip/swayipc/v2"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1"
) )
func main() { func main() {
@@ -37,7 +37,7 @@ func main() {
// finally execute the given commands on it, you can use any run // finally execute the given commands on it, you can use any run
// command, see sway(5) // command, see sway(5)
responses, err := ipc.RunContainerCommand(focused.Id, "floating toggle", "border toggle") responses, err := ipc.RunContainerCommand(focused.ID, "floating toggle", "border toggle")
if err != nil { if err != nil {
repr.Println(responses) repr.Println(responses)
log.Fatal(err) log.Fatal(err)

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f run_global_command

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -9,7 +9,7 @@ import (
"log" "log"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

View File

@@ -0,0 +1,5 @@
all:
go build .
clean:
rm -f send_tick

View File

@@ -0,0 +1,9 @@
module send_tick
go 1.26
require github.com/alecthomas/repr v0.5.4 // indirect
replace codeberg.org/scip/swayipc/v2 => ../..
require codeberg.org/scip/swayipc/v2 v2.1.0

View File

@@ -0,0 +1,2 @@
github.com/alecthomas/repr v0.5.4 h1:OVP7JEcuzU9CCDsT6STCr3rg17oQfWILtPWd2EG0uN4=
github.com/alecthomas/repr v0.5.4/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

View File

@@ -12,7 +12,7 @@ import (
"log" "log"
"os" "os"
"codeberg.org/scip/swayipc/v1" "codeberg.org/scip/swayipc/v2"
) )
func main() { func main() {

30
bar.go
View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// Container gaps // Gaps stores container gaps
type Gaps struct { type Gaps struct {
Top int `json:"top"` Top int `json:"top"`
Right int `json:"right"` Right int `json:"right"`
@@ -13,7 +13,7 @@ type Gaps struct {
Left int `json:"left"` Left int `json:"left"`
} }
// Color definition, used primarily by bars // Colors stores color definitions, used primarily by bars
type Colors struct { type Colors struct {
Background string `json:"background"` Background string `json:"background"`
Statusline string `json:"statusline"` Statusline string `json:"statusline"`
@@ -27,23 +27,23 @@ type Colors struct {
InactiveWorkspaceBorder string `json:"inactive_workspace_border"` InactiveWorkspaceBorder string `json:"inactive_workspace_border"`
InactiveWorkspaceBg string `json:"inactive_workspace_bg"` InactiveWorkspaceBg string `json:"inactive_workspace_bg"`
InactiveWorkspaceText string `json:"inactive_workspace_text"` InactiveWorkspaceText string `json:"inactive_workspace_text"`
Active_workspaceBorder string `json:"active_workspace_border"` ActiveWorkspaceBorder string `json:"active_workspace_border"`
Active_workspaceBg string `json:"active_workspace_bg"` ActiveWorkspaceBg string `json:"active_workspace_bg"`
Active_workspaceText string `json:"active_workspace_text"` ActiveWorkspaceText string `json:"active_workspace_text"`
Urgent_workspaceBorder string `json:"urgent_workspace_border"` UrgentWorkspaceBorder string `json:"urgent_workspace_border"`
Urgent_workspaceBg string `json:"urgent_workspace_bg"` UrgentWorkspaceBg string `json:"urgent_workspace_bg"`
Urgent_workspaceText string `json:"urgent_workspace_text"` UrgentWorkspaceText string `json:"urgent_workspace_text"`
BindingModeBorder string `json:"binding_mode_border"` BindingModeBorder string `json:"binding_mode_border"`
BindingModeBg string `json:"binding_mode_bg"` BindingModeBg string `json:"binding_mode_bg"`
BindingModeText string `json:"binding_mode_text"` BindingModeText string `json:"binding_mode_text"`
} }
// A bar such as a swaybar(5) // Bar stores information about a bar such as a swaybar(5)
type Bar struct { type Bar struct {
Id string `json:"id"` ID string `json:"id"`
Mode string `json:"mode"` Mode string `json:"mode"`
Position string `json:"position"` Position string `json:"position"`
Status_command string `json:"status_command"` StatusCommand string `json:"status_command"`
Font string `json:"font"` Font string `json:"font"`
Gaps *Gaps `json:"gaps"` Gaps *Gaps `json:"gaps"`
Height int `json:"bar_height"` Height int `json:"bar_height"`
@@ -57,9 +57,9 @@ type Bar struct {
Colors *Colors `json:"colors"` Colors *Colors `json:"colors"`
} }
// Get a list of currently visible and active bar names // GetBars returns a list of currently visible and active bar names
func (ipc *SwayIPC) GetBars() ([]string, error) { func (ipc *SwayIPC) GetBars() ([]string, error) {
payload, err := ipc.get(GET_BAR_CONFIG) payload, err := ipc.get(MsgGetBarConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -72,9 +72,9 @@ func (ipc *SwayIPC) GetBars() ([]string, error) {
return bars, nil return bars, nil
} }
// Get the bar object of the bar specified by the string 'id' // GetBar returns the bar object of the bar specified by the string 'id'
func (ipc *SwayIPC) GetBar(id string) (*Bar, error) { func (ipc *SwayIPC) GetBar(id string) (*Bar, error) {
err := ipc.sendHeader(GET_BAR_CONFIG, uint32(len(id))) err := ipc.sendHeader(MsgGetBarConfig, uint32(len(id)))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -7,24 +7,26 @@ import (
"strings" "strings"
) )
// Execute the specified global command[s] (one or more commands can be // RunGlobalCommand can be used to execute the specified global
// given) and returns a response list. // command[s] (one or more commands can be given) and returns a
// response list.
// //
// Possible commands are all non-specific commands, see sway(5) // Possible commands are all non-specific commands, see sway(5)
func (ipc *SwayIPC) RunGlobalCommand(command ...string) ([]Response, error) { func (ipc *SwayIPC) RunGlobalCommand(command ...string) ([]Response, error) {
return ipc.RunCommand(0, "", command...) return ipc.RunCommand(0, "", command...)
} }
// Execute the specified container command[s] (one or more commands can be // RunContainerCommand can be used to execute the specified container
// given) and returns a response list. // command[s] (one or more commands can be given) and returns a
// response list.
// //
// Possible commands are all container-specific commands, see sway(5) // Possible commands are all container-specific commands, see sway(5)
func (ipc *SwayIPC) RunContainerCommand(id int, command ...string) ([]Response, error) { func (ipc *SwayIPC) RunContainerCommand(id int, command ...string) ([]Response, error) {
return ipc.RunCommand(id, "con", command...) return ipc.RunCommand(id, "con", command...)
} }
// Execute the specified (target) command[s] (one or more commands can be // RunCommand executes the specified (target) command[s] (one or more
// given) and returns a response list. // commands can be given) and returns a response list.
// //
// Possible commands are all container-specific commands, see sway(5). // Possible commands are all container-specific commands, see sway(5).
// //
@@ -41,7 +43,7 @@ func (ipc *SwayIPC) RunCommand(id int, target string, command ...string) ([]Resp
commands = fmt.Sprintf("[%s_id=%d] %s", target, id, commands) commands = fmt.Sprintf("[%s_id=%d] %s", target, id, commands)
} }
err := ipc.sendHeader(RUN_COMMAND, uint32(len(commands))) err := ipc.sendHeader(MsgRunCommand, uint32(len(commands)))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to send run_command to IPC %w", err) return nil, fmt.Errorf("failed to send run_command to IPC %w", err)
} }

135
event.go
View File

@@ -3,136 +3,105 @@ package swayipc
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect"
) )
// Event types. // Event types.
const ( const (
EV_Workspace int = 0x80000000 EvWorkspace int = 0x80000000
EV_Output int = 0x80000001 EvOutput int = 0x80000001
EV_Mode int = 0x80000002 EvMode int = 0x80000002
EV_Window int = 0x80000003 EvWindow int = 0x80000003
EV_BarconfigUpdate int = 0x80000004 EvBarconfigUpdate int = 0x80000004
EV_Binding int = 0x80000005 EvBinding int = 0x80000005
EV_Shutdown int = 0x80000006 EvShutdown int = 0x80000006
EV_Tick int = 0x80000007 EvTick int = 0x80000007
EV_BarStateUpdate int = 0x80000014 EvBarStateUpdate int = 0x80000014
EV_Input int = 0x80000015 EvInput int = 0x80000015
) )
// Subscriber struct, use this to tell swayipc which events you want to // Event is the subscriber struct, use this to tell swayipc which
// subscribe. // events you want to subscribe.
type Event struct { type Event struct {
Workspace bool Workspace bool `json:"workspace"`
Output bool Output bool `json:"output"`
Mode bool Mode bool `json:"mode"`
Window bool Window bool `json:"window"`
BarconfigUpdate bool BarconfigUpdate bool `json:"barconfig_update"`
Binding bool Binding bool `json:"binding"`
Shutdown bool Shutdown bool `json:"shutdown"`
Tick bool Tick bool `json:"tick"`
BarStateUpdate bool BarStateUpdate bool `json:"bar_state_update"`
Input bool Input bool `json:"input"`
} }
// Workspace event response // EventWorkspace stores a workspace event response
type EventWorkspace struct { type EventWorkspace struct {
Change string `json:"change"` Change string `json:"change"`
Current *Node `json:"workspace"` Current *Node `json:"workspace"`
Old *Node `json:"old"` Old *Node `json:"old"`
} }
// Output event response // EventOutput stores an output event response
type EventOutput struct { type EventOutput struct {
Change string `json:"change"` Change string `json:"change"`
} }
// Mode event response // EventMode stores a ode event response
type EventMode struct { type EventMode struct {
Change string `json:"change"` Change string `json:"change"`
PangoMarkup *Node `json:"pango_markup"` PangoMarkup *Node `json:"pango_markup"`
} }
// Window event response // EventWindow stores a window event response
type EventWindow struct { type EventWindow struct {
Change string `json:"change"` Change string `json:"change"`
Container *Node `json:"container"` Container *Node `json:"container"`
} }
// BarConfig event response // EventBarConfig stores a BarConfig event response
type EventBarConfig struct { type EventBarConfig struct {
Change string `json:"change"` Change string `json:"change"`
Binding *Binding `json:"binding"` Binding *Binding `json:"binding"`
} }
// Shutdown event response // EventShutdown stores a Shutdown event response
type EventShutdown struct { type EventShutdown struct {
Change string `json:"change"` Change string `json:"change"`
} }
// Tick event response // EventTick stores a Tick event response
type EventTick struct { type EventTick struct {
First bool `json:"first"` First bool `json:"first"`
Payload string `json:"payload"` Payload string `json:"payload"`
} }
// BarState event response // EventBarState stores a BarState event response
type EventBarState struct { type EventBarState struct {
Id string `json:"id"` ID string `json:"id"`
VisibleByModifier bool `json:"visible_by_modifier"` VisibleByModifier bool `json:"visible_by_modifier"`
} }
// Input event response // EventInput stores an Input event response
type EventInput struct { type EventInput struct {
Change string `json:"change"` Change string `json:"change"`
Input *Input `json:"input"` Input *Input `json:"input"`
} }
// Subscribe to one or more events. Fill the swayipc.Event object // Subscribe allows to subscribe to one or more events. Fill the
// accordingly. // Event object accordingly.
// //
// Returns a response list containing a response for every subscribed // Returns a response list containing a response for every subscribed
// event. // event.
func (ipc *SwayIPC) Subscribe(sub *Event) ([]*Response, error) { func (ipc *SwayIPC) Subscribe(sub *Event) ([]*Response, error) {
events := []string{} events := eventList(sub)
// looks ugly but makes it much more comfortable for the user
if sub.Workspace {
events = append(events, "workspace")
}
if sub.Output {
events = append(events, "output")
}
if sub.Mode {
events = append(events, "mode")
}
if sub.Window {
events = append(events, "window")
}
if sub.BarconfigUpdate {
events = append(events, "barconfig_update")
}
if sub.Binding {
events = append(events, "binding")
}
if sub.Shutdown {
events = append(events, "shutdown")
}
if sub.Tick {
events = append(events, "tick")
}
if sub.BarStateUpdate {
events = append(events, "bar_state_update")
}
if sub.Input {
events = append(events, "input")
}
jsonpayload, err := json.Marshal(events) jsonpayload, err := json.Marshal(events)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to json marshal event list: %w", err) return nil, fmt.Errorf("failed to json marshal event list: %w", err)
} }
err = ipc.sendHeader(SUBSCRIBE, uint32(len(jsonpayload))) err = ipc.sendHeader(MsgSubscribe, uint32(len(jsonpayload)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -158,7 +127,9 @@ func (ipc *SwayIPC) Subscribe(sub *Event) ([]*Response, error) {
return nil, nil return nil, nil
} }
// Event loop: Once you have subscribed to an event, you need to enter // EventLoop starts an event loop.
//
// Once you have subscribed to an event, you need to enter
// an event loop over the same running socket connection. Sway will // an event loop over the same running socket connection. Sway will
// send event payloads for every subscribed event whenever it happens. // send event payloads for every subscribed event whenever it happens.
// //
@@ -181,3 +152,29 @@ func (ipc *SwayIPC) EventLoop(callback func(event *RawResponse) error) error {
} }
} }
} }
// eventList returns a list of subscribe events based on given Event objectstrucstruc
func eventList(sub *Event) []string {
out := []string{}
subv := reflect.ValueOf(sub).Elem()
subType := subv.Type()
for i := range subv.NumField() {
field := subv.Field(i)
structField := subType.Field(i)
value := field.Interface()
key := structField.Name
if tag := structField.Tag.Get(`json`); tag != "" {
key = tag
}
if value.(bool) {
out = append(out, key)
}
}
return out
}

2
go.mod
View File

@@ -1,5 +1,5 @@
module codeberg.org/scip/swayipc/v2 module codeberg.org/scip/swayipc/v2
go 1.23 go 1.26
require github.com/alecthomas/repr v0.5.1 // indirect require github.com/alecthomas/repr v0.5.1 // indirect

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// An input (keyboard, mouse, whatever) // Input represents an input (keyboard, mouse, whatever)
type Input struct { type Input struct {
Identifier string `json:"identifier"` Identifier string `json:"identifier"`
Name string `json:"name"` Name string `json:"name"`
@@ -19,7 +19,7 @@ type Input struct {
Libinput *LibInput `json:"libinput"` Libinput *LibInput `json:"libinput"`
} }
// Holds the data associated with libinput // LibInput stores the data associated with libinput
type LibInput struct { type LibInput struct {
SendEvents string `json:"send_events"` SendEvents string `json:"send_events"`
Tap string `json:"tap"` Tap string `json:"tap"`
@@ -41,7 +41,7 @@ type LibInput struct {
CalibrationMatrix []float32 `json:"calibration_matrix"` CalibrationMatrix []float32 `json:"calibration_matrix"`
} }
// A key binding // Binding is a key binding
type Binding struct { type Binding struct {
Command string `json:"command"` Command string `json:"command"`
EventStateMask []string `json:"event_state_mask"` EventStateMask []string `json:"event_state_mask"`
@@ -50,9 +50,9 @@ type Binding struct {
InputType string `json:"input_type"` InputType string `json:"input_type"`
} }
// Get a list of all currently supported inputs // GetInputs returns a list of all currently supported inputs
func (ipc *SwayIPC) GetInputs() ([]*Input, error) { func (ipc *SwayIPC) GetInputs() ([]*Input, error) {
payload, err := ipc.get(GET_INPUTS) payload, err := ipc.get(MsgGetInputs)
if err != nil { if err != nil {
return nil, err return nil, err
} }

1
io.go
View File

@@ -4,7 +4,6 @@ import "os"
func fileExists(filename string) bool { func fileExists(filename string) bool {
info, err := os.Stat(filename) info, err := os.Stat(filename)
if err != nil { if err != nil {
return false return false
} }

16
net.go
View File

@@ -8,7 +8,7 @@ import (
"os" "os"
) )
// Contains a raw json response, not marshalled yet. // RawResponse contains a raw json response, not marshalled yet.
type RawResponse struct { type RawResponse struct {
PayloadType int PayloadType int
Payload []byte Payload []byte
@@ -39,14 +39,13 @@ func (ipc *SwayIPC) Close() error {
} }
func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error { func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error {
sendPayload := make([]byte, IPC_HEADER_SIZE) sendPayload := make([]byte, IpcHeaderSize)
copy(sendPayload, []byte(IPC_MAGIC)) copy(sendPayload, []byte(IpcMagix))
binary.LittleEndian.PutUint32(sendPayload[IPC_MAGIC_LEN:], len) binary.LittleEndian.PutUint32(sendPayload[IpcMagicLen:], len)
binary.LittleEndian.PutUint32(sendPayload[IPC_MAGIC_LEN+4:], messageType) binary.LittleEndian.PutUint32(sendPayload[IpcMagicLen+4:], messageType)
_, err := ipc.socket.Write(sendPayload) _, err := ipc.socket.Write(sendPayload)
if err != nil { if err != nil {
return fmt.Errorf("failed to send header to IPC socket %w", err) return fmt.Errorf("failed to send header to IPC socket %w", err)
} }
@@ -56,7 +55,6 @@ func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error {
func (ipc *SwayIPC) sendPayload(payload []byte) error { func (ipc *SwayIPC) sendPayload(payload []byte) error {
_, err := ipc.socket.Write(payload) _, err := ipc.socket.Write(payload)
if err != nil { if err != nil {
return fmt.Errorf("failed to send payload to IPC socket %w", err) return fmt.Errorf("failed to send payload to IPC socket %w", err)
} }
@@ -66,14 +64,14 @@ func (ipc *SwayIPC) sendPayload(payload []byte) error {
func (ipc *SwayIPC) readResponse() (*RawResponse, error) { func (ipc *SwayIPC) readResponse() (*RawResponse, error) {
// read header // read header
buf := make([]byte, IPC_HEADER_SIZE) buf := make([]byte, IpcHeaderSize)
_, err := ipc.socket.Read(buf) _, err := ipc.socket.Read(buf)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read header from ipc socket: %s", err) return nil, fmt.Errorf("failed to read header from ipc socket: %s", err)
} }
if string(buf[:6]) != IPC_MAGIC { if string(buf[:6]) != IpcMagix {
return nil, errors.New("got invalid response from IPC socket") return nil, errors.New("got invalid response from IPC socket")
} }

96
node.go
View File

@@ -5,10 +5,18 @@ import (
"fmt" "fmt"
) )
// A node can be an output, a workspace, a container or a container const (
// containing a window. NodeTypeRoot = iota + 1 // A root node
NodeTypeOutput // An output node
NodeTypeWorkspace // A workspace
NodeTypeCon // A container node (containing more nodes)
NodeTypeFloating // A floating node
)
// Node can be an output, a workspace, a container or a container
// containing other containers.
type Node struct { type Node struct {
Id int `json:"id"` ID int `json:"id"`
Type string `json:"type"` // output, workspace or container Type string `json:"type"` // output, workspace or container
Name string `json:"name"` // workspace number or app name Name string `json:"name"` // workspace number or app name
Output string `json:"output"` Output string `json:"output"`
@@ -26,26 +34,24 @@ type Node struct {
Focus []int `json:"focus"` Focus []int `json:"focus"`
Window int `json:"window"` // wayland native Window int `json:"window"` // wayland native
X11Window string `json:"app_id"` // x11 compat X11Window string `json:"app_id"` // x11 compat
Current_workspace string `json:"current_workspace"` CurrentWorkspace string `json:"current_workspace"`
Rect Rect `json:"rect"` Rect Rect `json:"rect"`
WindowRect Rect `json:"window_rect"` WindowRect Rect `json:"window_rect"`
DecoRect Rect `json:"deco_rect"` DecoRect Rect `json:"deco_rect"`
Geometry Rect `json:"geometry"` Geometry Rect `json:"geometry"`
} }
var __focused *Node // GetTree returns the whole information tree, which contains
var __currentworkspace string // everything from output to containers as a tree of nodes. Each node
// has a field 'Nodes' which points to a list subnodes. Some nodes
// Get the whole information tree, contains everything from output to // also have a field 'FloatingNodes' which points to a list of
// containers as a tree of nodes. Each node has a field 'Nodes' which // floating containers.
// points to a list subnodes. Some nodes also have a field
// 'FloatingNodes' which points to a list of floating containers.
// //
// The top level node is the "root" node. // The top level node is the "root" node.
// //
// Use the returned node oject to further investigate the wm setup. // Use the returned node oject to further investigate the wm setup.
func (ipc *SwayIPC) GetTree() (*Node, error) { func (ipc *SwayIPC) GetTree() (*Node, error) {
err := ipc.sendHeader(GET_TREE, 0) err := ipc.sendHeader(MsgGettTree, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -63,48 +69,48 @@ func (ipc *SwayIPC) GetTree() (*Node, error) {
return node, nil return node, nil
} }
// Usually called on the root node, returns the container which has // FindFocused returns the container which has currently the
// currently the focus. // focus. Usually called on the root node.
func (node *Node) FindFocused() *Node { func (node *Node) FindFocused() *Node {
searchFocused(node.Nodes) focused := searchFocused(node.Nodes)
if __focused == nil { if focused == nil {
searchFocused(node.FloatingNodes) return searchFocused(node.FloatingNodes)
} }
return __focused return nil
} }
// internal recursive focus node searcher // FindCurrentWorkspace returns the current active
func searchFocused(nodes []*Node) { // workspace name. Usually called on the root node.
func (node *Node) FindCurrentWorkspace() string {
return searchCurrentWorkspace(node.Nodes)
}
// searchCurrentWorkspace search for current workspace
func searchCurrentWorkspace(nodes []*Node) string {
for _, node := range nodes {
if node.CurrentWorkspace != "" {
return node.CurrentWorkspace
} else {
return searchCurrentWorkspace(node.Nodes)
}
}
return ""
}
// searchFocused recursively search focused node
func searchFocused(nodes []*Node) *Node {
for _, node := range nodes { for _, node := range nodes {
if node.Focused { if node.Focused {
__focused = node return node
return
} else { } else {
searchFocused(node.Nodes) focused := searchFocused(node.Nodes)
if __focused == nil { if focused == nil {
searchFocused(node.FloatingNodes) return searchFocused(node.FloatingNodes)
}
} }
} }
} return nil
}
// Usually called on the root node, returns the current active
// workspace name.
func (node *Node) FindCurrentWorkspace() string {
searchCurrentWorkspace(node.Nodes)
return __currentworkspace
}
// internal recursive workspace node searcher
func searchCurrentWorkspace(nodes []*Node) {
for _, node := range nodes {
if node.Current_workspace != "" {
__currentworkspace = node.Current_workspace
return
} else {
searchCurrentWorkspace(node.Nodes)
}
}
} }

View File

@@ -5,14 +5,14 @@ import (
"fmt" "fmt"
) )
// Store an output mode. // Mode stores data of an output mode.
type Mode struct { type Mode struct {
Width int `json:"width"` Width int `json:"width"`
Height int `json:"height"` Height int `json:"height"`
Refresh int `json:"refresh"` Refresh int `json:"refresh"`
} }
// An output object (i.e. a physical monitor) // Output represents an output object (i.e. a physical monitor)
type Output struct { type Output struct {
Name string `json:"name"` Name string `json:"name"`
Make string `json:"make"` Make string `json:"make"`
@@ -21,14 +21,14 @@ type Output struct {
Primary bool `json:"primary"` Primary bool `json:"primary"`
SubpixelHinting string `json:"subpixel_hinting"` SubpixelHinting string `json:"subpixel_hinting"`
Transform string `json:"transform"` Transform string `json:"transform"`
Current_workspace string `json:"current_workspace"` CurrentWorkspace string `json:"current_workspace"`
Modes []*Mode `json:"modes"` Modes []*Mode `json:"modes"`
CurrentMode *Mode `json:"current_mode"` CurrentMode *Mode `json:"current_mode"`
} }
// Get a list of currently available and usable outputs. // GetOutputs returns a list of currently available and usable outputs.
func (ipc *SwayIPC) GetOutputs() ([]*Output, error) { func (ipc *SwayIPC) GetOutputs() ([]*Output, error) {
err := ipc.sendHeader(GET_OUTPUTS, 0) err := ipc.sendHeader(MsgGetOutputs, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// Information about a seat containing input devices // Seat stores information about a seat containing input devices
type Seat struct { type Seat struct {
Name string `json:"name"` Name string `json:"name"`
Capabilities int `json:"capabilities"` Capabilities int `json:"capabilities"`
@@ -13,9 +13,9 @@ type Seat struct {
Devices []*Input `json:"devices"` Devices []*Input `json:"devices"`
} }
// Get input seats // GetSeats returns input seats
func (ipc *SwayIPC) GetSeats() ([]*Seat, error) { func (ipc *SwayIPC) GetSeats() ([]*Seat, error) {
payload, err := ipc.get(GET_SEATS) payload, err := ipc.get(MsgGetSeats)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -5,8 +5,9 @@ import (
"fmt" "fmt"
) )
// GetWorkspaces returns a list of Nodes of type NodeTypeWorkspace
func (ipc *SwayIPC) GetWorkspaces() ([]*Node, error) { func (ipc *SwayIPC) GetWorkspaces() ([]*Node, error) {
payload, err := ipc.get(GET_WORKSPACES) payload, err := ipc.get(MsgGetWorkspaces)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -19,8 +20,9 @@ func (ipc *SwayIPC) GetWorkspaces() ([]*Node, error) {
return nodes, nil return nodes, nil
} }
// GetMarks returns a list of marks
func (ipc *SwayIPC) GetMarks() ([]string, error) { func (ipc *SwayIPC) GetMarks() ([]string, error) {
payload, err := ipc.get(GET_MARKS) payload, err := ipc.get(MsgGetMarks)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -33,8 +35,9 @@ func (ipc *SwayIPC) GetMarks() ([]string, error) {
return marks, nil return marks, nil
} }
// GetBindingModes returns a list of binding modes
func (ipc *SwayIPC) GetBindingModes() ([]string, error) { func (ipc *SwayIPC) GetBindingModes() ([]string, error) {
payload, err := ipc.get(GET_BINDING_MODES) payload, err := ipc.get(MsgGetBindingModes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -47,8 +50,9 @@ func (ipc *SwayIPC) GetBindingModes() ([]string, error) {
return modes, nil return modes, nil
} }
// GetBindingState returns a list of binding states
func (ipc *SwayIPC) GetBindingState() (*State, error) { func (ipc *SwayIPC) GetBindingState() (*State, error) {
payload, err := ipc.get(GET_BINDING_STATE) payload, err := ipc.get(MsgGetBindingState)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -61,8 +65,9 @@ func (ipc *SwayIPC) GetBindingState() (*State, error) {
return state, nil return state, nil
} }
// GetConfig return user wm config
func (ipc *SwayIPC) GetConfig() (string, error) { func (ipc *SwayIPC) GetConfig() (string, error) {
payload, err := ipc.get(GET_CONFIG) payload, err := ipc.get(MsgGetConfig)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -75,8 +80,9 @@ func (ipc *SwayIPC) GetConfig() (string, error) {
return config.Config, nil return config.Config, nil
} }
// SendTick sends a tick
func (ipc *SwayIPC) SendTick(payload string) error { func (ipc *SwayIPC) SendTick(payload string) error {
err := ipc.sendHeader(SEND_TICK, uint32(len(payload))) err := ipc.sendHeader(MsgSendTick, uint32(len(payload)))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -1,3 +1,6 @@
// Package swayipc can be used to control the sway and swayfx window
// managers ()and possibly i3wm)via a unix domain socket.
package swayipc package swayipc
import ( import (
@@ -5,41 +8,43 @@ import (
) )
const ( const (
VERSION = "v1.0.0" VERSION = "v2.1.0"
IPC_HEADER_SIZE = 14 IpcHeaderSize = 14
IPC_MAGIC = "i3-ipc" IpcMagix = "i3-ipc"
IPC_MAGIC_LEN = 6 IpcMagicLen = 6
)
// message types
const (
MsgRunCommand = iota
MsgGetWorkspaces
MsgSubscribe
MsgGetOutputs
MsgGettTree
MsgGetMarks
MsgGetBarConfig
MsgGetVersion
MsgGetBindingModes
MsgGetConfig
MsgSendTick
MsgSync
MsgGetBindingState
) )
const ( const (
// message types MsgGetInputs = 100
RUN_COMMAND = iota MsgGetSeats = 101
GET_WORKSPACES
SUBSCRIBE
GET_OUTPUTS
GET_TREE
GET_MARKS
GET_BAR_CONFIG
GET_VERSION
GET_BINDING_MODES
GET_CONFIG
SEND_TICK
SYNC
GET_BINDING_STATE
GET_INPUTS = 100
GET_SEATS = 101
) )
// This is the primary struct to work with the swayipc module. // SwayIPC is the primary struct to work with the swayipc module.
type SwayIPC struct { type SwayIPC struct {
socket net.Conn socket net.Conn
SocketFile string // filename of the i3 IPC socket SocketFile string // filename of the i3 IPC socket
Events *Event // store subscribed events, see swayipc.Subscribe() Events *Event // store subscribed events, see swayipc.Subscribe()
} }
// A rectangle struct, used at various places for geometry etc. // Rect stores geometrical information, used at various places for geometry etc.
type Rect struct { type Rect struct {
X int `json:"x"` // X coordinate X int `json:"x"` // X coordinate
Y int `json:"y"` // Y coordinate Y int `json:"y"` // Y coordinate
@@ -47,25 +52,26 @@ type Rect struct {
Height int `json:"height"` Height int `json:"height"`
} }
// Stores responses retrieved via ipc // Response stores meta data retrieved via ipc
type Response struct { type Response struct {
Success bool `json:"success"` Success bool `json:"success"`
ParseError bool `json:"parse_error"` ParseError bool `json:"parse_error"`
Error string `json:"error"` Error string `json:"error"`
} }
// Stores the user config for the WM // Config stores the user config for the WM
type Config struct { type Config struct {
Config string `json:"config"` Config string `json:"config"`
} }
// Stores the binding state // State stores the binding state
type State struct { type State struct {
Name string `json:"name"` Name string `json:"name"`
} }
// Create a new swayipc.SwayIPC object. Filename argument is optional and // NewSwayIPC returns a new swayipc.SwayIPC object. Filename argument
// may denote a filename or the name of an environment variable. // is optional and may denote a filename or the name of an environment
// variable.
// //
// By default and if nothing is specified we look for the environment // By default and if nothing is specified we look for the environment
// variable SWAYSOCK and use the file it points to as unix domain // variable SWAYSOCK and use the file it points to as unix domain
@@ -82,7 +88,7 @@ func NewSwayIPC(file ...string) *SwayIPC {
return ipc return ipc
} }
// internal convenience wrapper // get is a wrapper around sendHeader+readResponse
func (ipc *SwayIPC) get(command uint32) (*RawResponse, error) { func (ipc *SwayIPC) get(command uint32) (*RawResponse, error) {
err := ipc.sendHeader(command, 0) err := ipc.sendHeader(command, 0)
if err != nil { if err != nil {

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// A version struct holding the sway wm version // Version stores the sway wm version
type Version struct { type Version struct {
HumanReadable string `json:"human_readable"` HumanReadable string `json:"human_readable"`
Major int `json:"major"` Major int `json:"major"`
@@ -13,9 +13,9 @@ type Version struct {
Patch int `json:"patch"` Patch int `json:"patch"`
} }
// Get the sway software version // GetVersion returns the sway software version
func (ipc *SwayIPC) GetVersion() (*Version, error) { func (ipc *SwayIPC) GetVersion() (*Version, error) {
payload, err := ipc.get(GET_VERSION) payload, err := ipc.get(MsgGetVersion)
if err != nil { if err != nil {
return nil, err return nil, err
} }