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"""
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);
}
}
}
shade(false);
// XXX: deiconify
focus();
- openbox->screen(_screen)->restack(true, this); // raise
+ openbox->screen(_screen)->raiseWindow(this);
}
}
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;
}
}
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)
}
-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;
{ (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 },
_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
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();
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);
- // the stacking list is from highest to lowest
+ 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(), 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());
+ Client::List::iterator it = _stacking.begin();
+ Client::List::const_iterator end = _stacking.end();
+
+ // the stacking list is from highest to lowest
+ for (; it != end && (*it)->layer() > client->layer(); ++it);
+
+ /*
+ 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);
- // insert the remaining below this window
- for (; it != end; ++it)
- wins.push_back((*it)->frame->window());
- XRestackWindows(**otk::display, &wins[0], wins.size());
+ XRestackWindows(**otk::display, wins, 2);
changeStackingList();
}
*/
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
/*!