class SXLayoutMgr(Plugin): key = 'layoutmgr' def __init__(self, app): self.layouters = OrderedDict() self.register(FloatingLayout) self.register(MaxLayout) self.register(VertLayout) self.register(HorizLayout) self.app = app app.push_handlers(self) # register actions app.plugins['actions'].register('layoutmgr.set_layout', self.action_set_layout) app.plugins['actions'].register('layoutmgr.cycle', self.action_cycle) def action_set_layout(self, info): """ set the layout of the current desktop. parameters: `name`: str identifier of the layout needed: `screen` """ self.attach_layouter( info['screen'].data['desktops'].active_desktop, self.layouters[info['name']] ) def action_cycle(self, info): """ cycle the layouts for the current desktop parameters: `offset`: int offset to cycle, defaults to +1 needed: `screen` """ offset = info.get('offset', 1) desktop = info['screen'].data['desktops'].active_desktop layouter_cls = self.get_data(desktop).__class__ current_name = getattr(layouter_cls, 'name', layouter_cls.__name__) keys = self.layouters.keys() length = len(keys) index = keys.index(current_name) new_index = ((index or length) + offset) % length new_layouter_cls = self.layouters[keys[new_index]] self.attach_layouter(desktop, new_layouter_cls) def register(self, layouter_cls): name = getattr(layouter_cls, 'name', layouter_cls.__name__) log.info('registering layouter %s = %s', name, layouter_cls) self.layouters[name] = layouter_cls def on_ready(self, app): # should potentially do this in on_create_screen but # that means making sure desktop.on_create_screen is called # first... for screen in app.screens: screendata = screen.data['desktops'] screendata.push_handlers(self) for desktop in screendata.desktops: log.debug('trying to attach to %s...', desktop) layouter_name = desktop.config.get('layout') if not layouter_name: log.debug('no layouter_name') continue layouter_cls = self.layouters.get(layouter_name) if not layouter_cls: log.error('cant find layouter %s', name) return self.attach_layouter(desktop, layouter_cls) def attach_layouter(self, desktop, layouter_cls): """ attach the layouter class *layouter_cls* to *desktop*. That will overwrite any layouter that was attached before. """ if self.has_data(desktop): self.get_data(desktop).detach() self.remove_data(desktop) log.debug('attached %s', layouter_cls) layouter = layouter_cls(desktop) self.attach_data_to(desktop, layouter) #desktop.push_handlers(on_rearrange=self.on_rearrange) # rearrange it automatically layouter.layout()