def _reconfigure_floating(self, new_float_state=FLOATING): if new_float_state == MINIMIZED: self.state = IconicState self.hide() else: # make sure x, y is on the screen screen = self.qtile.find_closest_screen(self.x, self.y) if (screen is not None and self.group is not None and self.group.screen is not None and screen != self.group.screen): self.x = self.group.screen.x self.y = self.group.screen.y self.place(self.x, self.y, self.width, self.height, self.borderwidth, self.bordercolor, above=True, ) if self._float_state != new_float_state: self._float_state = new_float_state if self.group: # may be not, if it's called from hook self.group.mark_floating(self, True) hook.fire('float_change')
def unmanage(self, window): c = self.windowMap.get(window) if c: hook.fire("client_killed", c) if hasattr(c, "group"): c.group.remove(c) del self.windowMap[window]
def add(self, window): hook.fire("window_add") self.windows.add(window) window.group = self for i in self.layouts: i.add(window) self.focus(window, True)
def prevLayout(self): self.layout.hide() self.currentLayout = (self.currentLayout - 1) % (len(self.layouts)) hook.fire("layout_change", self.layouts[self.currentLayout], self) self.layoutAll() screen = self.screen.get_rect() self.layout.show(screen)
def _reconfigure_floating(self, new_float_state=FLOATING): if new_float_state == MINIMIZED: self.state = IconicState self.hide() else: # make sure x, y is on the screen screen = self.qtile.find_closest_screen(self.x, self.y) if (screen is not None and self.group is not None and self.group.screen is not None and screen != self.group.screen): self.x = self.group.screen.x self.y = self.group.screen.y self.place( self.x, self.y, self.width, self.height, self.borderwidth, self.bordercolor, above=True, ) if self._float_state != new_float_state: self._float_state = new_float_state if self.group: # may be not, if it's called from hook self.group.mark_floating(self, True) hook.fire('float_change')
def focus(self, win, warp): """ if win is in the group, blur any windows and call ``focus`` on the layout (in case it wants to track anything), fire focus_change hook and invoke layoutAll. warp - warp pointer to win """ if self.qtile._drag: # don't change focus while dragging windows return if win: if not win in self.windows: return else: self.currentWindow = win if win.floating: for l in self.layouts: l.blur() self.floating_layout.focus(win) else: self.floating_layout.blur() for l in self.layouts: l.focus(win) else: self.currentWindow = None hook.fire("focus_change") # !!! note that warp isn't hooked up now self.layoutAll(warp)
def updateHints(self): """ update the local copy of the window's WM_HINTS http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS """ h = self.window.get_wm_hints() # FIXME # h values #{ # 'icon_pixmap': 4194337, # 'icon_window': 0, # 'icon_mask': 4194340, # 'icon_y': 0, # 'input': 1, # 'icon_x': 0, # 'window_group': 4194305 # 'initial_state': 1, # 'flags': set(['StateHint', # 'IconMaskHint', # 'WindowGroupHint', # 'InputHint', # 'UrgencyHint', # 'IconPixmapHint']), #} if h and 'UrgencyHint' in h['flags']: self.hints['urgent'] = True hook.fire('client_urgent_hint_changed', self) elif self.urgent: self.hints['urgent'] = False hook.fire('client_urgent_hint_changed', self) return
def handle_EnterNotify(self, e): hook.fire("client_mouse_enter", self) if self.group.currentWindow != self: self.group.focus(self, False) if self.group.screen and self.qtile.currentScreen != self.group.screen: self.qtile.toScreen(self.group.screen.index) return True
def focus(self, win, warp): """ if win is in the group, blur any windows and call ``focus`` on the layout (in case it wants to track anything), fire focus_change hook and invoke layoutAll. warp - warp pointer to win """ if self.qtile._drag: # don't change focus while dragging windows return if win: if win not in self.windows: return else: self.currentWindow = win if win.floating: for l in self.layouts: l.blur() self.floating_layout.focus(win) else: self.floating_layout.blur() for l in self.layouts: l.focus(win) else: self.currentWindow = None hook.fire("focus_change") # !!! note that warp isn't hooked up now self.layoutAll(warp)
def focus(self, warp): if not self.hidden: if "WM_TAKE_FOCUS" in self.window.get_wm_protocols(): vals = [ 33, 32, 0, self.window.wid, self.qtile.conn.atoms["WM_PROTOCOLS"], self.qtile.conn.atoms["WM_TAKE_FOCUS"], xcb.xproto.Time.CurrentTime, 0, 0, 0, ] e = struct.pack('BBHII5I', *vals) self.window.send_event(e) if self.hints['input']: self.window.set_input_focus() try: if warp and self.qtile.config.cursor_warp: self.window.warp_pointer(self.width // 2, self.height // 2) except AttributeError: pass hook.fire("client_focus", self)
def updateHints(self): """ update the local copy of the window's WM_HINTS http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS """ try: h = self.window.get_wm_hints() normh = self.window.get_wm_normal_hints() except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return # FIXME # h values # { # 'icon_pixmap': 4194337, # 'icon_window': 0, # 'icon_mask': 4194340, # 'icon_y': 0, # 'input': 1, # 'icon_x': 0, # 'window_group': 4194305 # 'initial_state': 1, # 'flags': set(['StateHint', # 'IconMaskHint', # 'WindowGroupHint', # 'InputHint', # 'UrgencyHint', # 'IconPixmapHint']), # } if normh: normh.pop('flags') normh['min_width'] = max(0, normh.get('min_width', 0)) normh['min_height'] = max(0, normh.get('min_height', 0)) if not normh['base_width'] and \ normh['min_width'] and \ normh['width_inc']: # seems xcb does ignore base width :( normh['base_width'] = (normh['min_width'] % normh['width_inc']) if not normh['base_height'] and \ normh['min_height'] and \ normh['height_inc']: # seems xcb does ignore base height :( normh['base_height'] = (normh['min_height'] % normh['height_inc']) self.hints.update(normh) if h and 'UrgencyHint' in h['flags']: if self.qtile.currentWindow != self: self.hints['urgent'] = True hook.fire('client_urgent_hint_changed', self) elif self.urgent: self.hints['urgent'] = False hook.fire('client_urgent_hint_changed', self) if getattr(self, 'group', None): self.group.layoutAll() return
def setWindowType(self, window_type): try: oldtype = self._type except: oldtype = None self._type = window_type if self._type != oldtype: hook.fire("client_type_changed", self)
def updateName(self): try: self.name = self.window.get_wm_name() hook.fire("window_name_change") except (Xlib.error.BadWindow, Xlib.error.BadValue): # This usually means the window has just been deleted, and a new # focus will be acquired shortly. We don't raise an event for this. pass
def handle_EnterNotify(self, e): hook.fire("client_mouse_enter", self) if self.qtile.config.follow_mouse_focus and \ self.group.currentWindow != self: self.group.focus(self, False) if self.group.screen and self.qtile.currentScreen != self.group.screen: self.qtile.toScreen(self.group.screen.index) return True
def focus(self, warp): if not self.hidden and self.hints['input']: self.window.set_input_focus() try: if warp and self.qtile.config.cursor_warp: self.window.warp_pointer(self.width//2, self.height//2) except AttributeError: pass hook.fire("client_focus", self)
def focus(self, warp): if not self.hidden and self.hints['input']: self.window.set_input_focus( X.RevertToPointerRoot, X.CurrentTime ) if warp: self.window.warp_pointer(0, 0) hook.fire("client_focus", self)
def disablefloating(self): if self._float_state != NOT_FLOATING: self._float_state = NOT_FLOATING self._float_info['x'] = self.x self._float_info['y'] = self.y self._float_info['w'] = self.width self._float_info['h'] = self.height self.group.mark_floating(self, False) hook.fire('float_change')
def addGroup(self, name): if name not in self.groupMap.keys(): g = Group(name) self.groups.append(g) g._configure(self.config.layouts, self.config.floating_layout, self) self.groupMap[name] = g hook.fire("addgroup") return True return False
def focus(self, warp): if not self.hidden and self.hints['input']: self.window.set_input_focus() try: if warp and self.qtile.config.cursor_warp: self.window.warp_pointer(self.width // 2, self.height // 2) except AttributeError: pass hook.fire("client_focus", self)
def disablefloating(self): if self._float_state != NOT_FLOATING: if self._float_state == FLOATING: # store last size fi = self._float_info fi['w'] = self.width fi['h'] = self.height self._float_state = NOT_FLOATING self.group.mark_floating(self, False) hook.fire('float_change')
def add(self, window): hook.fire("group_window_add") self.windows.add(window) window.group = self if window.floating: self.floating_layout.add(window) else: for i in self.layouts: i.add(window) self.focus(window, True)
def focus(self, window, warp): if window and not window in self.windows: return if not window: self.currentWindow = None else: self.currentWindow = window self.layout.focus(window) hook.fire("focus_change") self.layoutAll()
def updateHints(self): """ update the local copy of the window's WM_HINTS http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS """ try: h = self.window.get_wm_hints() normh = self.window.get_wm_normal_hints() except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return # FIXME # h values #{ # 'icon_pixmap': 4194337, # 'icon_window': 0, # 'icon_mask': 4194340, # 'icon_y': 0, # 'input': 1, # 'icon_x': 0, # 'window_group': 4194305 # 'initial_state': 1, # 'flags': set(['StateHint', # 'IconMaskHint', # 'WindowGroupHint', # 'InputHint', # 'UrgencyHint', # 'IconPixmapHint']), #} if normh: normh.pop('flags') if(not normh['base_width'] and normh['min_width'] and normh['width_inc']): # seems xcb does ignore base width :( normh['base_width'] = (normh['min_width'] % normh['width_inc']) if(not normh['base_height'] and normh['min_height'] and normh['height_inc']): # seems xcb does ignore base height :( normh['base_height'] = (normh['min_height'] % normh['height_inc']) self.hints.update(normh) if h and 'UrgencyHint' in h['flags']: self.hints['urgent'] = True hook.fire('client_urgent_hint_changed', self) elif self.urgent: self.hints['urgent'] = False hook.fire('client_urgent_hint_changed', self) if getattr(self, 'group', None): self.group.layoutAll() return
def unmanage(self, win): c = self.windowMap.get(win) if c: hook.fire("client_killed", c) self.reset_gaps(c) if getattr(c, "group", None): c.window.unmap() c.state = window.WithdrawnState c.group.remove(c) del self.windowMap[win] self.update_client_list()
def handle_PropertyNotify(self, e): name = self.conn.atoms.get_name(e.atom) # it's the selection property if name in ("PRIMARY", "CLIPBOARD"): assert e.window == self.selection_window.wid prop = self.selection_window.get_property(e.atom, "UTF8_STRING") data = "".join([chr(i) for i in prop.value]) self.selection[name]["selection"] = data hook.fire("selection_change", name, self.selection[name])
def handle_SelectionNotify(self, e): if not getattr(e, "owner", None): return name = self.conn.atoms.get_name(e.selection) self.selection[name]["owner"] = e.owner self.selection[name]["selection"] = "" self.convert_selection(e.selection) hook.fire("selection_notify", name, self.selection[name])
def toScreen(self, n): """ Have Qtile move to screen and put focus there """ if len(self.screens) < n - 1: return old = self.currentScreen self.currentScreen = self.screens[n] if old != self.currentScreen: hook.fire("current_screen_change") self.currentGroup.focus(self.currentWindow, True)
def updateHints(self): """ update the local copy of the window's WM_HINTS http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS """ try: h = self.window.get_wm_hints() normh = self.window.get_wm_normal_hints() except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return # FIXME # h values # { # 'icon_pixmap': 4194337, # 'icon_window': 0, # 'icon_mask': 4194340, # 'icon_y': 0, # 'input': 1, # 'icon_x': 0, # 'window_group': 4194305 # 'initial_state': 1, # 'flags': set(['StateHint', # 'IconMaskHint', # 'WindowGroupHint', # 'InputHint', # 'UrgencyHint', # 'IconPixmapHint']), # } if normh: normh.pop("flags") normh["min_width"] = max(0, normh.get("min_width", 0)) normh["min_height"] = max(0, normh.get("min_height", 0)) if not normh["base_width"] and normh["min_width"] and normh["width_inc"]: # seems xcb does ignore base width :( normh["base_width"] = normh["min_width"] % normh["width_inc"] if not normh["base_height"] and normh["min_height"] and normh["height_inc"]: # seems xcb does ignore base height :( normh["base_height"] = normh["min_height"] % normh["height_inc"] self.hints.update(normh) if h and "UrgencyHint" in h["flags"]: if self.qtile.currentWindow != self: self.hints["urgent"] = True hook.fire("client_urgent_hint_changed", self) elif self.urgent: self.hints["urgent"] = False hook.fire("client_urgent_hint_changed", self) if getattr(self, "group", None): self.group.layoutAll() return
def layout(self, layout): """ "layout" is a string with matching the name of a Layout object. """ for index, obj in enumerate(self.layouts): if obj.name == layout: self.currentLayout = index hook.fire("layout_change", self.layouts[self.currentLayout], self) self.layoutAll() return raise ValueError("No such layout: %s" % layout)
def delGroup(self, name): if len(self.groups) == 1: raise ValueError("Can't delete all groups.") if name in self.groupMap.keys(): group = self.groupMap[name] prev = group.prevGroup() for i in list(group.windows): i.togroup(prev.name) if self.currentGroup.name == name: self.currentGroup.cmd_prevgroup() self.groups.remove(group) del(self.groupMap[name]) hook.fire("delgroup")
def addGroup(self, name, layout=None): if name not in self.groupMap.keys(): g = _Group(name, layout) self.groups.append(g) g._configure(self.config.layouts, self.config.floating_layout, self) self.groupMap[name] = g hook.fire("addgroup", self, name) hook.fire("changegroup") self.update_net_desktops() return True return False
def addGroup(self, name): if name not in self.groupMap.keys(): g = _Group(name) self.groups.append(g) g._configure( self.config.layouts, self.config.floating_layout, self) self.groupMap[name] = g hook.fire("addgroup", self, name) hook.fire("changegroup") self.update_net_desktops() return True return False
def loop(self): try: while 1: fds, _, _ = select.select([self.server.sock, self.conn.conn.get_file_descriptor()], [], [], 0.01) if self._exit: sys.exit(1) self.server.receive() self.xpoll() self.conn.flush() hook.fire("tick") except: # We've already written a report. if not self._exit: self.writeReport(traceback.format_exc())
def setState(self, state, val): if state not in self.possible_states: print "No such state: %s" % state return oldstate = self.states[0] if val: if self.states[0] != state: self.states.insert(0, state) else: if self.states[0] == state: self.states = self.states[1:] if not self.states: self.states = ["normal"] if oldstate != self.states[0]: hook.fire("client_state_changed", state, self)
def manage(self, w): attrs = w.get_attributes() internal = w.get_property("QTILE_INTERNAL") if attrs and attrs.override_redirect: return if not w.wid in self.windowMap: if internal: c = window.Internal(w, self) self.windowMap[w.wid] = c else: c = window.Window(w, self) hook.fire("client_new", c) self.windowMap[w.wid] = c self.currentScreen.group.add(c)
def static(self, screen, x=None, y=None, width=None, height=None): """ Makes this window a static window, attached to a Screen. If any of the arguments are left unspecified, the values given by the window itself are used instead. So, for a window that's aware of its appropriate size and location (like dzen), you don't have to specify anything. """ self.defunct = True screen = self.qtile.screens[screen] if self.group: self.group.remove(self) s = Static(self.window, self.qtile, screen, x, y, width, height) self.qtile.windowMap[self.window.wid] = s hook.fire("client_managed", s) return s
def _reconfigure_floating(self, new_float_state=FLOATING): if new_float_state == MINIMIZED: self.state = IconicState self.hide() else: # make sure x, y is on the screen screen = self.qtile.find_closest_screen(self.x, self.y) if not screen is None and \ not self.group is None and \ not self.group.screen is None and \ screen != self.group.screen: self.x = self.group.screen.x self.y = self.group.screen.y if self.width < self.hints.get('min_width', 0): self.width = self.hints['min_width'] if self.height < self.hints.get('min_height', 0): self.height = self.hints['min_height'] width = self.width if self.hints.get('width_inc', 0): width = (width - ((width - self.hints['base_width']) % self.hints['width_inc'])) height = self.height if self.hints.get('height_inc', 0): height = (height - ((height - self.hints['base_height']) % self.hints['height_inc'])) self.place( self.x, self.y, width, height, self.borderwidth, self.bordercolor, above=True, ) if self._float_state != new_float_state: self._float_state = new_float_state if self.group: # may be not, if it's called from hook self.group.mark_floating(self, True) hook.fire('float_change')
def focus(self, warp): # Workaround for misbehaving java applications (actually it might be # qtile who misbehaves by not implementing some X11 protocol correctly). # # See this xmonad issue for more information on the problem: # http://code.google.com/p/xmonad/issues/detail?id=177 # # 'sun-awt-X11-XFramePeer' is a main window of a java application. # Only send WM_TAKE_FOCUS not FocusIn # 'sun-awt-X11-XDialogPeer' is a dialog of a java application. Do not # send any event. cls = self.window.get_wm_class() or '' is_java_main = 'sun-awt-X11-XFramePeer' in cls is_java_dialog = 'sun-awt-X11-XDialogPeer' in cls is_java = is_java_main or is_java_dialog if not self.hidden: # Never send TAKE_FOCUS on java *dialogs* if (not is_java_dialog and "WM_TAKE_FOCUS" in self.window.get_wm_protocols()): vals = [ 33, 32, 0, self.window.wid, self.qtile.conn.atoms["WM_PROTOCOLS"], self.qtile.conn.atoms["WM_TAKE_FOCUS"], xcb.xproto.Time.CurrentTime, 0, 0, 0, ] e = struct.pack('BBHII5I', *vals) self.window.send_event(e) # Never send FocusIn to java windows if not is_java and self.hints['input']: self.window.set_input_focus() try: if warp and self.qtile.config.cursor_warp: self.window.warp_pointer(self.width // 2, self.height // 2) except AttributeError: pass self.qtile.root.set_property("_NET_ACTIVE_WINDOW", self.window.wid) hook.fire("client_focus", self)
def cmd_switch_groups(self, groupa, groupb): """ Switch position of groupa to groupb """ if groupa not in self.groupMap or groupb not in self.groupMap: return indexa = self.groups.index(self.groupMap[groupa]) indexb = self.groups.index(self.groupMap[groupb]) self.groups[indexa], self.groups[indexb] = \ self.groups[indexb], self.groups[indexa] hook.fire("setgroup") # update window _NET_WM_DESKTOP for group in (self.groups[indexa], self.groups[indexb]): for window in group.windows: window.group = group
def add(self, win): hook.fire("group_window_add") self.windows.add(win) win.group = self try: if win.window.get_net_wm_state() == 'fullscreen' and \ self.qtile.config.auto_fullscreen: win._float_state = window.FULLSCREEN elif self.floating_layout.match(win): # !!! tell it to float, can't set floating # because it's too early # so just set the flag underneath win._float_state = window.FLOATING except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): pass # doesn't matter if win.floating: self.floating_layout.add(win) else: for i in self.layouts: i.add(win) self.focus(win, True)
def manage(self, w): try: attrs = w.get_attributes() internal = w.get_property("QTILE_INTERNAL") except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return if attrs and attrs.override_redirect: return if not w.wid in self.windowMap: if internal: try: c = window.Internal(w, self) except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return self.windowMap[w.wid] = c else: try: c = window.Window(w, self) except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return if w.get_wm_type() == "dock" or c.strut: c.static(self.currentScreen.index) else: hook.fire("client_new", c) # Window may be defunct because # it's been declared static in hook. if c.defunct: return self.windowMap[w.wid] = c # Window may have been bound to a group in the hook. if not c.group: self.currentScreen.group.add(c) self.update_client_list() hook.fire("client_managed", c) return c else: return self.windowMap[w.wid]
def update_wm_net_icon(self): """ Set a dict with the icons of the window """ ret = self.window.get_property('_NET_WM_ICON', 'CARDINAL') if not ret: return icon = ret.value icons = {} while True: if not icon: break size = icon[:8] if len(size) != 8 or not size[0] or not size[4]: break icon = icon[8:] width = size[0] height = size[4] next_pix = width * height * 4 data = icon[:next_pix] arr = array.array("B", data) for i in range(0, len(arr), 4): mult = (arr[i + 3]) / 255. arr[i + 0] = int(arr[i + 0] * mult) arr[i + 1] = int(arr[i + 1] * mult) arr[i + 2] = int(arr[i + 2] * mult) icon = icon[next_pix:] icons["%sx%s" % (width, height)] = arr self.icons = icons hook.fire("net_wm_icon_change", self)
def delGroup(self, name): # one group per screen is needed if len(self.groups) == len(self.screens): raise ValueError("Can't delete all groups.") if name in self.groupMap.keys(): group = self.groupMap[name] if group.screen and group.screen.previous_group: target = group.screen.previous_group else: target = group.prevGroup() # Find a group that's not currently on a screen to bring to the # front. This will terminate because of our check above. while target.screen: target = target.prevGroup() for i in list(group.windows): i.togroup(target.name) if self.currentGroup.name == name: self.currentScreen.setGroup(target) self.groups.remove(group) del (self.groupMap[name]) hook.fire("delgroup", self, name) hook.fire("changegroup") self.update_net_desktops()
def setGroup(self, new_group): """ Put group on this screen """ if new_group.screen == self: return self.previous_group = self.group if new_group is None: return if new_group.screen: # g1 <-> s1 (self) # g2 (new_group) <-> s2 to # g1 <-> s2 # g2 <-> s1 g1 = self.group s1 = self g2 = new_group s2 = new_group.screen s2.group = g1 g1._setScreen(s2) s1.group = g2 g2._setScreen(s1) else: old_group = self.group self.group = new_group # display clients of the new group and then hide from old group # to remove the screen flickering new_group._setScreen(self) if old_group is not None: old_group._setScreen(None) hook.fire("setgroup") hook.fire("focus_change") hook.fire("layout_change", self.group.layouts[self.group.currentLayout], self.group)
def updateName(self): try: self.name = self.window.get_name() except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): return hook.fire("window_name_change")
def handle_ScreenChangeNotify(self, e): hook.fire("screen_change", self, e)
def __init__(self, config, displayName=None, fname=None, no_spawn=False, log=None, state=None): gobject.threads_init() self.log = log or init_log() if hasattr(config, "log_level"): self.log.setLevel(config.log_level) self.no_spawn = no_spawn if not displayName: displayName = os.environ.get("DISPLAY") if not displayName: raise QtileError("No DISPLAY set.") if not fname: # Dots might appear in the host part of the display name # during remote X sessions. Let's strip the host part first. displayNum = displayName.partition(":")[2] if not "." in displayNum: displayName = displayName + ".0" fname = command.find_sockfile(displayName) self.conn = xcbq.Connection(displayName) self.config = config self.fname = fname hook.init(self) self.keyMap = {} self.windowMap = {} self.widgetMap = {} self.groupMap = {} self.groups = [] self.keyMap = {} # Find the modifier mask for the numlock key, if there is one: nc = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"]) self.numlockMask = xcbq.ModMasks[self.conn.get_modifier(nc)] self.validMask = ~(self.numlockMask | xcbq.ModMasks["lock"]) # Because we only do Xinerama multi-screening, # we can assume that the first # screen's root is _the_ root. self.root = self.conn.default_screen.root self.root.set_attribute( eventmask=(EventMask.StructureNotify | EventMask.SubstructureNotify | EventMask.SubstructureRedirect | EventMask.EnterWindow | EventMask.LeaveWindow)) self.root.set_property( '_NET_SUPPORTED', [self.conn.atoms[x] for x in xcbq.SUPPORTED_ATOMS]) self.supporting_wm_check_window = self.conn.create_window(-1, -1, 1, 1) self.root.set_property('_NET_SUPPORTING_WM_CHECK', self.supporting_wm_check_window.wid) # TODO: maybe allow changing the name without external tools? self.supporting_wm_check_window.set_property('_NET_WM_NAME', "qtile") self.supporting_wm_check_window.set_property( '_NET_SUPPORTING_WM_CHECK', self.supporting_wm_check_window.wid) if config.main: config.main(self) if self.config.groups: key_binder = None if hasattr(self.config, 'dgroups_key_binder'): key_binder = self.config.dgroups_key_binder DGroups(self, self.config.groups, key_binder) if hasattr(config, "widget_defaults") and config.widget_defaults: _Widget.global_defaults = config.widget_defaults else: _Widget.global_defaults = {} for i in self.groups: self.groupMap[i.name] = i self.currentScreen = None self.screens = [] self._process_screens() self.currentScreen = self.screens[0] self._drag = None self.ignoreEvents = set([ xcb.xproto.KeyReleaseEvent, xcb.xproto.ReparentNotifyEvent, xcb.xproto.CreateNotifyEvent, # DWM handles this to help "broken focusing windows". xcb.xproto.MapNotifyEvent, xcb.xproto.LeaveNotifyEvent, xcb.xproto.FocusOutEvent, xcb.xproto.FocusInEvent, xcb.xproto.NoExposureEvent ]) self.conn.flush() self.conn.xsync() self._xpoll() self.server = command._Server(self.fname, self, config) # Map and Grab keys for key in self.config.keys: self.mapKey(key) # It fixes problems with focus when clicking windows of some specific clients like xterm def noop(qtile): pass self.config.mouse += (Click([], "Button1", command.lazy.function(noop), focus="after"), ) self.mouseMap = {} for i in self.config.mouse: if self.mouseMap.get(i.button_code) is None: self.mouseMap[i.button_code] = [] self.mouseMap[i.button_code].append(i) self.grabMouse() hook.fire("startup") self.scan() self.update_net_desktops() hook.subscribe.setgroup(self.update_net_desktops) if state: st = pickle.load(StringIO(state)) st.apply(self)