]> icculus.org git repositories - mikachu/openbox.git/blob - scripts/motion.py
just a comment fix
[mikachu/openbox.git] / scripts / motion.py
1 ############################################################################
2 ###    Functions that provide callbacks for motion events to move and    ###
3 ###    resize windows.                                                   ###
4 ############################################################################
5
6 #############################################################################
7 ### Options that can be modified to change the functions' behaviors.      ###
8 ###                                                                       ###
9 # edge_resistance - the amount of resistance to provide to moving a       ###
10 ###                 window past a screen boundary. Specify a value of 0   ###
11 ###                 to disable edge resistance.                           ###
12 edge_resistance = 10                                                      ###
13 ###                                                                       ###
14 # move_popup - display a coordinates popup when moving windows.           ###
15 move_popup = 1                                                            ###
16 ###                                                                       ###
17 # NOT IMPLEMENTED (yet?)                                                  ###
18 # move_rubberband - display an outline while moving instead of moving the ###
19 ###                 actual window, until the move is completed. Good for  ###
20 ###                 slower systems.                                       ###
21 move_rubberband = 0                                                       ###
22 ###                                                                       ###
23 # resize_popup - display a size popup when resizing windows.              ###
24 resize_popup = 1                                                          ###
25 ###                                                                       ###
26 # NOT IMPLEMENTED (yet?)                                                  ###
27 # resize_rubberband - display an outline while resizing instead of        ###
28 ###                   resizing the actual window, until the resize is     ###
29 ###                   completed. Good for slower systems.                 ###
30 resize_rubberband = 0                                                     ###
31 ###                                                                       ###
32 # resize_nearest - 1 to resize from the corner nearest where the mouse    ###
33 ###                is, 0 to resize always from the bottom right corner.   ###
34 resize_nearest = 1                                                        ###
35 ###                                                                       ###
36 ###                                                                       ###
37 # Provides:                                                               ###
38 # def move(data):                                                         ###
39 #     """Moves the window interactively. This should only be used with    ###
40 #        MouseMotion events. If move_popup or move_rubberband is enabled, ###
41 #        then the end_move function needs to be bound as well."""         ###
42 # def end_move(data):                                                     ###
43 #     """Complete the interactive move of a window."""                    ###
44 # def resize(data):                                                       ###
45 #     """Resizes the window interactively. This should only be used with  ###
46 #        MouseMotion events"""                                            ###
47 # def end_resize(data):                                                   ###
48 #     """Complete the interactive resize of a window."""                  ###
49 ###                                                                       ###
50 #############################################################################
51
52 import ob
53 import otk
54
55 _popwidget = 0
56 _poplabel = 0
57
58 # motion state
59 _inmove = 0
60 _inresize = 0
61
62 # last motion data
63 _cx = 0
64 _cy = 0
65 _cw = 0
66 _ch = 0
67 _px = 0
68 _py = 0
69 _dx = 0
70 _dy = 0
71 _client = 0
72 _screen = 0
73
74 _motion_mask = 0
75
76 def _motion_grab(data):
77     global _motion_mask, _inmove, _inresize;
78
79     if data.action == ob.KeyAction.Release:
80         # have all the modifiers this started with been released?
81         if not _motion_mask & data.state:
82             if _inmove:
83                 end_move(data)
84             elif _inresize:
85                 end_resize(data)
86             else:
87                 raise RuntimeError
88
89 _last_x = 0
90 _last_y = 0
91
92 def _do_move():
93     global _screen, _client, _cx, _cy, _dx, _dy
94
95     # get destination x/y for the *frame*
96     x = _cx + _dx + _client.frame.rect().x() - _client.area().x()
97     y = _cy + _dy + _client.frame.rect().y() - _client.area().y()
98
99     global edge_resistance
100     global _last_x, _last_y
101     if edge_resistance:
102         fs = _client.frame.size()
103         w = _client.area().width() + fs.left + fs.right
104         h = _client.area().height() + fs.top + fs.bottom
105         # use the area based on the struts
106         area = ob.openbox.screen(_screen).area()
107         l = area.left()
108         r = area.right() - w + 1
109         t = area.top()
110         b = area.bottom() - h + 1
111         # left screen edge
112         if _last_x > x and x < l and x >= l - edge_resistance:
113             x = l
114         # right screen edge
115         if _last_x < x and x > r and x <= r + edge_resistance:
116             x = r
117         # top screen edge
118         if _last_y > y and y < t and y >= t - edge_resistance:
119             y = t
120         # right screen edge
121         if _last_y < y and y > b and y <= b + edge_resistance:
122             y = b
123
124     global _inmove
125     if not _inmove:
126         _last_x = 0
127         _last_y = 0
128     else:
129         _last_x = x
130         _last_y = y
131
132     global move_rubberband
133     if move_rubberband:
134         # draw the outline ...
135         f=0
136     else:
137         print "moving " + str(x) + " " + str(y)
138         _client.move(x, y, 1) # move the *frame*
139
140     global move_popup
141     if move_popup:
142         global _popwidget, _poplabel
143         style = ob.openbox.screen(_screen).style()
144         font = style.labelFont()
145         text = "X: " + str(x) + " Y: " + str(y)
146         length = font.measureString(text)
147         if not _popwidget:
148             _popwidget = otk.Widget(ob.openbox, style,
149                                     otk.Widget.Horizontal, 0,
150                                     style.bevelWidth(), 1)
151             _popwidget.setTexture(style.titlebarFocusBackground())
152             _poplabel = otk.Label(_popwidget)
153             _poplabel.setTexture(style.labelFocusBackground())
154         _poplabel.fitString(text)
155         _poplabel.setText(text)
156         _popwidget.update() 
157         area = otk.display.screenInfo(_screen).rect()
158         _popwidget.move(area.x() + (area.width() -
159                                     _popwidget.width()) / 2,
160                         area.y() + (area.height() -
161                                     _popwidget.height()) / 2)
162         _popwidget.show(1)
163
164 def move(data):
165     """Moves the window interactively. This should only be used with
166        MouseMotion events. If move_popup or move_rubberband is enabled, then
167        the end_move function needs to be bound as well."""
168     if not data.client: return
169
170     # not-normal windows dont get moved
171     if not data.client.normal(): return
172
173     global _screen, _client, _cx, _cy, _dx, _dy
174     _screen = data.screen
175     _client = data.client
176     _cx = data.press_clientx
177     _cy = data.press_clienty
178     _dx = data.xroot - data.pressx
179     _dy = data.yroot - data.pressy
180     _do_move()
181     global _inmove
182     if not _inmove:
183         ob.kgrab(_screen, _motion_grab)
184         _inmove = 1
185
186 def end_move(data):
187     """Complete the interactive move of a window."""
188     global move_rubberband, _inmove
189     global _popwidget, _poplabel
190     if _inmove:
191         r = move_rubberband
192         move_rubberband = 0
193         _do_move()
194         move_rubberband = r
195         _inmove = 0
196     _poplabel = 0
197     _popwidget = 0
198     ob.kungrab()
199
200 def _do_resize():
201     global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
202
203     dx = _dx
204     dy = _dy
205     
206     # pick a corner to anchor
207     if not (resize_nearest or _context == ob.MouseContext.Grip):
208         corner = ob.Client.TopLeft
209     else:
210         x = _px - _cx
211         y = _py - _cy
212         if y < _ch / 2:
213             if x < _cw / 2:
214                 corner = ob.Client.BottomRight
215                 dx *= -1
216             else:
217                 corner = ob.Client.BottomLeft
218             dy *= -1
219         else:
220             if x < _cw / 2:
221                 corner = ob.Client.TopRight
222                 dx *= -1
223             else:
224                 corner = ob.Client.TopLeft
225
226     w = _cw + dx
227     h = _ch + dy
228
229     global resize_popup
230     if resize_rubberband:
231         # draw the outline ...
232         f=0
233     else:
234         _client.resize(corner, w, h)
235
236     global resize_popup
237     if resize_popup:
238         global _popwidget, _poplabel
239         style = ob.openbox.screen(_screen).style()
240         ls = _client.logicalSize()
241         text = "W: " + str(ls.x()) + " H: " + str(ls.y())
242         if not _popwidget:
243             _popwidget = otk.Widget(ob.openbox, style,
244                                     otk.Widget.Horizontal, 0,
245                                     style.bevelWidth(), 1)
246             _popwidget.setTexture(style.titlebarFocusBackground())
247             _poplabel = otk.Label(_popwidget)
248             _poplabel.setTexture(style.labelFocusBackground())
249         _poplabel.fitString(text)
250         _poplabel.setText(text)
251         area = otk.display.screenInfo(_screen).rect()
252         _popwidget.update() 
253         _popwidget.move(area.x() + (area.width() -
254                                     _popwidget.width()) / 2,
255                         area.y() + (area.height() -
256                                     _popwidget.height()) / 2)
257         _popwidget.show(1)
258
259 def resize(data):
260     """Resizes the window interactively. This should only be used with
261        MouseMotion events"""
262     if not data.client: return
263
264     # not-normal windows dont get resized
265     if not data.client.normal(): return
266
267     global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
268     _screen = data.screen
269     _client = data.client
270     _cx = data.press_clientx
271     _cy = data.press_clienty
272     _cw = data.press_clientwidth
273     _ch = data.press_clientheight
274     _px = data.pressx
275     _py = data.pressy
276     _dx = data.xroot - _px
277     _dy = data.yroot - _py
278     _do_resize()
279     global _inresize
280     if not _inresize:
281         ob.kgrab(_screen, _motion_grab)
282         _inresize = 1
283
284 def end_resize(data):
285     """Complete the interactive resize of a window."""
286     global resize_rubberband, _inresize
287     global _popwidget, _poplabel
288     if _inresize:
289         r = resize_rubberband
290         resize_rubberband = 0
291         _do_resize()
292         resize_rubberband = r
293         _inresize = 0
294     _poplabel = 0
295     _popwidget = 0
296     ob.kungrab()