| | 113 | def __init__(self, conn, *args): |
| | 114 | self.conn = conn |
| | 115 | list.__init__(self, *args) |
| | 116 | |
| | 117 | def sort(self): |
| | 118 | list.sort(self, cmp = self._sort) |
| | 119 | |
| | 120 | def _sort(self, client_a, client_b): |
| | 121 | # from: |
| | 122 | # http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#STACKINGORDER |
| | 123 | |
| | 124 | # Stacking order |
| | 125 | |
| | 126 | # To obtain good interoperability between different Desktop |
| | 127 | # Environments, the following layered stacking order is |
| | 128 | # recommended, from the bottom: |
| | 129 | # |
| | 130 | # * windows of type _NET_WM_TYPE_DESKTOP |
| | 131 | # * windows having state _NET_WM_STATE_BELOW |
| | 132 | # * windows not belonging in any other layer |
| | 133 | # * windows of type _NET_WM_TYPE_DOCK |
| | 134 | # (unless they have state _NET_WM_TYPE_BELOW) and windows |
| | 135 | # having state _NET_WM_STATE_ABOVE |
| | 136 | # * focused windows having state _NET_WM_STATE_FULLSCREEN |
| | 137 | # |
| | 138 | # Windows that are transient for another window should be kept above this |
| | 139 | # window. |
| | 140 | # |
| | 141 | # The window manager may choose to put some windows in different stacking |
| | 142 | # positions, for example to allow the user to bring currently a active |
| | 143 | # window to the top and return it back when the window looses focus. |
| | 144 | |
| | 145 | if ( self.conn.atoms['_NET_WM_WINDOW_TYPE_DESKTOP'] in client_a.window_type |
| | 146 | and self.conn.atoms['_NET_WM_WINDOW_TYPE_DESKTOP'] not in client_b.window_type): |
| | 147 | return -1 |
| | 148 | elif ( self.conn.atoms['_NET_WM_WINDOW_TYPE_DESKTOP'] not in client_a.window_type |
| | 149 | and self.conn.atoms['_NET_WM_WINDOW_TYPE_DESKTOP'] in client_b.window_type): |
| | 150 | return 1 |
| | 151 | if ( self.conn.atoms['_NET_WM_STATE_BELOW'] in client_a.state |
| | 152 | and self.conn.atoms['_NET_WM_STATE_BELOW'] not in client_b.state): |
| | 153 | return -1 |
| | 154 | elif ( self.conn.atoms['_NET_WM_STATE_BELOW'] not in client_a.state |
| | 155 | and self.conn.atoms['_NET_WM_STATE_BELOW'] in client_b.state): |
| | 156 | return 1 |
| | 157 | if ( self.conn.atoms['_NET_WM_TYPE_DOCK'] in client_a.state |
| | 158 | and self.conn.atoms['_NET_WM_TYPE_DOCK'] not in client_b.state): |
| | 159 | return -1 |
| | 160 | elif ( self.conn.atoms['_NET_WM_TYPE_DOCK'] not in client_a.state |
| | 161 | and self.conn.atoms['_NET_WM_TYPE_DOCK'] in client_b.state): |
| | 162 | return 1 |
| | 163 | if ( self.conn.atoms['_NET_WM_STATE_FULLSCREEN'] in client_a.state |
| | 164 | and self.conn.atoms['_NET_WM_STATE_FULLSCREEN'] not in client_b.state): |
| | 165 | return -1 |
| | 166 | elif ( self.conn.atoms['_NET_WM_STATE_FULLSCREEN'] not in client_a.state |
| | 167 | and self.conn.atoms['_NET_WM_STATE_FULLSCREEN'] in client_b.state): |
| | 168 | return 1 |
| | 169 | |
| | 170 | # TODO should compare x stacking order here? |
| | 171 | |
| | 172 | return 0 |
| | 173 | |
| | 174 | # define our own append so we can insert the client in the right place |
| | 175 | def append(self, client): |
| | 176 | # TODO make this much more clever... we just need to loop to the |
| | 177 | # right point |
| | 178 | list.append(self, client) |
| | 179 | #self.sort() |
| | 180 | |