1 import ob, config, hooks, focus
2 from input import Pointer, Keyboard
4 config.add('stackedcycle',
5 'activate_while_cycling',
6 'Activate While Cycling',
7 "If this is True then windows will be activated as they are" + \
8 "highlighted in the cycling list (except iconified windows).",
12 config.add('stackedcycle',
14 'Raise After Cycling',
15 "If this is True, the selected window will be raised as well as " +\
20 config.add('stackedcycle',
21 'include_all_desktops',
22 'Include Windows From All Desktops',
23 "If this is True then windows from all desktops will be included" +\
24 " in the stacking list.",
28 config.add('stackedcycle',
31 "If this is True then windows which are iconified on the current" +\
32 " desktop will be included in the stacking list.",
36 config.add('stackedcycle',
37 'include_icons_all_desktops',
38 'Include Icons From All Desktops',
39 "If this is True then windows which are iconified from all " +\
40 "desktops will be included in the stacking list (if Include Icons"+\
45 config.add('stackedcycle',
46 'include_omnipresent',
47 'Include Omnipresent Windows',
48 "If this is True then windows which are on all-desktops at once " +\
49 "will be included in the stacking list.",
53 def next(keydata, client): _cycle(keydata, client, True)
54 def previous(keydata, client): _cycle(keydata, client, False)
56 def _shouldAdd(client):
57 """Determines if a client should be added to the cycling list."""
58 curdesk = ob.Openbox.desktop()
59 desk = client.desktop()
61 if not (client.normal() and client.canFocus()): return False
62 if config.get('focus', 'avoid_skip_taskbar') and client.skipTaskbar():
66 if config.get('stackedcycle', 'include_icons'):
67 if config.get('stackedcycle', 'include_icons_all_desktops'):
69 if desk == curdesk: return True
71 if config.get('stackedcycle', 'include_omnipresent') and \
72 desk == 0xffffffff: return True
73 if config.get('stackedcycle', 'include_all_desktops'): return True
74 if desk == curdesk: return True
80 # get the list of clients, keeping iconic windows at the bottom
83 for c in focus._clients:
85 if c.iconic(): iconic_clients.append(c)
86 else: _items.append(c)
87 _items.extend(iconic_clients)
92 current = _items[_pos]
102 # current item might have shifted after a populateItems()
103 # call, so we need to do this test.
108 # The item we were on might be gone entirely
110 # try stay at the same spot in the menu
111 if oldpos >= len(_items):
112 _pos = len(_items) - 1
117 def _activate(final):
119 Activates (focuses and, if the user requested it, raises a window).
120 If final is True, then this is the very last window we're activating
121 and the user has finished cycling.
125 client = _items[_pos]
126 except IndexError: return # empty list
129 # move the to client's desktop if required
130 if not (client.iconic() or client.desktop() == 0xffffffff or \
131 client.desktop() == ob.Openbox.desktop()):
132 ob.Openbox.setDesktop(client.desktop())
134 if final or not client.iconic():
135 if final: r = config.get('stackedcycle', 'raise_window')
138 if final and client.shaded(): client.setShaded(False)
139 print "final", final, "raising", r
140 if r: client.raiseWindow()
144 def _cycle(keydata, client, forward):
145 global _cycling, _state, _pos, _inititem, _items
148 _items = [] # so it doesnt try start partway through the list
151 if not _items: return # don't bother doing anything
153 Keyboard.grab(_grabfunc)
154 # the pointer grab causes pointer events during the keyboard grab
155 # to go away, which means we don't get enter notifies when the
156 # popup disappears, screwing up the focus
157 Pointer.grabPointer(True)
160 _state = keydata.state
162 _inititem = _items[_pos]
169 if _pos < 0: _pos = len(_items) - 1
170 elif _pos >= len(_items): _pos = 0
171 if config.get('stackedcycle', 'activate_while_cycling'):
172 _activate(False) # activate, but dont deiconify/unshade/raise
174 def _grabfunc(keydata, client):
179 # have all the modifiers this started with been released?
180 if not _state & keydata.state:
183 # has Escape been pressed?
184 if keydata.keychain == "Escape":
189 _pos = _items.index(_inititem)
192 # has Enter been pressed?
193 elif keydata.keychain == "Return":
197 # activate, and deiconify/unshade/raise
198 _activate(notreverting)
201 Pointer.grabPointer(False)
211 if _cycling: _populate()
213 if _cycling: _populate()
215 hooks.managed.append(_newwin)
216 hooks.closed.append(_closewin)