code: def invalidation_hash(self):
          
  #        if not self.root:
  #            return '<empty-window>'
  
          def _hash_for_split(split):
              result = []
              for item in split:
                  if isinstance(item, (VSplit, HSplit)):
                      result.append(_hash_for_split(item))
                  elif isinstance(item, Pane):
                      result.append('p%s' % item.pane_id)
  
              if isinstance(split, HSplit):
                  return 'HSplit(%s)' % (','.join(result))
              else:
                  return 'VSplit(%s)' % (','.join(result))
  
          return '<window_id=%s,zoom=%s,children=%s>' % (
              self.window_id, self.zoom, _hash_for_split(self.root))
docs: Return a hash (string) that can be used to determine when the layout
          has to be rebuild.