1 Commits

Author SHA1 Message Date
7079004e63 add caution for github users 2025-11-10 21:02:33 +01:00
79 changed files with 296 additions and 743 deletions

47
.github/workflows/ci.yaml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: build-and-test
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
version: ['1.22']
os: [ubuntu-latest, windows-latest, macos-latest]
name: Build
runs-on: ${{ matrix.os }}
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '${{ matrix.version }}'
id: go
- name: checkout
uses: actions/checkout@v3
- name: build
run: go build
# - name: test
# run: make test
# - name: Update coverage report
# uses: ncruces/go-coverage-report@main
# with:
# report: true
# chart: true
# amend: true
# if: |
# matrix.os == 'ubuntu-latest' &&
# github.event_name == 'push'
# continue-on-error: true
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.22
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3

View File

@@ -1,104 +0,0 @@
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

@@ -1,30 +0,0 @@
matrix:
platform:
- linux/amd64
goversion:
- 1.26
lintversion:
- v2.12.2
labels:
platform: ${platform}
steps:
build:
when:
event: [push]
image: golang:${goversion}
commands:
- go get
- go build
linter:
when:
event: [push]
image: golang:${goversion}
commands:
- 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 run ./...
depends_on: [build]

View File

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

View File

@@ -1,7 +1,14 @@
[![status-badge](https://ci.codeberg.org/api/badges/15565/status.svg)](https://ci.codeberg.org/repos/15565) [![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/swayipc)](https://goreportcard.com/report/github.com/tlinden/swayipc)
[![Go Report Card](https://goreportcard.com/badge/codeberg.org/scip/swayipc)](https://goreportcard.com/report/codeberg.org/scip/swayipc) [![Actions](https://github.com/tlinden/swayipc/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/swayipc/actions)
[![License](https://img.shields.io/badge/license-GPL-blue.svg)](https://codeberg.org/scip/swayipc/raw/branch/main/LICENSE) ![GitHub License](https://img.shields.io/github/license/tlinden/swayipc)
[![GoDoc](https://godoc.org/codeberg.org/scip/swayipc?status.svg)](https://godoc.org/codeberg.org/scip/swayipc/v2) [![GoDoc](https://godoc.org/github.com/tlinden/swayipc?status.svg)](https://godoc.org/github.com/tlinden/swayipc)
> [!CAUTION]
> This software is now being maintained on [Codeberg](https://codeberg.org/scip/swaycycle/).
>
> You may still use the `github.com/tlinden/swayipc` module, but this
> version here is no longer being maintained. To use the current version,
> import `codeberg.org/scip/swayipc/v1`.
# swayipc - go bindings to control sway and swayfx # swayipc - go bindings to control sway and swayfx
@@ -26,7 +33,7 @@ haven't tested it on i3wm.
The module uses the i3-IPC proctocol as outlined in sway-ipc(7). The module uses the i3-IPC proctocol as outlined in sway-ipc(7).
For details on how to use the library, see the For details on how to use the library, see the
[reference documentation](https://godoc.org/codeberg.org/scip/swayipc/v2). [reference documentation](https://godoc.org/github.com/tlinden/swayipc).
## Example usage ## Example usage
@@ -39,7 +46,7 @@ import (
"fmt" "fmt"
"log" "log"
"codeberg.org/scip/swayipc/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {
@@ -69,17 +76,17 @@ func main() {
Also take a look into the **_examples** folder for more examples. Also take a look into the **_examples** folder for more examples.
For a more comprehensive and practical example look at the For a more comprehensive and practical example look at the
[descratch](https://codeberg.org/scip/sway-descratch) program which [descratch](https://github.com/TLINDEN/sway-descratch) program which
you can use to selectively retrieve a window from the scratchpad. you can use to selectively retrieve a window from the scratchpad.
You may also take a look at the [tool swaycycle](https://codeberg.org/scip/swaycycle) You may also take a look at the [tool swaycycle](https://github.com/tlinden/swaycycle)
which is using this module. which is using this module.
## Installation ## Installation
Execute this to add the module to your project: Execute this to add the module to your project:
```sh ```sh
go get codeberg.org/scip/swayipc/v2 go get github.com/tlinden/swayipc
``` ```
## Acknowledgements ## Acknowledgements
@@ -95,7 +102,7 @@ best way for me to forget to do something.
In order to report a bug, unexpected behavior, feature requests or to In order to report a bug, unexpected behavior, feature requests or to
submit a patch, please open an issue on github: submit a patch, please open an issue on github:
https://codeberg.org/scip/swayipc/issues. https://github.com/TLINDEN/swayipc/issues.
## Copyright and license ## Copyright and license
@@ -107,7 +114,7 @@ T.v.Dein <tom AT vondein DOT org>
## Project homepage ## Project homepage
https://codeberg.org/scip/swayipc https://github.com/TLINDEN/swayipc
## Copyright and License ## Copyright and License

View File

@@ -1,88 +0,0 @@
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

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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"
"github.com/tlinden/swayipc"
) )
// 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.EvTick: case swayipc.EV_Tick:
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.EvWindow: case swayipc.EV_Window:
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

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
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

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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"
"github.com/tlinden/swayipc"
) )
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

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

View File

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

View File

@@ -1,9 +0,0 @@
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

@@ -1,2 +0,0 @@
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/v2" "github.com/tlinden/swayipc"
) )
func main() { func main() {

30
bar.go
View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// Gaps stores container gaps // 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"`
} }
// Colors stores color definitions, used primarily by bars // Color definition, 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"`
ActiveWorkspaceBorder string `json:"active_workspace_border"` Active_workspaceBorder string `json:"active_workspace_border"`
ActiveWorkspaceBg string `json:"active_workspace_bg"` Active_workspaceBg string `json:"active_workspace_bg"`
ActiveWorkspaceText string `json:"active_workspace_text"` Active_workspaceText string `json:"active_workspace_text"`
UrgentWorkspaceBorder string `json:"urgent_workspace_border"` Urgent_workspaceBorder string `json:"urgent_workspace_border"`
UrgentWorkspaceBg string `json:"urgent_workspace_bg"` Urgent_workspaceBg string `json:"urgent_workspace_bg"`
UrgentWorkspaceText string `json:"urgent_workspace_text"` Urgent_workspaceText 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"`
} }
// Bar stores information about a bar such as a swaybar(5) // 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"`
StatusCommand string `json:"status_command"` Status_command 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"`
} }
// GetBars returns a list of currently visible and active bar names // Get 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(MsgGetBarConfig) payload, err := ipc.get(GET_BAR_CONFIG)
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
} }
// GetBar returns the bar object of the bar specified by the string 'id' // Get 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(MsgGetBarConfig, uint32(len(id))) err := ipc.sendHeader(GET_BAR_CONFIG, uint32(len(id)))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -7,26 +7,24 @@ import (
"strings" "strings"
) )
// RunGlobalCommand can be used to execute the specified global // Execute the specified global command[s] (one or more commands can be
// command[s] (one or more commands can be given) and returns a // given) and returns a response list.
// 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...)
} }
// RunContainerCommand can be used to execute the specified container // Execute the specified container command[s] (one or more commands can be
// command[s] (one or more commands can be given) and returns a // given) and returns a response list.
// 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...)
} }
// RunCommand executes the specified (target) command[s] (one or more // Execute the specified (target) command[s] (one or more commands can be
// commands can be given) and returns a response list. // 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).
// //
@@ -43,7 +41,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(MsgRunCommand, uint32(len(commands))) err := ipc.sendHeader(RUN_COMMAND, 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,105 +3,136 @@ package swayipc
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect"
) )
// Event types. // Event types.
const ( const (
EvWorkspace int = 0x80000000 EV_Workspace int = 0x80000000
EvOutput int = 0x80000001 EV_Output int = 0x80000001
EvMode int = 0x80000002 EV_Mode int = 0x80000002
EvWindow int = 0x80000003 EV_Window int = 0x80000003
EvBarconfigUpdate int = 0x80000004 EV_BarconfigUpdate int = 0x80000004
EvBinding int = 0x80000005 EV_Binding int = 0x80000005
EvShutdown int = 0x80000006 EV_Shutdown int = 0x80000006
EvTick int = 0x80000007 EV_Tick int = 0x80000007
EvBarStateUpdate int = 0x80000014 EV_BarStateUpdate int = 0x80000014
EvInput int = 0x80000015 EV_Input int = 0x80000015
) )
// Event is the subscriber struct, use this to tell swayipc which // Subscriber struct, use this to tell swayipc which events you want to
// events you want to subscribe. // subscribe.
type Event struct { type Event struct {
Workspace bool `json:"workspace"` Workspace bool
Output bool `json:"output"` Output bool
Mode bool `json:"mode"` Mode bool
Window bool `json:"window"` Window bool
BarconfigUpdate bool `json:"barconfig_update"` BarconfigUpdate bool
Binding bool `json:"binding"` Binding bool
Shutdown bool `json:"shutdown"` Shutdown bool
Tick bool `json:"tick"` Tick bool
BarStateUpdate bool `json:"bar_state_update"` BarStateUpdate bool
Input bool `json:"input"` Input bool
} }
// EventWorkspace stores a workspace event response // 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"`
} }
// EventOutput stores an output event response // Output event response
type EventOutput struct { type EventOutput struct {
Change string `json:"change"` Change string `json:"change"`
} }
// EventMode stores a ode event response // Mode 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"`
} }
// EventWindow stores a window event response // 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"`
} }
// EventBarConfig stores a BarConfig event response // 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"`
} }
// EventShutdown stores a Shutdown event response // Shutdown event response
type EventShutdown struct { type EventShutdown struct {
Change string `json:"change"` Change string `json:"change"`
} }
// EventTick stores a Tick event response // 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"`
} }
// EventBarState stores a BarState event response // 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"`
} }
// EventInput stores an Input event response // 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 allows to subscribe to one or more events. Fill the // Subscribe to one or more events. Fill the swayipc.Event object
// Event object accordingly. // 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 := eventList(sub) events := []string{}
// 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(MsgSubscribe, uint32(len(jsonpayload))) err = ipc.sendHeader(SUBSCRIBE, uint32(len(jsonpayload)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -127,9 +158,7 @@ func (ipc *SwayIPC) Subscribe(sub *Event) ([]*Response, error) {
return nil, nil return nil, nil
} }
// EventLoop starts an event loop. // Event loop: Once you have subscribed to an event, you need to enter
//
// 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.
// //
@@ -152,29 +181,3 @@ 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
}

6
go.mod
View File

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

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// Input represents an input (keyboard, mouse, whatever) // 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"`
} }
// LibInput stores the data associated with libinput // Holds 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"`
} }
// Binding is a key binding // 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"`
} }
// GetInputs returns a list of all currently supported inputs // Get a list of all currently supported inputs
func (ipc *SwayIPC) GetInputs() ([]*Input, error) { func (ipc *SwayIPC) GetInputs() ([]*Input, error) {
payload, err := ipc.get(MsgGetInputs) payload, err := ipc.get(GET_INPUTS)
if err != nil { if err != nil {
return nil, err return nil, err
} }

1
io.go
View File

@@ -4,6 +4,7 @@ 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
} }

20
net.go
View File

@@ -8,7 +8,7 @@ import (
"os" "os"
) )
// RawResponse contains a raw json response, not marshalled yet. // Contains a raw json response, not marshalled yet.
type RawResponse struct { type RawResponse struct {
PayloadType int PayloadType int
Payload []byte Payload []byte
@@ -34,18 +34,19 @@ func (ipc *SwayIPC) Connect() error {
} }
// Close the socket. // Close the socket.
func (ipc *SwayIPC) Close() error { func (ipc *SwayIPC) Close() {
return ipc.socket.Close() ipc.socket.Close()
} }
func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error { func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error {
sendPayload := make([]byte, IpcHeaderSize) sendPayload := make([]byte, IPC_HEADER_SIZE)
copy(sendPayload, []byte(IpcMagix)) copy(sendPayload, []byte(IPC_MAGIC))
binary.LittleEndian.PutUint32(sendPayload[IpcMagicLen:], len) binary.LittleEndian.PutUint32(sendPayload[IPC_MAGIC_LEN:], len)
binary.LittleEndian.PutUint32(sendPayload[IpcMagicLen+4:], messageType) binary.LittleEndian.PutUint32(sendPayload[IPC_MAGIC_LEN+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)
} }
@@ -55,6 +56,7 @@ 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)
} }
@@ -64,14 +66,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, IpcHeaderSize) buf := make([]byte, IPC_HEADER_SIZE)
_, 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]) != IpcMagix { if string(buf[:6]) != IPC_MAGIC {
return nil, errors.New("got invalid response from IPC socket") return nil, errors.New("got invalid response from IPC socket")
} }

118
node.go
View File

@@ -5,25 +5,15 @@ import (
"fmt" "fmt"
) )
const ( // A node can be an output, a workspace, a container or a container
NodeTypeRoot = "root" // containing a window.
NodeTypeOutput = "output"
NodeTypeWorkspace = "workspace"
NodeTypeCon = "con"
NodeTypeFloating = "floating_con"
)
// 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"`
Nodes []*Node `json:"nodes"` Nodes []*Node `json:"nodes"`
FloatingNodes []*Node `json:"floating_nodes"` FloatingNodes []*Node `json:"floating_nodes"`
Focused bool `json:"focused"` Focused bool `json:"focused"`
Visible bool `json:"visible"`
Urgent bool `json:"urgent"` Urgent bool `json:"urgent"`
Sticky bool `json:"sticky"` Sticky bool `json:"sticky"`
Border string `json:"border"` Border string `json:"border"`
@@ -34,24 +24,26 @@ 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
CurrentWorkspace string `json:"current_workspace"` Current_workspace 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"`
} }
// GetTree returns the whole information tree, which contains var __focused *Node
// everything from output to containers as a tree of nodes. Each node var __currentworkspace string
// has a field 'Nodes' which points to a list subnodes. Some nodes
// also have a field 'FloatingNodes' which points to a list of // Get the whole information tree, contains everything from output to
// floating containers. // containers as a tree of nodes. Each node has a field 'Nodes' which
// 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(MsgGettTree, 0) err := ipc.sendHeader(GET_TREE, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -69,68 +61,48 @@ func (ipc *SwayIPC) GetTree() (*Node, error) {
return node, nil return node, nil
} }
// FindFocused returns the container which has currently the // Usually called on the root node, returns the container which has
// focus. Usually called on the root node. // currently the focus.
func (node *Node) FindFocused() *Node { func (node *Node) FindFocused() *Node {
focused := searchFocused(node.Nodes) searchFocused(node.Nodes)
if focused == nil { if __focused == nil {
return searchFocused(node.FloatingNodes) searchFocused(node.FloatingNodes)
} }
return nil return __focused
} }
// FindCurrentWorkspace returns the current active // internal recursive focus node searcher
// workspace name. Usually called on the root node. func searchFocused(nodes []*Node) {
func (node *Node) FindCurrentWorkspace() string {
return searchCurrentWorkspace(node.Nodes)
}
func (node *Node) IsRoot() bool {
return node.Type == NodeTypeRoot
}
func (node *Node) IsOutput() bool {
return node.Type == NodeTypeOutput
}
func (node *Node) IsWorkspace() bool {
return node.Type == NodeTypeWorkspace
}
func (node *Node) IsContainer() bool {
return node.Type == NodeTypeCon
}
func (node *Node) IsFloating() bool {
return node.Type == NodeTypeFloating
}
// 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 {
return node __focused = node
return
} else { } else {
focused := searchFocused(node.Nodes) searchFocused(node.Nodes)
if focused == nil { if __focused == nil {
return searchFocused(node.FloatingNodes) 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"
) )
// Mode stores data of an output mode. // Store 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"`
} }
// Output represents an output object (i.e. a physical monitor) // 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"`
CurrentWorkspace string `json:"current_workspace"` Current_workspace string `json:"current_workspace"`
Modes []*Mode `json:"modes"` Modes []*Mode `json:"modes"`
CurrentMode *Mode `json:"current_mode"` CurrentMode *Mode `json:"current_mode"`
} }
// GetOutputs returns a list of currently available and usable outputs. // Get a list of currently available and usable outputs.
func (ipc *SwayIPC) GetOutputs() ([]*Output, error) { func (ipc *SwayIPC) GetOutputs() ([]*Output, error) {
err := ipc.sendHeader(MsgGetOutputs, 0) err := ipc.sendHeader(GET_OUTPUTS, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
) )
// Seat stores information about a seat containing input devices // 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"`
} }
// GetSeats returns input seats // Get input seats
func (ipc *SwayIPC) GetSeats() ([]*Seat, error) { func (ipc *SwayIPC) GetSeats() ([]*Seat, error) {
payload, err := ipc.get(MsgGetSeats) payload, err := ipc.get(GET_SEATS)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -5,9 +5,8 @@ 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(MsgGetWorkspaces) payload, err := ipc.get(GET_WORKSPACES)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -20,9 +19,8 @@ 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(MsgGetMarks) payload, err := ipc.get(GET_MARKS)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -35,9 +33,8 @@ 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(MsgGetBindingModes) payload, err := ipc.get(GET_BINDING_MODES)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -50,9 +47,8 @@ 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(MsgGetBindingState) payload, err := ipc.get(GET_BINDING_STATE)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -65,9 +61,8 @@ 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(MsgGetConfig) payload, err := ipc.get(GET_CONFIG)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -80,9 +75,8 @@ 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(MsgSendTick, uint32(len(payload))) err := ipc.sendHeader(SEND_TICK, uint32(len(payload)))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -1,6 +1,3 @@
// 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 (
@@ -8,43 +5,41 @@ import (
) )
const ( const (
VERSION = "v2.1.2" VERSION = "v0.3.0"
IpcHeaderSize = 14 IPC_HEADER_SIZE = 14
IpcMagix = "i3-ipc" IPC_MAGIC = "i3-ipc"
IpcMagicLen = 6 IPC_MAGIC_LEN = 6
)
// message types
const (
MsgRunCommand = iota
MsgGetWorkspaces
MsgSubscribe
MsgGetOutputs
MsgGettTree
MsgGetMarks
MsgGetBarConfig
MsgGetVersion
MsgGetBindingModes
MsgGetConfig
MsgSendTick
MsgSync
MsgGetBindingState
) )
const ( const (
MsgGetInputs = 100 // message types
MsgGetSeats = 101 RUN_COMMAND = iota
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
) )
// SwayIPC is the primary struct to work with the swayipc module. // This 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()
} }
// Rect stores geometrical information, used at various places for geometry etc. // A rectangle struct, 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
@@ -52,26 +47,25 @@ type Rect struct {
Height int `json:"height"` Height int `json:"height"`
} }
// Response stores meta data retrieved via ipc // Stores responses 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"`
} }
// Config stores the user config for the WM // Stores the user config for the WM
type Config struct { type Config struct {
Config string `json:"config"` Config string `json:"config"`
} }
// State stores the binding state // Stores the binding state
type State struct { type State struct {
Name string `json:"name"` Name string `json:"name"`
} }
// NewSwayIPC returns a new swayipc.SwayIPC object. Filename argument // Create a new swayipc.SwayIPC object. Filename argument is optional and
// is optional and may denote a filename or the name of an environment // may denote a filename or the name of an environment variable.
// 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
@@ -88,7 +82,7 @@ func NewSwayIPC(file ...string) *SwayIPC {
return ipc return ipc
} }
// get is a wrapper around sendHeader+readResponse // internal convenience wrapper
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"
) )
// Version stores the sway wm version // A version struct holding 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"`
} }
// GetVersion returns the sway software version // Get the sway software version
func (ipc *SwayIPC) GetVersion() (*Version, error) { func (ipc *SwayIPC) GetVersion() (*Version, error) {
payload, err := ipc.get(MsgGetVersion) payload, err := ipc.get(GET_VERSION)
if err != nil { if err != nil {
return nil, err return nil, err
} }