]> Dogcows Code - chaz/openbox/blob - scripts/builtins.py
make the 'toggle all desktops' button work
[chaz/openbox] / scripts / builtins.py
1 ###########################################################################
2 ### Functions that can be used as callbacks for mouse/keyboard bindings ###
3 ###########################################################################
4
5 def state_above(data, add=2):
6 """Toggles, adds or removes the 'above' state on a window."""
7 if not data.client: return
8 send_client_msg(display.screenInfo(data.screen).rootWindow(),
9 Property_atoms().net_wm_state, data.client.window(), add,
10 Property_atoms().net_wm_state_above)
11
12 def state_below(data, add=2):
13 """Toggles, adds or removes the 'below' state on a window."""
14 if not data.client: return
15 send_client_msg(display.screenInfo(data.screen).rootWindow(),
16 Property_atoms().net_wm_state, data.client.window(), add,
17 Property_atoms().net_wm_state_below)
18
19 def state_shaded(data, add=2):
20 """Toggles, adds or removes the 'shaded' state on a window."""
21 if not data.client: return
22 send_client_msg(display.screenInfo(data.screen).rootWindow(),
23 Property_atoms().net_wm_state, data.client.window(), add,
24 Property_atoms().net_wm_state_shaded)
25
26 def close(data):
27 """Closes the window on which the event occured"""
28 if not data.client: return
29 send_client_msg(display.screenInfo(data.screen).rootWindow(),
30 Property_atoms().net_close_window, data.client.window(), 0)
31
32 def focus(data):
33 """Focuses the window on which the event occured"""
34 if not data.client: return
35 # !normal windows dont get focus from window enter events
36 if data.action == EventEnterWindow and not data.client.normal():
37 return
38 data.client.focus()
39
40 def move(data):
41 """Moves the window interactively. This should only be used with
42 MouseMotion events"""
43 if not data.client: return
44
45 # !normal windows dont get moved
46 if not data.client.normal(): return
47
48 dx = data.xroot - data.pressx
49 dy = data.yroot - data.pressy
50 data.client.move(data.press_clientx + dx, data.press_clienty + dy)
51
52 def resize(data):
53 """Resizes the window interactively. This should only be used with
54 MouseMotion events"""
55 if not data.client: return
56
57 # !normal windows dont get moved
58 if not data.client.normal(): return
59
60 px = data.pressx
61 py = data.pressy
62 dx = data.xroot - px
63 dy = data.yroot - py
64
65 # pick a corner to anchor
66 if not (resize_nearest or data.context == MC_Grip):
67 corner = Client.TopLeft
68 else:
69 x = px - data.press_clientx
70 y = py - data.press_clienty
71 if y < data.press_clientheight / 2:
72 if x < data.press_clientwidth / 2:
73 corner = Client.BottomRight
74 dx *= -1
75 else:
76 corner = Client.BottomLeft
77 dy *= -1
78 else:
79 if x < data.press_clientwidth / 2:
80 corner = Client.TopRight
81 dx *= -1
82 else:
83 corner = Client.TopLeft
84
85 data.client.resize(corner,
86 data.press_clientwidth + dx,
87 data.press_clientheight + dy);
88
89 def restart(data, other = ""):
90 """Restarts openbox, optionally starting another window manager."""
91 openbox.restart(other)
92
93 def raise_win(data):
94 """Raises the window on which the event occured"""
95 if not data.client: return
96 openbox.screen(data.screen).raiseWindow(data.client)
97
98 def lower_win(data):
99 """Lowers the window on which the event occured"""
100 if not data.client: return
101 openbox.screen(data.screen).lowerWindow(data.client)
102
103 def toggle_shade(data):
104 """Toggles the shade status of the window on which the event occured"""
105 state_shaded(data)
106
107 def shade(data):
108 """Shades the window on which the event occured"""
109 state_shaded(data, 1)
110
111 def unshade(data):
112 """Unshades the window on which the event occured"""
113 state_shaded(data, 0)
114
115 def change_desktop(data, num):
116 """Switches to a specified desktop"""
117 root = display.screenInfo(data.screen).rootWindow()
118 send_client_msg(root, Property_atoms().net_current_desktop, root, num)
119
120 def next_desktop(data, no_wrap=0):
121 """Switches to the next desktop, optionally (by default) cycling around to
122 the first when going past the last."""
123 screen = openbox.screen(data.screen)
124 d = screen.desktop()
125 n = screen.numDesktops()
126 if (d < (n-1)):
127 d = d + 1
128 elif not no_wrap:
129 d = 0
130 change_desktop(data, d)
131
132 def prev_desktop(data, no_wrap=0):
133 """Switches to the previous desktop, optionally (by default) cycling around
134 to the last when going past the first."""
135 screen = openbox.screen(data.screen)
136 d = screen.desktop()
137 n = screen.numDesktops()
138 if (d > 0):
139 d = d - 1
140 elif not no_wrap:
141 d = n - 1
142 change_desktop(data, d)
143
144 def send_to_desktop(data, num):
145 """Sends a client to a specified desktop"""
146 if not data.client: return
147 send_client_msg(display.screenInfo(data.screen).rootWindow(),
148 Property_atoms().net_wm_desktop, data.client.window(), num)
149
150 def toggle_all_desktops(data):
151 """Toggles between sending a client to all desktops and to the current
152 desktop."""
153 if not data.client: return
154 if not data.client.desktop() == 0xffffffff:
155 send_to_desktop(data, 0xffffffff)
156 else:
157 send_to_desktop(data, openbox.screen(data.screen).desktop())
158
159 def send_to_all_desktops(data):
160 """Sends a client to all desktops"""
161 if not data.client: return
162 send_to_desktop(data, 0xffffffff)
163
164 def send_to_next_desktop(data, no_wrap=0, follow=1):
165 """Sends a window to the next desktop, optionally (by default) cycling
166 around to the first when going past the last. Also optionally moving to
167 the new desktop after sending the window."""
168 if not data.client: return
169 screen = openbox.screen(data.screen)
170 d = screen.desktop()
171 n = screen.numDesktops()
172 if (d < (n-1)):
173 d = d + 1
174 elif not no_wrap:
175 d = 0
176 send_to_desktop(data, d)
177 if follow:
178 change_desktop(data, d)
179
180 def send_to_prev_desktop(data, no_wrap=0, follow=1):
181 """Sends a window to the previous desktop, optionally (by default) cycling
182 around to the last when going past the first. Also optionally moving to
183 the new desktop after sending the window."""
184 if not data.client: return
185 screen = openbox.screen(data.screen)
186 d = screen.desktop()
187 n = screen.numDesktops()
188 if (d > 0):
189 d = d - 1
190 elif not no_wrap:
191 d = n - 1
192 send_to_desktop(data, d)
193 if follow:
194 change_desktop(data, d)
195
196 #########################################
197 ### Convenience functions for scripts ###
198 #########################################
199
200 def execute(bin, screen = 0):
201 """Executes a command on the specified screen. It is recommended that you
202 use this call instead of a python system call. If the specified screen
203 is beyond your range of screens, the default is used instead."""
204 openbox.execute(screen, bin)
205
206 def setup_click_focus(click_raise = 1):
207 """Sets up for focusing windows by clicking on or in the window.
208 Optionally, clicking on or in a window can raise the window to the
209 front of its stacking layer."""
210 mbind("Left", MC_Titlebar, MousePress, focus)
211 mbind("Left", MC_Handle, MousePress, focus)
212 mbind("Left", MC_Grip, MousePress, focus)
213 mbind("Left", MC_Window, MousePress, focus)
214 if click_raise:
215 mbind("Left", MC_Titlebar, MousePress, raise_win)
216 mbind("Left", MC_Handle, MousePress, raise_win)
217 mbind("Left", MC_Grip, MousePress, raise_win)
218 mbind("Left", MC_Window, MousePress, raise_win)
219
220 def setup_sloppy_focus(click_focus = 1, click_raise = 0):
221 """Sets up for focusing windows when the mouse pointer enters them.
222 Optionally, clicking on or in a window can focus it if your pointer
223 ends up inside a window without focus. Also, optionally, clicking on or
224 in a window can raise the window to the front of its stacking layer."""
225 ebind(EventEnterWindow, focus)
226 if click_focus:
227 setup_click_focus(click_raise)
228
229 def setup_window_clicks():
230 """Sets up the default bindings for various mouse buttons for various
231 contexts.
232 This includes:
233 * Alt-left drag anywhere on a window will move it
234 * Alt-right drag anywhere on a window will resize it
235 * Left drag on a window's titlebar/handle will move it
236 * Left drag on a window's handle grips will resize it
237 * Alt-left press anywhere on a window's will raise it to the front of
238 its stacking layer.
239 * Left press on a window's titlebar/handle will raise it to the front
240 of its stacking layer.
241 * Alt-middle click anywhere on a window's will lower it to the bottom
242 of its stacking layer.
243 * Middle click on a window's titlebar/handle will lower it to the
244 bottom of its stacking layer.
245 * Double-left click on a window's titlebar will toggle shading it
246 """
247 mbind("A-Left", MC_Frame, MouseMotion, move)
248 mbind("Left", MC_Titlebar, MouseMotion, move)
249 mbind("Left", MC_Handle, MouseMotion, move)
250
251 mbind("A-Right", MC_Frame, MouseMotion, resize)
252 mbind("Left", MC_Grip, MouseMotion, resize)
253
254 mbind("Left", MC_Titlebar, MousePress, raise_win)
255 mbind("Left", MC_Handle, MousePress, raise_win)
256 mbind("A-Left", MC_Frame, MousePress, raise_win)
257 mbind("A-Middle", MC_Frame, MouseClick, lower_win)
258 mbind("Middle", MC_Titlebar, MouseClick, lower_win)
259 mbind("Middle", MC_Handle, MouseClick, lower_win)
260
261 mbind("Left", MC_Titlebar, MouseDoubleClick, toggle_shade)
262
263 def setup_window_buttons():
264 """Sets up the default behaviors for the buttons in the window titlebar."""
265 mbind("Left", MC_StickyButton, MouseClick, toggle_all_desktops)
266 mbind("Left", MC_CloseButton, MouseClick, close)
267
268 def setup_scroll():
269 """Sets up the default behaviors for the mouse scroll wheel.
270 This includes:
271 * scrolling on a window titlebar will shade/unshade it
272 * alt-scrolling anywhere will switch to the next/previous desktop
273 * control-alt-scrolling on a window will send it to the next/previous
274 desktop, and switch to the desktop with the window
275 """
276 mbind("Up", MC_Titlebar, MouseClick, shade)
277 mbind("Down", MC_Titlebar, MouseClick, unshade)
278
279 mbind("A-Up", MC_Frame, MouseClick, next_desktop)
280 mbind("A-Up", MC_Root, MouseClick, next_desktop)
281 mbind("A-Down", MC_Frame, MouseClick, prev_desktop)
282 mbind("A-Down", MC_Root, MouseClick, prev_desktop)
283
284 mbind("C-A-Up", MC_Frame, MouseClick, send_to_next_desktop)
285 mbind("C-A-Down", MC_Frame, MouseClick, send_to_prev_desktop)
286
287 def setup_fallback_focus():
288 """Sets up a focus fallback routine so that when no windows are focused,
289 the last window to have focus on the desktop will be focused."""
290 focus_stack = []
291 def focused(data):
292 #global focus_stack
293 if data.client:
294 window = data.client.window()
295 # add to front the stack
296 if window in focus_stack:
297 focus_stack.remove(window)
298 focus_stack.insert(0, window)
299 else:
300 # pass around focus
301 desktop = openbox.screen(data.screen).desktop()
302 l = len(focus_stack)
303 i = 0
304 while i < l:
305 w = focus_stack[i]
306 client = openbox.findClient(w)
307 if not client: # window is gone, remove it
308 focus_stack.pop(i)
309 l = l - 1
310 elif client.desktop() == desktop and \
311 client.normal() and client.focus():
312 break
313 else:
314 i = i + 1
315
316 ebind(EventFocus, focused)
317
318
319 ############################################################################
320 ### Window placement algorithms, choose one of these and ebind it to the ###
321 ### EventPlaceWindow action. ###
322 ############################################################################
323
324 ob_rand = None
325 import random
326 def placewindows_random(data):
327 if not data.client: return
328 client_area = data.client.area()
329 frame_size = data.client.frame.size()
330 screen = display.screenInfo(data.screen)
331 width = screen.width() - (client_area.width() +
332 frame_size.left + frame_size.right)
333 height = screen.height() - (client_area.height() +
334 frame_size.top + frame_size.bottom)
335 global ob_rand
336 if not ob_rand: ob_rand = random.Random()
337 x = ob_rand.randrange(0, width-1)
338 y = ob_rand.randrange(0, height-1)
339 data.client.move(x, y)
340
341
342 print "Loaded builtins.py"
This page took 0.050881 seconds and 4 git commands to generate.