1 ############################################################################
2 ### Functions that provide callbacks for motion events to move and ###
3 ### resize windows. ###
4 ############################################################################
7 """Moves the window interactively. This should only be used with
8 MouseAction.Motion events. If 'Coords Popup for Moving' or 'Rubberband
9 Mode for Moving' is enabled, then the end_move function needs to be
14 """Complete the interactive move of a window."""
18 """Resizes the window interactively. This should only be used with
19 MouseMotion events. If 'Coords Popup for Resizing' or 'Rubberband Mode
20 for Resizing' is enabled, then the end_resize function needs to be
25 """Complete the interactive resize of a window."""
28 export_functions
= move
, end_move
, resize
, end_resize
30 #############################################################################
37 "The amount of resistance to provide to moving a window past a " + \
38 "screen boundary. Specify a value of 0 to disable edge resistance.",
44 'Coords Popup In Window',
45 "When this is true, the coordinates popups will be placed " + \
46 "relative to the window being moved/resized. When false, they " + \
47 "will appear relative to the entire screen.",
52 'Coords Popup Centered',
53 "When this is true, the coordinates popups will be centered " + \
54 "relative to the window or screen (see 'Coords Popup In " + \
55 "Window'). When false, they will be placed based upon the " + \
56 "'Coords Popup Position' options.",
61 'Coords Popup Position - X',
62 "When 'Coords Popup Centered' is false, this position will be " + \
63 "used to place the coordinates popups. The popups will be " + \
64 "placed relative to the window or the screen (see 'Coords " + \
65 "Popup In Window'). A value of 0 would place it at the left " + \
66 "edge, while a value of -1 would place it at the right edge. " + \
67 "This value behaves similarly to those passed to the -geometry " + \
68 "flag of many applications.",
73 'Coords Popup Position - Y',
74 "When 'Coords Popup Centered' is false, this position will be " + \
75 "used to place the coordinates popups. The popups will be " + \
76 "placed relative to the window or the screen (see 'Coords Popup " +\
77 "In Window'). A value of 0 would place it at the top edge, " + \
78 "while a value of -1 would place it at the bottom edge. This " + \
79 "value behaves similarly to those passed to the -geometry flag " + \
80 "of many applications.",
85 'Coords Popup for Moving',
86 "Option to display a coordinates popup when moving windows.",
91 'Rubberband Mode for Moving',
92 "NOT IMPLEMENTED (yet?)\n"+\
93 "Display an outline while moving instead of moving the actual " + \
94 "window, until the move is completed. Good for slower systems.",
99 'Coords Popup for Resizing',
100 "Option to display a coordinates popup when resizing windows.",
105 'Rubberband Mode for Resizing',
106 "NOT IMPLEMENTED (yet?)\n"+\
107 "Display an outline while resizing instead of resizing the " + \
108 "actual window, until the resize is completed. Good for slower " + \
114 'Resize Nearest Corner',
115 "When true, resizing will occur from the corner nearest where " + \
116 "the mouse is. When false resizing will always occur from the " + \
117 "bottom right corner.",
121 ###########################################################################
122 ### Internal stuff, should not be accessed outside the module. ###
123 ###########################################################################
149 if config
.get('motion', 'popup_in_window'):
150 # use the actual client's area, not the frame's
151 area
= _client
.frame
.area()
152 size
= _client
.frame
.size()
153 area
= otk
.Rect(area
.x() + size
.left
, area
.y() + size
.top
,
154 area
.width() - size
.left
- size
.right
,
155 area
.height() - size
.top
- size
.bottom
)
157 area
= otk
.Rect(otk
.Point(0, 0), ob
.openbox
.screen(_screen
).size())
158 size
= _popwidget
.minSize()
159 if config
.get('motion', 'popup_centered'):
160 x
= area
.position().x() + (area
.size().width() - size
.width()) / 2
161 y
= area
.position().y() + (area
.size().height() - size
.height()) / 2
163 x
= config
.get('motion', 'popup_coords_x')
164 y
= config
.get('motion', 'popup_coords_y')
165 if x
< 0: x
+= area
.width() - size
.width() + 1
166 if y
< 0: y
+= area
.width() - size
.height() + 1
167 x
+= area
.position().x()
168 y
+= area
.position().y()
169 _popwidget
.moveresize(otk
.Rect(x
, y
, size
.width(), size
.height()))
171 def _motion_grab(data
):
172 global _motion_mask
, _inmove
, _inresize
;
174 # are all the modifiers this started with still pressed?
175 if not _motion_mask
& data
.state
:
187 global _screen
, _client
, _cx
, _cy
, _dx
, _dy
189 # get destination x/y for the *frame*
190 x
= _cx
+ _dx
+ _client
.frame
.area().x() - _client
.area().x()
191 y
= _cy
+ _dy
+ _client
.frame
.area().y() - _client
.area().y()
193 global _last_x
, _last_y
194 resist
= config
.get('motion', 'edge_resistance')
196 fs
= _client
.frame
.size()
197 w
= _client
.area().width() + fs
.left
+ fs
.right
198 h
= _client
.area().height() + fs
.top
+ fs
.bottom
199 # use the area based on the struts
200 area
= ob
.openbox
.screen(_screen
).area(_client
.desktop())
202 r
= area
.right() - w
+ 1
204 b
= area
.bottom() - h
+ 1
206 if _last_x
> x
and x
< l
and x
>= l
- resist
:
209 if _last_x
< x
and x
> r
and x
<= r
+ resist
:
212 if _last_y
> y
and y
< t
and y
>= t
- resist
:
215 if _last_y
< y
and y
> b
and y
<= b
+ resist
:
226 if not final
and config
.get('motion', 'move_rubberband'):
227 # XXX draw the outline ...
230 _client
.move(x
, y
, final
)
232 if config
.get('motion', 'move_popup'):
234 text
= "X: " + str(x
) + " Y: " + str(y
)
236 _popwidget
= otk
.Label(_screen
, ob
.openbox
)
237 _popwidget
.setHighlighted(1)
238 _popwidget
.setText(text
)
243 if not data
.client
: return
245 # not-normal windows dont get moved
246 if not data
.client
.normal(): return
248 global _screen
, _client
, _cx
, _cy
, _dx
, _dy
, _motion_mask
249 _screen
= data
.screen
250 _client
= data
.client
251 _cx
= data
.press_clientx
252 _cy
= data
.press_clienty
253 _dx
= data
.xroot
- data
.pressx
254 _dy
= data
.yroot
- data
.pressy
255 _motion_mask
= data
.state
259 ob
.kgrab(_screen
, _motion_grab
)
263 global _inmove
, _popwidget
270 def _do_resize(final
):
271 global _screen
, _client
, _cx
, _cy
, _cw
, _ch
, _px
, _py
, _dx
, _dy
276 # pick a corner to anchor
277 if not (config
.get('motion', 'resize_nearest') or
278 _context
== ob
.MouseContext
.Grip
):
279 corner
= ob
.Client
.TopLeft
285 corner
= ob
.Client
.BottomRight
288 corner
= ob
.Client
.BottomLeft
292 corner
= ob
.Client
.TopRight
295 corner
= ob
.Client
.TopLeft
300 if not final
and config
.get('motion', 'resize_rubberband'):
301 # XXX draw the outline ...
304 _client
.resize(corner
, w
, h
)
306 if config
.get('motion', 'resize_popup'):
308 ls
= _client
.logicalSize()
309 text
= "W: " + str(ls
.width()) + " H: " + str(ls
.height())
311 _popwidget
= otk
.Label(_screen
, ob
.openbox
)
312 _popwidget
.setHighlighted(1)
313 _popwidget
.setText(text
)
318 if not data
.client
: return
320 # not-normal windows dont get resized
321 if not data
.client
.normal(): return
323 global _screen
, _client
, _cx
, _cy
, _cw
, _ch
, _px
, _py
, _dx
, _dy
325 _screen
= data
.screen
326 _client
= data
.client
327 _cx
= data
.press_clientx
328 _cy
= data
.press_clienty
329 _cw
= data
.press_clientwidth
330 _ch
= data
.press_clientheight
333 _dx
= data
.xroot
- _px
334 _dy
= data
.yroot
- _py
335 _motion_mask
= data
.state
339 ob
.kgrab(_screen
, _motion_grab
)
342 def _end_resize(data
):
343 global _inresize
, _popwidget