-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
94 lines (81 loc) · 2.49 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
x "github.com/linuxdeepin/go-x11-client"
xkb "github.com/linuxdeepin/go-x11-client/ext/xkb"
"github.com/sirupsen/logrus"
"go.i3wm.org/i3"
)
var (
layouts map[i3.NodeID]uint8
currentWindow i3.NodeID
)
func watchXkb(conn *x.Conn) {
xkbLogger := logrus.WithField("module", "xkb")
eventChan := make(chan x.GenericEvent)
conn.AddEventChan(eventChan)
for {
event, ok := <-eventChan
if !ok {
xkbLogger.Error("xkb channel error")
return
}
stateEvent, err := xkb.NewStateNotifyEvent(event)
if err != nil {
xkbLogger.Error(err)
}
xkbLogger.WithFields(logrus.Fields{"id": currentWindow, "group": stateEvent.LockedGroup}).Info("layout changed")
layouts[currentWindow] = stateEvent.LockedGroup
}
}
func main() {
i3Logger := logrus.WithField("module", "i3")
xkbLogger := logrus.WithField("module", "xkb")
layouts = make(map[i3.NodeID]uint8)
i3ER := i3.Subscribe(i3.WindowEventType, i3.ShutdownEventType)
conn, err := x.NewConn()
if err != nil {
xkbLogger.Panic(err)
}
useExtCookie := xkb.UseExtension(conn, xkb.MajorVersion, xkb.MinorVersion)
_, err = useExtCookie.Reply(conn)
if err != nil {
xkbLogger.Panic(err)
}
selectOpts := xkb.SelectDetail(xkb.EventTypeStateNotify, map[uint]bool{1 << 7: true})
if err := xkb.SelectEventsChecked(conn, xkb.IDUseCoreKbd, selectOpts).Check(conn); err != nil {
xkbLogger.Panic(err)
}
itree, err := i3.GetTree()
if err != nil {
i3Logger.Error(err)
currentWindow = 0
} else {
currentWindow = itree.Root.FindFocused(func(n *i3.Node) bool { return n.Focused }).ID
}
go watchXkb(conn)
for i3ER.Next() {
switch i3ER.Event().(type) {
case *i3.WindowEvent:
event := i3ER.Event().(*i3.WindowEvent)
switch event.Change {
case "new":
i3Logger.WithField("id", event.Container.ID).Info("new")
layouts[event.Container.ID] = layouts[currentWindow]
case "focus":
i3Logger.WithField("id", event.Container.ID).Info("focus")
currentWindow = event.Container.ID
if err := xkb.LatchLockStateChecked(conn, xkb.IDUseCoreKbd, 0, 0, true, layouts[currentWindow], 0, 0, false, 0).Check(conn); err != nil {
xkbLogger.WithField("id", currentWindow).Error(err)
} else {
xkbLogger.WithFields(logrus.Fields{"id": currentWindow, "group": layouts[currentWindow]}).Info("layout changed")
}
case "close":
i3Logger.WithField("id", event.Container.ID).Info("close")
delete(layouts, event.Container.ID)
}
case *i3.ShutdownEvent:
i3Logger.Info("session shutdown")
return
}
}
}