grab the keyboard during move/resize to make sure the popup doesnt get left onscreen if the modifiers are released before the button
This commit is contained in:
parent
3409b046a0
commit
f7a0eb7624
6 changed files with 80 additions and 13 deletions
|
@ -136,7 +136,8 @@ def _focus_stacked_ungrab(data):
|
||||||
# have all the modifiers this started with been released?
|
# have all the modifiers this started with been released?
|
||||||
if not _cyc_mask & data.state:
|
if not _cyc_mask & data.state:
|
||||||
_destroy_popup_list()
|
_destroy_popup_list()
|
||||||
ob.kungrab() # ungrab ourself
|
ob.kungrab()
|
||||||
|
ob.mungrab()
|
||||||
_doing_stacked = 0;
|
_doing_stacked = 0;
|
||||||
if cycle_raise:
|
if cycle_raise:
|
||||||
client = ob.openbox.findClient(_cyc_w)
|
client = ob.openbox.findClient(_cyc_w)
|
||||||
|
@ -246,6 +247,10 @@ def focus_next_stacked(data, forward=1):
|
||||||
_create_popup_list(data)
|
_create_popup_list(data)
|
||||||
|
|
||||||
ob.kgrab(data.screen, _focus_stacked_ungrab)
|
ob.kgrab(data.screen, _focus_stacked_ungrab)
|
||||||
|
# the pointer grab causes pointer events during the keyboard grab to
|
||||||
|
# go away, which means we don't get enter notifies when the popup
|
||||||
|
# disappears, screwing up the focus
|
||||||
|
ob.mgrab(data.screen)
|
||||||
focus_next_stacked(data, forward) # start with the first press
|
focus_next_stacked(data, forward) # start with the first press
|
||||||
|
|
||||||
def focus_prev_stacked(data):
|
def focus_prev_stacked(data):
|
||||||
|
|
|
@ -37,7 +37,8 @@ _popwidget = 0
|
||||||
_poplabel = 0
|
_poplabel = 0
|
||||||
|
|
||||||
# motion state
|
# motion state
|
||||||
_inmotion = 0
|
_inmove = 0
|
||||||
|
_inresize = 0
|
||||||
|
|
||||||
# last motion data
|
# last motion data
|
||||||
_cx = 0
|
_cx = 0
|
||||||
|
@ -51,6 +52,21 @@ _dy = 0
|
||||||
_client = 0
|
_client = 0
|
||||||
_screen = 0
|
_screen = 0
|
||||||
|
|
||||||
|
_motion_mask = 0
|
||||||
|
|
||||||
|
def _motion_grab(data):
|
||||||
|
global _motion_mask, _inmove, _inresize;
|
||||||
|
|
||||||
|
if data.action == ob.KeyAction.Release:
|
||||||
|
# have all the modifiers this started with been released?
|
||||||
|
if not _motion_mask & data.state:
|
||||||
|
if _inmove:
|
||||||
|
end_move(data)
|
||||||
|
elif _inresize:
|
||||||
|
end_resize(data)
|
||||||
|
else:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
def _do_move():
|
def _do_move():
|
||||||
global _screen, _client, _cx, _cy, _dx, _dy
|
global _screen, _client, _cx, _cy, _dx, _dy
|
||||||
|
|
||||||
|
@ -105,20 +121,26 @@ def move(data):
|
||||||
_dx = data.xroot - data.pressx
|
_dx = data.xroot - data.pressx
|
||||||
_dy = data.yroot - data.pressy
|
_dy = data.yroot - data.pressy
|
||||||
_do_move()
|
_do_move()
|
||||||
_inmotion = 1
|
global _inmove
|
||||||
|
if not _inmove:
|
||||||
|
ob.kgrab(_screen, _motion_grab)
|
||||||
|
print "GRAB"
|
||||||
|
_inmove = 1
|
||||||
|
|
||||||
def end_move(data):
|
def end_move(data):
|
||||||
"""Complete the interactive move of a window."""
|
"""Complete the interactive move of a window."""
|
||||||
global move_rubberband, _inmotion
|
global move_rubberband, _inmove
|
||||||
global _popwidget, _poplabel
|
global _popwidget, _poplabel
|
||||||
if _inmotion:
|
if _inmove:
|
||||||
r = move_rubberband
|
r = move_rubberband
|
||||||
move_rubberband = 0
|
move_rubberband = 0
|
||||||
_do_move()
|
_do_move()
|
||||||
move_rubberband = r
|
move_rubberband = r
|
||||||
_inmotion = 0
|
_inmove = 0
|
||||||
_poplabel = 0
|
_poplabel = 0
|
||||||
_popwidget = 0
|
_popwidget = 0
|
||||||
|
print "UNGRAB"
|
||||||
|
ob.kungrab()
|
||||||
|
|
||||||
def _do_resize():
|
def _do_resize():
|
||||||
global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
|
global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
|
||||||
|
@ -196,17 +218,21 @@ def resize(data):
|
||||||
_dx = data.xroot - _px
|
_dx = data.xroot - _px
|
||||||
_dy = data.yroot - _py
|
_dy = data.yroot - _py
|
||||||
_do_resize()
|
_do_resize()
|
||||||
_inmotion = 1
|
global _inresize
|
||||||
|
if not _inresize:
|
||||||
|
ob.kgrab(_screen, _motion_grab)
|
||||||
|
_inresize = 1
|
||||||
|
|
||||||
def end_resize(data):
|
def end_resize(data):
|
||||||
"""Complete the interactive resize of a window."""
|
"""Complete the interactive resize of a window."""
|
||||||
global resize_rubberband, _inmotion
|
global resize_rubberband, _inresize
|
||||||
global _popwidget, _poplabel
|
global _popwidget, _poplabel
|
||||||
if _inmotion:
|
if _inresize:
|
||||||
r = resize_rubberband
|
r = resize_rubberband
|
||||||
resize_rubberband = 0
|
resize_rubberband = 0
|
||||||
_do_resize()
|
_do_resize()
|
||||||
resize_rubberband = r
|
resize_rubberband = r
|
||||||
_inmotion = 0
|
_inresize = 0
|
||||||
_poplabel = 0
|
_poplabel = 0
|
||||||
_popwidget = 0
|
_popwidget = 0
|
||||||
|
ob.kungrab()
|
||||||
|
|
|
@ -385,9 +385,6 @@ bool Bindings::grabKeyboard(int screen, PyObject *callback)
|
||||||
if (XGrabKeyboard(**otk::display, root, false, GrabModeAsync,
|
if (XGrabKeyboard(**otk::display, root, false, GrabModeAsync,
|
||||||
GrabModeAsync, CurrentTime))
|
GrabModeAsync, CurrentTime))
|
||||||
return false;
|
return false;
|
||||||
// the pointer grab causes pointer events during the keyboard grab to go away
|
|
||||||
XGrabPointer(**otk::display, root, false, 0, GrabModeAsync,
|
|
||||||
GrabModeAsync, None, None, CurrentTime);
|
|
||||||
_keybgrab_callback = callback;
|
_keybgrab_callback = callback;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -403,6 +400,24 @@ void Bindings::ungrabKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Bindings::grabPointer(int screen)
|
||||||
|
{
|
||||||
|
if (!openbox->screen(screen))
|
||||||
|
return false; // the screen is not managed
|
||||||
|
|
||||||
|
Window root = otk::display->screenInfo(screen)->rootWindow();
|
||||||
|
XGrabPointer(**otk::display, root, false, 0, GrabModeAsync,
|
||||||
|
GrabModeAsync, None, None, CurrentTime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Bindings::ungrabPointer()
|
||||||
|
{
|
||||||
|
XUngrabPointer(**otk::display, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key,
|
void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key,
|
||||||
Time time, KeyAction::KA action)
|
Time time, KeyAction::KA action)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,6 +123,9 @@ public:
|
||||||
bool grabKeyboard(int screen, PyObject *callback);
|
bool grabKeyboard(int screen, PyObject *callback);
|
||||||
void ungrabKeyboard();
|
void ungrabKeyboard();
|
||||||
|
|
||||||
|
bool grabPointer(int screen);
|
||||||
|
void ungrabPointer();
|
||||||
|
|
||||||
bool addButton(const std::string &but, MouseContext::MC context,
|
bool addButton(const std::string &but, MouseContext::MC context,
|
||||||
MouseAction::MA action, PyObject *callback);
|
MouseAction::MA action, PyObject *callback);
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,21 @@ PyObject *kungrab()
|
||||||
Py_INCREF(Py_None); return Py_None;
|
Py_INCREF(Py_None); return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *mgrab(int screen)
|
||||||
|
{
|
||||||
|
if (!ob::openbox->bindings()->grabPointer(screen)) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,"Unable to grab pointer.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_INCREF(Py_None); return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *mungrab()
|
||||||
|
{
|
||||||
|
ob::openbox->bindings()->ungrabPointer();
|
||||||
|
Py_INCREF(Py_None); return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *kbind(PyObject *keylist, ob::KeyContext::KC context, PyObject *func)
|
PyObject *kbind(PyObject *keylist, ob::KeyContext::KC context, PyObject *func)
|
||||||
{
|
{
|
||||||
if (!PyCallable_Check(func)) {
|
if (!PyCallable_Check(func)) {
|
||||||
|
|
|
@ -249,6 +249,9 @@ PyObject *kbind(PyObject *keylist, ob::KeyContext::KC context, PyObject *func);
|
||||||
PyObject *kgrab(int screen, PyObject *func);
|
PyObject *kgrab(int screen, PyObject *func);
|
||||||
PyObject *kungrab();
|
PyObject *kungrab();
|
||||||
|
|
||||||
|
PyObject *mgrab(int screen);
|
||||||
|
PyObject *mungrab();
|
||||||
|
|
||||||
PyObject *ebind(ob::EventAction::EA action, PyObject *func);
|
PyObject *ebind(ob::EventAction::EA action, PyObject *func);
|
||||||
|
|
||||||
void set_reset_key(const std::string &key);
|
void set_reset_key(const std::string &key);
|
||||||
|
|
Loading…
Reference in a new issue