Skip to content

Instantly share code, notes, and snippets.

@m-bartlett
Created May 8, 2023 18:00
Show Gist options
  • Save m-bartlett/91ab79004f9d8601b76b6457e253f450 to your computer and use it in GitHub Desktop.
Save m-bartlett/91ab79004f9d8601b76b6457e253f450 to your computer and use it in GitHub Desktop.
Get IPC window properties from clicking on a window in the sway window manager (swaywm). Requires slurp.
#!/usr/bin/env python
import i3ipc
import subprocess
import json
def node_contains_point(node, x, y):
"""Determine if the given point (x,y) is contained by the given node's boundary"""
r = node.rect
return all((x > r.x,
x < (r.x + r.width),
y > r.y,
y < (r.y + r.height)))
def depth_first_search(node, x, y):
"""
Perform depth-first-search to identify the first window that contains the given point (x,y).
Floating nodes are checked first since they are always drawn on top of tiled windows. This also
checks the floating nodes which have been focused most recently (given by the `focus` attribute)
since they will be drawn on top of other floating nodes.
"""
floating_nodes_by_id = {n.id: n for n in node.floating_nodes}
floating_nodes_ordered = [n for node_id in node.focus if (n:=floating_nodes_by_id.get(node_id))]
children = floating_nodes_ordered+node.nodes
if not children and node.ipc_data.get('visible') and node_contains_point(node, x, y):
return node
for node in children:
if (d := depth_first_search(node, x, y)):
return d
def main():
i3 = i3ipc.Connection()
point_data = json.loads(subprocess.getoutput('slurp -p -f \'{"x":%X,"y":%Y,"o":"%o"}\''))
x, y, output_name = point_data['x'], point_data['y'], point_data['o']
output = next(o for o in i3.get_outputs() if o.name == output_name)
output_workspace_name = output.current_workspace
workspace = next(w for w in i3.get_tree().workspaces() if w.name == output_workspace_name)
focused_leaf = depth_first_search(workspace, x, y)
focused_leaf.command('focus')
print(json.dumps(focused_leaf.ipc_data))
if __name__ == "__main__":
exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment