]> icculus.org git repositories - dana/openbox.git/blob - scripts/callbacks.py
add support for desktop layouts specified by pagers
[dana/openbox.git] / scripts / callbacks.py
1 ############################################################################
2 ### Functions that can be used as callbacks for mouse/keyboard bindings  ###
3 ############################################################################
4
5 import ob
6 import otk
7
8 StateRemove = 0
9 """For the state_* callbacks. Indicates the state should be removed from the
10    window."""
11 StateAdd = 1
12 """For the state_* callbacks. Indicates the state should be add to the
13    window."""
14 StateToggle = 2
15 """For the state_* callbacks. Indicates the state should be toggled on the
16    window."""
17
18 def state_above(data, add=StateAdd):
19     """Toggles, adds or removes the 'above' state on a window.
20        The second paramater should one of: StateRemove, StateAdd, or
21        StateToggle."""
22     if not data.client: return
23     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
24                        otk.atoms.net_wm_state, data.client.window(),
25                        add, otk.atoms.net_wm_state_above)
26     
27 def state_below(data, add=StateAdd):
28     """Toggles, adds or removes the 'below' state on a window.
29        The second paramater should one of: StateRemove, StateAdd, or
30        StateToggle."""
31     if not data.client: return
32     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
33                        otk.atoms.net_wm_state, data.client.window(),
34                        add, otk.atoms.net_wm_state_below)
35     
36 def state_shaded(data, add=StateAdd):
37     """Toggles, adds or removes the 'shaded' state on a window.
38        The second paramater should one of: StateRemove, StateAdd, or
39        StateToggle."""
40     if not data.client: return
41     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
42                        otk.atoms.net_wm_state, data.client.window(),
43                        add, otk.atoms.net_wm_state_shaded)
44
45 def state_maximize(data, add=StateAdd):
46     """Toggles, adds or removes the horizontal and vertical 'maximized' state
47        on a window. The second paramater should one of: StateRemove, StateAdd,
48        or StateToggle."""
49     if not data.client: return
50     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
51                        otk.atoms.net_wm_state, data.client.window(),
52                        add, otk.atoms.net_wm_state_maximized_horz,
53                        otk.atoms.net_wm_state_maximized_vert)
54
55 def state_maximize_horz(data, add=StateAdd):
56     """Toggles, adds or removes the horizontal 'maximized' state on a window.
57        The second paramater should one of: StateRemove, StateAdd, or
58        StateToggle."""
59     if not data.client: return
60     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
61                        otk.atoms.net_wm_state, data.client.window(),
62                        add, otk.atoms.net_wm_state_maximized_horz)
63
64 def state_maximize_vert(data, add=StateAdd):
65     """Toggles, adds or removes the vertical 'maximized' state on a window.
66        The second paramater should one of: StateRemove, StateAdd, or
67        StateToggle."""
68     if not data.client: return
69     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
70                        otk.atoms.net_wm_state, data.client.window(),
71                        add, otk.atoms.net_wm_state_maximized_vert)
72
73 def state_skip_taskbar(data, add=StateAdd):
74     """Toggles, adds or removes the 'skip_taskbar' state on a window.
75        The second paramater should one of: StateRemove, StateAdd, or
76        StateToggle."""
77     if not data.client: return
78     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
79                        otk.atoms.net_wm_state, data.client.window(),
80                        add, otk.atoms.net_wm_state_skip_taskbar)
81     
82 def state_skip_pager(data, add=StateAdd):
83     """Toggles, adds or removes the 'skip_pager' state on a window.
84        The second paramater should one of: StateRemove, StateAdd, or
85        StateToggle."""
86     if not data.client: return
87     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
88                        otk.atoms.net_wm_state, data.client.window(),
89                        add, otk.atoms.net_wm_state_skip_pager)
90     
91 def iconify(data):
92     """Iconifies the window on which the event occured"""
93     if not data.client: return
94     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
95                        otk.atoms.wm_change_state,
96                        data.client.window(), 3) # IconicState
97     
98 def restore(data):
99     """Un-iconifies the window on which the event occured, but does not focus
100        if. If you want to focus the window too, it is recommended that you
101        use the activate() function."""
102     if not data.client: return
103     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
104                        otk.atoms.wm_change_state,
105                        data.client.window(), 1) # NormalState
106     
107 def close(data):
108     """Closes the window on which the event occured"""
109     if not data.client: return
110     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
111                        otk.atoms.net_close_window,
112                        data.client.window(), 0)
113
114 def focus(data):
115     """Focuses the window on which the event occured"""
116     if not data.client: return
117     # !normal windows dont get focus from window enter events
118     if data.action == ob.EventAction.EnterWindow and not data.client.normal():
119         return
120     data.client.focus()
121
122 def raise_win(data):
123     """Raises the window on which the event occured"""
124     if not data.client: return
125     ob.openbox.screen(data.screen).raiseWindow(data.client)
126
127 def lower_win(data):
128     """Lowers the window on which the event occured"""
129     if not data.client: return
130     ob.openbox.screen(data.screen).lowerWindow(data.client)
131
132 def toggle_maximize(data):
133     """Toggles the maximized status of the window on which the event occured"""
134     state_maximize(data, StateToggle)
135
136 def toggle_maximize_horz(data):
137     """Toggles the horizontal maximized status of the window on which the event
138        occured"""
139     state_maximize_horz(data, StateToggle)
140
141 def toggle_maximize_vert(data):
142     """Toggles the vertical maximized status of the window on which the event
143        occured"""
144     state_maximize_vert(data, StateToggle)
145
146 def maximize(data):
147     """Maximizes the window on which the event occured"""
148     state_maximize(data, StateAdd)
149
150 def maximize_horz(data):
151     """Horizontally maximizes the window on which the event occured"""
152     state_maximize_horz(data, StateAdd)
153
154 def maximize_vert(data):
155     """Vertically maximizes the window on which the event occured"""
156     state_maximize_vert(data, StateAdd)
157
158 def unmaximize(data):
159     """Unmaximizes the window on which the event occured"""
160     state_maximize(data, StateRemove)
161
162 def unmaximize_horz(data):
163     """Horizontally unmaximizes the window on which the event occured"""
164     state_maximize_horz(data, StateRemove)
165
166 def unmaximize_vert(data):
167     """Vertically unmaximizes the window on which the event occured"""
168     state_maximize_vert(data, StateRemove)
169
170 def toggle_shade(data):
171     """Toggles the shade status of the window on which the event occured"""
172     state_shaded(data, StateToggle)
173
174 def shade(data):
175     """Shades the window on which the event occured"""
176     state_shaded(data, StateAdd)
177
178 def unshade(data):
179     """Unshades the window on which the event occured"""
180     state_shaded(data, StateRemove)
181
182 def change_desktop(data, num):
183     """Switches to a specified desktop"""
184     root = otk.display.screenInfo(data.screen).rootWindow()
185     ob.send_client_msg(root, otk.atoms.net_current_desktop,
186                        root, num)
187
188 def next_desktop(data, no_wrap=0):
189     """Switches to the next desktop, optionally (by default) cycling around to
190        the first when going past the last."""
191     screen = ob.openbox.screen(data.screen)
192     d = screen.desktop()
193     n = screen.numDesktops()
194     if (d < (n-1)):
195         d = d + 1
196     elif not no_wrap:
197         d = 0
198     change_desktop(data, d)
199     
200 def prev_desktop(data, no_wrap=0):
201     """Switches to the previous desktop, optionally (by default) cycling around
202        to the last when going past the first."""
203     screen = ob.openbox.screen(data.screen)
204     d = screen.desktop()
205     n = screen.numDesktops()
206     if (d > 0):
207         d = d - 1
208     elif not no_wrap:
209         d = n - 1
210     change_desktop(data, d)
211
212 def up_desktop(data, num=1):
213     """Switches to the desktop vertically above the current one. This is based
214        on the desktop layout chosen by an EWMH compliant pager. Optionally, num
215        can be specified to move more than one row at a time."""
216     screen = ob.openbox.screen(data.screen)
217     d = screen.desktop()
218     n = screen.numDesktops()
219     l = screen.desktopLayout()
220
221     target = d - num * l.columns
222     if target < 0:
223         target += l.rows * l.columns
224     while target >= n:
225         target -= l.columns
226     change_desktop(data, target)
227
228 def down_desktop(data, num=1):
229     """Switches to the desktop vertically below the current one. This is based
230        on the desktop layout chosen by an EWMH compliant pager. Optionally, num
231        can be specified to move more than one row at a time."""
232     screen = ob.openbox.screen(data.screen)
233     d = screen.desktop()
234     n = screen.numDesktops()
235     l = screen.desktopLayout()
236
237     target = d + num * l.columns
238     if target >= n:
239         target -= l.rows * l.columns
240     while target < 0:
241         target += l.columns
242     change_desktop(data, target)
243
244 def left_desktop(data, num=1):
245     """Switches to the desktop horizotally left of the current one. This is
246        based on the desktop layout chosen by an EWMH compliant pager.
247        Optionally, num can be specified to move more than one column at a
248        time."""
249     screen = ob.openbox.screen(data.screen)
250     d = screen.desktop()
251     n = screen.numDesktops()
252     l = screen.desktopLayout()
253
254     rowstart = d - d % l.columns
255     target = d - num
256     while target < rowstart:
257         target += l.columns
258     change_desktop(data, target)
259
260 def right_desktop(data, num=1):
261     """Switches to the desktop horizotally right of the current one. This is
262        based on the desktop layout chosen by an EWMH compliant pager.
263        Optionally, num can be specified to move more than one column at a
264        time."""
265     screen = ob.openbox.screen(data.screen)
266     d = screen.desktop()
267     n = screen.numDesktops()
268     l = screen.desktopLayout()
269
270     rowstart = d - d % l.columns
271     target = d + num
272     while target >= rowstart + l.columns:
273         target -= l.columns
274     change_desktop(data, target)
275
276 def send_to_desktop(data, num=1):
277     """Sends a client to a specified desktop"""
278     if not data.client: return
279     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
280                        otk.atoms.net_wm_desktop,
281                        data.client.window(),num)
282
283 def toggle_all_desktops(data):
284     """Toggles between sending a client to all desktops and to the current
285        desktop."""
286     if not data.client: return
287     if not data.client.desktop() == 0xffffffff:
288         send_to_desktop(data, 0xffffffff)
289     else:
290         send_to_desktop(data, ob.openbox.screen(data.screen).desktop())
291     
292 def send_to_all_desktops(data):
293     """Sends a client to all desktops"""
294     if not data.client: return
295     send_to_desktop(data, 0xffffffff)
296     
297 def send_to_next_desktop(data, no_wrap=0, follow=1):
298     """Sends a window to the next desktop, optionally (by default) cycling
299        around to the first when going past the last. Also optionally moving to
300        the new desktop after sending the window."""
301     if not data.client: return
302     screen = ob.openbox.screen(data.screen)
303     d = screen.desktop()
304     n = screen.numDesktops()
305     if (d < (n-1)):
306         d = d + 1
307     elif not no_wrap:
308         d = 0
309     send_to_desktop(data, d)
310     if follow:
311         change_desktop(data, d)
312     
313 def send_to_prev_desktop(data, no_wrap=0, follow=1):
314     """Sends a window to the previous desktop, optionally (by default) cycling
315        around to the last when going past the first. Also optionally moving to
316        the new desktop after sending the window."""
317     if not data.client: return
318     screen = ob.openbox.screen(data.screen)
319     d = screen.desktop()
320     n = screen.numDesktops()
321     if (d > 0):
322         d = d - 1
323     elif not no_wrap:
324         d = n - 1
325     send_to_desktop(data, d)
326     if follow:
327         change_desktop(data, d)
328
329 def restart(data=0, other = ""):
330     """Restarts Openbox, optionally starting another window manager."""
331     ob.openbox.restart(other)
332
333 def exit(data=0):
334     """Exits Openbox."""
335     ob.openbox.shutdown()
336
337 print "Loaded callbacks.py"