all repos — openbox @ 3409b046a043d8ffabf2e9c33ea037c2e5be15e4

openbox fork - make it a bit more like ryudo

add motion.py, which provides funtions for moving/resizing a window interactively
Dana Jansens danakj@orodu.net
commit

3409b046a043d8ffabf2e9c33ea037c2e5be15e4

parent

bb6ac36d410ba62bc8bb481dd6461a30aace42fd

1 files changed, 212 insertions(+), 0 deletions(-)

jump to
A scripts/motion.py

@@ -0,0 +1,212 @@

+############################################################################ +### Functions that provide callbacks for motion events to move and ### +### windows. ### +############################################################################ + +############################################################################# +### Options that can be modified to change the functions' behaviors. ### +### ### +# move_popup - display a coordinates popup when moving windows. ### +move_popup = 1 ### +### ### +# NOT IMPLEMENTED (yet?) ### +# move_rubberband - display an outline while moving instead of moving the ### +### actual window, until the move is completed. Good for ### +### slower systems. ### +move_rubberband = 0 ### +### ### +# resize_popup - display a size popup when resizing windows. ### +resize_popup = 1 ### +### ### +# NOT IMPLEMENTED (yet?) ### +# resize_rubberband - display an outline while resizing instead of ### +### resizing the actual window, until the resize is ### +### completed. Good for slower systems. ### +resize_rubberband = 0 ### +### ### +# resize_nearest - 1 to resize from the corner nearest where the mouse ### +### is, 0 to resize always from the bottom right corner. ### +resize_nearest = 1 ### +### ### +############################################################################# + +import ob +import otk + +_popwidget = 0 +_poplabel = 0 + +# motion state +_inmotion = 0 + +# last motion data +_cx = 0 +_cy = 0 +_cw = 0 +_ch = 0 +_px = 0 +_py = 0 +_dx = 0 +_dy = 0 +_client = 0 +_screen = 0 + +def _do_move(): + global _screen, _client, _cx, _cy, _dx, _dy + + x = _cx + _dx + y = _cy + _dy + + global move_rubberband + if move_rubberband: + # draw the outline ... + f=0 + else: + _client.move(x, y) + + global move_popup + if move_popup: + global _popwidget, _poplabel + style = ob.openbox.screen(_screen).style() + font = style.labelFont() + text = "X: " + str(x) + " Y: " + str(y) + length = font.measureString(text) + if not _popwidget: + _popwidget = otk.Widget(ob.openbox, style, + otk.Widget.Horizontal, 0, + style.bevelWidth(), 1) + _popwidget.setTexture(style.titlebarFocusBackground()) + _poplabel = otk.Label(_popwidget) + _poplabel.setTexture(style.labelFocusBackground()) + _popwidget.show(1) + _poplabel.resize(length, font.height()) + _poplabel.setText(text) + area = otk.display.screenInfo(_screen).rect() + _popwidget.update() + _popwidget.move(area.x() + (area.width() - + _popwidget.width()) / 2, + area.y() + (area.height() - + _popwidget.height()) / 2) + +def move(data): + """Moves the window interactively. This should only be used with + MouseMotion events. If move_popup or move_rubberband is enabled, then + the end_move function needs to be bound as well.""" + if not data.client: return + + # not-normal windows dont get moved + if not data.client.normal(): return + + global _screen, _client, _cx, _cy, _dx, _dy + _screen = data.screen + _client = data.client + _cx = data.press_clientx + _cy = data.press_clienty + _dx = data.xroot - data.pressx + _dy = data.yroot - data.pressy + _do_move() + _inmotion = 1 + +def end_move(data): + """Complete the interactive move of a window.""" + global move_rubberband, _inmotion + global _popwidget, _poplabel + if _inmotion: + r = move_rubberband + move_rubberband = 0 + _do_move() + move_rubberband = r + _inmotion = 0 + _poplabel = 0 + _popwidget = 0 + +def _do_resize(): + global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy + + # pick a corner to anchor + if not (resize_nearest or _context == ob.MouseContext.Grip): + corner = ob.Client.TopLeft + else: + x = _px - _cx + y = _py - _cy + if y < _ch / 2: + if x < _cw / 2: + corner = ob.Client.BottomRight + _dx *= -1 + else: + corner = ob.Client.BottomLeft + _dy *= -1 + else: + if x < _cw / 2: + corner = ob.Client.TopRight + _dx *= -1 + else: + corner = ob.Client.TopLeft + + w = _cw + _dx + h = _ch + _dy + + global resize_popup + if resize_rubberband: + # draw the outline ... + f=0 + else: + _client.resize(corner, w, h) + + global resize_popup + if resize_popup: + global _popwidget, _poplabel + style = ob.openbox.screen(_screen).style() + ls = _client.logicalSize() + text = "W: " + str(ls.x()) + " H: " + str(ls.y()) + if not _popwidget: + _popwidget = otk.Widget(ob.openbox, style, + otk.Widget.Horizontal, 0, + style.bevelWidth(), 1) + _popwidget.setTexture(style.titlebarFocusBackground()) + _poplabel = otk.Label(_popwidget) + _poplabel.setTexture(style.labelFocusBackground()) + _popwidget.show(1) + _poplabel.fitString(text) + _poplabel.setText(text) + area = otk.display.screenInfo(_screen).rect() + _popwidget.update() + _popwidget.move(area.x() + (area.width() - + _popwidget.width()) / 2, + area.y() + (area.height() - + _popwidget.height()) / 2) + +def resize(data): + """Resizes the window interactively. This should only be used with + MouseMotion events""" + if not data.client: return + + # not-normal windows dont get resized + if not data.client.normal(): return + + global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy + _screen = data.screen + _client = data.client + _cx = data.press_clientx + _cy = data.press_clienty + _cw = data.press_clientwidth + _ch = data.press_clientheight + _px = data.pressx + _py = data.pressy + _dx = data.xroot - _px + _dy = data.yroot - _py + _do_resize() + _inmotion = 1 + +def end_resize(data): + """Complete the interactive resize of a window.""" + global resize_rubberband, _inmotion + global _popwidget, _poplabel + if _inmotion: + r = resize_rubberband + resize_rubberband = 0 + _do_resize() + resize_rubberband = r + _inmotion = 0 + _poplabel = 0 + _popwidget = 0