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"