From bf6077fc0c280df62d94c12213092e7592ce267c Mon Sep 17 00:00:00 2001 From: Tordarus Date: Mon, 15 Sep 2025 14:35:55 +0200 Subject: [PATCH] updated for Niri Version 25.08 --- model_action.go | 30 +++++++++++++++--- model_event.go | 57 +++++++++++++++++++++++++++-------- model_window_layout_change.go | 36 ++++++++++++++++++++++ utils.go | 32 ++++++++++++++++++++ 4 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 model_window_layout_change.go diff --git a/model_action.go b/model_action.go index 9ed7d54..ca291d1 100644 --- a/model_action.go +++ b/model_action.go @@ -26,6 +26,10 @@ func ActionSpawn(command []string) Action { return ActionCustom("Spawn", map[string]any{"command": command}) } +func ActionSpawnSh(command string) Action { + return ActionCustom("SpawnSh", map[string]any{"command": command}) +} + func ActionDoScreenTransition(delay Option[time.Duration]) Action { return ActionCustom("DoScreenTransition", map[string]any{"delay_ms": mapOption(delay, time.Duration.Milliseconds)}) } @@ -266,12 +270,12 @@ func ActionFocusWorkspacePrevious() Action { return ActionCustom("FocusWorkspacePrevious", map[string]any{}) } -func ActionMoveWindowToWorkspaceDown() Action { - return ActionCustom("MoveWindowToWorkspaceDown", map[string]any{}) +func ActionMoveWindowToWorkspaceDown(focus bool) Action { + return ActionCustom("MoveWindowToWorkspaceDown", map[string]any{"focus": focus}) } -func ActionMoveWindowToWorkspaceUp() Action { - return ActionCustom("MoveWindowToWorkspaceUp", map[string]any{}) +func ActionMoveWindowToWorkspaceUp(focus bool) Action { + return ActionCustom("MoveWindowToWorkspaceUp", map[string]any{"focus": focus}) } func ActionMoveWindowToWorkspace(id Option[WindowID], reference WorkspaceReferenceArg, focus bool) Action { @@ -335,7 +339,7 @@ func ActionFocusMonitorNext() Action { } func ActionFocusMonitor(output OutputName) Action { - return ActionCustom("FocusMonitorNext", map[string]any{"output": output}) + return ActionCustom("FocusMonitor", map[string]any{"output": output}) } func ActionMoveWindowToMonitorLeft() Action { @@ -410,14 +414,26 @@ func ActionSwitchPresetColumnWidth() Action { return ActionCustom("SwitchPresetColumnWidth", map[string]any{}) } +func ActionSwitchPresetColumnWidthBack() Action { + return ActionCustom("SwitchPresetColumnWidthBack", map[string]any{}) +} + func ActionSwitchPresetWindowWidth(id Option[WindowID]) Action { return ActionCustom("SwitchPresetWindowWidth", map[string]any{"id": id}) } +func ActionSwitchPresetWindowWidthBack(id Option[WindowID]) Action { + return ActionCustom("SwitchPresetWindowWidthBack", map[string]any{"id": id}) +} + func ActionSwitchPresetWindowHeight(id Option[WindowID]) Action { return ActionCustom("SwitchPresetWindowHeight", map[string]any{"id": id}) } +func ActionSwitchPresetWindowHeightBack(id Option[WindowID]) Action { + return ActionCustom("SwitchPresetWindowHeightBack", map[string]any{"id": id}) +} + func ActionMaximizeColumn() Action { return ActionCustom("MaximizeColumn", map[string]any{}) } @@ -545,3 +561,7 @@ func ActionSetWindowUrgent(id Option[WindowID]) Action { func ActionUnsetWindowUrgent(id Option[WindowID]) Action { return ActionCustom("UnsetWindowUrgent", map[string]any{"id": id}) } + +func ActionLoadConfigFile() Action { + return ActionCustom("LoadConfigFile", map[string]any{}) +} diff --git a/model_event.go b/model_event.go index 41b7ea4..3054bf9 100644 --- a/model_event.go +++ b/model_event.go @@ -7,18 +7,25 @@ type Event interface { } type eventContainer struct { - EventWorkspacesChanged *EventWorkspacesChanged `json:"WorkspacesChanged"` - EventWorkspaceUrgencyChanged *EventWorkspaceUrgencyChanged `json:"WorkspaceUrgencyChanged"` - EventWorkspaceActivated *EventWorkspaceActivated `json:"WorkspaceActivated"` - EventWorkspaceActiveWindowChanged *EventWorkspaceActiveWindowChanged `json:"WorkspaceActiveWindowChanged"` - EventWindowsChanged *EventWindowsChanged `json:"WindowsChanged"` - EventWindowOpenedOrChanged *EventWindowOpenedOrChanged `json:"WindowOpenedOrChanged"` - EventWindowClosed *EventWindowClosed `json:"WindowClosed"` - EventWindowFocusChanged *EventWindowFocusChanged `json:"WindowFocusChanged"` - EventWindowUrgencyChanged *EventWindowUrgencyChanged `json:"WindowUrgencyChanged"` - EventKeyboardLayoutsChanged *EventKeyboardLayoutsChanged `json:"KeyboardLayoutsChanged"` - EventKeyboardLayoutSwitched *EventKeyboardLayoutSwitched `json:"KeyboardLayoutSwitched"` - EventOverviewOpenedOrClosed *EventOverviewOpenedOrClosed `json:"OverviewOpenedOrClosed"` + EventWorkspacesChanged *EventWorkspacesChanged `json:"WorkspacesChanged,omitempty"` + EventWorkspaceUrgencyChanged *EventWorkspaceUrgencyChanged `json:"WorkspaceUrgencyChanged,omitempty"` + EventWorkspaceActivated *EventWorkspaceActivated `json:"WorkspaceActivated,omitempty"` + EventWorkspaceActiveWindowChanged *EventWorkspaceActiveWindowChanged `json:"WorkspaceActiveWindowChanged,omitempty"` + EventWindowsChanged *EventWindowsChanged `json:"WindowsChanged,omitempty"` + EventWindowOpenedOrChanged *EventWindowOpenedOrChanged `json:"WindowOpenedOrChanged,omitempty"` + EventWindowClosed *EventWindowClosed `json:"WindowClosed,omitempty"` + EventWindowFocusChanged *EventWindowFocusChanged `json:"WindowFocusChanged,omitempty"` + EventWindowUrgencyChanged *EventWindowUrgencyChanged `json:"WindowUrgencyChanged,omitempty"` + EventWindowLayoutsChanged *EventWindowLayoutsChanged `json:"WindowLayoutsChanged,omitempty"` + EventKeyboardLayoutsChanged *EventKeyboardLayoutsChanged `json:"KeyboardLayoutsChanged,omitempty"` + EventKeyboardLayoutSwitched *EventKeyboardLayoutSwitched `json:"KeyboardLayoutSwitched,omitempty"` + EventOverviewOpenedOrClosed *EventOverviewOpenedOrClosed `json:"OverviewOpenedOrClosed,omitempty"` + EventConfigLoaded *EventConfigLoaded `json:"ConfigLoaded,omitempty"` +} + +func (m *eventContainer) String() string { + data, _ := json.Marshal(m) + return string(data) } func (c *eventContainer) event() Event { @@ -40,12 +47,16 @@ func (c *eventContainer) event() Event { return c.EventWindowFocusChanged } else if c.EventWindowUrgencyChanged != nil { return c.EventWindowUrgencyChanged + } else if c.EventWindowLayoutsChanged != nil { + return c.EventWindowLayoutsChanged } else if c.EventKeyboardLayoutsChanged != nil { return c.EventKeyboardLayoutsChanged } else if c.EventKeyboardLayoutSwitched != nil { return c.EventKeyboardLayoutSwitched } else if c.EventOverviewOpenedOrClosed != nil { return c.EventOverviewOpenedOrClosed + } else if c.EventConfigLoaded != nil { + return c.EventConfigLoaded } return &EventInvalid{} @@ -164,6 +175,17 @@ func (m *EventWindowUrgencyChanged) String() string { return string(data) } +type EventWindowLayoutsChanged struct { + Changes []WindowLayoutChange `json:"changes"` +} + +func (m *EventWindowLayoutsChanged) private() {} + +func (m *EventWindowLayoutsChanged) String() string { + data, _ := json.Marshal(m) + return string(data) +} + type EventKeyboardLayoutsChanged struct { KeyboardLayouts KeyboardLayouts `json:"keyboard_layouts"` } @@ -196,3 +218,14 @@ func (m *EventOverviewOpenedOrClosed) String() string { data, _ := json.Marshal(m) return string(data) } + +type EventConfigLoaded struct { + Failed bool `json:"failed"` +} + +func (m *EventConfigLoaded) private() {} + +func (m *EventConfigLoaded) String() string { + data, _ := json.Marshal(m) + return string(data) +} diff --git a/model_window_layout_change.go b/model_window_layout_change.go new file mode 100644 index 0000000..ed1c3fc --- /dev/null +++ b/model_window_layout_change.go @@ -0,0 +1,36 @@ +package niri + +import ( + "encoding/json" + "fmt" +) + +type WindowLayoutChange struct { + WindowID WindowID + WindowLayout WindowLayout +} + +func (m *WindowLayoutChange) UnmarshalJSON(data []byte) error { + arr := []any{} + if err := json.Unmarshal(data, &arr); err != nil { + return err + } + + if len(arr) != 2 { + return fmt.Errorf("expected array of length 2 but got array of length %d", len(arr)) + } + + if wid, ok := arr[0].(float64); !ok { + return fmt.Errorf("expected array element at index 0 to be of type int") + } else { + m.WindowID = WindowID(wid) + } + + if windowLayout, err := reencodeJson[WindowLayout](arr[1]); err != nil { + return fmt.Errorf("expected array element at index 1 to be of type WindowLayout") + } else if windowLayout != nil { + m.WindowLayout = *windowLayout + } + + return nil +} diff --git a/utils.go b/utils.go index 0f470a4..0fb78fa 100644 --- a/utils.go +++ b/utils.go @@ -1,6 +1,7 @@ package niri import ( + "bufio" "bytes" "context" "encoding/json" @@ -8,6 +9,7 @@ import ( "io" "net" "os" + "sync" ) func notNull(c *Client) bool { @@ -85,6 +87,8 @@ func readSocketGeneric[T any](ctx context.Context, socket string, body io.Reader if errors.Is(err, io.EOF) { return } else { + // JSON parsing errors + //fmt.Println(err) continue } } @@ -113,3 +117,31 @@ func asJsonReader(v any) io.Reader { data, _ := json.Marshal(v) return bytes.NewReader(append(data, '\n')) } + +func reencodeJson[T any](data any) (*T, error) { + r, w := io.Pipe() + defer w.Close() + defer r.Close() + + wbuf := bufio.NewWriter(w) + rbuf := bufio.NewReader(r) + + wg := &sync.WaitGroup{} + + value := new(T) + + var encErr error + wg.Go(func() { encErr = json.NewEncoder(wbuf).Encode(data); wbuf.Flush() }) + + var decErr error + wg.Go(func() { decErr = json.NewDecoder(rbuf).Decode(value) }) + + wg.Wait() + if encErr != nil { + return nil, encErr + } else if decErr != nil { + return nil, decErr + } + + return value, nil +}