Add the "obsetroot" tool. Use it to set the root background.
[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 show_desktop(data, show=1):
189     """Shows and focuses the desktop, hiding any client windows. Optionally,
190        if show is zero, this will hide the desktop, leaving show-desktop
191        mode."""
192     root = otk.display.screenInfo(data.screen).rootWindow()
193     ob.send_client_msg(root, otk.atoms.net_showing_desktop, root, show)
194
195 def hide_desktop(data):
196     """Hides the desktop, re-showing the client windows. Leaves show-desktop
197        mode."""
198     show_desktop(data, 0)
199
200 def toggle_show_desktop(data):
201     """Requests the Openbox to show the desktop, hiding the client windows, or
202        redisplay the clients."""
203     # get the current desktop state
204     root = otk.display.screenInfo(data.screen).rootWindow()
205     result, value = otk.Property_get(root, otk.atoms.net_showing_desktop,
206                                      otk.atoms.cardinal)
207     if not result: return
208     show = not value
209     ob.send_client_msg(root, otk.atoms.net_showing_desktop, root, show)
210
211 def next_desktop(data, no_wrap=0):
212     """Switches to the next desktop, optionally (by default) cycling around to
213        the first when going past the last."""
214     screen = ob.openbox.screen(data.screen)
215     d = screen.desktop()
216     n = screen.numDesktops()
217     if (d < (n-1)):
218         d = d + 1
219     elif not no_wrap:
220         d = 0
221     change_desktop(data, d)
222     
223 def prev_desktop(data, no_wrap=0):
224     """Switches to the previous desktop, optionally (by default) cycling around
225        to the last when going past the first."""
226     screen = ob.openbox.screen(data.screen)
227     d = screen.desktop()
228     n = screen.numDesktops()
229     if (d > 0):
230         d = d - 1
231     elif not no_wrap:
232         d = n - 1
233     change_desktop(data, d)
234
235 def up_desktop(data, num=1):
236     """Switches to the desktop vertically above the current one. This is based
237        on the desktop layout chosen by an EWMH compliant pager. Optionally, num
238        can be specified to move more than one row at a time."""
239     screen = ob.openbox.screen(data.screen)
240     d = screen.desktop()
241     n = screen.numDesktops()
242     l = screen.desktopLayout()
243
244     target = d - num * l.columns
245     if target < 0:
246         target += l.rows * l.columns
247     while target >= n:
248         target -= l.columns
249     change_desktop(data, target)
250
251 def down_desktop(data, num=1):
252     """Switches to the desktop vertically below the current one. This is based
253        on the desktop layout chosen by an EWMH compliant pager. Optionally, num
254        can be specified to move more than one row at a time."""
255     screen = ob.openbox.screen(data.screen)
256     d = screen.desktop()
257     n = screen.numDesktops()
258     l = screen.desktopLayout()
259
260     target = d + num * l.columns
261     if target >= n:
262         target -= l.rows * l.columns
263     while target < 0:
264         target += l.columns
265     change_desktop(data, target)
266
267 def left_desktop(data, num=1):
268     """Switches to the desktop horizotally left of the current one. This is
269        based on the desktop layout chosen by an EWMH compliant pager.
270        Optionally, num can be specified to move more than one column at a
271        time."""
272     screen = ob.openbox.screen(data.screen)
273     d = screen.desktop()
274     n = screen.numDesktops()
275     l = screen.desktopLayout()
276
277     rowstart = d - d % l.columns
278     target = d - num
279     while target < rowstart:
280         target += l.columns
281     change_desktop(data, target)
282
283 def right_desktop(data, num=1):
284     """Switches to the desktop horizotally right of the current one. This is
285        based on the desktop layout chosen by an EWMH compliant pager.
286        Optionally, num can be specified to move more than one column at a
287        time."""
288     screen = ob.openbox.screen(data.screen)
289     d = screen.desktop()
290     n = screen.numDesktops()
291     l = screen.desktopLayout()
292
293     rowstart = d - d % l.columns
294     target = d + num
295     while target >= rowstart + l.columns:
296         target -= l.columns
297     change_desktop(data, target)
298
299 def send_to_desktop(data, num=1):
300     """Sends a client to a specified desktop"""
301     if not data.client: return
302     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
303                        otk.atoms.net_wm_desktop,
304                        data.client.window(),num)
305
306 def toggle_all_desktops(data):
307     """Toggles between sending a client to all desktops and to the current
308        desktop."""
309     if not data.client: return
310     if not data.client.desktop() == 0xffffffff:
311         send_to_desktop(data, 0xffffffff)
312     else:
313         send_to_desktop(data, ob.openbox.screen(data.screen).desktop())
314     
315 def send_to_all_desktops(data):
316     """Sends a client to all desktops"""
317     if not data.client: return
318     send_to_desktop(data, 0xffffffff)
319     
320 def send_to_next_desktop(data, no_wrap=0, follow=1):
321     """Sends a window to the next desktop, optionally (by default) cycling
322        around to the first when going past the last. Also optionally moving to
323        the new desktop after sending the window."""
324     if not data.client: return
325     screen = ob.openbox.screen(data.screen)
326     d = screen.desktop()
327     n = screen.numDesktops()
328     if (d < (n-1)):
329         d = d + 1
330     elif not no_wrap:
331         d = 0
332     send_to_desktop(data, d)
333     if follow:
334         change_desktop(data, d)
335     
336 def send_to_prev_desktop(data, no_wrap=0, follow=1):
337     """Sends a window to the previous desktop, optionally (by default) cycling
338        around to the last when going past the first. Also optionally moving to
339        the new desktop after sending the window."""
340     if not data.client: return
341     screen = ob.openbox.screen(data.screen)
342     d = screen.desktop()
343     n = screen.numDesktops()
344     if (d > 0):
345         d = d - 1
346     elif not no_wrap:
347         d = n - 1
348     send_to_desktop(data, d)
349     if follow:
350         change_desktop(data, d)
351
352 def restart(data=0, other = ""):
353     """Restarts Openbox, optionally starting another window manager."""
354     ob.openbox.restart(other)
355
356 def exit(data=0):
357     """Exits Openbox."""
358     ob.openbox.shutdown()
359
360 print "Loaded callbacks.py"