88import re
99import subprocess
1010from enum import Enum
11+ from collections import deque
1112
1213
1314class 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