i3

package module
v0.0.0-...-36e6ec8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2019 License: BSD-3-Clause Imports: 14 Imported by: 14

README

Build Status Go Report Card GoDoc

Package i3 provides a convenient interface to the i3 window manager via its IPC interface.

See its documentation for more details.

Advantages over other i3 IPC packages

Here comes a grab bag of features to which we paid attention. At the time of writing, most other i3 IPC packages lack at least a good number of these features:

  • Retries are transparently handled: programs using this package will recover automatically from in-place i3 restarts. Additionally, programs can be started from xsession or user sessions before i3 is even running.

  • Version checks are transparently handled: if your program uses features which are not supported by the running i3 version, helpful error messages will be returned at run time.

  • Comprehensive: the entire documented IPC interface of the latest stable i3 version is covered by this package. Tagged releases match i3’s major and minor version.

  • Consistent and familiar: once familiar with the i3 IPC protocol’s features, you should have no trouble matching the documentation to API and vice-versa.

  • Good test coverage (hard to display in a badge, as our multi-process setup breaks go test’s -coverprofile flag).

  • Implemented in pure Go, without resorting to the unsafe package.

  • Works on little and big endian architectures.

Scope

i3’s entire documented IPC interface is available in this package.

In addition, helper functions which are useful for a broad range of programs (and only those!) are provided, e.g. Node’s FindChild and FindFocused.

Packages which introduce higher-level abstractions should feel free to use this package as a building block.

Assumptions

  • The i3(1) binary must be in $PATH so that the IPC socket path can be retrieved.
  • For transparent version checks to work, the running i3 version must be ≥ 4.3 (released 2012-09-19).

Testing

Be sure to include the target i3 version (the most recent stable release) in $PATH and use go test as usual:

PATH=~/i3/build/i3:$PATH go test -v go.i3wm.org/i3

Documentation

Overview

Package i3 provides a convenient interface to the i3 window manager.

Its function and type names don’t stutter, and all functions and methods are safe for concurrent use (except where otherwise noted). The package does not import "unsafe" and hence should be widely applicable.

UNIX socket connections to i3 are transparently managed by the package. Upon any read/write errors on a UNIX socket, the package transparently retries for up to 10 seconds, but only as long as the i3 process keeps running.

The package is published in versioned releases, where the major and minor version are identical to the i3 release the package is compatible with (e.g. 4.14 implements the entire documented IPC interface of i3 4.14).

This package will only ever receive additions, so versioning should only be relevant to you if you are interested in a recently-introduced IPC feature.

Message type functions and event types are annotated with the i3 version in which they were introduced. Under the covers, they use AtLeast, so they return a helpful error message at runtime if the running i3 version is too old.

Index

Examples

Constants

This section is empty.

Variables

View Source
var IsRunningHook = func() bool {
	lastPid.Lock()
	defer lastPid.Unlock()
	if !wasRestart || lastPid.pid == 0 {
		lastPid.pid = i3Pid()
	}
	return pidValid(lastPid.pid)
}

IsRunningHook provides a method to override the method which detects if i3 is running or not

View Source
var SocketPathHook = func() (string, error) {
	out, err := exec.Command("i3", "--get-socketpath").CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("getting i3 socketpath: %v (output: %s)", err, out)
	}
	return string(out), nil
}

SocketPathHook Provides a way to override the default socket path lookup mechanism. Overriding this is unsupported.

Functions

func AtLeast

func AtLeast(major int64, minor int64) error

AtLeast returns nil if i3’s major version matches major and i3’s minor version is at least minor or newer. Otherwise, it returns an error message stating i3 is too old.

func GetBarIDs

func GetBarIDs() ([]string, error)

GetBarIDs returns an array of configured bar IDs.

GetBarIDs is supported in i3 ≥ v4.1 (2011-11-11).

func GetBindingModes

func GetBindingModes() ([]string, error)

GetBindingModes returns the names of all currently configured binding modes.

GetBindingModes is supported in i3 ≥ v4.13 (2016-11-08).

func GetMarks

func GetMarks() ([]string, error)

GetMarks returns the names of all currently set marks.

GetMarks is supported in i3 ≥ v4.1 (2011-11-11).

func IsUnsuccessful

func IsUnsuccessful(err error) bool

IsUnsuccessful is a convenience function which can be used to check if an error is a CommandUnsuccessfulError.

Example
package main

import (
	"log"

	"go.i3wm.org/i3"
)

func main() {
	cr, err := i3.RunCommand("norp")
	// “norp” is not implemented, so this command is expected to fail.
	if err != nil && !i3.IsUnsuccessful(err) {
		log.Fatal(err)
	}
	log.Printf("error for norp: %v", cr[0].Error)
}
Output:

func Restart

func Restart() error

Restart sends the restart command to i3. Sending restart via RunCommand will result in a deadlock: since i3 restarts before it sends the reply to the restart command, RunCommand will retry the command indefinitely.

Restart is supported in i3 ≥ v4.14 (2017-09-04).

Types

type BarConfig

type BarConfig struct {
	ID                   string          `json:"id"`
	Mode                 string          `json:"mode"`
	Position             string          `json:"position"`
	StatusCommand        string          `json:"status_command"`
	Font                 string          `json:"font"`
	WorkspaceButtons     bool            `json:"workspace_buttons"`
	BindingModeIndicator bool            `json:"binding_mode_indicator"`
	Verbose              bool            `json:"verbose"`
	Colors               BarConfigColors `json:"colors"`
}

BarConfig describes a serialized bar configuration block.

See https://i3wm.org/docs/ipc.html#_bar_config_reply for more details.

func GetBarConfig

func GetBarConfig(barID string) (BarConfig, error)

GetBarConfig returns the configuration for the bar with the specified barID.

Obtain the barID from GetBarIDs.

GetBarConfig is supported in i3 ≥ v4.1 (2011-11-11).

type BarConfigColors

type BarConfigColors struct {
	Background string `json:"background"`
	Statusline string `json:"statusline"`
	Separator  string `json:"separator"`

	FocusedBackground string `json:"focused_background"`
	FocusedStatusline string `json:"focused_statusline"`
	FocusedSeparator  string `json:"focused_separator"`

	FocusedWorkspaceText       string `json:"focused_workspace_text"`
	FocusedWorkspaceBackground string `json:"focused_workspace_bg"`
	FocusedWorkspaceBorder     string `json:"focused_workspace_border"`

	ActiveWorkspaceText       string `json:"active_workspace_text"`
	ActiveWorkspaceBackground string `json:"active_workspace_bg"`
	ActiveWorkspaceBorder     string `json:"active_workspace_border"`

	InactiveWorkspaceText       string `json:"inactive_workspace_text"`
	InactiveWorkspaceBackground string `json:"inactive_workspace_bg"`
	InactiveWorkspaceBorder     string `json:"inactive_workspace_border"`

	UrgentWorkspaceText       string `json:"urgent_workspace_text"`
	UrgentWorkspaceBackground string `json:"urgent_workspace_bg"`
	UrgentWorkspaceBorder     string `json:"urgent_workspace_border"`

	BindingModeText       string `json:"binding_mode_text"`
	BindingModeBackground string `json:"binding_mode_bg"`
	BindingModeBorder     string `json:"binding_mode_border"`
}

BarConfigColors describes a serialized bar colors configuration block.

See https://i3wm.org/docs/ipc.html#_bar_config_reply for more details.

type BarconfigUpdateEvent

type BarconfigUpdateEvent BarConfig

BarconfigUpdateEvent contains details about various bar config-related changes.

See https://i3wm.org/docs/ipc.html#_barconfig_update_event for more details.

type BindingEvent

type BindingEvent struct {
	Change  string `json:"change"`
	Binding struct {
		Command        string   `json:"command"`
		EventStateMask []string `json:"event_state_mask"`
		InputCode      int64    `json:"input_code"`
		Symbol         string   `json:"symbol"`
		InputType      string   `json:"input_type"`
	} `json:"binding"`
}

BindingEvent contains details about various binding-related changes.

See https://i3wm.org/docs/ipc.html#_binding_event for more details.

type BorderStyle

type BorderStyle string

BorderStyle indicates the border style of a node.

const (
	NormalBorder BorderStyle = "normal"
	NoBorder     BorderStyle = "none"
	PixelBorder  BorderStyle = "pixel"
)

i3 currently implements the following border styles:

type CommandResult

type CommandResult struct {
	// Success indicates whether the command was run without any errors.
	Success bool `json:"success"`

	// Error is a human-readable error message, non-empty for unsuccessful
	// commands.
	Error string `json:"error"`
}

CommandResult always contains Success, and command-specific fields where appropriate.

func RunCommand

func RunCommand(command string) ([]CommandResult, error)

RunCommand makes i3 run the specified command.

Error is non-nil if any CommandResult.Success is not true. See IsUnsuccessful if you send commands which are expected to fail.

RunCommand is supported in i3 ≥ v4.0 (2011-07-31).

type CommandUnsuccessfulError

type CommandUnsuccessfulError struct {
	// contains filtered or unexported fields
}

CommandUnsuccessfulError is returned by RunCommand for unsuccessful commands. This type is exported so that you can ignore this error if you expect your command(s) to fail.

func (*CommandUnsuccessfulError) Error

func (e *CommandUnsuccessfulError) Error() string

Error implements error.

type Config

type Config struct {
	Config string `json:"config"`
}

Config contains details about the configuration file.

See https://i3wm.org/docs/ipc.html#_config_reply for more details.

func GetConfig

func GetConfig() (Config, error)

GetConfig returns i3’s in-memory copy of the configuration file contents.

GetConfig is supported in i3 ≥ v4.14 (2017-09-04).

type Event

type Event interface{}

Event is an event received from i3.

Type-assert or type-switch on Event to obtain a more specific type.

type EventReceiver

type EventReceiver struct {
	// contains filtered or unexported fields
}

EventReceiver is not safe for concurrent use.

func Subscribe

func Subscribe(eventTypes ...EventType) *EventReceiver

Subscribe returns an EventReceiver for receiving events of the specified types from i3.

Unless the ordering of events matters to your use-case, you are encouraged to call Subscribe once per event type, so that you can use type assertions instead of type switches.

Subscribe is supported in i3 ≥ v4.0 (2011-07-31).

Example
package main

import (
	"log"

	"go.i3wm.org/i3"
)

func main() {
	recv := i3.Subscribe(i3.WindowEventType)
	for recv.Next() {
		ev := recv.Event().(*i3.WindowEvent)
		log.Printf("change: %s", ev.Change)
	}
	log.Fatal(recv.Close())
}
Output:

func (*EventReceiver) Close

func (r *EventReceiver) Close() error

Close closes the connection to i3. If you don’t ever call Close, you must consume events via Next to prevent i3 from deadlocking.

func (*EventReceiver) Event

func (r *EventReceiver) Event() Event

Event returns the most recent event received from i3 by a call to Next.

func (*EventReceiver) Next

func (r *EventReceiver) Next() bool

Next advances the EventReceiver to the next event, which will then be available through the Event method. It returns false when reaching an error. After Next returns false, the Close method will return the first error.

Until you call Close, you must call Next in a loop for every EventReceiver (usually in a separate goroutine), otherwise i3 will deadlock as soon as the UNIX socket buffer is full of unprocessed events.

type EventType

type EventType string

EventType indicates the specific kind of event to subscribe to.

const (
	WorkspaceEventType       EventType = "workspace"        // since 4.0
	OutputEventType          EventType = "output"           // since 4.0
	ModeEventType            EventType = "mode"             // since 4.4
	WindowEventType          EventType = "window"           // since 4.5
	BarconfigUpdateEventType EventType = "barconfig_update" // since 4.6
	BindingEventType         EventType = "binding"          // since 4.9
	ShutdownEventType        EventType = "shutdown"         // since 4.14
	TickEventType            EventType = "tick"             // since 4.15
)

i3 currently implements the following event types:

type Layout

type Layout string

Layout indicates the layout of a Node.

const (
	SplitH         Layout = "splith"
	SplitV         Layout = "splitv"
	Stacked        Layout = "stacked"
	Tabbed         Layout = "tabbed"
	DockareaLayout Layout = "dockarea"
	OutputLayout   Layout = "output"
)

i3 currently implements the following layouts:

type ModeEvent

type ModeEvent struct {
	Change      string `json:"change"`
	PangoMarkup bool   `json:"pango_markup"`
}

ModeEvent contains details about various mode-related changes.

See https://i3wm.org/docs/ipc.html#_mode_event for more details.

type Node

type Node struct {
	ID                 NodeID           `json:"id"`
	Name               string           `json:"name"` // window: title, container: internal 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"`        // absolute (= relative to X11 display)
	WindowRect         Rect             `json:"window_rect"` // window, relative to Rect
	DecoRect           Rect             `json:"deco_rect"`   // decoration, relative to Rect
	Geometry           Rect             `json:"geometry"`    // original window geometry, absolute
	Window             int64            `json:"window"`      // X11 window ID of the client window
	WindowProperties   WindowProperties `json:"window_properties"`
	Urgent             bool             `json:"urgent"` // urgency hint set
	Focused            bool             `json:"focused"`
	Focus              []NodeID         `json:"focus"`
	Nodes              []*Node          `json:"nodes"`
	FloatingNodes      []*Node          `json:"floating_nodes"`
}

Node is a node in a Tree.

See https://i3wm.org/docs/ipc.html#_tree_reply for more details.

func (*Node) FindChild

func (n *Node) FindChild(predicate func(*Node) bool) *Node

FindChild returns the first Node matching predicate, using pre-order depth-first search.

func (*Node) FindFocused

func (n *Node) FindFocused(predicate func(*Node) bool) *Node

FindFocused returns the first Node matching predicate from the sub-tree of directly and indirectly focused containers.

As an example, consider this layout tree (simplified):

 root
   │
 HDMI2
  ╱ ╲
…  workspace 1
     ╱ ╲
XTerm   Firefox

In this example, if Firefox is focused, FindFocused will return the first container matching predicate of root, HDMI2, workspace 1, Firefox (in this order).

type NodeID

type NodeID int64

NodeID is an i3-internal ID for the node, which can be used to identify containers within the IPC interface.

type NodeType

type NodeType string

NodeType indicates the specific kind of Node.

const (
	Root          NodeType = "root"
	OutputNode    NodeType = "output"
	Con           NodeType = "con"
	FloatingCon   NodeType = "floating_con"
	WorkspaceNode NodeType = "workspace"
	DockareaNode  NodeType = "dockarea"
)

i3 currently implements the following node types:

type Output

type Output struct {
	Name             string `json:"name"`
	Active           bool   `json:"active"`
	Primary          bool   `json:"primary"`
	CurrentWorkspace string `json:"current_workspace"`
	Rect             Rect   `json:"rect"`
}

Output describes an i3 output.

See https://i3wm.org/docs/ipc.html#_outputs_reply for more details.

func GetOutputs

func GetOutputs() ([]Output, error)

GetOutputs returns i3’s current outputs.

GetOutputs is supported in i3 ≥ v4.0 (2011-07-31).

type OutputEvent

type OutputEvent struct {
	Change string `json:"change"`
}

OutputEvent contains details about various output-related changes.

See https://i3wm.org/docs/ipc.html#_output_event for more details.

type Rect

type Rect struct {
	X      int64 `json:"x"`
	Y      int64 `json:"y"`
	Width  int64 `json:"width"`
	Height int64 `json:"height"`
}

Rect is a rectangle, used for various dimensions in Node, for example.

type ShutdownEvent

type ShutdownEvent struct {
	Change string `json:"change"`
}

ShutdownEvent contains the reason for which the IPC connection is about to be shut down.

See https://i3wm.org/docs/ipc.html#_shutdown_event for more details.

type SyncRequest

type SyncRequest struct {
	Window uint32 `json:"window"` // X11 window id
	Rnd    uint32 `json:"rnd"`    // Random value for distinguishing requests
}

SyncRequest represents the payload of a Sync request.

type SyncResult

type SyncResult struct {
	Success bool `json:"success"`
}

SyncResult attests the sync command was successful.

func Sync

func Sync(req SyncRequest) (SyncResult, error)

Sync sends a tick event with the provided payload.

Sync is supported in i3 ≥ v4.16 (2018-11-04).

type TickEvent

type TickEvent struct {
	First   bool   `json:"first"`
	Payload string `json:"payload"`
}

TickEvent contains the payload of the last tick command.

See https://i3wm.org/docs/ipc.html#_tick_event for more details.

type TickResult

type TickResult struct {
	Success bool `json:"success"`
}

TickResult attests the tick command was successful.

func SendTick

func SendTick(command string) (TickResult, error)

SendTick sends a tick event with the provided payload.

SendTick is supported in i3 ≥ v4.15 (2018-03-10).

type Tree

type Tree struct {
	// Root is the root node of the layout tree.
	Root *Node
}

Tree is an i3 layout tree, starting with Root.

func GetTree

func GetTree() (Tree, error)

GetTree returns i3’s layout tree.

GetTree is supported in i3 ≥ v4.0 (2011-07-31).

Example
package main

import (
	"fmt"
	"log"
	"strings"

	"go.i3wm.org/i3"
)

func main() {
	// Focus or start Google Chrome on the focused workspace.

	tree, err := i3.GetTree()
	if err != nil {
		log.Fatal(err)
	}

	ws := tree.Root.FindFocused(func(n *i3.Node) bool {
		return n.Type == i3.WorkspaceNode
	})
	if ws == nil {
		log.Fatalf("could not locate workspace")
	}

	chrome := ws.FindChild(func(n *i3.Node) bool {
		return strings.HasSuffix(n.Name, "- Google Chrome")
	})
	if chrome != nil {
		_, err = i3.RunCommand(fmt.Sprintf(`[con_id="%d"] focus`, chrome.ID))
	} else {
		_, err = i3.RunCommand(`exec google-chrome`)
	}
	if err != nil {
		log.Fatal(err)
	}
}
Output:

type Version

type Version struct {
	Major                int64  `json:"major"`
	Minor                int64  `json:"minor"`
	Patch                int64  `json:"patch"`
	Variant              string `json:"variant,omitempty"`
	HumanReadable        string `json:"human_readable"`
	LoadedConfigFileName string `json:"loaded_config_file_name"`
}

Version describes an i3 version.

See https://i3wm.org/docs/ipc.html#_version_reply for more details.

func GetVersion

func GetVersion() (Version, error)

GetVersion returns i3’s version.

GetVersion is supported in i3 ≥ v4.3 (2012-09-19).

type WindowEvent

type WindowEvent struct {
	Change    string `json:"change"`
	Container Node   `json:"container"`
}

WindowEvent contains details about various window-related changes.

See https://i3wm.org/docs/ipc.html#_window_event for more details.

type WindowProperties

type WindowProperties struct {
	Title     string `json:"title"`
	Instance  string `json:"instance"`
	Class     string `json:"class"`
	Role      string `json:"window_role"`
	Transient NodeID `json:"transient_for"`
}

WindowProperties correspond to X11 window properties

See https://build.i3wm.org/docs/ipc.html#_tree_reply

type Workspace

type Workspace struct {
	Num     int64  `json:"num"`
	Name    string `json:"name"`
	Visible bool   `json:"visible"`
	Focused bool   `json:"focused"`
	Urgent  bool   `json:"urgent"`
	Rect    Rect   `json:"rect"`
	Output  string `json:"output"`
}

Workspace describes an i3 workspace.

See https://i3wm.org/docs/ipc.html#_workspaces_reply for more details.

func GetWorkspaces

func GetWorkspaces() ([]Workspace, error)

GetWorkspaces returns i3’s current workspaces.

GetWorkspaces is supported in i3 ≥ v4.0 (2011-07-31).

type WorkspaceEvent

type WorkspaceEvent struct {
	Change  string `json:"change"`
	Current Node   `json:"current"`
	Old     Node   `json:"old"`
}

WorkspaceEvent contains details about various workspace-related changes.

See https://i3wm.org/docs/ipc.html#_workspace_event for more details.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL