def __init__(self, wid): self.wid = wid self.gdk = gtk.gdk.window_foreign_new_for_display( state.gtk_display, self.wid) self.name = ewmh.get_wm_name(self.wid).reply() self.geom = self.get_geometry() self.desk = ewmh.get_wm_desktop(self.wid).reply() self.invis = gtk.Invisible() self.gdk.set_events(gtk.gdk.PROPERTY_CHANGE_MASK | gtk.gdk.STRUCTURE_MASK) self.gdk.set_user_data(self.invis) self.invis.connect('property_notify_event', self.cb_prop_change) # This is interesting; look for configure events on the decor window if state.wmname.lower() == 'openbox': pid = window.get_parent_window(self.wid) pgdk = gtk.gdk.window_foreign_new_for_display( state.gtk_display, pid) pinvis = gtk.Invisible() pgdk.set_events(gtk.gdk.STRUCTURE_MASK) pgdk.set_user_data(pinvis) pinvis.connect('configure_event', self.cb_configure) else: self.invis.connect('configure_event', self.cb_configure) self.update_state()
def __init__(self, wid): self.wid = wid self.name = ewmh.get_wm_name(self.wid).reply() or "N/A" debug("Connecting to %s" % self) window.listen(self.wid, "PropertyChange", "FocusChange") event.connect("PropertyNotify", self.wid, self.cb_property_notify) event.connect("FocusIn", self.wid, self.cb_focus_in) event.connect("FocusOut", self.wid, self.cb_focus_out) # This connects to the parent window (decorations) # We get all resize AND move events... might be too much self.parentid = window.get_parent_window(self.wid) window.listen(self.parentid, "StructureNotify") event.connect("ConfigureNotify", self.parentid, self.cb_configure_notify) debug("Parent: %s" % str(self.parentid)) # A window should only be floating if that is default self.floating = getattr(config, "floats_default", False) # Not currently in a "moving" state self.moving = False # Load some data self.desk = ewmh.get_wm_desktop(self.wid).reply() debug("Desk: %s" % str(self.desk)) # Add it to this desktop's tilers ret = tile.update_client_add(self) # does this work? debug("Ret: %s" % str(ret)) # First cut at saving client geometry self.save() debug("Init finished and save() called %s" % self)
def __init__(self, wid): self.wid = wid self.name = ewmh.get_wm_name(self.wid).reply() or 'N/A' debug('Connecting to %s' % self) window.listen(self.wid, 'PropertyChange', 'FocusChange') event.connect('PropertyNotify', self.wid, self.cb_property_notify) event.connect('FocusIn', self.wid, self.cb_focus_in) event.connect('FocusOut', self.wid, self.cb_focus_out) # This connects to the parent window (decorations) # We get all resize AND move events... might be too much self.parentid = window.get_parent_window(self.wid) window.listen(self.parentid, 'StructureNotify') event.connect('ConfigureNotify', self.parentid, self.cb_configure_notify) # A window should only be floating if that is default self.floating = config.floats_default # Not currently in a "moving" state self.moving = False # Load some data self.desk = ewmh.get_wm_desktop(self.wid).reply() # Add it to this desktop's tilers tile.update_client_add(self) # First cut at saving client geometry self.save()
def windows(result_fun, prefix_complete=False, homogenous=False, current_desk=False): global currentPrompt desks = range(0, ewmh.get_number_of_desktops().reply()) names = ewmh.get_desktop_names().reply() content = {} for d in desks: if current_desk and state.desktop != d: continue name = d if d < len(names): name = names[d] content[name] = [] clients = ewmh.get_client_list_stacking().reply() for c in reversed(clients): nm = ewmh.get_wm_desktop(c).reply() if nm < len(names): nm = names[nm] if nm in content: wm_name = ewmh.get_wm_name(c).reply() if not wm_name: wm_name = icccm.get_wm_name(c).reply() if not wm_name or not isinstance(wm_name, basestring): wm_name = 'N/A' content[nm].append((wm_name, c)) currentPrompt = Prompt(content, result_fun, prefix_complete, homogenous)
def do_output(visibles, currentdesk, names, deskcnt): out_visible = [] out_hidden = [] for visible in visibles: if visible == currentdesk: out_visible.append(markup['current'] % names[visible]) else: out_visible.append(markup['visible'] % names[visible]) clients = ewmh.get_client_list().reply() nonemptydesks = set() for client in clients: nonemptydesks.add(ewmh.get_wm_desktop(client).reply()) for d in xrange(deskcnt): if d not in visibles: if d in nonemptydesks: out_hidden.append(markup['hidden'] % names[d]) else: out_hidden.append(markup['hidden_empty'] % names[d]) print '[%s] %s' % (' '.join(out_visible), ' '.join(out_hidden)) sys.stdout.flush()
def __init__(self, wid): self.wid = wid self.gdk = gtk.gdk.window_foreign_new_for_display(state.gtk_display, self.wid) self.name = ewmh.get_wm_name(self.wid).reply() self.geom = self.get_geometry() self.desk = ewmh.get_wm_desktop(self.wid).reply() self.invis = gtk.Invisible() self.gdk.set_events(gtk.gdk.PROPERTY_CHANGE_MASK | gtk.gdk.STRUCTURE_MASK) self.gdk.set_user_data(self.invis) self.invis.connect('property_notify_event', self.cb_prop_change) # This is interesting; look for configure events on the decor window if state.wmname.lower() == 'openbox': pid = window.get_parent_window(self.wid) pgdk = gtk.gdk.window_foreign_new_for_display(state.gtk_display, pid) pinvis = gtk.Invisible() pgdk.set_events(gtk.gdk.STRUCTURE_MASK) pgdk.set_user_data(pinvis) pinvis.connect('configure_event', self.cb_configure) else: self.invis.connect('configure_event', self.cb_configure) self.update_state()
def list_mapped_windows(workspace: Optional[int] = None) -> List[Window]: mapped_window_ids = get_client_list().reply() if mapped_window_ids is None: mapped_window_ids = list() mapped_windows = [Window(wid) for wid in mapped_window_ids if wid is not None] if workspace is not None: cookies = [get_wm_desktop(wid) for wid in mapped_window_ids] workspaces = [_try_unwrap(cookie) for cookie in cookies] mapped_windows = [win for win, ws in zip(mapped_windows, workspaces) if ws == workspace] return mapped_windows
def cb_prop_change(self, widget, e): try: if e.atom == '_NET_WM_DESKTOP': newd = ewmh.get_wm_desktop(self.wid).reply() if newd is not None and newd != self.desk: oldd = self.desk self.desk = newd pager.update(oldd) pager.update(self.desk) elif e.atom == '_NET_WM_STATE': self.update_state() pager.update(self.desk) except xproto.BadWindow: pass
def goto_window(win_name_or_id): wid = win_name_or_id if isinstance(wid, basestring): clients = ewmh.get_client_list().reply() for c in clients: if wid == ewmh.get_wm_name(c).reply(): wid = c break if isinstance(wid, int): wdesk = ewmh.get_wm_desktop(wid).reply() if wdesk not in ewmh.get_visible_desktops().reply(): ewmh.request_current_desktop_checked(wdesk).check() ewmh.request_active_window_checked(wid, source=2).check()
def remove_empty_current_desktop(): # This isn't as straight-forward as decrementing _NET_NUMBER_OF_DESKTOPS. # We need to make sure we remove the right name, too. # AND only do it if there are no clients on this desktop. clients = ewmh.get_client_list().reply() cur = ewmh.get_current_desktop().reply() for c in clients: if ewmh.get_wm_desktop(c).reply() == cur: return names = ewmh.get_desktop_names().reply() if cur < len(names): names.pop(cur) ewmh.set_desktop_names_checked(names).check() # Subtract one from every client's desktop above the current one for c in clients: cdesk = ewmh.get_wm_desktop(c).reply() if cdesk > cur and cdesk != 0xffffffff: ewmh.set_wm_desktop_checked(c, cdesk - 1).check() ndesks = ewmh.get_number_of_desktops().reply() ewmh.request_number_of_desktops_checked(ndesks - 1).check()
def cb_prop_change(self, widget, e): try: if e.atom == '_NET_WM_DESKTOP': newd = ewmh.get_wm_desktop(self.wid).reply() if newd is not None and newd != self.desk: oldd = self.desk self.desk = newd pager.update(oldd) pager.update(self.desk) elif e.atom == '_NET_WM_STATE': self.update_state() pager.update(self.desk) except xcb.xproto.BadWindow: pass
def do_goto_window(letter): if letter not in marked: print("mark %s does not exist" % letter, file=sys.stderr) return wid = marked[letter] try: wdesk = ewmh.get_wm_desktop(wid).reply() desktop = ewmh.get_current_desktop().reply() visibles = ewmh.get_visible_desktops().reply() or [desktop] if wdesk is not None and wdesk not in visibles: ewmh.request_current_desktop_checked(wdesk).check() ewmh.request_active_window_checked(wid, source=1).check() except xproto.BadWindow: print("%d no longer exists" % wid, file=sys.stderr)
def do_goto_window(letter): if letter not in marked: print >> sys.stderr, 'mark %s does not exist' % letter return wid = marked[letter] try: wdesk = ewmh.get_wm_desktop(wid).reply() desktop = ewmh.get_current_desktop().reply() visibles = ewmh.get_visible_desktops().reply() or [desktop] if wdesk is not None and wdesk not in visibles: ewmh.request_current_desktop_checked(wdesk).check() ewmh.request_active_window_checked(wid, source=1).check() except xcb.xproto.BadWindow: print >> sys.stderr, '%d no longer exists' % wid
def cb_property_notify(self, e): aname = util.get_atom_name(e.atom) try: if aname == '_NET_WM_DESKTOP': if should_ignore(self.wid): untrack_client(self.wid) return olddesk = self.desk self.desk = ewmh.get_wm_desktop(self.wid).reply() if self.desk is not None and self.desk != olddesk: tile.update_client_desktop(self, olddesk) else: self.desk = olddesk elif aname == '_NET_WM_STATE': if should_ignore(self.wid): untrack_client(self.wid) return except xcb.xproto.BadWindow: pass # S'ok...
def cli(): ARGS = sys.argv[1:] bus = SessionBus() rofi_bus = bus.get('pro.wizardsoftheweb.pyrofibus') if ARGS and ARGS[0]: rofi_bus.ActivateWindow(int(ARGS[0].split(' ')[-1])) exit(0) window_ids = rofi_bus.GetWindowList() desktops = get_desktop_names().reply() items = [] max_desktop = 0 max_class = 0 max_name = 0 for window_id in window_ids: new_item = [ desktops[get_wm_desktop(window_id).reply()], get_property( window_id, 'WM_CLASS').reply().value.to_string().split('\x00')[1], get_wm_name(window_id).reply().encode('utf-8'), window_id, ] max_desktop = len( new_item[0]) if len(new_item[0]) > max_desktop else max_desktop max_class = len( new_item[1]) if len(new_item[1]) > max_class else max_class max_name = len( new_item[2]) if len(new_item[2]) > max_name else max_name items.append(new_item) items.append(items.pop(0)) for item in items: print("{:{max_desktop}} {:{max_class}} {:{max_name}} {}".format( *item, max_desktop=max_desktop + 2, max_class=max_class + 2, max_name=max_name))
def activate_window(window_id): request_current_desktop(get_wm_desktop(window_id).reply()) request_active_window(window_id)
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
def count_windows(desktop): cookies = [get_wm_desktop(window) for window in list_mapped_windows()] window_desktops = [cookie.reply() for cookie in cookies] return sum([d == desktop for d in window_desktops])
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 get_rofi_desktop_name(window_id): return DESKTOP_NAMES[get_wm_desktop(window_id).reply()]