############################################################################## ### The history window placement algorithm. ebind historyplacement.place ### ### to the ob.EventAction.PlaceWindow event to use it. ### ############################################################################## import windowplacement, config, hooks def place(data): """Place a window usingthe history placement algorithm.""" _place(data) export_functions = place ############################################################################## config.add('historyplacement', 'ignore_requested_positions', 'Ignore Requested Positions', "When true, the placement algorithm will attempt to place " + \ "windows even when they request a position (like XMMS can)." + \ "Note this only applies to 'normal' windows, not to special " + \ "cases like desktops and docks.", 'boolean', 0) config.add('historyplacement', 'dont_duplicate', "Don't Diplicate", "When true, if 2 copies of the same match in history are to be " + \ "placed before one of them is closed (so it would be placed " + \ "over-top of the last one), this will cause the second window to "+\ "not be placed via history, and the 'Fallback Algorithm' will be "+\ "used instead.", 'boolean', 1) config.add('historyplacement', 'filename', 'History Database Filename', "The name of the file where history data will be stored. The " + \ "number of the screen is appended onto this name. The file will " +\ "be placed in ~/.openbox/.", 'string', 'historydb') config.add('historyplacement', 'fallback', 'Fallback Algorithm', "The window placement algorithm that will be used when history " + \ "placement does not have a place for the window.", 'enum', windowplacement.random, options = windowplacement.export_functions) ########################################################################### ########################################################################### ### Internal stuff, should not be accessed outside the module. ### ########################################################################### import ob, os, string _data = [] class _State: def __init__(self, resname, resclass, role, x, y): self.resname = resname self.resclass = resclass self.role = role self.x = x self.y = y self.placed = 0 def __eq__(self, other): if self.resname == other.resname and \ self.resclass == other.resclass and \ self.role == other.role: return 1 return 0 def _load(): global _data try: file = open(os.environ['HOME'] + '/.openbox/' + \ config.get('historyplacement', 'filename') + \ "." + str(ob.Openbox.screenNumber()), 'r') # read data for line in file.readlines(): line = line[:-1] # drop the '\n' try: s = string.split(line, '\0') state = _State(s[0], s[1], s[2], int(s[3]), int(s[4])) _data.append(state) except ValueError: pass except IndexError: pass file.close() except IOError: pass def _save(): file = open(os.environ['HOME'] + '/.openbox/'+ \ config.get('historyplacement', 'filename') + \ "." + str(ob.Openbox.screenNumber()), 'w') if file: for i in _data: file.write(i.resname + '\0' + i.resclass + '\0' + i.role + '\0' + str(i.x) + '\0' + str(i.y) + '\n') file.close() def _create_state(client): area = client.area() return _State(client.resName(), client.resClass(), client.role(), area[0], area[1]) def _place(client): state = _create_state(client) try: print "looking for : " + state.resname + " : " + \ state.resclass + " : " + state.role try: i = _data.index(state) except ValueError: print "No match in history" else: coords = _data[i] # get the equal element print "Found in history ("+str(coords.x)+","+\ str(coords.y)+")" if not (config.get('historyplacement', 'dont_duplicate') \ and coords.placed): coords.placed = 1 if ob.Openbox.state() != ob.State.Starting: # if not (config.get('historyplacement', 'ignore_requested_positions') \ # and data.client.normal()): # if data.client.positionRequested(): return ca = client.area() client.setArea((coords.x, coords.y, ca[2], ca[3])) return else: print "Already placed another window there" except TypeError: pass fallback = config.get('historyplacement', 'fallback') if fallback: fallback(client) def _save_window(client): global _data state = _create_state(client) print "looking for : " + state.resname + " : " + state.resclass + \ " : " + state.role try: print "replacing" i = _data.index(state) _data[i] = state # replace it except ValueError: print "appending" _data.append(state) hooks.startup.append(_load) hooks.shutdown.append(_save) hooks.closed.append(_save_window) print "Loaded historyplacement.py"