1 ##############################################################################
2 ### The history window placement algorithm. ebind historyplacement.place ###
3 ### to the ob.EventAction.PlaceWindow event to use it. ###
4 ##############################################################################
6 import windowplacement, config, hooks
9 """Place a window usingthe history placement algorithm."""
12 export_functions = place
14 ##############################################################################
16 config.add('historyplacement',
17 'ignore_requested_positions',
18 'Ignore Requested Positions',
19 "When true, the placement algorithm will attempt to place " + \
20 "windows even when they request a position (like XMMS can)." + \
21 "Note this only applies to 'normal' windows, not to special " + \
22 "cases like desktops and docks.",
25 config.add('historyplacement',
28 "When true, if 2 copies of the same match in history are to be " + \
29 "placed before one of them is closed (so it would be placed " + \
30 "over-top of the last one), this will cause the second window to "+\
31 "not be placed via history, and the 'Fallback Algorithm' will be "+\
35 config.add('historyplacement',
37 'History Database Filename',
38 "The name of the file where history data will be stored. The " + \
39 "number of the screen is appended onto this name. The file will " +\
40 "be placed in ~/.openbox/.",
43 config.add('historyplacement',
46 "The window placement algorithm that will be used when history " + \
47 "placement does not have a place for the window.",
49 windowplacement.random,
50 options = windowplacement.export_functions)
52 ###########################################################################
54 ###########################################################################
55 ### Internal stuff, should not be accessed outside the module. ###
56 ###########################################################################
63 def __init__(self, resname, resclass, role, x, y):
64 self.resname = resname
65 self.resclass = resclass
70 def __eq__(self, other):
71 if self.resname == other.resname and \
72 self.resclass == other.resclass and \
73 self.role == other.role:
80 file = open(os.environ['HOME'] + '/.openbox/' + \
81 config.get('historyplacement', 'filename') + \
82 "." + str(ob.Openbox.screenNumber()), 'r')
84 for line in file.readlines():
85 line = line[:-1] # drop the '\n'
87 s = string.split(line, '\0')
88 state = _State(s[0], s[1], s[2],
93 except ValueError: pass
94 except IndexError: pass
99 file = open(os.environ['HOME'] + '/.openbox/'+ \
100 config.get('historyplacement', 'filename') + \
101 "." + str(ob.Openbox.screenNumber()), 'w')
104 file.write(i.resname + '\0' +
111 def _create_state(client):
113 return _State(client.resName(), client.resClass(),
114 client.role(), area[0], area[1])
117 state = _create_state(client)
119 print "looking for : " + state.resname + " : " + \
120 state.resclass + " : " + state.role
122 i = _data.index(state)
124 print "No match in history"
126 coords = _data[i] # get the equal element
127 print "Found in history ("+str(coords.x)+","+\
129 if not (config.get('historyplacement', 'dont_duplicate') \
132 if ob.Openbox.state() != ob.State.Starting:
133 # if not (config.get('historyplacement', 'ignore_requested_positions') \
134 # and data.client.normal()):
135 # if data.client.positionRequested(): return
137 client.setArea((coords.x, coords.y, ca[2], ca[3]))
140 print "Already placed another window there"
143 fallback = config.get('historyplacement', 'fallback')
144 if fallback: fallback(client)
146 def _save_window(client):
148 state = _create_state(client)
149 print "looking for : " + state.resname + " : " + state.resclass + \
154 i = _data.index(state)
155 _data[i] = state # replace it
160 hooks.startup.append(_load)
161 hooks.shutdown.append(_save)
162 hooks.closed.append(_save_window)
164 print "Loaded historyplacement.py"