renamed to swayipc

This commit is contained in:
2025-08-16 19:50:30 +02:00
parent c8096780a8
commit 177eecd475
29 changed files with 110 additions and 104 deletions

View File

@@ -1,26 +1,32 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/i3ipc)](https://goreportcard.com/report/github.com/tlinden/i3ipc)
[![Actions](https://github.com/tlinden/i3ipc/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/i3ipc/actions)
![GitHub License](https://img.shields.io/github/license/tlinden/i3ipc)
[![GoDoc](https://godoc.org/github.com/tlinden/i3ipc?status.svg)](https://godoc.org/github.com/tlinden/i3ipc)
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/swayipc)](https://goreportcard.com/report/github.com/tlinden/swayipc)
[![Actions](https://github.com/tlinden/swayipc/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/swayipc/actions)
![GitHub License](https://img.shields.io/github/license/tlinden/swayipc)
[![GoDoc](https://godoc.org/github.com/tlinden/swayipc?status.svg)](https://godoc.org/github.com/tlinden/swayipc)
# i3ipc - go bindings to control sway (and possibly i3)
# swayipc - go bindings to control sway (and possibly i3)
This is a go module which you can use to control [sway](https://swaywm.org/),
[swayfx](https://github.com/WillPower3309/swayfx) and possibly [i3wm](http://i3wm.org/).
Package swayipc can be used to control [sway](https://swaywm.org/),
[swayfx](https://github.com/WillPower3309/swayfx) and possibly
[i3wm](http://i3wm.org/) window managers via a unix domain socket.
## About
i3ipc's interprocess communication (or ipc) is the interface i3wm and
sway use to receive commands from client applications such as
i3-msg. It also features a publish/subscribe mechanism for notifying
interested parties of window manager events.
i3ipc is a go module for controlling the window manager. This project
swaywm's interprocess communication (or ipc) is the interface sway,
swayfx and i3wm use to receive commands from client applications such
as sway-msg. It also features a publish/subscribe mechanism for
notifying interested parties of window manager events.
swayipc is a go module for controlling the window manager. This project
is intended to be useful for general scripting, and for applications
that interact with the window manager like status line generators,
notification daemons, and window pagers.
notification daemons, and window pagers. It is primarily designed to
work with sway and swayfx, but may also work with i3wm, although I
haven't tested it on i3wm.
The module uses the i3-IPC proctocol as outlined in sway-ipc(7).
For details on how to use the library, see the
[reference documentation](https://godoc.org/github.com/tlinden/i3ipc).
[reference documentation](https://godoc.org/github.com/tlinden/swayipc).
## Example usage
@@ -33,11 +39,11 @@ import (
"fmt"
"log"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {
@@ -69,7 +75,7 @@ which is using this module.
Execute this to add the module to your project:
```sh
go get github.com/tlinden/i3ipc
go get github.com/tlinden/swayipc
```
## Acknowledgements
@@ -80,12 +86,12 @@ one is not just a port of it and has been written from scratch.
## Getting help
Although I'm happy to hear from i3ipc users in private email, that's the
Although I'm happy to hear from swayipc users in private email, that's the
best way for me to forget to do something.
In order to report a bug, unexpected behavior, feature requests or to
submit a patch, please open an issue on github:
https://github.com/TLINDEN/i3ipc/issues.
https://github.com/TLINDEN/swayipc/issues.
## Copyright and license
@@ -97,7 +103,7 @@ T.v.Dein <tom AT vondein DOT org>
## Project homepage
https://github.com/TLINDEN/i3ipc
https://github.com/TLINDEN/swayipc
## Copyright and License

View File

@@ -4,11 +4,11 @@ import (
"fmt"
"log"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -10,20 +10,20 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
// Event callback function, needs to implement each subscribed events,
// fed to it as RawResponse
func ProcessTick(event *i3ipc.RawResponse) error {
func ProcessTick(event *swayipc.RawResponse) error {
var err error
switch event.PayloadType {
case i3ipc.EV_Tick:
ev := &i3ipc.EventTick{}
case swayipc.EV_Tick:
ev := &swayipc.EventTick{}
err = json.Unmarshal(event.Payload, &ev)
repr.Println(ev)
case i3ipc.EV_Window:
ev := &i3ipc.EventWindow{}
case swayipc.EV_Window:
ev := &swayipc.EventWindow{}
err = json.Unmarshal(event.Payload, &ev)
repr.Println(ev)
default:
@@ -38,7 +38,7 @@ func ProcessTick(event *i3ipc.RawResponse) error {
}
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {
@@ -46,7 +46,7 @@ func main() {
}
defer ipc.Close()
_, err = ipc.Subscribe(&i3ipc.Event{
_, err = ipc.Subscribe(&swayipc.Event{
Tick: true,
Window: true,
})

View File

@@ -4,11 +4,11 @@ import (
"fmt"
"log"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -9,11 +9,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"fmt"
"log"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -4,11 +4,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -8,11 +8,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -10,11 +10,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -9,11 +9,11 @@ import (
"log"
"github.com/alecthomas/repr"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

View File

@@ -12,7 +12,7 @@ import (
"log"
"os"
"github.com/tlinden/i3ipc"
"github.com/tlinden/swayipc"
)
func main() {
@@ -22,7 +22,7 @@ func main() {
payload = os.Args[1]
}
ipc := i3ipc.NewI3ipc()
ipc := swayipc.NewSwayIPC()
err := ipc.Connect()
if err != nil {

6
bar.go
View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -74,7 +74,7 @@ type Bar struct {
}
// Get a list of currently visible and active bar names
func (ipc *I3ipc) GetBars() ([]string, error) {
func (ipc *SwayIPC) GetBars() ([]string, error) {
payload, err := ipc.get(GET_BAR_CONFIG)
if err != nil {
return nil, err
@@ -89,7 +89,7 @@ func (ipc *I3ipc) GetBars() ([]string, error) {
}
// Get the bar object of the bar specified by the string 'id'
func (ipc *I3ipc) GetBar(id string) (*Bar, error) {
func (ipc *SwayIPC) GetBar(id string) (*Bar, error) {
err := ipc.sendHeader(GET_BAR_CONFIG, uint32(len(id)))
if err != nil {
return nil, err

View File

@@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -28,7 +28,7 @@ import (
// given) and returns a response list.
//
// Possible commands are all non-specific commands, see sway(5)
func (ipc *I3ipc) RunGlobalCommand(command ...string) ([]Response, error) {
func (ipc *SwayIPC) RunGlobalCommand(command ...string) ([]Response, error) {
return ipc.RunCommand(0, "", command...)
}
@@ -36,7 +36,7 @@ func (ipc *I3ipc) RunGlobalCommand(command ...string) ([]Response, error) {
// given) and returns a response list.
//
// Possible commands are all container-specific commands, see sway(5)
func (ipc *I3ipc) RunContainerCommand(id int, command ...string) ([]Response, error) {
func (ipc *SwayIPC) RunContainerCommand(id int, command ...string) ([]Response, error) {
return ipc.RunCommand(id, "con", command...)
}
@@ -46,7 +46,7 @@ func (ipc *I3ipc) RunContainerCommand(id int, command ...string) ([]Response, er
// Possible commands are all container-specific commands, see sway(5).
//
// Target can be one of con, workspace, output, input, etc. see sway-ipc(7).
func (ipc *I3ipc) RunCommand(id int, target string, command ...string) ([]Response, error) {
func (ipc *SwayIPC) RunCommand(id int, target string, command ...string) ([]Response, error) {
if len(command) == 0 {
return nil, errors.New("empty command arg")
}

View File

@@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -36,7 +36,7 @@ const (
EV_Input int = 0x80000015
)
// Subscriber struct, use this to tell i3ipc which events you want to
// Subscriber struct, use this to tell swayipc which events you want to
// subscribe.
type Event struct {
Workspace bool
@@ -104,12 +104,12 @@ type EventInput struct {
Input *Input `json:"input"`
}
// Subscribe to one or more events. Fill the i3ipc.Event object
// Subscribe to one or more events. Fill the swayipc.Event object
// accordingly.
//
// Returns a response list containing a response for every subscribed
// event.
func (ipc *I3ipc) Subscribe(sub *Event) ([]*Response, error) {
func (ipc *SwayIPC) Subscribe(sub *Event) ([]*Response, error) {
events := []string{}
// looks ugly but makes it much more comfortable for the user
@@ -181,12 +181,12 @@ func (ipc *I3ipc) Subscribe(sub *Event) ([]*Response, error) {
//
// You supply the loop a generic callback function, which will be
// called every time an event occurs. The function will receive the
// i3ipc.RawResponse object for the event. You need to Unmarshall the
// swayipc.RawResponse object for the event. You need to Unmarshall the
// Payload field yourself.
//
// If your callback function returns an error, the event loop returns
// with this error and finishes thus.
func (ipc *I3ipc) EventLoop(callback func(event *RawResponse) error) error {
func (ipc *SwayIPC) EventLoop(callback func(event *RawResponse) error) error {
for {
payload, err := ipc.readResponse()
if err != nil {

4
go.mod
View File

@@ -1,5 +1,5 @@
module github.com/tlinden/i3ipc
module github.com/tlinden/swayipc
go 1.22
go 1.23
require github.com/alecthomas/repr v0.5.1 // indirect

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -67,7 +67,7 @@ type Binding struct {
}
// Get a list of all currently supported inputs
func (ipc *I3ipc) GetInputs() ([]*Input, error) {
func (ipc *SwayIPC) GetInputs() ([]*Input, error) {
payload, err := ipc.get(GET_INPUTS)
if err != nil {
return nil, err

2
io.go
View File

@@ -1,4 +1,4 @@
package i3ipc
package swayipc
import "os"

12
net.go
View File

@@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/binary"
@@ -32,7 +32,7 @@ type RawResponse struct {
}
// Connect to unix domain ipc socket.
func (ipc *I3ipc) Connect() error {
func (ipc *SwayIPC) Connect() error {
if !fileExists(ipc.SocketFile) {
ipc.SocketFile = os.Getenv(ipc.SocketFile)
if ipc.SocketFile == "" {
@@ -51,11 +51,11 @@ func (ipc *I3ipc) Connect() error {
}
// Close the socket.
func (ipc *I3ipc) Close() {
func (ipc *SwayIPC) Close() {
ipc.socket.Close()
}
func (ipc *I3ipc) sendHeader(messageType uint32, len uint32) error {
func (ipc *SwayIPC) sendHeader(messageType uint32, len uint32) error {
sendPayload := make([]byte, IPC_HEADER_SIZE)
copy(sendPayload, []byte(IPC_MAGIC))
@@ -71,7 +71,7 @@ func (ipc *I3ipc) sendHeader(messageType uint32, len uint32) error {
return nil
}
func (ipc *I3ipc) sendPayload(payload []byte) error {
func (ipc *SwayIPC) sendPayload(payload []byte) error {
_, err := ipc.socket.Write(payload)
if err != nil {
@@ -81,7 +81,7 @@ func (ipc *I3ipc) sendPayload(payload []byte) error {
return nil
}
func (ipc *I3ipc) readResponse() (*RawResponse, error) {
func (ipc *SwayIPC) readResponse() (*RawResponse, error) {
// read header
buf := make([]byte, IPC_HEADER_SIZE)

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -58,7 +58,7 @@ var __currentworkspace string
// The top level node is the "root" node.
//
// Use the returned node oject to further investigate the wm setup.
func (ipc *I3ipc) GetTree() (*Node, error) {
func (ipc *SwayIPC) GetTree() (*Node, error) {
err := ipc.sendHeader(GET_TREE, 0)
if err != nil {
return nil, err

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -43,7 +43,7 @@ type Output struct {
}
// Get a list of currently available and usable outputs.
func (ipc *I3ipc) GetOutputs() ([]*Output, error) {
func (ipc *SwayIPC) GetOutputs() ([]*Output, error) {
err := ipc.sendHeader(GET_OUTPUTS, 0)
if err != nil {
return nil, err

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -30,7 +30,7 @@ type Seat struct {
}
// Get input seats
func (ipc *I3ipc) GetSeats() ([]*Seat, error) {
func (ipc *SwayIPC) GetSeats() ([]*Seat, error) {
payload, err := ipc.get(GET_SEATS)
if err != nil {
return nil, err

View File

@@ -1,11 +1,11 @@
package i3ipc
package swayipc
import (
"encoding/json"
"fmt"
)
func (ipc *I3ipc) GetWorkspaces() ([]*Node, error) {
func (ipc *SwayIPC) GetWorkspaces() ([]*Node, error) {
payload, err := ipc.get(GET_WORKSPACES)
if err != nil {
return nil, err
@@ -19,7 +19,7 @@ func (ipc *I3ipc) GetWorkspaces() ([]*Node, error) {
return nodes, nil
}
func (ipc *I3ipc) GetMarks() ([]string, error) {
func (ipc *SwayIPC) GetMarks() ([]string, error) {
payload, err := ipc.get(GET_MARKS)
if err != nil {
return nil, err
@@ -33,7 +33,7 @@ func (ipc *I3ipc) GetMarks() ([]string, error) {
return marks, nil
}
func (ipc *I3ipc) GetBindingModes() ([]string, error) {
func (ipc *SwayIPC) GetBindingModes() ([]string, error) {
payload, err := ipc.get(GET_BINDING_MODES)
if err != nil {
return nil, err
@@ -47,7 +47,7 @@ func (ipc *I3ipc) GetBindingModes() ([]string, error) {
return modes, nil
}
func (ipc *I3ipc) GetBindingState() (*State, error) {
func (ipc *SwayIPC) GetBindingState() (*State, error) {
payload, err := ipc.get(GET_BINDING_STATE)
if err != nil {
return nil, err
@@ -61,7 +61,7 @@ func (ipc *I3ipc) GetBindingState() (*State, error) {
return state, nil
}
func (ipc *I3ipc) GetConfig() (string, error) {
func (ipc *SwayIPC) GetConfig() (string, error) {
payload, err := ipc.get(GET_CONFIG)
if err != nil {
return "", err
@@ -75,7 +75,7 @@ func (ipc *I3ipc) GetConfig() (string, error) {
return config.Config, nil
}
func (ipc *I3ipc) SendTick(payload string) error {
func (ipc *SwayIPC) SendTick(payload string) error {
err := ipc.sendHeader(SEND_TICK, uint32(len(payload)))
if err != nil {
return err

View File

@@ -15,14 +15,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"net"
)
const (
VERSION = "v0.1.0"
VERSION = "v0.2.0"
IPC_HEADER_SIZE = 14
IPC_MAGIC = "i3-ipc"
@@ -49,11 +49,11 @@ const (
GET_SEATS = 101
)
// This is the primary struct to work with the i3ipc module.
type I3ipc struct {
// This is the primary struct to work with the swayipc module.
type SwayIPC struct {
socket net.Conn
SocketFile string // filename of the i3 IPC socket
Events *Event // store subscribed events, see i3ipc.Subscribe()
Events *Event // store subscribed events, see swayipc.Subscribe()
}
// A rectangle struct, used at various places for geometry etc.
@@ -81,14 +81,14 @@ type State struct {
Name string `json:"name"`
}
// Create a new i3ipc.I3ipc object. Filename argument is optional and
// Create a new swayipc.SwayIPC object. Filename argument 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
// variable SWAYSOCK and use the file it points to as unix domain
// socket to communicate with sway (and possible i3).
func NewI3ipc(file ...string) *I3ipc {
ipc := &I3ipc{}
func NewSwayIPC(file ...string) *SwayIPC {
ipc := &SwayIPC{}
if len(file) == 0 {
ipc.SocketFile = "SWAYSOCK"
@@ -100,7 +100,7 @@ func NewI3ipc(file ...string) *I3ipc {
}
// internal convenience wrapper
func (ipc *I3ipc) get(command uint32) (*RawResponse, error) {
func (ipc *SwayIPC) get(command uint32) (*RawResponse, error) {
err := ipc.sendHeader(command, 0)
if err != nil {
return nil, err

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package i3ipc
package swayipc
import (
"encoding/json"
@@ -30,7 +30,7 @@ type Version struct {
}
// Get the sway software version
func (ipc *I3ipc) GetVersion() (*Version, error) {
func (ipc *SwayIPC) GetVersion() (*Version, error) {
payload, err := ipc.get(GET_VERSION)
if err != nil {
return nil, err