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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
package sway
import (
"context"
)
// EventType is used to choose which events to Subscribe to
type EventType string
const (
// EventTypeWorkspace is sent whenever an event involving a workspace occurs
// such as initialization of a new workspace or a different workspace gains
// focus
EventTypeWorkspace EventType = "workspace"
// EventTypeMode is sent whenever the binding mode changes
EventTypeMode EventType = "mode"
// EventTypeWindow is sent whenever an event involving a view occurs such as
// being reparented, focused, or closed
EventTypeWindow EventType = "window"
// EventTypeBarConfigUpdate is sent whenever a bar config changes
EventTypeBarConfigUpdate EventType = "barconfig_update"
// EventTypeBinding is sent when a configured binding is executed
EventTypeBinding EventType = "binding"
// EventTypeShutdown is sent when the ipc shuts down because sway is exiting
EventTypeShutdown EventType = "shutdown"
// EventTypeTick is sent when an ipc client sends a SEND_TICK message
EventTypeTick EventType = "tick"
// EventTypeBarStateUpdate is sent when the visibility of a bar should change
// due to a modifier
EventTypeBarStateUpdate EventType = "bar_state_update"
// Deprecated: EventTypeBarStatusUpdate is deprecated
// you should use EventTypeBarStateUpdate instead
EventTypeBarStatusUpdate EventType = EventTypeBarStateUpdate
// EventTypeInput is sent when something related to input devices changes
EventTypeInput EventType = "input"
)
// An EventHandler is passed to Subscribe and its methods are called in response
// to sway events
type EventHandler interface {
Workspace(context.Context, WorkspaceEvent)
Mode(context.Context, ModeEvent)
Window(context.Context, WindowEvent)
BarConfigUpdate(context.Context, BarConfigUpdateEvent)
Binding(context.Context, BindingEvent)
Shutdown(context.Context, ShutdownEvent)
Tick(context.Context, TickEvent)
BarStateUpdate(context.Context, BarStateUpdateEvent)
BarStatusUpdate(context.Context, BarStatusUpdateEvent)
Input(context.Context, InputEvent)
}
// NoOpEventHandler is used to help provide empty methods that aren't intended
// to be handled by Subscribe
//
// type handler struct {
// sway.EventHandler
// }
//
// func (h handler) Window(ctx context.Context, e sway.WindowEvent) {
// ...
// }
//
// func main() {
// h := handler{
// EventHandler: sway.NoOpEventHandler(),
// }
//
// ctx := context.Background()
//
// sway.Subscribe(ctx, h, sway.EventTypeWindow)
// }
func NoOpEventHandler() EventHandler {
return noOpEventHandler{}
}
type noOpEventHandler struct{}
func (h noOpEventHandler) Workspace(context.Context, WorkspaceEvent) {}
func (h noOpEventHandler) Mode(context.Context, ModeEvent) {}
func (h noOpEventHandler) Window(context.Context, WindowEvent) {}
func (h noOpEventHandler) BarConfigUpdate(context.Context, BarConfigUpdateEvent) {}
func (h noOpEventHandler) Binding(context.Context, BindingEvent) {}
func (h noOpEventHandler) Shutdown(context.Context, ShutdownEvent) {}
func (h noOpEventHandler) Tick(context.Context, TickEvent) {}
func (h noOpEventHandler) BarStateUpdate(context.Context, BarStateUpdateEvent) {}
func (h noOpEventHandler) BarStatusUpdate(context.Context, BarStatusUpdateEvent) {}
func (h noOpEventHandler) Input(context.Context, InputEvent) {}
// Subscribe the IPC connection to the events listed in the payload
func Subscribe(ctx context.Context, handler EventHandler, events ...EventType) error {
n, err := New(ctx)
if err != nil {
return err
}
c := n.(*client)
if err = c.subscribe(ctx, events...); err != nil {
return err
}
for {
msg, err := c.recvMsg(ctx)
if err != nil {
return err
}
processEvent(ctx, handler, msg)
}
}
func processEvent(ctx context.Context, h EventHandler, msg *message) {
switch msg.Type {
case eventTypeWorkspace:
var e WorkspaceEvent
if err := msg.Decode(&e); err == nil {
h.Workspace(ctx, e)
}
case eventTypeMode:
var e ModeEvent
if err := msg.Decode(&e); err == nil {
h.Mode(ctx, e)
}
case eventTypeWindow:
var e WindowEvent
if err := msg.Decode(&e); err == nil {
h.Window(ctx, e)
}
case eventTypeBarConfigUpdate:
var e BarConfigUpdateEvent
if err := msg.Decode(&e); err == nil {
h.BarConfigUpdate(ctx, e)
}
case eventTypeBinding:
var e BindingEvent
if err := msg.Decode(&e); err == nil {
h.Binding(ctx, e)
}
case eventTypeShutdown:
var e ShutdownEvent
if err := msg.Decode(&e); err == nil {
h.Shutdown(ctx, e)
}
case eventTypeTick:
var e TickEvent
if err := msg.Decode(&e); err == nil {
h.Tick(ctx, e)
}
case eventTypeBarStateUpdate:
var e BarStateUpdateEvent
if err := msg.Decode(&e); err == nil {
h.BarStateUpdate(ctx, e)
}
case eventTypeInput:
var e InputEvent
if err := msg.Decode(&e); err == nil {
h.Input(ctx, e)
}
}
}
|