def activate(self): # we don't know where we are... if not self.screen: return PROBE.window_activate(self.xobj) State.reload_active(self)
def reload_active(active = None, force = False): if not active: activeid = PROBE.get_active_window_id() else: activeid = active.id # Check to make sure we need to probe for anything... if not force and activeid and State._DESKTOP and State._DESKTOP._VIEWPORT and State._DESKTOP._VIEWPORT._SCREEN: current = State._DESKTOP._VIEWPORT._SCREEN.get_active() if current and current.id == activeid: return State._DESKTOP = State.get_desktops()[PROBE.get_desktop()] if not activeid: if not State._DESKTOP._VIEWPORT: State._DESKTOP._VIEWPORT = State._DESKTOP.viewports[0] if not State._DESKTOP._VIEWPORT._SCREEN: State._DESKTOP._VIEWPORT._SCREEN = State._DESKTOP._VIEWPORT.screens[0] else: for viewport in State._DESKTOP.viewports.values(): for screen in viewport.screens.values(): if activeid in screen.windows: State._DESKTOP._VIEWPORT = viewport State._DESKTOP._VIEWPORT._SCREEN = screen State._DESKTOP._VIEWPORT._SCREEN.set_active(screen.windows[activeid]) break
def reload_active(active=None, force=False): if not active: activeid = PROBE.get_active_window_id() else: activeid = active.id # Check to make sure we need to probe for anything... if not force and activeid and State._DESKTOP and State._DESKTOP._VIEWPORT and State._DESKTOP._VIEWPORT._SCREEN: current = State._DESKTOP._VIEWPORT._SCREEN.get_active() if current and current.id == activeid: return State._DESKTOP = State.get_desktops()[PROBE.get_desktop()] if not activeid: if not State._DESKTOP._VIEWPORT: State._DESKTOP._VIEWPORT = State._DESKTOP.viewports[0] if not State._DESKTOP._VIEWPORT._SCREEN: State._DESKTOP._VIEWPORT._SCREEN = State._DESKTOP._VIEWPORT.screens[ 0] else: for viewport in State._DESKTOP.viewports.values(): for screen in viewport.screens.values(): if activeid in screen.windows: State._DESKTOP._VIEWPORT = viewport State._DESKTOP._VIEWPORT._SCREEN = screen State._DESKTOP._VIEWPORT._SCREEN.set_active( screen.windows[activeid]) break
def register_hotkeys(): for mapping in Config.KEYMAP: callback = Config.KEYMAP[mapping] codes = mapping.split('-') mods = codes[:-1] key = codes[-1] # No key? if not key: print( 'Could not map %s to %s' % (mapping, callback), file = sys.stderr ) continue # generate key code and mod mask... keycode = PROBE.generate_keycode(key) modmask = PROBE.generate_modmask(mods) # Tell X we want to hear about it when this key is pressed... try: PROBE.grab_key(keycode, modmask) except: print('Nada:', callback) # Finally register the key with the dispatcher... State.register_hotkey(keycode, modmask, callback)
def unregister_hotkeys(): for mapping in Config.KEYMAP: callback = Config.KEYMAP[mapping] codes = mapping.split('-') mods = codes[:-1] key = codes[-1] # No key? if not key: print >> sys.stderr, "Could not map %s to %s" % (mapping, callback) continue # generate key code and mod mask... keycode = PROBE.generate_keycode(key) modmask = PROBE.generate_modmask(mods) # Tell X we want to hear about it when this key is pressed... try: PROBE.ungrab_key(keycode, modmask) except: print "Nada:", callback # And finally reset the dispatcher... State._DISPATCHER = {}
def resize(self, x, y, width, height): if width < 1 or height < 1 or not self.screen.is_in_screen(x, y, width, height): return PROBE.window_resize(self.xobj, x, y, width, height) self.x = x self.y = y self.width = width self.height = height
def resize(self, x, y, width, height): if width < 1 or height < 1 or not self.screen.is_in_screen( x, y, width, height): return PROBE.window_resize(self.xobj, x, y, width, height) self.x = x self.y = y self.width = width self.height = height
def load_desktops(): # initialize all desktops and their associated windows for desk in PROBE.get_desktops().values(): desktop = Desktop(desk) for viewport in desktop.viewports.values(): for screen in viewport.screens.values(): desk_or_view = desktop.id if PROBE.is_compiz(): desk_or_view = viewport.id screen.set_tiler(Config.tilers(Config.tiling(screen.id, desk_or_view)))
def __init__(self, screen, attrs): self.update_attributes(attrs) self.x = 0 self.y = 0 self.origx = attrs['x'] self.origy = attrs['y'] self.origwidth = self.width self.origheight = self.height self.screen = screen if self.xobj: PROBE.window_listen(self.xobj)
def load_desktops(): # initialize all desktops and their associated windows for desk in PROBE.get_desktops().values(): desktop = Desktop(desk) for viewport in desktop.viewports.values(): for screen in viewport.screens.values(): desk_or_view = desktop.id if PROBE.is_compiz(): desk_or_view = viewport.id screen.set_tiler( Config.tilers(Config.tiling(screen.id, desk_or_view)))
def load_window(window_id): attrs = PROBE.get_window_by_id(window_id) if not attrs['popup'] and attrs['desktop'] in State.get_desktops(): for viewport in State.get_desktops()[attrs['desktop']].viewports.values(): if viewport.is_on_viewport(attrs['x'], attrs['y']): for screen in viewport.screens.values(): if screen.is_on_screen(attrs['x'], attrs['y']): win = Window(screen, attrs) if not win.filtered(): screen.add_window(win) screen.needs_tiling() if win.id == PROBE.get_active_window_id(): win.activate()
def load_window(window_id): attrs = PROBE.get_window_by_id(window_id) if not attrs['popup'] and attrs['desktop'] in State.get_desktops(): for viewport in State.get_desktops()[ attrs['desktop']].viewports.values(): if viewport.is_on_viewport(attrs['x'], attrs['y']): for screen in viewport.screens.values(): if screen.is_on_screen(attrs['x'], attrs['y']): win = Window(screen, attrs) if not win.filtered(): screen.add_window(win) screen.needs_tiling() if win.id == PROBE.get_active_window_id(): win.activate()
def load_screens(self): screens = PROBE.get_screens() for screen in screens: obj = Screen(self, screen) obj.x += self.x obj.y += self.y self.screens[screen['id']] = obj
def scan_all_windows(): ret = [] windows = PROBE.get_window_list() for window in windows: ret.append(window) return ret
def refresh(self): oldscreen = self.screen oldviewport = oldscreen.viewport olddesk = oldviewport.desktop oldstate = self.hidden update = PROBE.get_window(self.xobj) # So this is a little bit weird- we're updating the window, but while # we care about it's new x,y (screen change?), we don't care about it's # new width and height. We're tiling, so we're in complete control of # width and height. (The key here is that x/y *completely* determines # which screen the window is on.) Therefore, we don't update them- but # why? It would seem harmless, except that some windows (like terminals, # text editors, etc) set width_inc/height_inc hints which standards # compliant window managers honor- like OpenBox. Therefore, the WM could # be resizing the width/height of a given window slightly differently than # what PyTyle thinks it's at. This causes the width/height to change slightly # on each window update, and has a cascading effect that mangles the # window's size. YUCK. (And these width_inc/height_inc hints seemingly # cannot be reset.) update['width'] = self.width update['height'] = self.height self.update_attributes(update) if olddesk.id != self.desktop or not oldviewport.is_on_viewport( update['x'], update['y']) or not oldscreen.is_on_screen( update['x'], update['y']): for viewport in State.get_desktops()[ self.desktop].viewports.values(): if viewport.is_on_viewport(update['x'], update['y']): for screen in viewport.screens.values(): if screen.is_on_screen(update['x'], update['y']): oldscreen.delete_window(self) screen.add_window(self) screen.needs_tiling() oldscreen.needs_tiling() self.screen = screen elif oldstate != self.hidden: self.screen.needs_tiling() # If it's the active window, then make sure PyTyle knows that. We don't # want to set input focus (well, it should already have it if X tells us # it's the active window) because it will generate another window change # event, and we end up in a positive feedback loop. Yuck. if self.id == PROBE.get_active_window_id(): State.reload_active()
def refresh_desktops(): for desk in PROBE.get_desktops().values(): if desk['id'] in State.get_desktops(): desktop = State.get_desktops()[desk['id']] desktop.update_attributes(desk) for viewport in desktop.viewports.values(): for screen in viewport.screens.values(): screen.needs_tiling()
def scan_new_windows(): ret = [] windows = PROBE.get_window_list() for window in windows: if hex(window) not in State.get_windows(): ret.append(window) return ret
def refresh(self): oldscreen = self.screen oldviewport = oldscreen.viewport olddesk = oldviewport.desktop oldstate = self.hidden update = PROBE.get_window(self.xobj) # So this is a little bit weird- we're updating the window, but while # we care about it's new x,y (screen change?), we don't care about it's # new width and height. We're tiling, so we're in complete control of # width and height. (The key here is that x/y *completely* determines # which screen the window is on.) Therefore, we don't update them- but # why? It would seem harmless, except that some windows (like terminals, # text editors, etc) set width_inc/height_inc hints which standards # compliant window managers honor- like OpenBox. Therefore, the WM could # be resizing the width/height of a given window slightly differently than # what PyTyle thinks it's at. This causes the width/height to change slightly # on each window update, and has a cascading effect that mangles the # window's size. YUCK. (And these width_inc/height_inc hints seemingly # cannot be reset.) update['width'] = self.width update['height'] = self.height self.update_attributes(update) if olddesk.id != self.desktop or not oldviewport.is_on_viewport(update['x'], update['y']) or not oldscreen.is_on_screen(update['x'], update['y']): for viewport in State.get_desktops()[self.desktop].viewports.values(): if viewport.is_on_viewport(update['x'], update['y']): for screen in viewport.screens.values(): if screen.is_on_screen(update['x'], update['y']): oldscreen.delete_window(self) screen.add_window(self) screen.needs_tiling() oldscreen.needs_tiling() self.screen = screen elif oldstate != self.hidden: self.screen.needs_tiling() # If it's the active window, then make sure PyTyle knows that. We don't # want to set input focus (well, it should already have it if X tells us # it's the active window) because it will generate another window change # event, and we end up in a positive feedback loop. Yuck. if self.id == PROBE.get_active_window_id(): State.reload_active()
def __init__(self, desktop, attrs): self.update_attributes(attrs) self._SCREEN = None self.desktop = desktop if PROBE.is_compiz(): self.width = self.desktop.width self.height = self.desktop.height else: self.width = self.desktop.resx self.height = self.desktop.resy self.screens = {} self.load_screens()
def restore(self): PROBE.window_reset(self.xobj)
def save_geometry(self): geom = PROBE.get_window_geometry(self.xobj) self.origx = geom['x'] self.origy = geom['y'] self.origwidth = geom['width'] self.origheight = geom['height']
def __init__(self): self._event = PROBE.get_display().next_event()
def close(self): PROBE.window_close(self.xobj)
def get_wm_name(): return PROBE.get_wm_name()
def lives(self): try: PROBE.get_window_geometry(self.xobj) except: return False return True
def add_decorations(self): PROBE.window_add_decorations(self.xobj) self.static = True
def remove_decorations(self): PROBE.window_remove_decorations(self.xobj) self.static = False
def remove_static_property(self): PROBE.window_remove_static(self.xobj)
def is_windowlist_change(self): if self._event and self._event.type == X.PropertyNotify and self._event.atom == PROBE.atom("_NET_CLIENT_LIST"): return True return False
def stack_lower(self): PROBE.window_stackbelow(self.xobj)
def maximize(self): PROBE.window_maximize(self.xobj)
def stack_raise(self): PROBE.window_stackabove(self.xobj)
def load_viewports(self): viewports = PROBE.get_viewports() for viewport in viewports: obj = Viewport(self, viewport) self.viewports[viewport['id']] = obj
def is_workarea_change(self): if self._event and self._event.type == X.PropertyNotify and self._event.atom == PROBE.atom("_NET_WORKAREA"): return True return False
def is_window_change(self): if self._event and ((self._event.type == X.ConfigureNotify and self._event.event != PROBE.get_root()) or (self._event.type == X.PropertyNotify and self._event.atom == PROBE.atom("_NET_WM_DESKTOP"))): return True return False
def is_state_change(self): if self._event and self._event.type == X.PropertyNotify and self._event.atom == PROBE.atom("WM_STATE"): return True return False