new raise/lower window code. only restacks 2 windows (1 move) at a time, ever. ManMower, u rulz.
This commit is contained in:
parent
3a83fe7e6c
commit
af1ac846cc
6 changed files with 90 additions and 40 deletions
|
@ -93,12 +93,12 @@ def restart(data, other = ""):
|
||||||
def raise_win(data):
|
def raise_win(data):
|
||||||
"""Raises the window on which the event occured"""
|
"""Raises the window on which the event occured"""
|
||||||
if not data.client: return
|
if not data.client: return
|
||||||
openbox.screen(data.screen).restack(1, data.client)
|
openbox.screen(data.screen).raiseWindow(data.client)
|
||||||
|
|
||||||
def lower_win(data):
|
def lower_win(data):
|
||||||
"""Lowers the window on which the event occured"""
|
"""Lowers the window on which the event occured"""
|
||||||
if not data.client: return
|
if not data.client: return
|
||||||
openbox.screen(data.screen).restack(0, data.client)
|
openbox.screen(data.screen).lowerWindow(data.client)
|
||||||
|
|
||||||
def toggle_shade(data):
|
def toggle_shade(data):
|
||||||
"""Toggles the shade status of the window on which the event occured"""
|
"""Toggles the shade status of the window on which the event occured"""
|
||||||
|
|
|
@ -339,7 +339,7 @@ void Client::calcLayer() {
|
||||||
if we don't have a frame, then we aren't mapped yet (and this would
|
if we don't have a frame, then we aren't mapped yet (and this would
|
||||||
SIGSEGV :)
|
SIGSEGV :)
|
||||||
*/
|
*/
|
||||||
openbox->screen(_screen)->restack(true, this); // raise
|
openbox->screen(_screen)->raiseWindow(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -856,7 +856,7 @@ void Client::clientMessageHandler(const XClientMessageEvent &e)
|
||||||
shade(false);
|
shade(false);
|
||||||
// XXX: deiconify
|
// XXX: deiconify
|
||||||
focus();
|
focus();
|
||||||
openbox->screen(_screen)->restack(true, this); // raise
|
openbox->screen(_screen)->raiseWindow(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,13 +1165,13 @@ void Client::configureRequestHandler(const XConfigureRequestEvent &e)
|
||||||
switch (e.detail) {
|
switch (e.detail) {
|
||||||
case Below:
|
case Below:
|
||||||
case BottomIf:
|
case BottomIf:
|
||||||
openbox->screen(_screen)->restack(false, this); // lower
|
openbox->screen(_screen)->lowerWindow(this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Above:
|
case Above:
|
||||||
case TopIf:
|
case TopIf:
|
||||||
default:
|
default:
|
||||||
openbox->screen(_screen)->restack(true, this); // raise
|
openbox->screen(_screen)->raiseWindow(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,7 +665,8 @@ class Screen(EventHandler,):
|
||||||
def manageExisting(*args): return apply(_openbox.Screen_manageExisting,args)
|
def manageExisting(*args): return apply(_openbox.Screen_manageExisting,args)
|
||||||
def manageWindow(*args): return apply(_openbox.Screen_manageWindow,args)
|
def manageWindow(*args): return apply(_openbox.Screen_manageWindow,args)
|
||||||
def unmanageWindow(*args): return apply(_openbox.Screen_unmanageWindow,args)
|
def unmanageWindow(*args): return apply(_openbox.Screen_unmanageWindow,args)
|
||||||
def restack(*args): return apply(_openbox.Screen_restack,args)
|
def raiseWindow(*args): return apply(_openbox.Screen_raiseWindow,args)
|
||||||
|
def lowerWindow(*args): return apply(_openbox.Screen_lowerWindow,args)
|
||||||
def setDesktopName(*args): return apply(_openbox.Screen_setDesktopName,args)
|
def setDesktopName(*args): return apply(_openbox.Screen_setDesktopName,args)
|
||||||
def propertyHandler(*args): return apply(_openbox.Screen_propertyHandler,args)
|
def propertyHandler(*args): return apply(_openbox.Screen_propertyHandler,args)
|
||||||
def clientMessageHandler(*args): return apply(_openbox.Screen_clientMessageHandler,args)
|
def clientMessageHandler(*args): return apply(_openbox.Screen_clientMessageHandler,args)
|
||||||
|
|
|
@ -8333,21 +8333,36 @@ static PyObject *_wrap_Screen_unmanageWindow(PyObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *_wrap_Screen_restack(PyObject *self, PyObject *args) {
|
static PyObject *_wrap_Screen_raiseWindow(PyObject *self, PyObject *args) {
|
||||||
PyObject *resultobj;
|
PyObject *resultobj;
|
||||||
ob::Screen *arg1 = (ob::Screen *) 0 ;
|
ob::Screen *arg1 = (ob::Screen *) 0 ;
|
||||||
bool arg2 ;
|
ob::Client *arg2 = (ob::Client *) 0 ;
|
||||||
ob::Client *arg3 = (ob::Client *) 0 ;
|
|
||||||
PyObject * obj0 = 0 ;
|
PyObject * obj0 = 0 ;
|
||||||
PyObject * obj1 = 0 ;
|
PyObject * obj1 = 0 ;
|
||||||
PyObject * obj2 = 0 ;
|
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args,(char *)"OOO:Screen_restack",&obj0,&obj1,&obj2)) goto fail;
|
if(!PyArg_ParseTuple(args,(char *)"OO:Screen_raiseWindow",&obj0,&obj1)) goto fail;
|
||||||
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Screen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Screen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||||
arg2 = (bool) PyInt_AsLong(obj1);
|
if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||||
if (PyErr_Occurred()) SWIG_fail;
|
(arg1)->raiseWindow(arg2);
|
||||||
if ((SWIG_ConvertPtr(obj2,(void **) &arg3, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
|
||||||
(arg1)->restack(arg2,arg3);
|
Py_INCREF(Py_None); resultobj = Py_None;
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *_wrap_Screen_lowerWindow(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *resultobj;
|
||||||
|
ob::Screen *arg1 = (ob::Screen *) 0 ;
|
||||||
|
ob::Client *arg2 = (ob::Client *) 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args,(char *)"OO:Screen_lowerWindow",&obj0,&obj1)) goto fail;
|
||||||
|
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Screen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||||
|
if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||||
|
(arg1)->lowerWindow(arg2);
|
||||||
|
|
||||||
Py_INCREF(Py_None); resultobj = Py_None;
|
Py_INCREF(Py_None); resultobj = Py_None;
|
||||||
return resultobj;
|
return resultobj;
|
||||||
|
@ -10995,7 +11010,8 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"Screen_manageExisting", _wrap_Screen_manageExisting, METH_VARARGS },
|
{ (char *)"Screen_manageExisting", _wrap_Screen_manageExisting, METH_VARARGS },
|
||||||
{ (char *)"Screen_manageWindow", _wrap_Screen_manageWindow, METH_VARARGS },
|
{ (char *)"Screen_manageWindow", _wrap_Screen_manageWindow, METH_VARARGS },
|
||||||
{ (char *)"Screen_unmanageWindow", _wrap_Screen_unmanageWindow, METH_VARARGS },
|
{ (char *)"Screen_unmanageWindow", _wrap_Screen_unmanageWindow, METH_VARARGS },
|
||||||
{ (char *)"Screen_restack", _wrap_Screen_restack, METH_VARARGS },
|
{ (char *)"Screen_raiseWindow", _wrap_Screen_raiseWindow, METH_VARARGS },
|
||||||
|
{ (char *)"Screen_lowerWindow", _wrap_Screen_lowerWindow, METH_VARARGS },
|
||||||
{ (char *)"Screen_setDesktopName", _wrap_Screen_setDesktopName, METH_VARARGS },
|
{ (char *)"Screen_setDesktopName", _wrap_Screen_setDesktopName, METH_VARARGS },
|
||||||
{ (char *)"Screen_propertyHandler", _wrap_Screen_propertyHandler, METH_VARARGS },
|
{ (char *)"Screen_propertyHandler", _wrap_Screen_propertyHandler, METH_VARARGS },
|
||||||
{ (char *)"Screen_clientMessageHandler", _wrap_Screen_clientMessageHandler, METH_VARARGS },
|
{ (char *)"Screen_clientMessageHandler", _wrap_Screen_clientMessageHandler, METH_VARARGS },
|
||||||
|
|
|
@ -125,7 +125,7 @@ Screen::Screen(int screen)
|
||||||
_focuswindow = XCreateWindow(**otk::display, _info->rootWindow(),
|
_focuswindow = XCreateWindow(**otk::display, _info->rootWindow(),
|
||||||
-100, -100, 1, 1, 0, 0, InputOnly,
|
-100, -100, 1, 1, 0, 0, InputOnly,
|
||||||
_info->visual(), CWOverrideRedirect, &attr);
|
_info->visual(), CWOverrideRedirect, &attr);
|
||||||
XMapWindow(**otk::display, _focuswindow);
|
XMapRaised(**otk::display, _focuswindow);
|
||||||
|
|
||||||
// these may be further updated if any pre-existing windows are found in
|
// these may be further updated if any pre-existing windows are found in
|
||||||
// the manageExising() function
|
// the manageExising() function
|
||||||
|
@ -512,7 +512,7 @@ void Screen::manageWindow(Window window)
|
||||||
clients.push_back(client);
|
clients.push_back(client);
|
||||||
// this puts into the stacking order, then raises it
|
// this puts into the stacking order, then raises it
|
||||||
_stacking.push_back(client);
|
_stacking.push_back(client);
|
||||||
restack(true, client);
|
raiseWindow(client);
|
||||||
// update the root properties
|
// update the root properties
|
||||||
changeClientList();
|
changeClientList();
|
||||||
|
|
||||||
|
@ -590,30 +590,54 @@ void Screen::unmanageWindow(Client *client)
|
||||||
changeClientList();
|
changeClientList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::restack(bool raise, Client *client)
|
void Screen::lowerWindow(Client *client)
|
||||||
{
|
{
|
||||||
const int layer = client->layer();
|
Window wins[2]; // only ever restack 2 windows.
|
||||||
std::vector<Window> wins;
|
|
||||||
|
assert(!_stacking.empty()); // this would be bad
|
||||||
|
|
||||||
|
Client::List::iterator it = --_stacking.end();
|
||||||
|
Client::List::const_iterator end = _stacking.begin();
|
||||||
|
|
||||||
|
for (; it != end && (*it)->layer() < client->layer(); --it);
|
||||||
|
if (*it == client) return; // already the bottom, return
|
||||||
|
|
||||||
|
wins[0] = (*it)->frame->window();
|
||||||
|
wins[1] = client->frame->window();
|
||||||
|
|
||||||
_stacking.remove(client);
|
_stacking.remove(client);
|
||||||
|
_stacking.insert(++it, client);
|
||||||
|
|
||||||
|
XRestackWindows(**otk::display, wins, 2);
|
||||||
|
changeStackingList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::raiseWindow(Client *client)
|
||||||
|
{
|
||||||
|
Window wins[2]; // only ever restack 2 windows.
|
||||||
|
|
||||||
|
assert(!_stacking.empty()); // this would be bad
|
||||||
|
|
||||||
|
// remove the client before looking so we can't run into ourselves
|
||||||
|
_stacking.remove(client);
|
||||||
|
|
||||||
|
Client::List::iterator it = _stacking.begin();
|
||||||
|
Client::List::const_iterator end = _stacking.end();
|
||||||
|
|
||||||
// the stacking list is from highest to lowest
|
// the stacking list is from highest to lowest
|
||||||
|
for (; it != end && (*it)->layer() > client->layer(); ++it);
|
||||||
Client::List::iterator it = _stacking.begin(), end = _stacking.end();
|
|
||||||
// insert the windows above this window
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
if ((*it)->layer() < layer || (raise && (*it)->layer() == layer))
|
|
||||||
break;
|
|
||||||
wins.push_back((*it)->frame->window());
|
|
||||||
}
|
|
||||||
// insert our client
|
|
||||||
wins.push_back(client->frame->window());
|
|
||||||
_stacking.insert(it, client);
|
|
||||||
// insert the remaining below this window
|
|
||||||
for (; it != end; ++it)
|
|
||||||
wins.push_back((*it)->frame->window());
|
|
||||||
|
|
||||||
XRestackWindows(**otk::display, &wins[0], wins.size());
|
/*
|
||||||
|
if our new position is the top, we want to stack under the _focuswindow
|
||||||
|
otherwise, we want to stack under the previous window in the stack.
|
||||||
|
*/
|
||||||
|
wins[0] = (it == _stacking.begin() ? _focuswindow :
|
||||||
|
((*(--Client::List::const_iterator(it)))->frame->window()));
|
||||||
|
wins[1] = client->frame->window();
|
||||||
|
|
||||||
|
_stacking.insert(it, client);
|
||||||
|
|
||||||
|
XRestackWindows(**otk::display, wins, 2);
|
||||||
changeStackingList();
|
changeStackingList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,9 +182,18 @@ public:
|
||||||
*/
|
*/
|
||||||
void unmanageWindow(Client *client);
|
void unmanageWindow(Client *client);
|
||||||
|
|
||||||
//! Raises/Lowers a client window above/below all others in its stacking
|
//! Raises a client window above all others in its stacking layer
|
||||||
//! layer
|
/*!
|
||||||
void restack(bool raise, Client *client);
|
raiseWindow has a couple of constraints that lowerWindow does not.<br>
|
||||||
|
1) raiseWindow can be called after changing a Client's stack layer, and
|
||||||
|
the list will be reorganized properly.<br>
|
||||||
|
2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be
|
||||||
|
called for the specified client.
|
||||||
|
*/
|
||||||
|
void raiseWindow(Client *client);
|
||||||
|
|
||||||
|
//! Lowers a client window below all others in its stacking layer
|
||||||
|
void lowerWindow(Client *client);
|
||||||
|
|
||||||
//! Sets the name of a desktop by changing the root window property
|
//! Sets the name of a desktop by changing the root window property
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in a new issue