def __init__(self, wid): GeometryWindow.__init__(self, wid) self._properties = core.ListProperties(self.id) self._protocols = icccm.get_wm_protocols(conn, self.id) self._hints = icccm.get_wm_hints(conn, self.id) self._normal_hints = icccm.get_wm_normal_hints(conn, self.id) self._class = icccm.get_wm_class(conn, self.id) self._motif = motif.get_hints(conn, self.id) self._wmname = ewmh.get_wm_name(conn, self.id) self._wmclass = icccm.get_wm_class(conn, self.id)
def properties(self) -> Dict: """Get a dictionary with the window class and instance.""" # Properties are cached after the first call to this function and so might not necessarily # be correct if the properties are changed between calls. This is acceptable for our # purposes because Windows are short-lived objects. if not self._properties: try: reply = get_wm_class(self.id).reply() except (struct.error, WindowError) as e: raise WMError("Invalid window: %s", self.id) from e try: self._properties = {"window_id": reply[0], "window_class": reply[1]} except TypeError: pass return self._properties
def icon_for_window(window): """Try all window classes and use the first one we have an icon for.""" name = get_wm_name(window.window).reply() classes = get_wm_class(window.window).reply() if name: name = name[0].split()[0] if name in WINDOW_ICONS: return WINDOW_ICONS[name] if classes: for cls in classes: cls = cls.lower() # case-insensitive matching if cls in WINDOW_ICONS: return WINDOW_ICONS[cls] logging.info('No icon available for window with classes: %s' % str(classes)) return DEFAULT_ICON
def should_ignore(client): # Don't waste time on clients we'll never possibly tile if client in ignore: return True nm = ewmh.get_wm_name(client).reply() wm_class = icccm.get_wm_class(client).reply() if wm_class is not None: try: inst, cls = wm_class matchNames = set([inst.lower(), cls.lower()]) if matchNames.intersection(config.ignore): debug('Ignoring %s because it is in the ignore list' % nm) return True if hasattr(config, 'tile_only') and config.tile_only: if not matchNames.intersection(config.tile_only): debug('Ignoring %s because it is not in the tile_only ' 'list' % nm) return True except ValueError: pass if icccm.get_wm_transient_for(client).reply() is not None: debug('Ignoring %s because it is transient' % nm) ignore.append(client) return True wtype = ewmh.get_wm_window_type(client).reply() if wtype: for atom in wtype: aname = util.get_atom_name(atom) if aname in ('_NET_WM_WINDOW_TYPE_DESKTOP', '_NET_WM_WINDOW_TYPE_DOCK', '_NET_WM_WINDOW_TYPE_TOOLBAR', '_NET_WM_WINDOW_TYPE_MENU', '_NET_WM_WINDOW_TYPE_UTILITY', '_NET_WM_WINDOW_TYPE_SPLASH', '_NET_WM_WINDOW_TYPE_DIALOG', '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU', '_NET_WM_WINDOW_TYPE_POPUP_MENU', '_NET_WM_WINDOW_TYPE_TOOLTIP', '_NET_WM_WINDOW_TYPE_NOTIFICATION', '_NET_WM_WINDOW_TYPE_COMBO', '_NET_WM_WINDOW_TYPE_DND'): debug('Ignoring %s because it has type %s' % (nm, aname)) ignore.append(client) return True wstate = ewmh.get_wm_state(client).reply() if wstate is None: debug('Ignoring %s because it does not have a state' % nm) return True for atom in wstate: aname = util.get_atom_name(atom) # For now, while I decide how to handle these guys if aname == '_NET_WM_STATE_STICKY': debug('Ignoring %s because it is sticky and they are weird' % nm) return True if aname in ('_NET_WM_STATE_SHADED', '_NET_WM_STATE_HIDDEN', '_NET_WM_STATE_FULLSCREEN', '_NET_WM_STATE_MODAL'): debug('Ignoring %s because it has state %s' % (nm, aname)) return True d = ewmh.get_wm_desktop(client).reply() if d == 0xffffffff: debug('Ignoring %s because it\'s on all desktops' \ '(not implemented)' % nm) return True return False
def should_ignore(client): debug("Entering should_ignore %s" % str(client)) # debug_object(clients) # debug("This client: %s" % str(client)) # Don't waste time on clients we'll never possibly tile if client in ignore: # debug("Ignoring client %s" % client) # debug("Ignore is:") # debug(ignore) return True nm = ewmh.get_wm_name(client).reply() wm_class = icccm.get_wm_class(client).reply() if wm_class is not None: try: inst, cls = wm_class matchNames = set([inst.lower(), cls.lower()]) if matchNames.intersection(config.ignore): debug("Ignoring %s because it is in the ignore list" % nm) return True if hasattr(config, "tile_only") and config.tile_only: if not matchNames.intersection(config.tile_only): debug("Ignoring %s because it is not in the tile_only " "list" % nm) debug("Ignoring client %s" % client) return True except ValueError: pass if icccm.get_wm_transient_for(client).reply() is not None: debug("Ignoring %s because it is transient" % nm) ignore.append(client) return True wtype = ewmh.get_wm_window_type(client).reply() if wtype: for atom in wtype: aname = util.get_atom_name(atom) if aname in ( "_NET_WM_WINDOW_TYPE_DESKTOP", "_NET_WM_WINDOW_TYPE_DOCK", "_NET_WM_WINDOW_TYPE_TOOLBAR", "_NET_WM_WINDOW_TYPE_MENU", "_NET_WM_WINDOW_TYPE_UTILITY", "_NET_WM_WINDOW_TYPE_SPLASH", "_NET_WM_WINDOW_TYPE_DIALOG", "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", "_NET_WM_WINDOW_TYPE_POPUP_MENU", "_NET_WM_WINDOW_TYPE_TOOLTIP", "_NET_WM_WINDOW_TYPE_NOTIFICATION", "_NET_WM_WINDOW_TYPE_COMBO", "_NET_WM_WINDOW_TYPE_DND", ): debug("Ignoring %s because it has type %s" % (nm, aname)) ignore.append(client) return True wstate = ewmh.get_wm_state(client).reply() if wstate is None: debug("Ignoring %s because it does not have a state" % nm) return True for atom in wstate: aname = util.get_atom_name(atom) # For now, while I decide how to handle these guys if aname == "_NET_WM_STATE_STICKY": debug("Ignoring %s because it is sticky and they are weird" % nm) return True if aname in ( "_NET_WM_STATE_SHADED", "_NET_WM_STATE_HIDDEN", "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_MODAL", ): debug("Ignoring %s because it has state %s" % (nm, aname)) return True d = ewmh.get_wm_desktop(client).reply() if d == 0xFFFFFFFF: debug("Ignoring %s because it's on all desktops" "(not implemented)" % nm) return True debug("Not ignoring client %s" % client) return False