Created
May 8, 2023 18:00
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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