rework focus event handling. does it basically like ob2 did now. and it seems to work too :>
This commit is contained in:
parent
3b4d453f90
commit
bd748f7402
3 changed files with 111 additions and 63 deletions
|
@ -11,7 +11,7 @@
|
|||
namespace otk {
|
||||
|
||||
OtkEventDispatcher::OtkEventDispatcher()
|
||||
: _fallback(0), _master(0)
|
||||
: _fallback(0), _master(0), _focus(None)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -45,67 +45,119 @@ void OtkEventDispatcher::dispatchEvents(void)
|
|||
printf("Event %d window %lx\n", e.type, e.xany.window);
|
||||
#endif
|
||||
|
||||
Window win;
|
||||
if (e.type == FocusIn || e.type == FocusOut) {
|
||||
// focus events are a beast all their own.. yuk, hate, etc.
|
||||
dispatchFocus(e);
|
||||
} else {
|
||||
Window win;
|
||||
|
||||
// pick a window
|
||||
switch (e.type) {
|
||||
case UnmapNotify:
|
||||
win = e.xunmap.window;
|
||||
break;
|
||||
case DestroyNotify:
|
||||
win = e.xdestroywindow.window;
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
win = e.xconfigurerequest.window;
|
||||
break;
|
||||
default:
|
||||
win = e.xany.window;
|
||||
// pick a window
|
||||
switch (e.type) {
|
||||
case UnmapNotify:
|
||||
win = e.xunmap.window;
|
||||
break;
|
||||
case DestroyNotify:
|
||||
win = e.xdestroywindow.window;
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
win = e.xconfigurerequest.window;
|
||||
break;
|
||||
default:
|
||||
win = e.xany.window;
|
||||
}
|
||||
|
||||
// grab the lasttime and hack up the modifiers
|
||||
switch (e.type) {
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
_lasttime = e.xbutton.time;
|
||||
e.xbutton.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case KeyPress:
|
||||
e.xkey.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case MotionNotify:
|
||||
_lasttime = e.xmotion.time;
|
||||
e.xmotion.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case PropertyNotify:
|
||||
_lasttime = e.xproperty.time;
|
||||
break;
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
_lasttime = e.xcrossing.time;
|
||||
break;
|
||||
}
|
||||
|
||||
dispatch(win, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OtkEventDispatcher::dispatchFocus(const XEvent &e)
|
||||
{
|
||||
Window newfocus = None;
|
||||
|
||||
// any other types are not ones we're interested in
|
||||
if (e.xfocus.detail != NotifyNonlinear)
|
||||
return;
|
||||
|
||||
if (e.type == FocusIn) {
|
||||
printf("---\n");
|
||||
printf("Got FocusIn!\n");
|
||||
printf("Using FocusIn\n");
|
||||
newfocus = e.xfocus.window;
|
||||
|
||||
if (newfocus != _focus) {
|
||||
// send a FocusIn to whatever was just focused
|
||||
dispatch(newfocus, e);
|
||||
printf("Sent FocusIn 0x%lx\n", newfocus);
|
||||
|
||||
// send a FocusOut to whatever used to be focused
|
||||
if (_focus) {
|
||||
XEvent ev;
|
||||
ev.xfocus = e.xfocus;
|
||||
ev.xfocus.window = _focus;
|
||||
ev.type = FocusOut;
|
||||
dispatch(_focus, ev);
|
||||
printf("Sent FocusOut 0x%lx\n", _focus);
|
||||
}
|
||||
|
||||
// store the new focused window
|
||||
_focus = newfocus;
|
||||
}
|
||||
|
||||
// grab the lasttime and hack up the modifiers
|
||||
switch (e.type) {
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
_lasttime = e.xbutton.time;
|
||||
e.xbutton.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case KeyPress:
|
||||
e.xkey.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case MotionNotify:
|
||||
_lasttime = e.xmotion.time;
|
||||
e.xmotion.state &= ~(LockMask | OBDisplay::numLockMask() |
|
||||
OBDisplay::scrollLockMask());
|
||||
break;
|
||||
case PropertyNotify:
|
||||
_lasttime = e.xproperty.time;
|
||||
break;
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
_lasttime = e.xcrossing.time;
|
||||
break;
|
||||
}
|
||||
} else if (e.type == FocusOut) {
|
||||
bool focused = false; // found a new focus target?
|
||||
printf("---\n");
|
||||
printf("Got FocusOut!\n");
|
||||
|
||||
if (e.type == FocusIn || e.type == FocusOut)
|
||||
// any other types are not ones we're interested in
|
||||
if (e.xfocus.detail != NotifyNonlinear)
|
||||
continue;
|
||||
|
||||
if (e.type == FocusOut) {
|
||||
XEvent fi;
|
||||
// send a FocusIn first if one exists
|
||||
while (XCheckTypedEvent(OBDisplay::display, FocusIn, &fi)) {
|
||||
// any other types are not ones we're interested in
|
||||
if (fi.xfocus.detail == NotifyNonlinear) {
|
||||
dispatch(fi.xfocus.window, fi);
|
||||
break;
|
||||
}
|
||||
// FocusOut events just make us look for FocusIn events. They are ignored
|
||||
// otherwise.
|
||||
XEvent fi;
|
||||
while (XCheckTypedEvent(OBDisplay::display, FocusIn, &fi)) {
|
||||
if (e.xfocus.detail == NotifyNonlinear) {
|
||||
printf("Found FocusIn\n");
|
||||
dispatchFocus(fi);
|
||||
focused = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(win, e);
|
||||
if (!focused) {
|
||||
// send a FocusOut to whatever used to be focused
|
||||
if (_focus) {
|
||||
XEvent ev;
|
||||
ev.xfocus = e.xfocus;
|
||||
ev.xfocus.window = _focus;
|
||||
dispatch(_focus, ev);
|
||||
printf("Sent FocusOut 0x%lx\n", _focus);
|
||||
}
|
||||
// store that no window has focus anymore
|
||||
_focus = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,13 @@ private:
|
|||
OtkEventMap _map;
|
||||
OtkEventHandler *_fallback;
|
||||
OtkEventHandler *_master;
|
||||
Window _focus;
|
||||
|
||||
//! The time at which the last XEvent with a time was received
|
||||
Time _lasttime;
|
||||
|
||||
void dispatch(Window win, const XEvent &e);
|
||||
void dispatchFocus(const XEvent &e);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1604,19 +1604,13 @@ static PyObject *_wrap_OBScreen_unmanageWindow(PyObject *self, PyObject *args) {
|
|||
PyObject *resultobj;
|
||||
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
|
||||
ob::OBClient *arg2 = (ob::OBClient *) 0 ;
|
||||
bool arg3 = (bool) false ;
|
||||
PyObject * obj0 = 0 ;
|
||||
PyObject * obj1 = 0 ;
|
||||
PyObject * obj2 = 0 ;
|
||||
|
||||
if(!PyArg_ParseTuple(args,(char *)"OO|O:OBScreen_unmanageWindow",&obj0,&obj1,&obj2)) goto fail;
|
||||
if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_unmanageWindow",&obj0,&obj1)) goto fail;
|
||||
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
if (obj2) {
|
||||
arg3 = (bool) PyInt_AsLong(obj2);
|
||||
if (PyErr_Occurred()) SWIG_fail;
|
||||
}
|
||||
(arg1)->unmanageWindow(arg2,arg3);
|
||||
(arg1)->unmanageWindow(arg2);
|
||||
|
||||
Py_INCREF(Py_None); resultobj = Py_None;
|
||||
return resultobj;
|
||||
|
|
Loading…
Reference in a new issue