Source code for libqtile.dgroups

import collections

import libqtile.hook
from libqtile.config import Key
from libqtile.command import lazy
from libqtile.config import Group
from libqtile.config import Rule
from libqtile.config import Match

[docs]def simple_key_binder(mod, keynames=None): """ Bind keys to mod+group position or to the keys specified as second argument. """ def func(dgroup): # unbind all for key in dgroup.keys[:]: dgroup.qtile.unmapKey(key) dgroup.keys.remove(key) if keynames: keys = keynames else: # keys 1 to 9 and 0 keys = list(map(str, list(range(1, 10)) + [0])) # bind all keys for keyname, group in zip(keys, dgroup.qtile.groups): name = key = Key([mod], keyname,[name].toscreen()) key_s = Key([mod, "shift"], keyname, lazy.window.togroup(name)) key_c = Key( [mod, "control"], keyname, ) dgroup.keys.append(key) dgroup.keys.append(key_s) dgroup.keys.append(key_c) dgroup.qtile.mapKey(key) dgroup.qtile.mapKey(key_s) dgroup.qtile.mapKey(key_c) return func
class DGroups(object): """ Dynamic Groups """ def __init__(self, qtile, dgroups, key_binder=None, delay=1): self.qtile = qtile self.groups = dgroups self.groupMap = {} self.rules = [] self.rules_map = {} self.last_rule_id = 0 for rule in getattr(qtile.config, 'dgroups_app_rules', []): self.add_rule(rule) self.keys = [] self.key_binder = key_binder self._setup_hooks() self._setup_groups() self.delay = delay self.timeout = {} def add_rule(self, rule, last=True): rule_id = self.last_rule_id self.rules_map[rule_id] = rule if last: self.rules.append(rule) else: self.rules.insert(0, rule) self.last_rule_id += 1 return rule_id def remove_rule(self, rule_id): rule = self.rules_map.get(rule_id, None) if rule: self.rules.remove(rule) del self.rules_map[rule_id] else: self.qtile.log.warn('Rule "%s" not found' % rule_id) def add_dgroup(self, group, start=False): self.groupMap[] = group rules = [Rule(m, for m in group.matches] self.rules.extend(rules) if start: self.qtile.addGroup(, group.layout, group.layouts) def _setup_groups(self): for group in self.groups: self.add_dgroup(group, group.init) if group.spawn and not self.qtile.no_spawn: pid = self.qtile.cmd_spawn(group.spawn) self.add_rule(Rule(Match(net_wm_pid=[pid]), def _setup_hooks(self): libqtile.hook.subscribe.addgroup(self._addgroup) libqtile.hook.subscribe.client_new(self._add) libqtile.hook.subscribe.client_killed(self._del) if self.key_binder: libqtile.hook.subscribe.setgroup( lambda: self.key_binder(self) ) libqtile.hook.subscribe.changegroup( lambda: self.key_binder(self) ) def _addgroup(self, qtile, group_name): if group_name not in self.groupMap: self.add_dgroup(Group(group_name, persist=False)) def _add(self, client): if client in self.timeout:'Remove dgroup source') self.timeout.pop(client).cancel() # ignore static windows if client.defunct: return group_set = False intrusive = False for rule in self.rules: # Matching Rules if rule.matches(client): if try: layout = self.groupMap[].layout except KeyError: layout = None try: layouts = self.groupMap[].layouts except KeyError: layouts = None group_added = self.qtile.addGroup(, layout, layouts) client.togroup( group_set = True group_obj = self.qtile.groupMap[] group = self.groupMap.get( if group and group_added: for k, v in list(group.layout_opts.items()): if isinstance(v, collections.Callable): v(group_obj.layout) else: setattr(group_obj.layout, k, v) affinity = group.screen_affinity if affinity and len(self.qtile.screens) > affinity: self.qtile.screens[affinity].setGroup(group_obj) if rule.float: client.enablefloating() if rule.intrusive: intrusive = rule.intrusive if rule.break_on_match: break # If app doesn't have a group if not group_set: current_group = if current_group in self.groupMap and \ self.groupMap[current_group].exclusive and \ not intrusive: wm_class = client.window.get_wm_class() if wm_class: if len(wm_class) > 1: wm_class = wm_class[1] else: wm_class = wm_class[0] group_name = wm_class else: group_name = or 'Unnamed' self.add_dgroup(Group(group_name, persist=False), start=True) client.togroup(group_name) self.sort_groups() def sort_groups(self): self.qtile.groups.sort(key=lambda g: self.groupMap[].position)"setgroup") def _del(self, client): group = def delete_client(): # Delete group if empty and dont persist if group and in self.groupMap and \ not self.groupMap[].persist and \ len( <= 0: self.qtile.delGroup( self.sort_groups() # Wait the delay until really delete the group'Add dgroup timer') self.timeout[client] = self.qtile._eventloop.call_later( self.delay, delete_client )