Add native i3 desktop announcements
This commit is contained in:
1 parent
49eeae89f4
commit
bf1f155018
22 files changed
+1835
-1
No files matched your search
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// Package i3ipc observes i3 without issuing window-management commands.
|
||||
package i3ipc
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
workspaces = 1
|
||||
subscribe = 2
|
||||
tree = 4
|
||||
eventBit uint32 = 1 << 31
|
||||
workspaceEvent = eventBit
|
||||
modeEvent = eventBit | 2
|
||||
windowEvent = eventBit | 3
|
||||
// A corrupt peer cannot cause an unbounded allocation or event backlog.
|
||||
maxPayload = 16 << 20
|
||||
maxPending = 256
|
||||
)
|
||||
|
||||
type message struct {
|
||||
kind uint32
|
||||
body []byte
|
||||
}
|
||||
|
||||
func readMessage(r io.Reader) (message, error) {
|
||||
var header [14]byte
|
||||
if _, err := io.ReadFull(r, header[:]); err != nil {
|
||||
return message{}, err
|
||||
}
|
||||
if string(header[:6]) != "i3-ipc" {
|
||||
return message{}, errors.New("invalid i3 magic")
|
||||
}
|
||||
size := binary.NativeEndian.Uint32(header[6:10])
|
||||
if size > maxPayload {
|
||||
return message{}, errors.New("i3 payload too large")
|
||||
}
|
||||
body := make([]byte, int(size))
|
||||
if _, err := io.ReadFull(r, body); err != nil {
|
||||
return message{}, err
|
||||
}
|
||||
if len(body) != 0 && !json.Valid(body) {
|
||||
return message{}, errors.New("invalid i3 JSON")
|
||||
}
|
||||
return message{binary.NativeEndian.Uint32(header[10:]), body}, nil
|
||||
}
|
||||
|
||||
func writeMessage(w io.Writer, kind uint32, body []byte) error {
|
||||
if len(body) > maxPayload {
|
||||
return errors.New("i3 payload too large")
|
||||
}
|
||||
var header [14]byte
|
||||
copy(header[:], "i3-ipc")
|
||||
binary.NativeEndian.PutUint32(header[6:10], uint32(len(body)))
|
||||
binary.NativeEndian.PutUint32(header[10:], kind)
|
||||
for _, part := range [][]byte{header[:], body} {
|
||||
for len(part) > 0 {
|
||||
n, err := w.Write(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
part = part[n:]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user