Skip to content

Commit c4d9ee4

Browse files
author
Tony Crisci
committed
Add descendents iterator to Con
You can now iterate through the Con to get a generator of all the descendents. fixes #66
1 parent 26b2972 commit c4d9ee4

2 files changed

Lines changed: 32 additions & 22 deletions

File tree

README.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ Example
6565
for container in i3.get_tree().find_fullscreen():
6666
container.command('fullscreen')
6767
68+
# Print the names of all the containers in the tree
69+
root = i3.get_tree()
70+
print(root.name)
71+
for con in root:
72+
print(con.name)
73+
6874
# Define a callback to be called when you switch workspaces.
6975
def on_workspace_focus(self, e):
7076
# The first parameter is the connection to the ipc and the second is an object

i3ipc/i3ipc.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import subprocess
1010
from enum import Enum
11+
from collections import deque
1112

1213

1314
class MessageType(Enum):
@@ -875,6 +876,20 @@ def __init__(self, data, parent, conn):
875876
if 'gaps' in data:
876877
self.gaps = Gaps(data['gaps'])
877878

879+
def __iter__(self):
880+
"""
881+
Iterate through the descendents of this node (breadth-first tree traversal)
882+
"""
883+
queue = deque()
884+
queue.append(self)
885+
886+
while queue:
887+
con = queue.popleft()
888+
if not con is self:
889+
yield con
890+
891+
queue.extend(con.nodes)
892+
878893
def root(self):
879894
"""
880895
Retrieves the root container.
@@ -899,18 +914,7 @@ def descendents(self):
899914
900915
:rtype: List of :class:`Con`.
901916
"""
902-
descendents = []
903-
904-
def collect_descendents(con):
905-
for c in con.nodes:
906-
descendents.append(c)
907-
collect_descendents(c)
908-
for c in con.floating_nodes:
909-
descendents.append(c)
910-
collect_descendents(c)
911-
912-
collect_descendents(self)
913-
return descendents
917+
return [c for c in self]
914918

915919
def leaves(self):
916920
"""
@@ -922,7 +926,7 @@ def leaves(self):
922926
"""
923927
leaves = []
924928

925-
for c in self.descendents():
929+
for c in self:
926930
if not c.nodes and c.type == "con" and c.parent.type != "dockarea":
927931
leaves.append(c)
928932

@@ -978,45 +982,45 @@ def find_focused(self):
978982
:rtype class Con:
979983
"""
980984
try:
981-
return next(c for c in self.descendents() if c.focused)
985+
return next(c for c in self if c.focused)
982986
except StopIteration:
983987
return None
984988

985989
def find_by_id(self, id):
986990
try:
987-
return next(c for c in self.descendents() if c.id == id)
991+
return next(c for c in self if c.id == id)
988992
except StopIteration:
989993
return None
990994

991995
def find_by_window(self, window):
992996
try:
993-
return next(c for c in self.descendents() if c.window == window)
997+
return next(c for c in self if c.window == window)
994998
except StopIteration:
995999
return None
9961000

9971001
def find_by_role(self, pattern):
998-
return [c for c in self.descendents()
1002+
return [c for c in self
9991003
if c.window_role and re.search(pattern, c.window_role)]
10001004

10011005
def find_named(self, pattern):
1002-
return [c for c in self.descendents()
1006+
return [c for c in self
10031007
if c.name and re.search(pattern, c.name)]
10041008

10051009
def find_classed(self, pattern):
1006-
return [c for c in self.descendents()
1010+
return [c for c in self
10071011
if c.window_class and re.search(pattern, c.window_class)]
10081012

10091013
def find_instanced(self, pattern):
1010-
return [c for c in self.descendents()
1014+
return [c for c in self
10111015
if c.window_instance and re.search(pattern, c.window_instance)]
10121016

10131017
def find_marked(self, pattern=".*"):
10141018
pattern = re.compile(pattern)
1015-
return [c for c in self.descendents()
1019+
return [c for c in self
10161020
if any(pattern.search(mark) for mark in c.marks)]
10171021

10181022
def find_fullscreen(self):
1019-
return [c for c in self.descendents()
1023+
return [c for c in self
10201024
if c.type == 'con' and c.fullscreen_mode]
10211025

10221026
def workspace(self):

0 commit comments

Comments
 (0)