1
0
mirror of https://github.com/joshuarubin/go-sway synced 2024-11-22 21:11:59 +01:00

finish the sway api

Signed-off-by: Joshua Rubin <me@jawa.dev>
This commit is contained in:
Joshua Rubin 2019-04-14 00:13:12 -06:00
parent 66e28f3069
commit 441d8a7846
No known key found for this signature in database
GPG Key ID: 673103A1CC175722
8 changed files with 572 additions and 127 deletions

121
client.go

@ -22,6 +22,17 @@ type client struct {
type Client interface {
GetTree(context.Context) (*Node, error)
RunCommand(context.Context, string) ([]RunCommandReply, error)
GetWorkspaces(context.Context) ([]Workspace, error)
GetMarks(context.Context) ([]string, error)
GetOutputs(context.Context) ([]Output, error)
GetBarIDs(context.Context) ([]BarID, error)
GetBarConfig(context.Context, BarID) (*BarConfig, error)
GetVersion(context.Context) (*Version, error)
GetBindingModes(context.Context) ([]string, error)
GetConfig(context.Context) (*Config, error)
SendTick(context.Context, string) (*TickReply, error)
GetInputs(context.Context) ([]Input, error)
GetSeats(context.Context) ([]Seat, error)
Close() error
}
@ -140,3 +151,113 @@ func (c *client) RunCommand(ctx context.Context, command string) ([]RunCommandRe
return replies, err
}
func (c *client) GetWorkspaces(ctx context.Context) ([]Workspace, error) {
msg, err := c.roundTrip(ctx, messageTypeGetWorkspaces, nil)
if err != nil {
return nil, err
}
var ret []Workspace
return ret, msg.Decode(&ret)
}
func (c *client) GetOutputs(ctx context.Context) ([]Output, error) {
msg, err := c.roundTrip(ctx, messageTypeGetOutputs, nil)
if err != nil {
return nil, err
}
var ret []Output
return ret, msg.Decode(&ret)
}
func (c *client) GetMarks(ctx context.Context) ([]string, error) {
msg, err := c.roundTrip(ctx, messageTypeGetMarks, nil)
if err != nil {
return nil, err
}
var ret []string
return ret, msg.Decode(&ret)
}
func (c *client) GetBarIDs(ctx context.Context) ([]BarID, error) {
msg, err := c.roundTrip(ctx, messageTypeGetBarConfig, nil)
if err != nil {
return nil, err
}
var ret []BarID
return ret, msg.Decode(&ret)
}
func (c *client) GetBarConfig(ctx context.Context, id BarID) (*BarConfig, error) {
msg, err := c.roundTrip(ctx, messageTypeGetBarConfig, []byte(id))
if err != nil {
return nil, err
}
var ret BarConfig
return &ret, msg.Decode(&ret)
}
func (c *client) GetVersion(ctx context.Context) (*Version, error) {
msg, err := c.roundTrip(ctx, messageTypeGetVersion, nil)
if err != nil {
return nil, err
}
var ret Version
return &ret, msg.Decode(&ret)
}
func (c *client) GetBindingModes(ctx context.Context) ([]string, error) {
msg, err := c.roundTrip(ctx, messageTypeGetBindingModes, nil)
if err != nil {
return nil, err
}
var ret []string
return ret, msg.Decode(&ret)
}
func (c *client) GetConfig(ctx context.Context) (*Config, error) {
msg, err := c.roundTrip(ctx, messageTypeGetConfig, nil)
if err != nil {
return nil, err
}
var ret Config
return &ret, msg.Decode(&ret)
}
func (c *client) SendTick(ctx context.Context, payload string) (*TickReply, error) {
msg, err := c.roundTrip(ctx, messageTypeSendTick, []byte(payload))
if err != nil {
return nil, err
}
var ret TickReply
return &ret, msg.Decode(&ret)
}
func (c *client) GetInputs(ctx context.Context) ([]Input, error) {
msg, err := c.roundTrip(ctx, messageTypeGetInputs, nil)
if err != nil {
return nil, err
}
var ret []Input
return ret, msg.Decode(&ret)
}
func (c *client) GetSeats(ctx context.Context) ([]Seat, error) {
msg, err := c.roundTrip(ctx, messageTypeGetSeats, nil)
if err != nil {
return nil, err
}
var ret []Seat
return ret, msg.Decode(&ret)
}

82
cmd/sway-focused/main.go Normal file

@ -0,0 +1,82 @@
package main
import (
"context"
"fmt"
"log"
"os"
"syscall"
sway "github.com/joshuarubin/go-sway"
"github.com/joshuarubin/lifecycle"
)
func main() {
if err := run(); err != nil && !isSignal(err) {
fmt.Fprintf(os.Stderr, "%+v\n", err)
os.Exit(1)
}
}
func isSignal(err error, sigs ...os.Signal) bool {
serr, ok := err.(lifecycle.ErrSignal)
if !ok {
return false
}
switch serr.Signal {
case syscall.SIGINT, syscall.SIGTERM:
return true
}
return false
}
func run() error {
ctx := lifecycle.New(context.Background())
client, err := sway.New(ctx)
if err != nil {
return err
}
defer client.Close()
fh := focusHandler(client)
n, err := client.GetTree(ctx)
if err != nil {
return err
}
fh(ctx, n.FocusedNode())
h := sway.EventHandler{
Window: func(ctx context.Context, e sway.WindowEvent) {
if e.Change != "focus" {
return
}
fh(ctx, e.Container.FocusedNode())
},
}
lifecycle.GoErr(ctx, func() error {
return sway.Subscribe(ctx, h, sway.EventTypeWindow)
})
return lifecycle.Wait(ctx)
}
func focusHandler(client sway.Client) func(context.Context, *sway.Node) {
return func(ctx context.Context, node *sway.Node) {
if node == nil {
return
}
opt := "none"
if node.AppID == nil || *node.AppID != "kitty" {
opt = "altwin:ctrl_win"
}
if _, err := client.RunCommand(ctx, `input '*' xkb_options `+opt); err != nil {
log.Println(err)
}
}
}

1
go.mod

@ -3,6 +3,7 @@ module github.com/joshuarubin/go-sway
go 1.12
require (
github.com/joshuarubin/lifecycle v0.0.3
github.com/stretchr/testify v1.3.0 // indirect
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0

4
go.sum

@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/joshuarubin/lifecycle v0.0.3 h1:CpBhY0kS+tln6u7/p3I84cu8sDzluVIF/lCO9BpodjQ=
github.com/joshuarubin/lifecycle v0.0.3/go.mod h1:uOdzFKF/2+tKiVSF2lLCuI1dQZo35yXr93rPOd7Hsio=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -9,3 +11,5 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

@ -36,18 +36,19 @@ const (
messageTypeGetBindingModes
messageTypeGetConfig
messageTypeSendTick
messageTypeSync
messageTypeGetInputs = 100
messageTypeGetSeats = 101
)
const (
eventReplyTypeWorkspace messageType = 0x80000000
eventReplyTypeMode messageType = 0x80000002
eventReplyTypeWindow messageType = 0x80000003
eventReplyTypeBarConfigUpdate messageType = 0x80000004
eventReplyTypeBinding messageType = 0x80000005
eventReplyTypeShutdown messageType = 0x80000006
eventReplyTypeTick messageType = 0x80000007
eventReplyTypeBarStatusUpdate messageType = 0x80000014
eventTypeWorkspace messageType = 0x80000000
eventTypeMode messageType = 0x80000002
eventTypeWindow messageType = 0x80000003
eventTypeBarConfigUpdate messageType = 0x80000004
eventTypeBinding messageType = 0x80000005
eventTypeShutdown messageType = 0x80000006
eventTypeTick messageType = 0x80000007
eventTypeBarStatusUpdate messageType = 0x80000014
)
var magic = [6]byte{'i', '3', '-', 'i', 'p', 'c'}

@ -2,6 +2,8 @@ package sway_test
import (
"context"
"encoding/json"
"fmt"
"log"
"testing"
"time"
@ -9,8 +11,13 @@ import (
sway "github.com/joshuarubin/go-sway"
)
func printJSON(v interface{}) {
out, _ := json.MarshalIndent(v, "", " ")
fmt.Println(string(out))
}
func TestSocket(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
client, err := sway.New(ctx)
@ -24,13 +31,90 @@ func TestSocket(t *testing.T) {
t.Fatal(err)
}
fh := focusHandler(client)
workspaces, err := client.GetWorkspaces(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(workspaces)
outputs, err := client.GetOutputs(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(outputs)
marks, err := client.GetMarks(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(marks)
barIDs, err := client.GetBarIDs(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(barIDs)
for _, id := range barIDs {
config, err := client.GetBarConfig(ctx, id)
if err != nil {
t.Fatal(err)
}
printJSON(config)
}
version, err := client.GetVersion(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(*version)
bindingModes, err := client.GetBindingModes(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(bindingModes)
config, err := client.GetConfig(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(config)
tick, err := client.SendTick(ctx, "foo")
if err != nil {
t.Fatal(err)
}
printJSON(tick)
inputs, err := client.GetInputs(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(inputs)
seats, err := client.GetSeats(ctx)
if err != nil {
t.Fatal(err)
}
printJSON(seats)
fh := focusHandler(client)
fh(ctx, n.FocusedNode())
h := sway.EventHandler{
Window: func(ctx context.Context, e sway.WindowEvent) {
if e.Change != sway.WindowChangeFocus {
if e.Change != "focus" {
return
}
fh(ctx, e.Container.FocusedNode())

@ -18,9 +18,14 @@ const (
)
type EventHandler struct {
Workspace func(context.Context, WorkspaceEvent)
Window func(context.Context, WindowEvent)
Shutdown func(context.Context, ShutdownEvent)
Workspace func(context.Context, WorkspaceEvent)
Mode func(context.Context, ModeEvent)
Window func(context.Context, WindowEvent)
BarConfigUpdate func(context.Context, BarConfigUpdateEvent)
Binding func(context.Context, BindingEvent)
Shutdown func(context.Context, ShutdownEvent)
Tick func(context.Context, TickEvent)
BarStatusUpdate func(context.Context, BarStatusUpdateEvent)
}
func Subscribe(ctx context.Context, handler EventHandler, events ...EventType) error {
@ -48,43 +53,77 @@ func Subscribe(ctx context.Context, handler EventHandler, events ...EventType) e
func (h EventHandler) process(ctx context.Context, reply *message) {
switch reply.Type {
case eventReplyTypeWorkspace:
case eventTypeWorkspace:
if h.Workspace == nil {
return
}
var e WorkspaceEvent
if err := reply.Decode(&e); err != nil {
if err := reply.Decode(&e); err == nil {
h.Workspace(ctx, e)
}
case eventTypeMode:
if h.Mode == nil {
return
}
h.Workspace(ctx, e)
case eventReplyTypeMode:
case eventReplyTypeWindow:
var e ModeEvent
if err := reply.Decode(&e); err == nil {
h.Mode(ctx, e)
}
case eventTypeWindow:
if h.Window == nil {
return
}
var e WindowEvent
if err := reply.Decode(&e); err != nil {
if err := reply.Decode(&e); err == nil {
h.Window(ctx, e)
}
case eventTypeBarConfigUpdate:
if h.BarConfigUpdate == nil {
return
}
h.Window(ctx, e)
case eventReplyTypeBarConfigUpdate:
case eventReplyTypeBinding:
case eventReplyTypeShutdown:
var e BarConfigUpdateEvent
if err := reply.Decode(&e); err == nil {
h.BarConfigUpdate(ctx, e)
}
case eventTypeBinding:
if h.Binding == nil {
return
}
var e BindingEvent
if err := reply.Decode(&e); err == nil {
h.Binding(ctx, e)
}
case eventTypeShutdown:
if h.Shutdown == nil {
return
}
var e ShutdownEvent
if err := reply.Decode(&e); err != nil {
if err := reply.Decode(&e); err == nil {
h.Shutdown(ctx, e)
}
case eventTypeTick:
if h.Tick == nil {
return
}
h.Shutdown(ctx, e)
case eventReplyTypeTick:
case eventReplyTypeBarStatusUpdate:
var e TickEvent
if err := reply.Decode(&e); err == nil {
h.Tick(ctx, e)
}
case eventTypeBarStatusUpdate:
if h.BarStatusUpdate == nil {
return
}
var e BarStatusUpdateEvent
if err := reply.Decode(&e); err == nil {
h.BarStatusUpdate(ctx, e)
}
}
}

309
types.go

@ -1,73 +1,44 @@
package sway
type NodeID int64
type NodeType string
const (
NodeTypeRoot NodeType = "root"
NodeTypeOutput NodeType = "output"
NodeTypeCon NodeType = "con"
NodeTypeFloatingCon NodeType = "floating_con"
NodeTypeWorkspace NodeType = "workspace"
)
type BorderStyle string
const (
BorderStyleNormal BorderStyle = "normal"
BorderStyleNone BorderStyle = "none"
BorderStylePixel BorderStyle = "pixel"
BorderStyleCSD BorderStyle = "csd"
)
type Layout string
const (
LayoutSplitH Layout = "splith"
LayoutSplitV Layout = "splitv"
LayoutStacked Layout = "stacked"
LayoutTabbed Layout = "tabbed"
LayoutOutput Layout = "output"
)
import "encoding/json"
type Rect struct {
X int64 `json:"x"`
Y int64 `json:"y"`
Width int64 `json:"width"`
Height int64 `json:"height"`
X int64 `json:"x,omitempty"`
Y int64 `json:"y,omitempty"`
Width int64 `json:"width,omitempty"`
Height int64 `json:"height,omitempty"`
}
type WindowProperties struct {
Title string `json:"title"`
Instance string `json:"instance"`
Class string `json:"class"`
Role string `json:"window_role"`
TransientFor NodeID `json:"transient_for"`
Title string `json:"title,omitempty"`
Instance string `json:"instance,omitempty"`
Class string `json:"class,omitempty"`
Role string `json:"window_role,omitempty"`
TransientFor int64 `json:"transient_for,omitempty"`
}
type Node struct {
ID NodeID `json:"id"`
Name string `json:"name"`
Type NodeType `json:"type"`
Border BorderStyle `json:"border"`
CurrentBorderWidth int64 `json:"current_border_width"`
Layout Layout `json:"layout"`
Percent *float64 `json:"percent"`
Rect Rect `json:"rect"`
WindowRect Rect `json:"window_rect"`
DecoRect Rect `json:"deco_rect"`
Geometry Rect `json:"geometry"`
Urgent *bool `json:"urgent"`
Focused bool `json:"focused"`
Focus []NodeID `json:"focus"`
Nodes []*Node `json:"nodes"`
FloatingNodes []*Node `json:"floating_nodes"`
Representation *string `json:"representation"`
AppID *string `json:"app_id"`
PID *uint32 `json:"pid"`
Window *int64 `json:"window"`
WindowProperties *WindowProperties `json:"window_properties"`
ID int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Border string `json:"border,omitempty"`
CurrentBorderWidth int64 `json:"current_border_width,omitempty"`
Layout string `json:"layout,omitempty"`
Percent *float64 `json:"percent,omitempty"`
Rect Rect `json:"rect,omitempty"`
WindowRect Rect `json:"window_rect,omitempty"`
DecoRect Rect `json:"deco_rect,omitempty"`
Geometry Rect `json:"geometry,omitempty"`
Urgent *bool `json:"urgent,omitempty"`
Focused bool `json:"focused,omitempty"`
Focus []int64 `json:"focus,omitempty"`
Nodes []*Node `json:"nodes,omitempty"`
FloatingNodes []*Node `json:"floating_nodes,omitempty"`
Representation *string `json:"representation,omitempty"`
AppID *string `json:"app_id,omitempty"`
PID *uint32 `json:"pid,omitempty"`
Window *int64 `json:"window,omitempty"`
WindowProperties *WindowProperties `json:"window_properties,omitempty"`
}
func (n *Node) FocusedNode() *Node {
@ -92,52 +63,194 @@ func (n *Node) FocusedNode() *Node {
type Event interface{}
type WorkspaceChange string
const (
WorkspaceChangeInit WorkspaceChange = "init"
WorkspaceChangeEmpty WorkspaceChange = "empty"
WorkspaceChangeFocus WorkspaceChange = "focus"
WorkspaceChangeMove WorkspaceChange = "move"
WorkspaceChangeRename WorkspaceChange = "rename"
WorkspaceChangeUrgent WorkspaceChange = "urgent"
WorkspaceChangeReload WorkspaceChange = "reload"
)
type WorkspaceEvent struct {
Change WorkspaceChange `json:"change"`
Current *Node `json:"current"`
Old *Node `json:"old"`
Change string `json:"change,omitempty"`
Current *Node `json:"current,omitempty"`
Old *Node `json:"old,omitempty"`
}
type WindowChange string
const (
WindowChangeNew WindowChange = "new"
WindowChangeClose WindowChange = "close"
WindowChangeFocus WindowChange = "focus"
WindowChangeTitle WindowChange = "title"
WindowChangeFullscreenMode WindowChange = "fullscreen_mode"
WindowChangeMove WindowChange = "move"
WindowChangeFloating WindowChange = "floating"
WindowChangeUrgent WindowChange = "urgent"
WindowChangeMark WindowChange = "mark"
)
type WindowEvent struct {
Change WindowChange `json:"change"`
Container Node `json:"container"`
Change string `json:"change,omitempty"`
Container Node `json:"container,omitempty"`
}
type ShutdownChange string
const ShutdownChangeExit ShutdownChange = "exit"
type ShutdownEvent struct {
Change ShutdownChange `json:"change"`
Change string `json:"change,omitempty"`
}
type RunCommandReply struct {
Success bool `json:"success"`
Error string `json:"error"`
Success bool `json:"success,omitempty"`
Error string `json:"error,omitempty"`
}
type Workspace struct {
Num int64 `json:"num,omitempty"`
Name string `json:"name,omitempty"`
Visible bool `json:"visible,omitempty"`
Focused bool `json:"focused,omitempty"`
Urgent bool `json:"urgent,omitempty"`
Rect Rect `json:"rect,omitempty"`
Output string `json:"output,omitempty"`
}
type Refresh float64
func (r *Refresh) UnmarshalJSON(raw []byte) error {
var n int64
if err := json.Unmarshal(raw, &n); err != nil {
return err
}
*r = Refresh(float64(n) / 1000)
return nil
}
type OutputMode struct {
Width int64 `json:"width,omitempty"`
Height int64 `json:"height,omitempty"`
Refresh Refresh `json:"refresh,omitempty"`
}
type Output struct {
Name string `json:"name,omitempty"`
Make string `json:"make,omitempty"`
Model string `json:"model,omitempty"`
Serial string `json:"serial,omitempty"`
Active bool `json:"active,omitempty"`
Primary bool `json:"primary,omitempty"`
Scale float64 `json:"scale,omitempty"`
Transform string `json:"transform,omitempty"`
CurrentWorkspace string `json:"current_workspace,omitempty"`
Modes []OutputMode `json:"modes,omitempty"`
CurrentMode OutputMode `json:"current_mode,omitempty"`
Rect Rect `json:"rect,omitempty"`
}
type BarConfigGaps struct {
Top int64 `json:"top,omitempty"`
Right int64 `json:"right,omitempty"`
Bottom int64 `json:"bottom,omitempty"`
Left int64 `json:"left,omitempty"`
}
type BarConfigColors struct {
Background string `json:"background,omitempty"`
Statusline string `json:"statusline,omitempty"`
Separator string `json:"separator,omitempty"`
FocusedBackground string `json:"focused_background,omitempty"`
FocusedStatusline string `json:"focused_statusline,omitempty"`
FocusedSeparator string `json:"focused_separator,omitempty"`
FocusedWorkspaceText string `json:"focused_workspace_text,omitempty"`
FocusedWorkspaceBG string `json:"focused_workspace_bg,omitempty"`
FocusedWorkspaceBorder string `json:"focused_workspace_border,omitempty"`
ActiveWorkspaceText string `json:"active_workspace_text,omitempty"`
ActiveWorkspaceBG string `json:"active_workspace_bg,omitempty"`
ActiveWorkspaceBorder string `json:"active_workspace_border,omitempty"`
InactiveWorkspaceText string `json:"inactive_workspace_text,omitempty"`
InactiveWorkspaceBG string `json:"inactive_workspace_bg,omitempty"`
InactiveWorkspaceBorder string `json:"inactive_workspace_border,omitempty"`
UrgentWorkspaceText string `json:"urgent_workspace_text,omitempty"`
UrgentWorkspaceBG string `json:"urgent_workspace_bg,omitempty"`
UrgentWorkspaceBorder string `json:"urgent_workspace_border,omitempty"`
BindingModeText string `json:"binding_mode_text,omitempty"`
BindingModeBG string `json:"binding_mode_bg,omitempty"`
BindingModeBorder string `json:"binding_mode_border,omitempty"`
}
type BarID string
type BarConfigUpdateEvent = BarConfig
type BarConfig struct {
ID BarID `json:"id,omitempty"`
Mode string `json:"mode,omitempty"`
Position string `json:"position,omitempty"`
StatusCommand string `json:"status_command,omitempty"`
Font string `json:"font,omitempty"`
WorkspaceButtons bool `json:"workspace_buttons,omitempty"`
BindingModeIndicator bool `json:"binding_mode_indicator,omitempty"`
Verbose bool `json:"verbose,omitempty"`
Colors BarConfigColors `json:"colors,omitempty"`
Gaps BarConfigGaps `json:"gaps,omitempty"`
BarHeight int64 `json:"bar_height,omitempty"`
StatusPadding int64 `json:"status_padding,omitempty"`
StatusEdgePadding int64 `json:"status_edge_padding,omitempty"`
}
type Version struct {
Major int64 `json:"major,omitempty"`
Minor int64 `json:"minor,omitempty"`
Patch int64 `json:"patch,omitempty"`
HumanReadable string `json:"human_readable,omitempty"`
LoadedConfigFileName string `json:"loaded_config_file_name,omitempty"`
}
type Config struct {
Config string `json:"config,omitempty"`
}
type TickReply struct {
Success bool `json:"success,omitempty"`
}
type LibInput struct {
SendEvents string `json:"send_events,omitempty"`
Tap string `json:"tap,omitempty"`
TapButtonMap string `json:"tap_button_map,omitempty"`
TapDrag string `json:"tap_drag,omitempty"`
TapDragLock string `json:"tap_drag_lock,omitempty"`
AccelSpeed float64 `json:"accel_speed,omitempty"`
AccelProfile string `json:"accel_profile,omitempty"`
NaturalScroll string `json:"natural_scroll,omitempty"`
LeftHanded string `json:"left_handed,omitempty"`
ClickMethod string `json:"click_method,omitempty"`
MiddleEmulation string `json:"middle_emulation,omitempty"`
ScrollMethod string `json:"scroll_method,omitempty"`
ScrollButton int64 `json:"scroll_button,omitempty"`
DWT string `json:"dwt,omitempty"`
}
type Input struct {
Identifier string `json:"identifier,omitempty"`
Name string `json:"name,omitempty"`
Vendor int64 `json:"vendor,omitempty"`
Product int64 `json:"product,omitempty"`
Type string `json:"type,omitempty"`
XKBActiveLayoutName *string `json:"xkb_active_layout_name,omitempty"`
LibInput *LibInput `json:"libinput,omitempty"`
}
type Seat struct {
Name string `json:"name,omitempty"`
Capabilities int64 `json:"capabilities,omitempty"`
Focus int64 `json:"focus,omitempty"`
Devices []Input `json:"devices,omitempty"`
}
type ModeEvent struct {
Change string `json:"change,omitempty"`
PangoMarkup bool `json:"pango_markup,omitempty"`
}
type Binding struct {
Change string `json:"change,omitempty"`
Command string `json:"command,omitempty"`
EventStateMask []string `json:"event_state_mask,omitempty"`
InputCode int64 `json:"input_code,omitempty"`
Symbol *string `json:"symbol,omitempty"`
InputType string `json:"input_type,omitempty"`
}
type BindingEvent struct {
Change string `json:"change,omitempty"`
Binding Binding `json:"binding,omitempty"`
}
type TickEvent struct {
First bool `json:"first,omitempty"`
Payload string `json:"payload,omitempty"`
}
type BarStatusUpdateEvent struct {
ID string `json:"id,omitempty"`
VisibleByModifier bool `json:"visible_by_modifier,omitempty"`
}