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)
-
Install the library
-
Arch Linux
Install the
lua-i3ipc-gitpackage with an AUR helper of your choice:$ yay -S lua-i3ipc-git
-
-
Create a file, i.e.
myscript.luaand 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)
-
Make the script executable:
$ chmod 744 myscript.lua
-
Put the script invocation in your i3/Sway config, using
execcommand
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)A wrapper around unix socket connection to Sway/I3 socket.
Initialize connection.
Returns: Connection.
Send a message to socket.
Parameters:
type: i3.COMMANDpayload:string- raw payload
Returns: IPC reply, (i.e. { { success = true } }).
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} }).
Subscribe to event.
Parameters:
event: i3.EVENTcallback:function- function with event as a parameter
Example:
conn:on(i3.EVENT.WINDOW, function(ipc, event)
print(event.container.name)
end)Subscribe to event, unsubscribe after one is received.
Parameters:
event: i3.EVENTcallback:function- function with event as a parameter.
Remove subscription to event.
Parameters:
event: i3.EVENTcallback:function- previously registered callback
Get layout tree.
Returns: Tree.
A Lua table, representing tree layout, with additional methods that are accessible via metatable.
Find con by predicate.
Parameters:
predicate:function- function with parameter that representsconand return true if thatconmatchesopts: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)Find all matched con's by predicate.
Parameters:
predicate:function- function with parameter that representsconand return true if thatconmatchesopts:table | nil- traverse options
Find focused node.
Returns: focused con.
Traverse con's through focus array on each node. Useful for searching for a
parent of the focused con, for example.
Returns: focused con.
Bound methods for Connection in lowercase that correspond to GET_* commands
in the spec.
A member of Connection class for receiving commands from
anyone through UNIX socket.
register a handler for the command.
Parameters:
predicate:function- function with parameter that representsconand return true if thatconmatches
Is a table with the following type
{
search_method = "bfs" | "dfs" | nil, -- default "bfs"
check_only = "tiling" | "floating" | nil, -- default "tiling"
}-
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)
-
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.