Skip to content

kraftwerk28/lua-i3ipc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lua-i3ipc

A Lua (LuaJIT) framework for controlling i3wm and Sway through IPC. Uses libuv bindings for I/O.

Currently supports Lua 5.1 (LuaJIT 2.0.5)

Table of contents

Installation and running

  1. Install the library

    • Arch Linux

      Install the lua-i3ipc-git package with an AUR helper of your choice:

      $ yay -S lua-i3ipc-git
  2. Create a file, i.e. myscript.lua and import the library:

    -- myscript.lua
    #!/usr/bin/env luajit
    local i3 = require("i3ipc")
    i3.main(function(ipc)
      local tree = ipc:get_tree()
      local focused_node = tree:find_focused()
      print("app_id: " .. focused_node.app_id)
      print("name:   " .. focused_node.name)
    end)
  3. Make the script executable:

    $ chmod 744 myscript.lua
  4. Put the script invocation in your i3/Sway config, using exec command

API

main(callback)

The entry point of the library, which you typically would use Takes a callback with one parameter, Connection

Parameters:

  • callback: function - function with one parameter (Connection)

Example:

local i3ipc = require("i3ipc")
i3ipc.main(function(conn)
  -- Invoke methods on `conn`
end)

Class Connection

A wrapper around unix socket connection to Sway/I3 socket.

Connection:new()

Initialize connection.

Returns: Connection.

Connection:send(type, payload)

Send a message to socket.

Parameters:

Returns: IPC reply, (i.e. { { success = true } }).

Connection:command(command)

Send a command. Equivalent to Connection:send(i3.COMMAND.RUN_COMMAND, command).

Parameters:

  • command: string - command to send

Returns: command reply, (e.g. { {success = true} }).

Connection:on(event, callback)

Subscribe to event.

Parameters:

  • event: i3.EVENT
  • callback: function - function with event as a parameter

Example:

conn:on(i3.EVENT.WINDOW, function(ipc, event)
  print(event.container.name)
end)

Connection:once(event, callback)

Subscribe to event, unsubscribe after one is received.

Parameters:

  • event: i3.EVENT
  • callback: function - function with event as a parameter.

Connection:off(event, callback)

Remove subscription to event.

Parameters:

  • event: i3.EVENT
  • callback: function - previously registered callback

Connection:get_tree()

Get layout tree.

Returns: Tree.

Class Tree

A Lua table, representing tree layout, with additional methods that are accessible via metatable.

Tree:find_con(predicate, opts)

Find con by predicate.

Parameters:

  • predicate: function - function with parameter that represents con and return true if that con matches
  • opts: table | nil - traverse options

Returns: matched con, or nil.

Example:

i3.main(function(ipc)
  local firefox = ipc:get_tree():find_con(function(con)
    return con.app_id == "firefox"
  end)
end)

Tree:find_all(predicate, opts)

Find all matched con's by predicate.

Parameters:

  • predicate: function - function with parameter that represents con and return true if that con matches
  • opts: table | nil - traverse options

Tree:find_focused()

Find focused node.

Returns: focused con.

Tree:walk_focus(cb)

Traverse con's through focus array on each node. Useful for searching for a parent of the focused con, for example.

Returns: focused con.

Connection:get_*

Bound methods for Connection in lowercase that correspond to GET_* commands in the spec.

Class Cmd

A member of Connection class for receiving commands from anyone through UNIX socket.

Cmd:on(command, callback)

register a handler for the command.

Parameters:

  • predicate: function - function with parameter that represents con and return true if that con matches

Traverse options

Is a table with the following type

{
  search_method = "bfs" | "dfs" | nil, -- default "bfs"
  check_only = "tiling" | "floating" | nil, -- default "tiling"
}

Examples

  1. Display a notification when switching to a workspace:

    local i3 = require"i3ipc"
    local EVENT, COMMAND = i3.EVENT, i3.COMMAND
    i3.main(function(conn)
      conn:once("workspace", function(ipc, event)
        local cmd = "exec notify-send 'switched to workspace %d'"
        conn:command(cmd:format(event.current.name))
      end)
    end)
  2. Switch back-and-forth between windows (Like Alt+F4 on some DE's):

    local i3 = require("i3ipc")
    local ipc = Connection:new()
    ipc:main(function()
      local focus_now, focus_prev
      do
        local focused_con = ipc:get_tree():find_focused()
        if focused_con then
          focus_now = focused_con.id
        end
      end
      ipc.cmd:on("focus_prev", function(ipc)
        if not focus_prev then return end
        ipc:command(("[con_id=%d] focus"):format(focus_prev))
      end)
      ipc:on("window::focus", function(ipc, event)
        focus_prev = focus_now
        focus_now = event.container.id
      end)
    end)

    then, in sway config, add the following bindsym:

    bindsym $mod+Tab nop focus_prev
    

Also check out examples for more useful snippets.

About

A Lua framework for controlling i3wm or sway

Topics

Resources

License

Stars

Watchers

Forks

Languages