From: Dana Jansens Date: Fri, 3 Jan 2003 18:21:28 +0000 (+0000) Subject: add/lower work X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=89e6d5c0e64513d06ac4368981239de969a6fc9d;p=chaz%2Fopenbox add/lower work --- diff --git a/otk/otk_wrap.cc b/otk/otk_wrap.cc index 0b0ebc19..f5562ad8 100644 --- a/otk/otk_wrap.cc +++ b/otk/otk_wrap.cc @@ -13599,6 +13599,7 @@ static swig_const_info swig_const_table[] = { { SWIG_PY_INT, (char *)"OBProperty_net_wm_action_change_desktop", (long) otk::OBProperty::net_wm_action_change_desktop, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_action_close", (long) otk::OBProperty::net_wm_action_close, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_modal", (long) otk::OBProperty::net_wm_state_modal, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_sticky", (long) otk::OBProperty::net_wm_state_sticky, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_maximized_vert", (long) otk::OBProperty::net_wm_state_maximized_vert, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_maximized_horz", (long) otk::OBProperty::net_wm_state_maximized_horz, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_shaded", (long) otk::OBProperty::net_wm_state_shaded, 0, 0, 0}, @@ -13606,7 +13607,8 @@ static swig_const_info swig_const_table[] = { { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_skip_pager", (long) otk::OBProperty::net_wm_state_skip_pager, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_hidden", (long) otk::OBProperty::net_wm_state_hidden, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_net_wm_state_fullscreen", (long) otk::OBProperty::net_wm_state_fullscreen, 0, 0, 0}, -{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_floating", (long) otk::OBProperty::net_wm_state_floating, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_above", (long) otk::OBProperty::net_wm_state_above, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_below", (long) otk::OBProperty::net_wm_state_below, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_kde_net_system_tray_windows", (long) otk::OBProperty::kde_net_system_tray_windows, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_kde_net_wm_system_tray_window_for", (long) otk::OBProperty::kde_net_wm_system_tray_window_for, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBProperty_kde_net_wm_window_type_override", (long) otk::OBProperty::kde_net_wm_window_type_override, 0, 0, 0}, diff --git a/otk/property.cc b/otk/property.cc index 9a0efe5b..5ebb2f0f 100644 --- a/otk/property.cc +++ b/otk/property.cc @@ -130,6 +130,7 @@ OBProperty::OBProperty() _atoms[net_wm_action_close] = create("_NET_WM_ACTION_CLOSE"); _atoms[net_wm_state_modal] = create("_NET_WM_STATE_MODAL"); + _atoms[net_wm_state_sticky] = create("_NET_WM_STATE_STICKY"); _atoms[net_wm_state_maximized_vert] = create("_NET_WM_STATE_MAXIMIZED_VERT"); _atoms[net_wm_state_maximized_horz] = create("_NET_WM_STATE_MAXIMIZED_HORZ"); _atoms[net_wm_state_shaded] = create("_NET_WM_STATE_SHADED"); @@ -137,7 +138,8 @@ OBProperty::OBProperty() _atoms[net_wm_state_skip_pager] = create("_NET_WM_STATE_SKIP_PAGER"); _atoms[net_wm_state_hidden] = create("_NET_WM_STATE_HIDDEN"); _atoms[net_wm_state_fullscreen] = create("_NET_WM_STATE_FULLSCREEN"); - _atoms[net_wm_state_floating] = create("_NET_WM_STATE_FLOATING"); + _atoms[net_wm_state_above] = create("_NET_WM_STATE_ABOVE"); + _atoms[net_wm_state_below] = create("_NET_WM_STATE_BELOW"); _atoms[kde_net_system_tray_windows] = create("_KDE_NET_SYSTEM_TRAY_WINDOWS"); _atoms[kde_net_wm_system_tray_window_for] = diff --git a/otk/property.hh b/otk/property.hh index 9e2d7aca..b016cd04 100644 --- a/otk/property.hh +++ b/otk/property.hh @@ -127,6 +127,7 @@ public: net_wm_action_close, net_wm_state_modal, + net_wm_state_sticky, net_wm_state_maximized_vert, net_wm_state_maximized_horz, net_wm_state_shaded, @@ -134,7 +135,8 @@ public: net_wm_state_skip_pager, net_wm_state_hidden, net_wm_state_fullscreen, - net_wm_state_floating, + net_wm_state_above, + net_wm_state_below, kde_net_system_tray_windows, kde_net_wm_system_tray_window_for, diff --git a/scripts/builtins.py b/scripts/builtins.py index 231d5ab5..8c042117 100644 --- a/scripts/builtins.py +++ b/scripts/builtins.py @@ -60,3 +60,18 @@ def resize(data): def execute(bin, screen = 0): Openbox_execute(openbox, screen, bin) + +def toggle_shade(data): + print "toggle_shade" + +def raise_win(data): + client = Openbox_findClient(openbox, data.window()) + if not client: return + screen = Openbox_screen(openbox, OBClient_screen(client)) + OBScreen_raise(screen, client) + +def lower_win(data): + client = Openbox_findClient(openbox, data.window()) + if not client: return + screen = Openbox_screen(openbox, OBClient_screen(client)) + OBScreen_lower(screen, client) diff --git a/src/client.cc b/src/client.cc index e626081c..f648c2c8 100644 --- a/src/client.cc +++ b/src/client.cc @@ -37,7 +37,7 @@ OBClient::OBClient(int screen, Window window) // update EVERYTHING the first time!! // the state is kinda assumed to be normal. is this right? XXX - _wmstate = NormalState; + _wmstate = NormalState; _iconic = false; // no default decors or functions, each has to be enabled _decorations = _functions = 0; // start unfocused @@ -91,53 +91,7 @@ OBClient::OBClient(int screen, Window window) updateIconTitle(); updateClass(); -/* -#ifdef DEBUG - printf("Mapped window: 0x%lx\n" - " title: \t%s\t icon title: \t%s\n" - " app name: \t%s\t\t class: \t%s\n" - " position: \t%d, %d\t\t size: \t%d, %d\n" - " desktop: \t%lu\t\t group: \t0x%lx\n" - " type: \t%d\t\t min size \t%d, %d\n" - " base size \t%d, %d\t\t max size \t%d, %d\n" - " size incr \t%d, %d\t\t gravity \t%d\n" - " wm state \t%ld\t\t can be focused:\t%s\n" - " notify focus: \t%s\t\t urgent: \t%s\n" - " shaped: \t%s\t\t modal: \t%s\n" - " shaded: \t%s\t\t iconic: \t%s\n" - " vert maximized:\t%s\t\t horz maximized:\t%s\n" - " fullscreen: \t%s\t\t floating: \t%s\n" - " requested pos: \t%s\n", - _window, - _title.c_str(), - _icon_title.c_str(), - _app_name.c_str(), - _app_class.c_str(), - _area.x(), _area.y(), - _area.width(), _area.height(), - _desktop, - _group, - _type, - _min_x, _min_y, - _base_x, _base_y, - _max_x, _max_y, - _inc_x, _inc_y, - _gravity, - _wmstate, - _can_focus ? "yes" : "no", - _focus_notify ? "yes" : "no", - _urgent ? "yes" : "no", - _shaped ? "yes" : "no", - _modal ? "yes" : "no", - _shaded ? "yes" : "no", - _iconic ? "yes" : "no", - _max_vert ? "yes" : "no", - _max_horz ? "yes" : "no", - _fullscreen ? "yes" : "no", - _floating ? "yes" : "no", - _positioned ? "yes" : "no"); -#endif -*/ + calcLayer(); } @@ -295,7 +249,8 @@ void OBClient::getState() { const otk::OBProperty *property = Openbox::instance->property(); - _modal = _shaded = _max_horz = _max_vert = _fullscreen = _floating = false; + _modal = _shaded = _max_horz = _max_vert = _fullscreen = _above = _below = + false; unsigned long *state; unsigned long num = (unsigned) -1; @@ -317,6 +272,12 @@ void OBClient::getState() else if (state[i] == property->atom(otk::OBProperty::net_wm_state_maximized_horz)) _max_horz = true; + else if (state[i] == + property->atom(otk::OBProperty::net_wm_state_above)) + _above = true; + else if (state[i] == + property->atom(otk::OBProperty::net_wm_state_below)) + _below = true; } delete [] state; @@ -343,6 +304,17 @@ void OBClient::getShaped() } +void OBClient::calcLayer() { + if (_iconic) _layer = OBScreen::Layer_Icon; + else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop; + else if (_type == Type_Dock) _layer = OBScreen::Layer_Top; + else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen; + else if (_above) _layer = OBScreen::Layer_Above; + else if (_below) _layer = OBScreen::Layer_Below; + else _layer = OBScreen::Layer_Normal; +} + + void OBClient::updateProtocols() { const otk::OBProperty *property = Openbox::instance->property(); @@ -596,8 +568,10 @@ void OBClient::setState(StateAction action, long data1, long data2) else if (state == property->atom(otk::OBProperty::net_wm_state_fullscreen)) action = _fullscreen ? State_Remove : State_Add; - else if (state == property->atom(otk::OBProperty::net_wm_state_floating)) - action = _floating ? State_Remove : State_Add; + else if (state == property->atom(otk::OBProperty::net_wm_state_above)) + action = _above ? State_Remove : State_Add; + else if (state == property->atom(otk::OBProperty::net_wm_state_below)) + action = _below ? State_Remove : State_Add; } if (action == State_Add) { @@ -626,10 +600,15 @@ void OBClient::setState(StateAction action, long data1, long data2) _fullscreen = true; // XXX: raise the window n shit } else if (state == - property->atom(otk::OBProperty::net_wm_state_floating)) { - if (_floating) continue; - _floating = true; + property->atom(otk::OBProperty::net_wm_state_above)) { + if (_above) continue; + _above = true; // XXX: raise the window n shit + } else if (state == + property->atom(otk::OBProperty::net_wm_state_below)) { + if (_below) continue; + _below = true; + // XXX: lower the window n shit } } else { // action == State_Remove @@ -657,13 +636,20 @@ void OBClient::setState(StateAction action, long data1, long data2) _fullscreen = false; // XXX: lower the window to its proper layer } else if (state == - property->atom(otk::OBProperty::net_wm_state_floating)) { - if (!_floating) continue; - _floating = false; + property->atom(otk::OBProperty::net_wm_state_above)) { + if (!_above) continue; + _above = false; // XXX: lower the window to its proper layer + } else if (state == + property->atom(otk::OBProperty::net_wm_state_below)) { + if (!_below) continue; + _below = false; + // XXX: raise the window to its proper layer } } } + calcLayer(); + Openbox::instance->screen(_screen)->raise(this); } @@ -928,7 +914,7 @@ void OBClient::configureRequestHandler(const XConfigureRequestEvent &e) if (e.value_mask & CWBorderWidth) _border_width = e.border_width; - // resize, then move, as specified in the EWMH section 7.7 + // resize, then move, as specified in the EWMH section 7.7 if (e.value_mask & (CWWidth | CWHeight)) { int w = (e.value_mask & CWWidth) ? e.width : _area.width(); int h = (e.value_mask & CWHeight) ? e.height : _area.height(); diff --git a/src/client.hh b/src/client.hh index d2a41dd7..a49ccd74 100644 --- a/src/client.hh +++ b/src/client.hh @@ -17,11 +17,12 @@ extern "C" { #include +#include "screen.hh" +#include "widget.hh" #include "otk/point.hh" #include "otk/strut.hh" #include "otk/rect.hh" #include "otk/eventhandler.hh" -#include "widget.hh" namespace ob { @@ -254,7 +255,11 @@ private: //! The window is a 'fullscreen' window, and should be on top of all others bool _fullscreen; //! The window should be on top of other windows of the same type - bool _floating; + bool _above; + //! The window should be underneath other windows of the same type + bool _below; + + OBScreen::StackLayer _layer; //! A bitmask of values in the OBClient::Decoration enum /*! @@ -293,6 +298,9 @@ private: //! Adjusts the window's net_state void setState(StateAction action, long data1, long data2); + //! Calculates the stacking layer for the client window + void calcLayer(); + //! Update the protocols that the window supports and adjusts things if they //! change void updateProtocols(); @@ -396,17 +404,8 @@ public: inline bool maxVert() const { return _max_vert; } //! Returns if the window is maximized horizontally inline bool maxHorz() const { return _max_horz; } - //! Returns if the window is fullscreen - /*! - When the window is fullscreen, it is kept above all others - */ - inline bool fullscreen() const { return _fullscreen; } - //! Returns if the window is floating - /*! - When the window is floating, it is kept above all others in the same - stacking layer as it - */ - inline bool floating() const { return _floating; } + //! Returns the window's stacking layer + inline OBScreen::StackLayer layer() const { return _layer; } //! Removes or reapplies the client's border to its window /*! diff --git a/src/openbox_wrap.cc b/src/openbox_wrap.cc index bbdbaa86..ffe61d6a 100644 --- a/src/openbox_wrap.cc +++ b/src/openbox_wrap.cc @@ -1560,6 +1560,44 @@ static PyObject *_wrap_OBScreen_unmanageWindow(PyObject *self, PyObject *args) { } +static PyObject *_wrap_OBScreen_raise(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; + ob::OBClient *arg2 = (ob::OBClient *) 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_raise",&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; + (arg1)->raise(arg2); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_OBScreen_lower(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; + ob::OBClient *arg2 = (ob::OBClient *) 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_lower",&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; + (arg1)->lower(arg2); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + static PyObject * OBScreen_swigregister(PyObject *self, PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char*)"O", &obj)) return NULL; @@ -2132,32 +2170,15 @@ static PyObject *_wrap_OBClient_maxHorz(PyObject *self, PyObject *args) { } -static PyObject *_wrap_OBClient_fullscreen(PyObject *self, PyObject *args) { - PyObject *resultobj; - ob::OBClient *arg1 = (ob::OBClient *) 0 ; - bool result; - PyObject * obj0 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"O:OBClient_fullscreen",&obj0)) goto fail; - if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - result = (bool)((ob::OBClient const *)arg1)->fullscreen(); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_OBClient_floating(PyObject *self, PyObject *args) { +static PyObject *_wrap_OBClient_layer(PyObject *self, PyObject *args) { PyObject *resultobj; ob::OBClient *arg1 = (ob::OBClient *) 0 ; - bool result; + int result; PyObject * obj0 = 0 ; - if(!PyArg_ParseTuple(args,(char *)"O:OBClient_floating",&obj0)) goto fail; + if(!PyArg_ParseTuple(args,(char *)"O:OBClient_layer",&obj0)) goto fail; if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - result = (bool)((ob::OBClient const *)arg1)->floating(); + result = (int)((ob::OBClient const *)arg1)->layer(); resultobj = PyInt_FromLong((long)result); return resultobj; @@ -2646,6 +2667,8 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBScreen_manageExisting", _wrap_OBScreen_manageExisting, METH_VARARGS }, { (char *)"OBScreen_manageWindow", _wrap_OBScreen_manageWindow, METH_VARARGS }, { (char *)"OBScreen_unmanageWindow", _wrap_OBScreen_unmanageWindow, METH_VARARGS }, + { (char *)"OBScreen_raise", _wrap_OBScreen_raise, METH_VARARGS }, + { (char *)"OBScreen_lower", _wrap_OBScreen_lower, METH_VARARGS }, { (char *)"OBScreen_swigregister", OBScreen_swigregister, METH_VARARGS }, { (char *)"MwmHints_flags_set", _wrap_MwmHints_flags_set, METH_VARARGS }, { (char *)"MwmHints_flags_get", _wrap_MwmHints_flags_get, METH_VARARGS }, @@ -2679,8 +2702,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBClient_iconic", _wrap_OBClient_iconic, METH_VARARGS }, { (char *)"OBClient_maxVert", _wrap_OBClient_maxVert, METH_VARARGS }, { (char *)"OBClient_maxHorz", _wrap_OBClient_maxHorz, METH_VARARGS }, - { (char *)"OBClient_fullscreen", _wrap_OBClient_fullscreen, METH_VARARGS }, - { (char *)"OBClient_floating", _wrap_OBClient_floating, METH_VARARGS }, + { (char *)"OBClient_layer", _wrap_OBClient_layer, METH_VARARGS }, { (char *)"OBClient_toggleClientBorder", _wrap_OBClient_toggleClientBorder, METH_VARARGS }, { (char *)"OBClient_area", _wrap_OBClient_area, METH_VARARGS }, { (char *)"OBClient_move", _wrap_OBClient_move, METH_VARARGS }, @@ -2789,6 +2811,15 @@ static swig_const_info swig_const_table[] = { { SWIG_PY_INT, (char *)"Openbox_State_Normal", (long) ob::Openbox::State_Normal, 0, 0, 0}, { SWIG_PY_INT, (char *)"Openbox_State_Exiting", (long) ob::Openbox::State_Exiting, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBScreen_event_mask", (long) ob::OBScreen::event_mask, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Icon", (long) ob::OBScreen::Layer_Icon, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Desktop", (long) ob::OBScreen::Layer_Desktop, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Below", (long) ob::OBScreen::Layer_Below, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Normal", (long) ob::OBScreen::Layer_Normal, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Above", (long) ob::OBScreen::Layer_Above, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Top", (long) ob::OBScreen::Layer_Top, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Fullscreen", (long) ob::OBScreen::Layer_Fullscreen, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_Layer_Internal", (long) ob::OBScreen::Layer_Internal, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"OBScreen_NUM_LAYERS", (long) ob::OBScreen::NUM_LAYERS, 0, 0, 0}, { SWIG_PY_INT, (char *)"MwmHints_elements", (long) ob::MwmHints::elements, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBClient_TopLeft", (long) ob::OBClient::TopLeft, 0, 0, 0}, { SWIG_PY_INT, (char *)"OBClient_TopRight", (long) ob::OBClient::TopRight, 0, 0, 0}, diff --git a/src/screen.cc b/src/screen.cc index 0116e470..f510749c 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -26,6 +26,8 @@ extern "C" { #include "python.hh" #include "otk/display.hh" +#include + static bool running; static int anotherWMRunning(Display *display, XErrorEvent *) { printf(_("Another window manager already running on display %s.\n"), @@ -87,7 +89,7 @@ OBScreen::OBScreen(int screen) } } _style.load(sconfig); - + // Set the netwm atoms for geomtery and viewport unsigned long geometry[] = { _info->width(), _info->height() }; @@ -402,6 +404,9 @@ void OBScreen::manageWindow(Window window) // add to the screen's list clients.push_back(client); + // this puts into the stacking order, then raises it + _stacking.push_back(client); + raise(client); // update the root properties setClientList(); @@ -447,7 +452,8 @@ void OBScreen::unmanageWindow(OBClient *client) delete client->frame; client->frame = 0; - // remove from the screen's list + // remove from the screen's lists + _stacking.remove(client); clients.remove(client); delete client; @@ -455,4 +461,56 @@ void OBScreen::unmanageWindow(OBClient *client) setClientList(); } +void OBScreen::raise(OBClient *client) +{ + const int layer = client->layer(); + std::vector wins; + + _stacking.remove(client); + + // the stacking list is from highest to lowest + + ClientList::iterator it = _stacking.begin(), end = _stacking.end(); + // insert the windows above this window + for (; it != end; ++it) { + if ((*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::OBDisplay::display, &wins[0], wins.size()); +} + +void OBScreen::lower(OBClient *client) +{ + const int layer = client->layer(); + std::vector wins; + + _stacking.remove(client); + + // the stacking list is from highest to lowest + + ClientList::iterator it = _stacking.begin(), end = _stacking.end(); + // insert the windows above this window + for (; it != end; ++it) { + if ((*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::OBDisplay::display, &wins[0], wins.size()); +} + } diff --git a/src/screen.hh b/src/screen.hh index 14e81111..ce6d6dea 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -43,7 +43,19 @@ public: ButtonPressMask | ButtonReleaseMask; - //! All managed clients on the screen + enum StackLayer { + Layer_Icon, // 0 - iconified windows, in any order at all + Layer_Desktop, // 1 - desktop windows + Layer_Below, // 2 - normal windows w/ below + Layer_Normal, // 3 - normal windows + Layer_Above, // 4 - normal windows w/ above + Layer_Top, // 5 - always-on-top-windows (docks?) + Layer_Fullscreen, // 6 - fullscreeen windows + Layer_Internal, // 7 - openbox windows/menus + NUM_LAYERS + }; + + //! All managed clients on the screen (in order of being mapped) ClientList clients; private: @@ -76,7 +88,9 @@ private: //! An offscreen window which gets focus when nothing else has it Window _focuswindow; - + + //! A list of all managed clients on the screen, in their stacking order + ClientList _stacking; //! Calculate the OBScreen::_area member void calcArea(); @@ -96,7 +110,7 @@ private: Set the _NET_WORKAREA root window property. */ void setWorkArea(); - + public: #ifndef SWIG //! Constructs a new OBScreen object @@ -138,6 +152,12 @@ public: it, etc. */ void unmanageWindow(OBClient *client); + + //! Raises a client window above all others in its stacking layer + void raise(OBClient *client); + + //! Lowers a client window below all others in its stacking layer + void lower(OBClient *client); }; }