wm/cmd/bspwm/main.go

138 lines
2.6 KiB
Go
Raw Normal View History

2022-12-26 05:06:40 +00:00
package main
import (
"context"
2023-06-11 14:11:36 +00:00
"fmt"
"net"
2022-12-26 05:06:40 +00:00
"os"
"os/signal"
2023-06-11 14:56:54 +00:00
"strconv"
2022-12-26 05:06:40 +00:00
"syscall"
2023-06-11 14:11:36 +00:00
"github.com/jezek/xgbutil"
2023-06-15 15:24:04 +00:00
"github.com/jezek/xgbutil/xevent"
2023-06-15 03:20:55 +00:00
"tuxpa.in/a/zlog/log"
2023-06-11 10:24:15 +00:00
"tuxpa.in/t/wm/src/bsp"
2022-12-26 05:06:40 +00:00
"tuxpa.in/t/wm/src/handler"
2023-06-11 10:24:15 +00:00
"tuxpa.in/t/wm/src/handler/domains"
2022-12-26 05:06:40 +00:00
"tuxpa.in/t/wm/src/sock"
)
func main() {
2023-06-11 14:11:36 +00:00
2023-06-11 14:56:54 +00:00
c, err := _main()
2022-12-26 05:06:40 +00:00
if err != nil {
panic(err)
}
2023-06-11 14:56:54 +00:00
os.Exit(c)
2023-06-11 14:11:36 +00:00
}
2023-06-11 14:56:54 +00:00
func _main() (code int, err error) {
2023-06-11 14:11:36 +00:00
// connect to the x server
log.Printf("connecting to xorg")
x11, err := xgbutil.NewConn()
if err != nil {
2023-06-11 14:56:54 +00:00
return 1, err
2023-06-11 14:11:36 +00:00
}
defer x11.Conn().Close()
addr := parsePath(x11, "./bspwm.sock")
// create socket
2022-12-26 05:06:40 +00:00
log.Printf("starting bspwm")
2023-06-11 14:11:36 +00:00
ln, err := sock.Server(addr)
if err != nil {
2023-06-11 14:56:54 +00:00
return 1, err
2023-06-11 14:11:36 +00:00
}
defer ln.Close()
// construct context
2022-12-26 05:06:40 +00:00
ctx, stop := signal.NotifyContext(context.Background(),
os.Interrupt,
syscall.SIGTERM,
2023-06-11 10:24:15 +00:00
syscall.SIGQUIT,
syscall.SIGINT,
)
2022-12-26 05:06:40 +00:00
defer stop()
2023-06-11 14:11:36 +00:00
2023-06-11 10:24:15 +00:00
// initialize WM state
w := bsp.NewWM()
2023-06-11 14:11:36 +00:00
// create a wm-x11 connection
xwm := bsp.NewXWM(w, x11)
2023-06-15 03:20:55 +00:00
go func() {
err := xwm.Start(ctx)
if err != nil {
log.Err(err).Msg("x server shutdown")
stop()
}
}()
2023-06-11 14:11:36 +00:00
// create a handler
2023-06-11 10:24:15 +00:00
h := &handler.Handler{
XWM: xwm,
}
2023-06-11 14:11:36 +00:00
// install the handlers
2023-06-15 15:57:08 +00:00
handler.AddDomain[domains.Node](h, "node")
2023-06-11 10:24:15 +00:00
handler.AddDomain[domains.Todo](h, "desktop")
2023-06-15 15:57:08 +00:00
handler.AddDomain[domains.Monitor](h, "monitor")
2023-06-11 14:11:36 +00:00
handler.AddDomain[domains.Wm](h, "wm")
2023-06-11 10:24:15 +00:00
handler.AddDomain[domains.Todo](h, "rule")
2023-06-11 14:19:01 +00:00
handler.AddDomain[domains.Config](h, "config")
2023-06-11 10:24:15 +00:00
handler.AddDomain[domains.Todo](h, "subscribe")
handler.AddDomain[domains.Query](h, "query")
handler.AddDomain[domains.Echo](h, "echo")
2023-06-11 14:11:36 +00:00
2023-06-11 14:56:54 +00:00
codeCh := make(chan int, 1)
handler.AddDomain[domains.Todo](h, "quit")
h.AddDomainFunc("quit", func() handler.Domain {
d := &domains.Lambda{
Fn: func(x *bsp.XWM, msg *sock.Msg) ([]byte, error) {
if !msg.HasNext() {
codeCh <- 0
return nil, nil
}
str := msg.Next()
cd, err := strconv.Atoi(str)
if err != nil {
return nil, err
}
codeCh <- cd
return nil, nil
},
}
return d
})
2023-06-15 15:24:04 +00:00
beforeCh, afterCh, quitCh := xevent.MainPing(xwm.X)
2023-06-11 14:11:36 +00:00
// message listen loop
2022-12-26 05:06:40 +00:00
for {
select {
2023-06-15 15:24:04 +00:00
case <-beforeCh:
<-afterCh
2022-12-26 05:06:40 +00:00
case m := <-ln.Msg():
h.Run(m)
2023-06-11 14:56:54 +00:00
case cint := <-codeCh:
stop()
return cint, nil
2023-06-15 15:24:04 +00:00
case <-quitCh:
stop()
2022-12-26 05:06:40 +00:00
case <-ctx.Done():
2023-06-11 14:56:54 +00:00
return 0, nil
2022-12-26 05:06:40 +00:00
}
}
}
2023-06-11 14:11:36 +00:00
func parsePath(xc *xgbutil.XUtil, path string) *net.UnixAddr {
if path == "" {
path = os.Getenv(sock.SOCKET_ENV_VAR)
}
if path == "" {
path = fmt.Sprintf(sock.SOCKET_PATH_TPL, "", xc.Conn().DisplayNumber, xc.Conn().DefaultScreen)
}
addr, err := net.ResolveUnixAddr("unix", path)
if err != nil {
panic(err)
}
return addr
}