all repos — openbox @ 6e29605d41cab8fd7e8ad6f28d6132bbd521f106

openbox fork - make it a bit more like ryudo

python/historyplacement.py (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
##############################################################################
### 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"