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):
|
||||
"""Raises the window on which the event occured"""
|
||||
if not data.client: return
|
||||
openbox.screen(data.screen).restack(1, data.client)
|
||||
openbox.screen(data.screen).raiseWindow(data.client)
|
||||
|
||||
def lower_win(data):
|
||||
"""Lowers the window on which the event occured"""
|
||||
if not data.client: return
|
||||
openbox.screen(data.screen).restack(0, data.client)
|
||||
openbox.screen(data.screen).lowerWindow(data.client)
|
||||
|
||||
def toggle_shade(data):
|
||||
"""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
|
||||
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);
|
||||
// XXX: deiconify
|
||||
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) {
|
||||
case Below:
|
||||
case BottomIf:
|
||||
openbox->screen(_screen)->restack(false, this); // lower
|
||||
openbox->screen(_screen)->lowerWindow(this);
|
||||
break;
|
||||
|
||||
case Above:
|
||||
case TopIf:
|
||||
default:
|
||||
openbox->screen(_screen)->restack(true, this); // raise
|
||||
openbox->screen(_screen)->raiseWindow(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -665,7 +665,8 @@ class Screen(EventHandler,):
|
|||
def manageExisting(*args): return apply(_openbox.Screen_manageExisting,args)
|
||||
def manageWindow(*args): return apply(_openbox.Screen_manageWindow,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 propertyHandler(*args): return apply(_openbox.Screen_propertyHandler,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;
|
||||
ob::Screen *arg1 = (ob::Screen *) 0 ;
|
||||
bool arg2 ;
|
||||
ob::Client *arg3 = (ob::Client *) 0 ;
|
||||
ob::Client *arg2 = (ob::Client *) 0 ;
|
||||
PyObject * obj0 = 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;
|
||||
arg2 = (bool) PyInt_AsLong(obj1);
|
||||
if (PyErr_Occurred()) SWIG_fail;
|
||||
if ((SWIG_ConvertPtr(obj2,(void **) &arg3, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
(arg1)->restack(arg2,arg3);
|
||||
if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
(arg1)->raiseWindow(arg2);
|
||||
|
||||
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;
|
||||
return resultobj;
|
||||
|
@ -10995,7 +11010,8 @@ static PyMethodDef SwigMethods[] = {
|
|||
{ (char *)"Screen_manageExisting", _wrap_Screen_manageExisting, METH_VARARGS },
|
||||
{ (char *)"Screen_manageWindow", _wrap_Screen_manageWindow, 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_propertyHandler", _wrap_Screen_propertyHandler, METH_VARARGS },
|
||||
{ (char *)"Screen_clientMessageHandler", _wrap_Screen_clientMessageHandler, METH_VARARGS },
|
||||
|
|
|
@ -125,7 +125,7 @@ Screen::Screen(int screen)
|
|||
_focuswindow = XCreateWindow(**otk::display, _info->rootWindow(),
|
||||
-100, -100, 1, 1, 0, 0, InputOnly,
|
||||
_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
|
||||
// the manageExising() function
|
||||
|
@ -512,7 +512,7 @@ void Screen::manageWindow(Window window)
|
|||
clients.push_back(client);
|
||||
// this puts into the stacking order, then raises it
|
||||
_stacking.push_back(client);
|
||||
restack(true, client);
|
||||
raiseWindow(client);
|
||||
// update the root properties
|
||||
changeClientList();
|
||||
|
||||
|
@ -590,30 +590,54 @@ void Screen::unmanageWindow(Client *client)
|
|||
changeClientList();
|
||||
}
|
||||
|
||||
void Screen::restack(bool raise, Client *client)
|
||||
void Screen::lowerWindow(Client *client)
|
||||
{
|
||||
const int layer = client->layer();
|
||||
std::vector<Window> wins;
|
||||
Window wins[2]; // only ever restack 2 windows.
|
||||
|
||||
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.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
|
||||
|
||||
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());
|
||||
for (; it != end && (*it)->layer() > client->layer(); ++it);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -182,9 +182,18 @@ public:
|
|||
*/
|
||||
void unmanageWindow(Client *client);
|
||||
|
||||
//! Raises/Lowers a client window above/below all others in its stacking
|
||||
//! layer
|
||||
void restack(bool raise, Client *client);
|
||||
//! Raises a client window above all others in its stacking layer
|
||||
/*!
|
||||
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
|
||||
/*!
|
||||
|
|
Loading…
Reference in a new issue